Hi,
this weekend i took Marco Gerards [1] as it is included in the debian
hurd source package. In order to make the routing for the dhcp renew
work. I do always add an route for 0.0.0.0 and the dhcp ports to the
devices. 

But now, when the /etc/dhclient-script calls fsysopts it will override
all other device informations, e.g. ipv6 addresses, gateways on other
devices. So i changed the commandline/fsysopts interface of pfinet a
little bit: when we call `fsysopts /servers/socket/2 -i eth0 -a
192.168.7.1` the address of eth1 isn't deleted anymore, but only the
address of eth0 is changed. All other values will be preserved.

I also made a few changes to the pfinet command line in order make 
pfinet work better with multiple interfaces. Now the -i INTERFACE
selects an interface to configure. After selecting the options like -a,
-g are passed. An example:

fsysopt /servers/socket/2 \
  -i eth0 \
    -a192.168.7.2 \
    -g192.168.7.1 \
    -m255.255.255.0 \
  -i eth1 \
    -a10.0.0.2 \
    -g10.0.0.1 \
    -m255.0.0.0 

The whitespaces beetween -a and the ip are missing because -a, -g, -m,
-p, -A, -G have only optional arguments. If the argument is no passed
the value will be unset e.g. the gateway. Because of this we have also
to modify the /etc/dhclient-script.

#v+
--- dhclient-script.dpkg-new    2007-06-13 03:57:40.010000000 +0200
+++ dhclient-script     2007-10-14 14:24:54.470000000 +0200
@@ -99,7 +99,6 @@ if [ x$reason = xMEDIUM ]; then
 fi
 
 if [ x$reason = xPREINIT ]; then
-  settrans -afg /servers/socket/2 /hurd/pfinet --dhcp -i $interface
   exit_with_hooks 0
 fi
 
@@ -130,7 +129,7 @@ if [ x$reason = xBOUND ] || [ x$reason =
     #route add -net $new_network_number $new_subnet_arg dev $interface
     fi
     for router in $new_routers; do
-      fsysopts /servers/socket/2 -i $interface -a $new_ip_address -m 
$new_subnet_mask -g $router
+      fsysopts /servers/socket/2 -i $interface -a$new_ip_address 
-m$new_subnet_mask -g$router
     done
   fi
   if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
#v-

To demonstrate this behaviour a little bit i wrote an very simple
ifconfig like configuration tool to set the .e.g. the ip.

regards,
  didi

[1] [EMAIL PROTECTED]
#!/bin/sh

FSYSOPTS=/bin/fsysopts
DSOCKET=/servers/socket/2
PFINET=/hurd/pfinet
DEFAULT_INTERFACE=eth0

# test if there is an pfinet on /servers/socket/2 
if ! $FSYSOPTS $DSOCKET | grep -q pfinet; then
  settrans -fga $DSOCKET $PFINET -i $DEFAULT_INTERFACE -d 
  $FSYSOPTS $DSOCKET -i $DEFAULT_INTERFACE -6 ${DSOCKET}6
fi



usage() {
  echo "$0 [-6] INTERFACE IP  -  set the ip (or ipv6) address of this device"
  echo "$0 [-6] INTERFACE gateway IP - set the default gateway of this device"
  echo "$0 INTERFACE nm MASK - set the netmask of this device"
  echo "$0 INTERFACE down - unset the (global) ip and the default gateway 
      of this device"
}

ipv4() {
  echo "$1" | grep -q "^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$"
}

ipv6() {
  echo "$1" | grep -q "^[0-9a-fA-F]*:[0-9a-fA-F]*"
}

get_interfaces() {
  $FSYSOPTS $DSOCKET | tr ' ' '\n' | sed -n 's/--interface=\([^ ]*\)/\1/p'
}
show_interface() {
  echo $1
  $FSYSOPTS $DSOCKET |  tr ' ' '\n' | \
    sed -n '/^--interface='"$1"'$/,/--interface/ {
      s/^--address=\([^ ]*\)/  Address: \1/p
      s/^--gateway=\([^ ]*\)/  Default Gateway: \1/p
      s/^--netmask=\([^ ]*\)/  Netmask: \1/p
      s/^--address6=\(fe80[^ ]*\)/  inet6 address: \1 (link local)/p
      s/^--address6=\([^ ]*\)/  inet6 address: \1 (global)/p
      s/^--gateway6=\([^ ]*\)/  inet6 gateway: \1/p
    }
    '
}

