diff options
author | Stefan Siegl <stesie@brokenpipe.de> | 2007-10-14 02:26:10 +0000 |
---|---|---|
committer | Stefan Siegl <stesie@brokenpipe.de> | 2007-10-14 02:26:10 +0000 |
commit | c1b43b0f2d28f6c103d1170cf064a86d6e4fd26c (patch) | |
tree | 48272bbda491e4efe44079fffc9a81adce97912e | |
parent | fe7832186ac403d2cf71c6429973a698d5fc0bf5 (diff) |
2007-10-14 Stefan Siegl <stesie@brokenpipe.de>
* options.c (ipv6_get_dflt_router) [CONFIG_IPV6]: New function.
(parse_opt) [CONFIG_IPV6]: Don't delete IPv6 interface address, if
it would be re-added immediately, but delete if otherwise.
Do not touch inet6_ifaddr after inet6_addr_del was called.
Don't purge and re-add IPv6 default router unless necessary.
(trivfs_append_args) [CONFIG_IPV6]: Use ipv6_get_dflt_router.
* linux-src/net/ipv6/addrconf.c (ipv6_del_addr): Call del_timer
on ifp->timer.
-rw-r--r-- | pfinet/ChangeLog | 11 | ||||
-rw-r--r-- | pfinet/linux-src/net/ipv6/addrconf.c | 3 | ||||
-rw-r--r-- | pfinet/options.c | 60 |
3 files changed, 53 insertions, 21 deletions
diff --git a/pfinet/ChangeLog b/pfinet/ChangeLog index aaa63a85..3549813a 100644 --- a/pfinet/ChangeLog +++ b/pfinet/ChangeLog @@ -1,3 +1,14 @@ +2007-10-14 Stefan Siegl <stesie@brokenpipe.de> + + * options.c (ipv6_get_dflt_router) [CONFIG_IPV6]: New function. + (parse_opt) [CONFIG_IPV6]: Don't delete IPv6 interface address, if + it would be re-added immediately, but delete if otherwise. + Do not touch inet6_ifaddr after inet6_addr_del was called. + Don't purge and re-add IPv6 default router unless necessary. + (trivfs_append_args) [CONFIG_IPV6]: Use ipv6_get_dflt_router. + * linux-src/net/ipv6/addrconf.c (ipv6_del_addr): Call del_timer + on ifp->timer. + 2007-10-13 Marco Gerards <metgerards@student.han.nl> * iioctl-ops.c (S_iioctl_siocgifhwaddr): New function. diff --git a/pfinet/linux-src/net/ipv6/addrconf.c b/pfinet/linux-src/net/ipv6/addrconf.c index 7fbf4061..e72c382c 100644 --- a/pfinet/linux-src/net/ipv6/addrconf.c +++ b/pfinet/linux-src/net/ipv6/addrconf.c @@ -5,7 +5,7 @@ * Authors: * Pedro Roque <roque@di.fc.ul.pt> * - * $Id: addrconf.c,v 1.2 2007/10/08 21:59:10 stesie Exp $ + * $Id: addrconf.c,v 1.3 2007/10/14 02:26:10 stesie Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -367,6 +367,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) } ipv6_ifa_notify(RTM_DELADDR, ifp); + del_timer(&ifp->timer); kfree(ifp); } diff --git a/pfinet/options.c b/pfinet/options.c index 85738a5b..d0a1ff2b 100644 --- a/pfinet/options.c +++ b/pfinet/options.c @@ -138,6 +138,19 @@ parse_hook_add_interface (struct parse_hook *h) return 0; } + +#ifdef CONFIG_IPV6 +static struct rt6_info * +ipv6_get_dflt_router (void) +{ + struct in6_addr daddr = { 0 }; + + struct fib6_node *fib = fib6_lookup + (&ip6_routing_table, &daddr, NULL); + return fib->leaf; +} +#endif /* CONFIG_IPV6 */ + static error_t parse_opt (int opt, char *arg, struct argp_state *state) @@ -363,17 +376,25 @@ parse_opt (int opt, char *arg, struct argp_state *state) if (!idev) continue; - if (!IN6_IS_ADDR_UNSPECIFIED (&in->address6.addr)) + /* First let's remove all non-local addresses. */ + struct inet6_ifaddr *ifa = idev->addr_list; + + while (ifa) { - /* First let's remove all non-local addresses. */ - struct inet6_ifaddr *ifa = idev->addr_list; - do - if (!IN6_IS_ADDR_LINKLOCAL (&ifa->addr) - && !IN6_IS_ADDR_SITELOCAL (&ifa->addr)) - inet6_addr_del (in->device->ifindex, &ifa->addr, - ifa->prefix_len); - while ((ifa = ifa->if_next)); + 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); @@ -441,9 +462,15 @@ parse_opt (int opt, char *arg, struct argp_state *state) #ifdef CONFIG_IPV6 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); + struct rt6_info *rt6i = ipv6_get_dflt_router (); + + if (!gw6_in || rt6i->rt6i_dev != gw6_in->device + || !IN6_ARE_ADDR_EQUAL (&rt6i->rt6i_gateway, &gw6_in->gateway6)) + { + rt6_purge_dflt_routers (0); + if (gw6_in) + rt6_add_dflt_router (&gw6_in->gateway6, gw6_in->device); + } } #endif @@ -514,16 +541,8 @@ trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len) if (idev) { struct inet6_ifaddr *ifa = idev->addr_list; - struct in6_addr daddr; static char addr_buf[INET6_ADDRSTRLEN]; - /* 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; - /* Push all IPv6 addresses assigned to the interface. */ do { @@ -533,6 +552,7 @@ trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len) while ((ifa = ifa->if_next)); /* Last not least push --gateway6 option. */ + struct rt6_info *rt6i = ipv6_get_dflt_router (); if(rt6i->rt6i_dev == dev) { inet_ntop (AF_INET6, &rt6i->rt6i_gateway, addr_buf, |