summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Siegl <stesie@brokenpipe.de>2007-10-14 02:26:10 +0000
committerStefan Siegl <stesie@brokenpipe.de>2007-10-14 02:26:10 +0000
commitc1b43b0f2d28f6c103d1170cf064a86d6e4fd26c (patch)
tree48272bbda491e4efe44079fffc9a81adce97912e
parentfe7832186ac403d2cf71c6429973a698d5fc0bf5 (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/ChangeLog11
-rw-r--r--pfinet/linux-src/net/ipv6/addrconf.c3
-rw-r--r--pfinet/options.c60
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,