aboutsummaryrefslogtreecommitdiff
path: root/pfinet/main.c
diff options
context:
space:
mode:
authorStefan Siegl <stesie@brokenpipe.de>2007-10-08 21:59:10 +0000
committerStefan Siegl <stesie@brokenpipe.de>2007-10-08 21:59:10 +0000
commit1145e4da1321f80b8f1fe9184bdd8e596f2dcd2a (patch)
treeebdd0cc6a174d8a585fa93fadfbde01c5f4a96ac /pfinet/main.c
parent9ef3092f3172c049beb847d1dca602e2b4b755c5 (diff)
downloadhurd-1145e4da1321f80b8f1fe9184bdd8e596f2dcd2a.tar.gz
hurd-1145e4da1321f80b8f1fe9184bdd8e596f2dcd2a.tar.bz2
hurd-1145e4da1321f80b8f1fe9184bdd8e596f2dcd2a.zip
2007-10-08 Stefan Siegl <stesie@brokenpipe.de>
* config.h (CONFIG_IPV6, CONFIG_IPV6_EUI64): New defines, set to 1. * Makefile (ipv6-srcs): New variable. (LINUXSRCS): Add ipv6-srcs. * ethernet.c (ethernet_demuxer): Call skb_put instead of changing skb->len directly, and thus now update skb->tail accordingly. * pfinet.h (PORTCLASS_INET, PORTCLASS_INET6): New enums. (trivfs_protid_portclasses, trivfs_protid_nportclasses) (trivfs_cntl_portclasses, trivfs_cntl_nportclasses): Declare these. (pfinet_bootstrap_portclass): New variable. (pfinet_bind): New function. * main.c: Define _HACK_ERRNO_H. Include <errno.h>. (trivfs_protid_portclasses, trivfs_cntl_portclasses): New slots for PORTCLASS_INET6. (trivfs_protid_nportclasses, trivfs_cntl_nportclasses): Set to 2. (pfinet_bootstrap_portclass): New variable. (pfinet_bind): New function. (pfinet_activate_ipv6) [CONFIG_IPV6]: New function. (main) [CONFIG_IPV6]: Call inet6_proto_init. (main): Reordered to allow pfinet to not be started as a translator, if pfinet_bind is used. If started as a translator, treat pfinet_bootstrap_portclass when calling trivfs_startup. * options.c: Include <net/sock.h>, <net/ip6_fib.h>, <net/ip6_route.h> and <net/addrconf.h>. (options): New option `ipv4'. (options) [CONFIG_IPV6]: New options `ipv6', `address6' and `gateway6'. (parse_interface) [CONFIG_IPV6]: Add address6 and gateway6. (parse_hook_add_interface) [CONFIG_IPV6]: Initialize address6 and gateway6. (parse_opt): Parse new args. * socket-ops.c (S_socket_create): Call either net_families[PF_INET]->create or net_families[PF_INET6]->create, depending on receiving master. (S_socket_create_address): Allow creation of AF_INET6 addresses. * glue-include/asm/delay.h: New stub file. * glue-include/linux/ipv6.h: Merged many bits unmodified from Linux header file. * glue-include/linux/in6.h: Likewise. (ipv6mr_ifindex): New define, glue to ipv6mr_interface. * glue-include/linux/socket.h (SOL_IPV6, SOL_ICMPV6): New defines. * linux-src/net/ipv6/addrconf.c (ipv6_find_idev, inet6_addr_add) (inet6_addr_del) [_HURD_]: Make these non-static. (addrconf_set_dstaddr, addrconf_add_ifaddr, addrconf_del_ifaddr) [_HURD_]: Don't define these functions. * linux-src/net/ipv6/route_ipv6.c (ipv6_route_ioctl) [_HURD_]: Likewise. * linux-src/net/ipv6/af_inet6.c (inet6_ioctl) [_HURD_]: Don't define the function, instead #define it to 0. (inet6_proto_init) [_HURD_]: Don't call sit_init. * linux-src/net/ipv6/udp_ipv6.c (udp_ioctl) [_HURD_]: Define to 0. (udp_v6_get_port): Put empty statement after label to silence compiler. * linux-src/net/ipv6/tcp_ipv6.c (tcp_v6_get_port, tcp_v6_rcv): Likewise. * linux-src/net/ipv6/icmpv6.c (icmpv6_rcv): Likewise. (icmpv6_init) [_HURD_]: Don't initialize i_uid and i_gid. * linux-src/net/ipv6/mcast.c (igmp6_init): Likewise. * linux-src/net/ipv6/ndisc.c (ndisc_init): Likewise. * linux-src/net/ipv6/ip6_fib.c (BUG_TRAP): Don't use __FUNCTION__ as a string but a variable, to keep gcc happy. (fib6_walker_list): Make it non-static, to keep gcc happy. * linux-src/net/ipv6/ip6_flowlabel.c (fl_create) [_HURD_]: Drop IPV6_FL_S_USER support, since current->euid is not available.
Diffstat (limited to 'pfinet/main.c')
-rw-r--r--pfinet/main.c174
1 files changed, 141 insertions, 33 deletions
diff --git a/pfinet/main.c b/pfinet/main.c
index 9337b27a..c1e080a6 100644
--- a/pfinet/main.c
+++ b/pfinet/main.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1995,96,97,99,2000,02 Free Software Foundation, Inc.
+ Copyright (C) 1995,96,97,99,2000,02,07 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -29,24 +29,40 @@
#include <fcntl.h>
#include <version.h>
+/* Include Hurd's errno.h file, but don't include glue-include/hurd/errno.h,
+ since it #undef's the errno macro. */
+#define _HACK_ERRNO_H
+#include <errno.h>
+
#include <linux/netdevice.h>
#include <linux/inet.h>
+static void pfinet_activate_ipv6 (void);
+
/* devinet.c */
extern error_t configure_device (struct device *dev,
uint32_t addr, uint32_t netmask,
uint32_t peer, uint32_t broadcast);
+/* addrconf.c */
+extern int addrconf_notify(struct notifier_block *this, unsigned long event,
+ void * data);
+
int trivfs_fstype = FSTYPE_MISC;
int trivfs_fsid;
int trivfs_support_read = 1;
int trivfs_support_write = 1;
int trivfs_support_exec = 0;
int trivfs_allow_open = O_READ | O_WRITE;
-struct port_class *trivfs_protid_portclasses[1];
-int trivfs_protid_nportclasses = 1;
-struct port_class *trivfs_cntl_portclasses[1];
-int trivfs_cntl_nportclasses = 1;
+
+struct port_class *trivfs_protid_portclasses[2];
+int trivfs_protid_nportclasses = 2;
+
+struct port_class *trivfs_cntl_portclasses[2];
+int trivfs_cntl_nportclasses = 2;
+
+/* Which portclass to install on the bootstrap port, default to IPv4. */
+int pfinet_bootstrap_portclass = PORTCLASS_INET;
struct port_class *shutdown_notify_class;
@@ -224,6 +240,7 @@ enumerate_devices (error_t (*fun) (struct device *dev))
extern void sk_init (void), skb_init (void);
extern int net_dev_init (void);
+extern void inet6_proto_init (struct net_proto *pro);
int
main (int argc,
@@ -234,8 +251,6 @@ main (int argc,
struct stat st;
pfinet_bucket = ports_create_bucket ();
- trivfs_protid_portclasses[0] = ports_create_class (trivfs_clean_protid, 0);
- trivfs_cntl_portclasses[0] = ports_create_class (trivfs_clean_cntl, 0);
addrport_class = ports_create_class (clean_addrport, 0);
socketport_class = ports_create_class (clean_socketport, 0);
trivfs_fsid = getpid ();
@@ -276,36 +291,59 @@ main (int argc,
(And when not sucessful, it never returns.) */
argp_parse (&pfinet_argp, argc, argv, 0,0,0);
- /* Ask init to tell us when the system is going down,
- so we can try to be friendly to our correspondents on the network. */
- arrange_shutdown_notification ();
-
- /* Talk to parent and link us in. */
task_get_bootstrap_port (mach_task_self (), &bootstrap);
- if (bootstrap == MACH_PORT_NULL)
- error (1, 0, "Must be started as a translator");
- err = trivfs_startup (bootstrap, 0,
- trivfs_cntl_portclasses[0], pfinet_bucket,
- trivfs_protid_portclasses[0], pfinet_bucket,
- &pfinetctl);
+ pfinet_owner = pfinet_group = 0;
- if (err)
- error (1, err, "contacting parent");
+ if (bootstrap != MACH_PORT_NULL) {
+ /* Create portclass to install on the bootstrap port. */
+ if(trivfs_protid_portclasses[pfinet_bootstrap_portclass]
+ != MACH_PORT_NULL)
+ error(1, 0, "No portclass left to assign to bootstrap port");
- /* Initialize status from underlying node. */
- err = io_stat (pfinetctl->underlying, &st);
- if (err)
- {
- /* We cannot stat the underlying node. Fallback to the defaults. */
- pfinet_owner = pfinet_group = 0;
- err = 0;
- }
- else
- {
- pfinet_owner = st.st_uid;
- pfinet_group = st.st_gid;
- }
+#ifdef CONFIG_IPV6
+ if (pfinet_bootstrap_portclass == PORTCLASS_INET6)
+ pfinet_activate_ipv6 ();
+#endif
+
+ trivfs_protid_portclasses[pfinet_bootstrap_portclass] =
+ ports_create_class (trivfs_clean_protid, 0);
+ trivfs_cntl_portclasses[pfinet_bootstrap_portclass] =
+ ports_create_class (trivfs_clean_cntl, 0);
+
+ /* Talk to parent and link us in. */
+ err = trivfs_startup (bootstrap, 0,
+ trivfs_cntl_portclasses[pfinet_bootstrap_portclass],
+ pfinet_bucket, trivfs_protid_portclasses
+ [pfinet_bootstrap_portclass], pfinet_bucket,
+ &pfinetctl);
+
+ if (err)
+ error (1, err, "contacting parent");
+
+ /* Initialize status from underlying node. */
+ err = io_stat (pfinetctl->underlying, &st);
+ if (! err)
+ {
+ pfinet_owner = st.st_uid;
+ pfinet_group = st.st_gid;
+ }
+ }
+ else { /* no bootstrap port. */
+ int i;
+ /* Check that at least one portclass has been bound,
+ error out otherwise. */
+ for (i = 0; i < trivfs_protid_nportclasses; i ++)
+ if (trivfs_protid_portclasses[i] != MACH_PORT_NULL)
+ break;
+
+ if (i == trivfs_protid_nportclasses)
+ error (1, 0, "should be started as a translator.\n");
+ }
+
+ /* Ask init to tell us when the system is going down,
+ so we can try to be friendly to our correspondents on the network. */
+ arrange_shutdown_notification ();
/* Launch */
ports_manage_port_operations_multithread (pfinet_bucket,
@@ -314,6 +352,76 @@ main (int argc,
return 0;
}
+#ifdef CONFIG_IPV6
+static void
+pfinet_activate_ipv6 (void)
+{
+ inet6_proto_init (0);
+
+ /* Since we're registering the protocol after the devices have been
+ initialized, we need to care for the linking by ourselves. */
+ struct device *dev = dev_base;
+
+ if (dev)
+ do
+ {
+ if (!(dev->flags & IFF_UP))
+ continue;
+
+ addrconf_notify (NULL, NETDEV_REGISTER, dev);
+ addrconf_notify (NULL, NETDEV_UP, dev);
+ }
+ while ((dev = dev->next));
+}
+#endif /* CONFIG_IPV6 */
+
+void
+pfinet_bind (int portclass, const char *name)
+{
+ struct trivfs_control *cntl;
+ error_t err = 0;
+ mach_port_t right;
+ file_t file = file_name_lookup (name, O_CREAT|O_NOTRANS, 0666);
+
+ if (file == MACH_PORT_NULL)
+ err = errno;
+
+ if (! err) {
+ if (trivfs_protid_portclasses[portclass] != MACH_PORT_NULL)
+ error (1, 0, "Cannot bind one protocol to multiple nodes.\n");
+
+#ifdef CONFIG_IPV6
+ if (portclass == PORTCLASS_INET6)
+ pfinet_activate_ipv6 ();
+#endif
+
+ trivfs_protid_portclasses[portclass] =
+ ports_create_class (trivfs_clean_protid, 0);
+ trivfs_cntl_portclasses[portclass] =
+ ports_create_class (trivfs_clean_cntl, 0);
+
+ err = trivfs_create_control (file, trivfs_cntl_portclasses[portclass],
+ pfinet_bucket,
+ trivfs_protid_portclasses[portclass],
+ pfinet_bucket, &cntl);
+ }
+
+ if (! err)
+ {
+ right = ports_get_send_right (cntl);
+ err = file_set_translator (file, 0, FS_TRANS_EXCL | FS_TRANS_SET,
+ 0, 0, 0, right, MACH_MSG_TYPE_COPY_SEND);
+ mach_port_deallocate (mach_task_self (), right);
+ }
+
+ if (err)
+ error (1, err, name);
+
+ ports_port_deref (cntl);
+
+}
+
+
void
trivfs_modify_stat (struct trivfs_protid *cred,
struct stat *st)