if [ "x$1" = "x--help" -o "x$1" = "x-h" ]; then
  usage
  exit 0
fi

if [ -z "$1" ]; then
  for ifname in `get_interfaces`; do
    show_interface $ifname
  done
else
  if [ "x$1" = "x-6" ]; then
    V6=true
    shift
  fi
  ifname="$1"
  if [ -z "$2" ]; then
    show_interface $ifname
  elif [ "x$2" = "xgateway" -o "x$2" = "xgw" ]; then
    if [ "x$V6" = "xtrue" ]; then
      if ipv6 "$3"; then
        $FSYSOPTS $DSOCKET -i $ifname -G$3
      else
        echo "No valid address"
      fi
    else
      if ipv4 "$3"; then
        $FSYSOPTS $DSOCKET -i $ifname -g$3
      else
        echo "No valid address"
      fi
    fi
  elif [ "x$2" = "xnetmask" -o "x$2" = "xnm" ]; then
    if ipv4 "$3"; then
      $FSYSOPTS $DSOCKET -i $ifname -m$3
    else
      if [ "x$V6" = "xtrue" ]; then
        echo "There are no real netmasks in ipv6"
      else
        echo "No valid netmask"
      fi
    fi
  elif [ "x$2" = "xup" ]; then
    if [ "x$V6" = "xtrue" ]; then
      $FSYSOPTS $DSOCKET -i $ifname -6 /servers/socket/26
    fi
  elif [ "x$2" = "xdown" ]; then
    if [ "x$V6" = "xtrue" ]; then
      $FSYSOPTS $DSOCKET -i $ifname -A
    else
      $FSYSOPTS $DSOCKET -i $ifname -d
    fi
  elif ipv4 "$2"; then
      $FSYSOPTS $DSOCKET -i $ifname -a$2
  elif ipv6 "$2"; then
      $FSYSOPTS $DSOCKET -i $ifname -A$2
  else
    echo "invalid options"
  fi
fi
Index: ChangeLog
===================================================================
RCS file: /sources/hurd/hurd/pfinet/ChangeLog,v
retrieving revision 1.86
diff -u -p -r1.86 ChangeLog
--- ChangeLog	14 Oct 2007 02:26:10 -0000	1.86
+++ ChangeLog	14 Oct 2007 12:23:33 -0000
@@ -1,3 +1,28 @@
+2007-10-14  Christian Dietrich  <[EMAIL PROTECTED]>
+	* options.c (options): Marked -a, -g -m, -p, -A, -G
+	OPTION_ARG_OPTIONAL. Adding -d option.
+	(parse_interface_copy_device): New function.
+	(parse_opt): When selecting another interface with -i 
+	set the options from e.g. a prior fsysopts call as default
+	values. For -a, -g, -p, -g, -A, -G set the optional 
+	argument as value. When there is no argument, delete the
+	value (e.g. unset default gateway). Delete delete default gateways
+	only if the set gateway is on an interface modified in this call.
+	Add always an route for dhcp packages on all devices. By doing
+	this we can send dhcp renew packages.
+	(trivfs_append_args): Add --gateway only once.
+
+2007-10-14  Marco Gerards  <[EMAIL PROTECTED]>
+	* options.c (options): Add the option `dhcp'.
+	(parse_hook_add_interface): Initialize the `dhcp' member for the
+	parse hook.
+	(parse_opt): In case pfinet is started with the argument `--dhcp',
+	set the address to `0.0.0.0', the netmask to `255.0.0.0' and add
+	the route for `0.0.0.0' so broadcasting works.
+
+	* linux-src/net/ipv4/devinet.c (inet_insert_ifa) [_HURD_]: Don't
+	fail when the address is `0.0.0.0'.
+      
 2007-10-14  Stefan Siegl  <[EMAIL PROTECTED]>
 
 	* options.c (ipv6_get_dflt_router) [CONFIG_IPV6]: New function.
