diff --git a/ChangeLog b/ChangeLog index c95cea7..7fc1aa5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,6 @@ set to 1. * Makefile (ipv6-srcs): New variable. (LINUXSRCS): Add ipv6-srcs. - (target): Set to pfinet6. * ethernet.c (ethernet_demuxer): Call skb_put instead of changing skb->len directly, and thus now update skb->tail accordingly. @@ -20,6 +19,7 @@ (trivfs_protid_nportclasses, trivfs_cntl_nportclasses): Set to 2. (pfinet_bootstrap_portclass): New variable. (pfinet_bind): New function. + (pfinet_active_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, diff --git a/Makefile b/Makefile index 3e8c7a6..9bc97e8 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. -dir := pfinet6 +dir := pfinet makemode := server core-srcs := datagram.c \ @@ -101,7 +101,7 @@ ASMHEADERS=bitops.h segment.h system.h HURDLIBS=trivfs fshelp threads ports ihash shouldbeinlibc iohelp -target = pfinet6 +target = pfinet include ../Makeconf @@ -114,7 +114,7 @@ CPPFLAGS += -imacros $(srcdir)/config.h \ -I$(srcdir)/linux-src/include # Don't ask... We use Linux code. The problem was first noticed when -# compiling `pfinet6' with GCC 4.2. +# compiling `pfinet' with GCC 4.2. CFLAGS += -fno-strict-aliasing asm/checksum.h: ../config.status diff --git a/main.c b/main.c index fbf3f4a..c1e080a 100644 --- a/main.c +++ b/main.c @@ -37,11 +37,17 @@ #include #include +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; @@ -267,10 +273,6 @@ main (int argc, #endif inet_proto_init (0); -#ifdef CONFIG_IPV6 - inet6_proto_init (0); -#endif - /* This initializes the Linux network device layer, including initializing each device on the `dev_base' list. For us, that means just loopback_dev, which will get fully initialized now. @@ -298,6 +300,11 @@ main (int argc, if(trivfs_protid_portclasses[pfinet_bootstrap_portclass] != MACH_PORT_NULL) error(1, 0, "No portclass left to assign to bootstrap port"); + +#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); @@ -345,6 +352,29 @@ 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) { @@ -357,6 +387,14 @@ pfinet_bind (int portclass, const char *name) 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] = diff --git a/options.c b/options.c index 8a9d2a3..85738a5 100644 --- a/options.c +++ b/options.c @@ -343,7 +343,8 @@ parse_opt (int opt, char *arg, struct argp_state *state) { #ifdef CONFIG_IPV6 struct inet6_dev *idev = NULL; - if (in->device) + if (trivfs_protid_portclasses[PORTCLASS_INET6] != MACH_PORT_NULL + && in->device) idev = ipv6_find_idev(in->device); #endif @@ -438,9 +439,12 @@ parse_opt (int opt, char *arg, struct argp_state *state) /* Set IPv6 default router. */ #ifdef CONFIG_IPV6 - rt6_purge_dflt_routers (0); - if (gw6_in) - rt6_add_dflt_router (&gw6_in->gateway6, gw6_in->device); + if (trivfs_protid_portclasses[PORTCLASS_INET6] != MACH_PORT_NULL) + { + rt6_purge_dflt_routers (0); + if (gw6_in) + rt6_add_dflt_router (&gw6_in->gateway6, gw6_in->device); + } #endif __mutex_unlock (&global_lock); @@ -502,7 +506,11 @@ trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len) #undef ADD_ADDR_OPT #ifdef CONFIG_IPV6 - struct inet6_dev *idev = ipv6_find_idev(dev); + struct inet6_dev *idev = NULL; + + if (trivfs_protid_portclasses[PORTCLASS_INET6] != MACH_PORT_NULL) + idev = ipv6_find_idev(dev); + if (idev) { struct inet6_ifaddr *ifa = idev->addr_list;