Hi Thomas!
On Mon, Oct 08, 2007 at 08:31:15PM +0200, Thomas Schwinge wrote:
> [...] Have pfinet include the IPv6 code by default, but
> only activate the IPv6 engine if IPv6 services are actually needed, i.e.,
> if they are requested by the pfinet translator setting. The increase in
> the pfinet translator's executable size does not matter in my opinion.
You're right that it doesn't make much sense to enable the IPv6 protocol
bits, if /servers/socket/26 is not bound. I've now patched pfinet to
to do late (on demand) initialization of the engine, however we now need
to manually care for the protocol <-> device link (see new
pfinet_activate_ipv6 function).
Now you can even first start pfinet (passivly), bound to
/servers/socket/2 only, and then activate the IPv6 engine using:
fsysopts /servers/socket/2 -6 /servers/socket/26 -a ...
It even works the other way round, but IPv6-only (currently) doesn't
make much sense, since DNS is usually configured to happen over IPv4.
cheers,
stesie
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 <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;
@@ -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;
_______________________________________________
Bug-hurd mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-hurd