Index: options.c
===================================================================
RCS file: /sources/hurd/hurd/pfinet/options.c,v
retrieving revision 1.14
diff -u -p -r1.14 options.c
--- options.c	14 Oct 2007 02:26:10 -0000	1.14
+++ options.c	14 Oct 2007 12:23:35 -0000
@@ -66,16 +66,17 @@ static const struct argp_option options[
 {
   {"interface", 'i', "DEVICE",  0,  "Network interface to use", 1},
   {0,0,0,0,"These apply to a given interface:", 2},
-  {"address",   'a', "ADDRESS", 0, "Set the network address"},
-  {"netmask",   'm', "MASK",    0, "Set the netmask"},
-  {"peer",      'p', "ADDRESS", 0, "Set the peer address"},
-  {"gateway",   'g', "ADDRESS", 0, "Set the default gateway"},
+  {"address",   'a', "ADDRESS", OPTION_ARG_OPTIONAL, "Set the network address"},
+  {"netmask",   'm', "MASK",    OPTION_ARG_OPTIONAL, "Set the netmask"},
+  {"peer",      'p', "ADDRESS", OPTION_ARG_OPTIONAL, "Set the peer address"},
+  {"gateway",   'g', "ADDRESS", OPTION_ARG_OPTIONAL, "Set the default gateway"},
   {"ipv4",      '4', "NAME",    0, "Put active IPv4 translator on NAME"},
 #ifdef CONFIG_IPV6  
   {"ipv6",      '6', "NAME",    0, "Put active IPv6 translator on NAME"},
-  {"address6",  'A', "ADDR/LEN",0, "Set the global IPv6 address"},
-  {"gateway6",  'G', "ADDRESS", 0, "Set the IPv6 default gateway"},
+  {"address6",  'A', "ADDR/LEN",OPTION_ARG_OPTIONAL, "Set the global IPv6 address"},
+  {"gateway6",  'G', "ADDRESS", OPTION_ARG_OPTIONAL, "Set the IPv6 default gateway"},
 #endif
+  {"dhcp",	'd', 0	      , 0, "Prepare pfinet for dhcp"},
   {"shutdown",  's', 0,         0, "Shut it down"},
   {0}
 };
@@ -112,6 +113,53 @@ struct parse_hook
   struct parse_interface *curint;
 };
 
+static void
+parse_interface_copy_device(struct device *src,
+                            struct parse_interface *dst)
+{
+  uint32_t broad;
+  struct rt_key key = { 0 };
+  struct inet6_dev *idev = NULL;
+  struct fib_result res;
+
+  inquire_device (src, &dst->address, &dst->netmask, 
+                  &dst->peer, &broad);
+  /* Get gateway */
+  dst->gateway = INADDR_NONE;
+  key.oif = src->ifindex;
+  if (! main_table->tb_lookup (main_table, &key, &res)
+      && FIB_RES_GW(res) != INADDR_ANY)
+    dst->gateway = FIB_RES_GW (res);
+#ifdef CONFIG_IPV6
+  if (trivfs_protid_portclasses[PORTCLASS_INET6] != MACH_PORT_NULL)
+    idev = ipv6_find_idev(src);
+
+  if (idev)
+  {
+    struct inet6_ifaddr *ifa = idev->addr_list;
+    struct in6_addr daddr;
+
+    /* Look for IPv6 default route (we use the first ifa->addr as
+       source address), but don't yet push it to the option stack. */
+    memset (&daddr, 0, sizeof(daddr));
+    struct fib6_node *fib = fib6_lookup
+      (&ip6_routing_table, &daddr, &ifa->addr);
+    struct rt6_info *rt6i = fib->leaf;
+    if(rt6i->rt6i_dev == src) 
+      memcpy(&dst->gateway6, &rt6i->rt6i_gateway, sizeof(struct in6_addr));
+    /* Search for global address and set it in dst */
+    do 
+    {
+      if(!IN6_IS_ADDR_LINKLOCAL(&ifa->addr)) {
+        memcpy(&dst->address6, ifa, sizeof(struct inet6_ifaddr));
+        break;
+      }
+    }
+    while ((ifa = ifa->if_next));
+  }
+#endif
+}
+
 /* Adds an empty interface slot to H, and sets H's current interface to it, or
    returns an error. */
 static error_t
@@ -152,6 +200,7 @@ ipv6_get_dflt_router (void)
 #endif /* CONFIG_IPV6 */
 
 
