diff options
author | Michael Banck <mbanck@debian.org> | 2007-11-19 15:16:01 +0000 |
---|---|---|
committer | Michael Banck <mbanck@debian.org> | 2007-11-19 15:16:01 +0000 |
commit | 80b43d2d039465ada92f995060995b05f036dc11 (patch) | |
tree | 2ed86128479e564d8b4b005e09710570c2636b35 | |
parent | 01801d97a7d7cfb167c1fa7f385cc16a7fa19bf2 (diff) |
* debian/patches/pfinet_dhcp.patch: Updated with new patch by Christian
Dietrich.
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | debian/patches/pfinet_dhcp.patch | 571 |
2 files changed, 488 insertions, 85 deletions
diff --git a/debian/changelog b/debian/changelog index 4bfddd8d..f6402f7a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -23,6 +23,8 @@ hurd (20071119-1) UNRELEASED; urgency=low * debian/hurd.dirs: Added servers/socket. * debian/patches/diskfs_no_inherit_dir_group.patch: Update with better patch by Thomas Schwinge. + * debian/patches/pfinet_dhcp.patch: Updated with new patch by Christian + Dietrich. -- Michael Banck <mbanck@debian.org> Thu, 16 Aug 2007 16:55:53 +0200 diff --git a/debian/patches/pfinet_dhcp.patch b/debian/patches/pfinet_dhcp.patch index 39f87a50..e707cdf9 100644 --- a/debian/patches/pfinet_dhcp.patch +++ b/debian/patches/pfinet_dhcp.patch @@ -1,4 +1,19 @@ -2005-01-06 Marco Gerards <metgerards@student.han.nl> +2007-10-14 Christian Dietrich <stettberger@dokucode.de> + + * 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 <metgerards@student.han.nl> * options.c (options): Add the option `dhcp'. (parse_hook_add_interface): Initialize the `dhcp' member for the @@ -9,107 +24,495 @@ * linux-src/net/ipv4/devinet.c (inet_insert_ifa) [_HURD_]: Don't fail when the address is `0.0.0.0'. - - ---- pfinet/options.c.orig 2007-11-19 15:11:07.000000000 +0100 -+++ pfinet/options.c 2007-11-19 15:53:11.000000000 +0100 -@@ -76,6 +76,7 @@ - {"address6", 'A', "ADDR/LEN",0, "Set the global IPv6 address"}, - {"gateway6", 'G', "ADDRESS", 0, "Set the IPv6 default gateway"}, + +Index: options.c +=================================================================== +RCS file: /sources/hurd/hurd/pfinet/options.c,v +retrieving revision 1.14 +diff -p -u -r1.14 options.c +--- pfinet/options.c 14 Oct 2007 02:26:10 -0000 1.14 ++++ pfinet/options.c 22 Oct 2007 20:49:02 -0000 +@@ -60,23 +60,27 @@ extern struct inet6_dev *ipv6_find_idev + extern int inet6_addr_add (int ifindex, struct in6_addr *pfx, int plen); + extern int inet6_addr_del (int ifindex, struct in6_addr *pfx, int plen); + ++#ifdef CONFIG_IPV6 ++static struct rt6_info * ipv6_get_dflt_router (void); ++#endif ++ + + /* Pfinet options. Used for both startup and runtime. */ + static const struct argp_option options[] = + { +- {"interface", 'i', "DEVICE", 0, "Network interface to use", 1}, ++ {"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"}, +- {"ipv4", '4', "NAME", 0, "Put active IPv4 translator on NAME"}, ++ {"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"}, ++ {"ipv6", '6', "NAME", 0, "Put active IPv6 translator on NAME"}, ++ {"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"}, +- {"shutdown", 's', 0, 0, "Shut it down"}, ++ {"shutdown", 's', 0, 0, "Shut it down"}, {0} }; -@@ -93,6 +94,9 @@ - /* New values to apply to it. (IPv4) */ - uint32_t address, netmask, peer, gateway; -+ /* Set to one if the interface is configured for DHCP. */ -+ int dhcp; +@@ -112,6 +116,50 @@ 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; + - #ifdef CONFIG_IPV6 - /* New IPv6 configuration to apply. */ - struct inet6_ifaddr address6; -@@ -130,6 +134,7 @@ - h->curint->netmask = INADDR_NONE; - h->curint->peer = INADDR_NONE; - h->curint->gateway = INADDR_NONE; -+ h->curint->dhcp = 0; ++ 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; ++ ++ /* Look for IPv6 default router and add it to the interface, ++ * if it belongs to it. ++ */ ++ struct rt6_info *rt6i = ipv6_get_dflt_router(); ++ 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 +@@ -185,8 +233,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 - memset (&h->curint->address6, 0, sizeof (struct inet6_ifaddr)); -@@ -234,6 +239,11 @@ - "%s: Illegal or undefined network address", arg); - } + struct parse_interface *gw6_in; + char *ptr; +@@ -216,31 +263,64 @@ parse_opt (int opt, char *arg, struct ar + 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 || ((state->next < state->argc) ++ && (*state->argv[state->next] != '-') ++ ? (arg = state->argv[state->next++]) : 0)) ++ { ++ 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->dhcp = 1; -+ 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; +- h->curint->netmask = ADDR (arg, "netmask"); break; ++ if (arg || ((state->next < state->argc) ++ && (*state->argv[state->next] != '-') ++ ? (arg = state->argv[state->next++]) : 0)) ++ h->curint->netmask = ADDR (arg, "netmask"); ++ else ++ h->curint->netmask = INADDR_NONE; ++ break; case 'p': -@@ -474,6 +484,55 @@ +- h->curint->peer = ADDR (arg, "peer"); break; ++ if (arg || ((state->next < state->argc) ++ && (*state->argv[state->next] != '-') ++ ? (arg = state->argv[state->next++]) : 0)) ++ h->curint->peer = ADDR (arg, "peer"); ++ else ++ h->curint->peer = INADDR_NONE; ++ break; + case 'g': +- h->curint->gateway = ADDR (arg, "gateway"); break; +- ++ if (arg || ((state->next < state->argc) ++ && (*state->argv[state->next] != '-') ++ ? (arg = state->argv[state->next++]) : 0)) ++ { ++ /* 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 +334,48 @@ 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 || ((state->next < state->argc) ++ && (*state->argv[state->next] != '-') ++ ? (arg = state->argv[state->next++]) : 0)) ++ { ++ 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 (arg || ((state->next < state->argc) ++ && (*state->argv[state->next] != '-') ++ ? (arg = state->argv[state->next++]) : 0)) ++ { ++ 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 (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 +415,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 +468,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); +@@ -418,33 +509,40 @@ parse_opt (int opt, char *arg, struct ar + req.nlh.nlmsg_seq = 0; + req.nlh.nlmsg_len = NLMSG_LENGTH (sizeof req.rtm); + +- bzero (&req.rtm, sizeof req.rtm); +- bzero (&rta, sizeof rta); ++ memset (&req.rtm, 0, sizeof req.rtm); ++ memset (&rta, 0, sizeof rta); + 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 default 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 +565,73 @@ 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 default 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++) -+ if (in->dhcp) -+ { -+ 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; -+ req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; -+ 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"); -+ } -+ } -+ ++ { ++ 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; ++ if (!in->device->name) ++ { ++ __mutex_unlock (&global_lock); ++ FAIL (ENODEV, 17, 0, "unknown device"); ++ } ++ dev = dev_get (in->device->name); ++ if (!dev) ++ { ++ __mutex_unlock (&global_lock); ++ FAIL (ENODEV, 17, 0, "unknown device"); ++ } ++ ++ /* Simulate the SIOCADDRT behavior. */ ++ memset (&route, 0, sizeof (struct rtentry)); ++ memset (&req.rtm, 0, sizeof req.rtm); ++ memset (&rta, 0, 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. */ -diff -u -p -r1.8 devinet.c +@@ -526,8 +684,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: linux-src/net/ipv4/devinet.c +=================================================================== +RCS file: /sources/hurd/hurd/pfinet/linux-src/net/ipv4/devinet.c,v +retrieving revision 1.8 +diff -p -u -r1.8 devinet.c --- pfinet/linux-src/net/ipv4/devinet.c 18 Jul 2001 17:37:13 -0000 1.8 -+++ pfinet/linux-src/net/ipv4/devinet.c 6 Jan 2005 18:52:32 -0000 ++++ pfinet/linux-src/net/ipv4/devinet.c 22 Oct 2007 20:49:04 -0000 @@ -214,10 +214,12 @@ inet_insert_ifa(struct in_device *in_dev { struct in_ifaddr *ifa1, **ifap, **last_primary; @@ -123,5 +526,3 @@ diff -u -p -r1.8 devinet.c ifa->ifa_flags &= ~IFA_F_SECONDARY; last_primary = &in_dev->ifa_list; - - |