+
 static error_t
 parse_opt (int opt, char *arg, struct argp_state *state)
 {
@@ -185,8 +234,7 @@ parse_opt (int opt, char *arg, struct ar
 
   switch (opt)
     {
-      struct parse_interface *in;
-      uint32_t gateway;
+      struct parse_interface *in, *gw4_in;
 #ifdef CONFIG_IPV6
       struct parse_interface *gw6_in;
       char *ptr;
@@ -212,35 +260,63 @@ parse_opt (int opt, char *arg, struct ar
 	}
       in = h->curint;
 
-      if (! err)
+      if (! err) 
 	err = find_device (arg, &in->device);
+      
       if (err)
 	FAIL (err, 10, err, "%s", arg);
-
+      /* Set old interface values */
+      parse_interface_copy_device(in->device, in);
       break;
 
     case 'a':
-      h->curint->address = ADDR (arg, "address");
-      if (!IN_CLASSA (ntohl (h->curint->address))
-	  && !IN_CLASSB (ntohl (h->curint->address))
-	  && !IN_CLASSC (ntohl (h->curint->address)))
-	{
-	  if (IN_MULTICAST (ntohl (h->curint->address)))
-	    FAIL (EINVAL, 1, 0,
-		  "%s: Cannot set interface address to multicast address",
-		  arg);
-	  else
-	    FAIL (EINVAL, 1, 0,
-		  "%s: Illegal or undefined network address", arg);
-	}
+      if (arg) {
+        h->curint->address = ADDR (arg, "address");
+        if (!IN_CLASSA (ntohl (h->curint->address))
+            && !IN_CLASSB (ntohl (h->curint->address))
+            && !IN_CLASSC (ntohl (h->curint->address)))
+          {
+            if (IN_MULTICAST (ntohl (h->curint->address)))
+              FAIL (EINVAL, 1, 0,
+                    "%s: Cannot set interface address to multicast address",
+                    arg);
+            else
+              FAIL (EINVAL, 1, 0,
+                    "%s: Illegal or undefined network address", arg);
+          }
+      } else { 
+        h->curint->address = ADDR ("0.0.0.0", "address");
+        h->curint->netmask = ADDR ("255.0.0.0", "netmask");
+        h->curint->gateway = INADDR_NONE;
+      }
+      break;
+    case 'd':
+      h->curint->address = ADDR ("0.0.0.0", "address");
+      h->curint->netmask = ADDR ("255.0.0.0", "netmask");
       break;
     case 'm':
-      h->curint->netmask = ADDR (arg, "netmask"); break;
+      if (arg) 
+        h->curint->netmask = ADDR (arg, "netmask"); 
+      else 
+        h->curint->netmask = INADDR_NONE;
+      break;
     case 'p':
-      h->curint->peer = ADDR (arg, "peer"); break;
+      if (arg)
+        h->curint->peer = ADDR (arg, "peer"); 
+      else 
+        h->curint->peer = INADDR_NONE;
+      break;
     case 'g':
-      h->curint->gateway = ADDR (arg, "gateway"); break;
-
+      if (arg) {
+        /* Remove an possible other default gateway */ 
+        for (in = h->interfaces; in < h->interfaces + h->num_interfaces; 
+             in++)
+          in->gateway = INADDR_NONE;
+        h->curint->gateway = ADDR (arg, "gateway");
+      }
+      else 
+        h->curint->gateway = INADDR_NONE;
+      break;
     case '4':
       pfinet_bind (PORTCLASS_INET, arg);
 
@@ -254,36 +330,42 @@ parse_opt (int opt, char *arg, struct ar
       break;
 
     case 'A':
-      if ((ptr = strchr (arg, '/'))) 
-	{
-	  h->curint->address6.prefix_len = atoi (ptr + 1);
-	  if (h->curint->address6.prefix_len > 128) 
-	    FAIL (EINVAL, 1, 0, "%s: The prefix-length is invalid", arg);
-
-	  *ptr = 0;
-	}
-      else
-	{
-	  h->curint->address6.prefix_len = 64;
-	  fprintf (stderr, "No prefix-length given, defaulting to %s/64.\n",
-		   arg);
-	}
-
-      if (inet_pton (AF_INET6, arg, &h->curint->address6.addr) <= 0)
-	PERR (EINVAL, "Malformed address");
-
-      if (IN6_IS_ADDR_MULTICAST (&h->curint->address6.addr))
-	FAIL (EINVAL, 1, 0, "%s: Cannot set interface address to "
-	      "multicast address", arg);
+      if (arg) {
+        if ((ptr = strchr (arg, '/'))) 
+          {
+            h->curint->address6.prefix_len = atoi (ptr + 1);
+            if (h->curint->address6.prefix_len > 128) 
+              FAIL (EINVAL, 1, 0, "%s: The prefix-length is invalid", arg);
+
+            *ptr = 0;
+          }
+        else
+          {
+            h->curint->address6.prefix_len = 64;
+            fprintf (stderr, "No prefix-length given, defaulting to %s/64.\n",
+                     arg);
+          }
+
+        if (inet_pton (AF_INET6, arg, &h->curint->address6.addr) <= 0)
+          PERR (EINVAL, "Malformed address");
+
+        if (IN6_IS_ADDR_MULTICAST (&h->curint->address6.addr))
+          FAIL (EINVAL, 1, 0, "%s: Cannot set interface address to "
+                "multicast address", arg);
+      } else
+        memset (&h->curint->address6, 0, sizeof (struct inet6_ifaddr));
       break;
 
     case 'G':
-      if (inet_pton (AF_INET6, arg, &h->curint->gateway6) <= 0)
-	PERR (EINVAL, "Malformed gateway");
-
-      if (IN6_IS_ADDR_MULTICAST (&h->curint->gateway6))
-	FAIL (EINVAL, 1, 0, "%s: Cannot set gateway to "
-	      "multicast address", arg);
+      if (arg) {
+        if (inet_pton (AF_INET6, arg, &h->curint->gateway6) <= 0)
+          PERR (EINVAL, "Malformed gateway");
+
+        if (IN6_IS_ADDR_MULTICAST (&h->curint->gateway6))
+          FAIL (EINVAL, 1, 0, "%s: Cannot set gateway to "
+                "multicast address", arg);
+      } else
+        memset (&h->curint->gateway6, 0, sizeof (struct in6_addr));
       break;
 #endif /* CONFIG_IPV6 */
 
@@ -323,20 +405,19 @@ parse_opt (int opt, char *arg, struct ar
 	  /* Specifying a netmask for an address-less interface is a no-no.  */
 	  FAIL (EDESTADDRREQ, 14, 0, "Cannot set netmask");
 #endif
-
-      gateway = INADDR_NONE;
 #ifdef CONFIG_IPV6
       gw6_in = NULL;
 #endif
+      gw4_in = NULL;
       for (in = h->interfaces; in < h->interfaces + h->num_interfaces; in++)
 	{
+          /* delete interface if it doesn't match the actual netmask */
+          if (! ( (h->curint->address & h->curint->netmask) 
+                  == (h->curint->gateway & h->curint->netmask))) 
+            h->curint->gateway = INADDR_NONE;
+
 	  if (in->gateway != INADDR_NONE)
-	    {
-	      if (gateway != INADDR_NONE)
-		FAIL (err, 15, 0, "Cannot have multiple default gateways");
-	      gateway = in->gateway;
-	      in->gateway = INADDR_NONE;
-	    }
+              gw4_in = in;
 
 #ifdef CONFIG_IPV6
 	  if (!IN6_IS_ADDR_UNSPECIFIED (&in->gateway6))
@@ -377,24 +458,24 @@ parse_opt (int opt, char *arg, struct ar
 	    continue;
 
 	  /* First let's remove all non-local addresses. */
-	  struct inet6_ifaddr *ifa = idev->addr_list;
-
-	  while (ifa)
-	    {
-	      struct inet6_ifaddr *c_ifa = ifa;
-	      ifa = ifa->if_next;
-
-	      if (IN6_ARE_ADDR_EQUAL (&c_ifa->addr, &in->address6.addr))
-		memset (&in->address6, 0, sizeof (struct inet6_ifaddr));
-
-	      else if (!IN6_IS_ADDR_LINKLOCAL (&c_ifa->addr)
-		       && !IN6_IS_ADDR_SITELOCAL (&c_ifa->addr))
-		inet6_addr_del (in->device->ifindex, &c_ifa->addr,
-				c_ifa->prefix_len);
-	    }
-
-	  if (!IN6_IS_ADDR_UNSPECIFIED (&in->address6.addr))
-	    {
+ 	  struct inet6_ifaddr *ifa = idev->addr_list;
+ 
+ 	  while (ifa)
+  	    {
+ 	      struct inet6_ifaddr *c_ifa = ifa;
+ 	      ifa = ifa->if_next;
+ 
+ 	      if (IN6_ARE_ADDR_EQUAL (&c_ifa->addr, &in->address6.addr))
+ 		memset (&in->address6, 0, sizeof (struct inet6_ifaddr));
+  
+ 	      else if (!IN6_IS_ADDR_LINKLOCAL (&c_ifa->addr)
+ 		       && !IN6_IS_ADDR_SITELOCAL (&c_ifa->addr))
+ 		inet6_addr_del (in->device->ifindex, &c_ifa->addr,
+ 				c_ifa->prefix_len);
+ 	    }
+ 
+ 	  if (!IN6_IS_ADDR_UNSPECIFIED (&in->address6.addr))
+ 	    {
 	      /* Now assign the new address */
 	      inet6_addr_add (in->device->ifindex, &in->address6.addr,
 			      in->address6.prefix_len);
@@ -423,28 +504,35 @@ parse_opt (int opt, char *arg, struct ar
 	req.rtm.rtm_scope = RT_SCOPE_UNIVERSE;
 	req.rtm.rtm_type = RTN_UNICAST;
 	req.rtm.rtm_protocol = RTPROT_STATIC;
-	rta.rta_gw = &gateway;
 
-	if (gateway == INADDR_NONE)
+	if (!gw4_in)
 	  {
-	    /* Delete any existing default route.  */
-	    req.nlh.nlmsg_type = RTM_DELROUTE;
-	    req.nlh.nlmsg_flags = 0;
-	    tb = fib_get_table (req.rtm.rtm_table);
-	    if (tb)
-	      {
-		err = - (*tb->tb_delete) (tb, &req.rtm, &rta, &req.nlh, 0);
-		if (err && err != ESRCH)
-		  {
-		    __mutex_unlock (&global_lock);
-		    FAIL (err, 17, 0, "cannot remove old default gateway");
-		  }
-		err = 0;
-	      }
+	    /* Delete any existing dflt route on configured devices  */
+            for (in = h->interfaces; in < h->interfaces + h->num_interfaces;
+                 in++) {
+              req.nlh.nlmsg_type = RTM_DELROUTE;
+              req.nlh.nlmsg_flags = 0;
+              rta.rta_oif = &in->device->ifindex;
+              tb = fib_get_table (req.rtm.rtm_table);
+              if (tb)
+                {
+                  err = - (*tb->tb_delete) 
+                    (tb, &req.rtm, &rta, &req.nlh, 0);
+                  if (err && err != ESRCH)
+                    {
+                      __mutex_unlock (&global_lock);
+                      FAIL (err, 17, 0, 
+                            "cannot remove old default gateway");
+                    }
+                  err = 0;
+                }
+            }
 	  }
 	else
 	  {
 	    /* Add a default route, replacing any existing one.  */
+            rta.rta_oif = &gw4_in->device->ifindex;
+            rta.rta_gw = &gw4_in->gateway;
 	    req.nlh.nlmsg_type = RTM_NEWROUTE;
 	    req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE;
 	    tb = fib_new_table (req.rtm.rtm_table);
@@ -467,13 +555,69 @@ parse_opt (int opt, char *arg, struct ar
 	  if (!gw6_in || rt6i->rt6i_dev != gw6_in->device
 	      || !IN6_ARE_ADDR_EQUAL (&rt6i->rt6i_gateway, &gw6_in->gateway6))
 	    {
-	      rt6_purge_dflt_routers (0);
+              /* Delete any existing dflt route on configured devices  */
+              for (in = h->interfaces; in < h->interfaces 
+                   + h->num_interfaces; in++) 
+                if (rt6i->rt6i_dev == in->device || gw6_in )
+                  rt6_purge_dflt_routers (0);
+
 	      if (gw6_in)
 		rt6_add_dflt_router (&gw6_in->gateway6, gw6_in->device);
 	    }
 	}
 #endif       
 
+      /*  Setup the routing required for DHCP. */
+      for (in = h->interfaces; in < h->interfaces + h->num_interfaces; in++)
+      {
+        struct kern_rta rta;
+        struct
+        {
+          struct nlmsghdr nlh;
+          struct rtmsg rtm;
+        } req;
+        struct fib_table *tb;
+        struct rtentry route;
+        struct sockaddr_in *dst;
+        struct device *dev;
+
+        dst = (struct sockaddr_in *) &route.rt_dst;
+
+        dev = dev_get (in->device->name);
+        if (!dev)
+        {
+          __mutex_unlock (&global_lock);
+          FAIL (ENODEV, 17, 0, "unknown device");
+        }
+
+        /* Simulate the SIOCADDRT behavior.  */
+        bzero (&route, sizeof (struct rtentry));
+        bzero (&req.rtm, sizeof req.rtm);
+        bzero (&rta, sizeof rta);
+        req.nlh.nlmsg_type = RTM_NEWROUTE;
+        /* Append this routing for 0.0.0.0. By this way we can send always
+         * dhcp messages (e.g dhcp renew 
+         */
+        req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE
+          | NLM_F_APPEND;
+        req.rtm.rtm_protocol = RTPROT_BOOT;
+        req.rtm.rtm_scope = RT_SCOPE_LINK;
+        req.rtm.rtm_type = RTN_UNICAST;
+        rta.rta_dst = &dst->sin_addr.s_addr;
+        rta.rta_oif = &dev->ifindex;
+        tb = fib_new_table (req.rtm.rtm_table);
+        if (tb)
+          err = tb->tb_insert (tb, &req.rtm, &rta, &req.nlh, NULL);
+        else
+          err = ENOBUFS;
+
+        if (err)
+        {
+          __mutex_unlock (&global_lock);
+          FAIL (err, 17, 0, "cannot add route");
+        }
+      }
+
       __mutex_unlock (&global_lock);
 
       /* Fall through to free hook.  */
@@ -526,8 +670,9 @@ trivfs_append_args (struct trivfs_contro
         ADD_ADDR_OPT ("netmask", mask);
       if (peer != addr)
 	ADD_ADDR_OPT ("peer", peer);
-      key.iif = dev->ifindex;
-      if (! main_table->tb_lookup (main_table, &key, &res)) 
+      key.oif = dev->ifindex;
+      if (! main_table->tb_lookup (main_table, &key, &res)
+          && FIB_RES_GW(res) != INADDR_ANY)
 	ADD_ADDR_OPT ("gateway", FIB_RES_GW (res));
 
 #undef ADD_ADDR_OPT
Index: timer-emul.c
===================================================================
RCS file: /sources/hurd/hurd/pfinet/timer-emul.c,v
retrieving revision 1.13
diff -u -p -r1.13 timer-emul.c
--- timer-emul.c	5 May 2002 03:25:53 -0000	1.13
+++ timer-emul.c	14 Oct 2007 12:23:35 -0000
@@ -132,7 +132,7 @@ del_timer (struct timer_list *timer)
       timer->prev = 0;
       return 1;
     }
-  else
+  else 
     return 0;
 }
 
Index: linux-src/net/ipv4/devinet.c
===================================================================
RCS file: /sources/hurd/hurd/pfinet/linux-src/net/ipv4/devinet.c,v
retrieving revision 1.8
diff -u -p -r1.8 devinet.c
--- linux-src/net/ipv4/devinet.c	18 Jul 2001 17:37:13 -0000	1.8
+++ linux-src/net/ipv4/devinet.c	14 Oct 2007 12:23:40 -0000
@@ -214,10 +214,12 @@ inet_insert_ifa(struct in_device *in_dev
 {
 	struct in_ifaddr *ifa1, **ifap, **last_primary;
 
+#ifndef _HURD_
 	if (ifa->ifa_local == 0) {
 		inet_free_ifa(ifa);
 		return 0;
 	}
+#endif
 
 	ifa->ifa_flags &= ~IFA_F_SECONDARY;
 	last_primary = &in_dev->ifa_list;
_______________________________________________
Bug-hurd mailing list
Bug-hurd@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-hurd

Reply via email to