summaryrefslogtreecommitdiffstats
path: root/ipv6.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2013-05-15 10:27:36 +0000
committerRoy Marples <roy@marples.name>2013-05-15 10:27:36 +0000
commita8df1b28fbc5dd08895418476d58fe11b8fc4def (patch)
tree74c0dd6d5f5789a90cf7b459e563ab6780d824f2 /ipv6.c
parenta83be7a8de4245f7838a2fc5f97d2c7e47edb14a (diff)
downloaddhcpcd-a8df1b28fbc5dd08895418476d58fe11b8fc4def.tar.xz
Use the kernel DAD for IPv6 addresses and finish the action once each
address DAD completes. BSD kernels will require a patch as noted within the README. The linux netlink part still needs to be written.
Diffstat (limited to 'ipv6.c')
-rw-r--r--ipv6.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/ipv6.c b/ipv6.c
index e8752815..5e201b19 100644
--- a/ipv6.c
+++ b/ipv6.c
@@ -28,8 +28,14 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <net/route.h>
#include <netinet/in.h>
+#ifdef __linux__
+# include <asm/types.h> /* for systems with broken headers */
+# include <linux/rtnetlink.h>
+#endif
+
#include <errno.h>
#include <ifaddrs.h>
#include <stdlib.h>
@@ -285,6 +291,49 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs)
return i;
}
+void
+ipv6_handleifa(int cmd, const char *ifname, const struct in6_addr *addr)
+{
+
+ ipv6rs_handleifa(cmd, ifname, addr);
+ dhcp6_handleifa(cmd, ifname, addr);
+}
+
+int
+ipv6_handleifa_addrs(int cmd,
+ struct ipv6_addrhead *addrs, const struct in6_addr *addr)
+{
+ struct ipv6_addr *ap, *apn;
+ uint8_t found, alldadcompleted;
+
+ alldadcompleted = 1;
+ found = 0;
+ TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
+ if (memcmp(addr->s6_addr, ap->addr.s6_addr,
+ sizeof(addr->s6_addr)))
+ {
+ if (ap->dadcompleted == 0)
+ alldadcompleted = 0;
+ continue;
+ }
+ switch (cmd) {
+ case RTM_DELADDR:
+ syslog(LOG_INFO, "%s: deleted address %s",
+ ap->iface->name, ap->saddr);
+ TAILQ_REMOVE(addrs, ap, next);
+ free(ap);
+ break;
+ case RTM_NEWADDR:
+ if (!ap->dadcompleted) {
+ found++;
+ ap->dadcompleted = 1;
+ }
+ }
+ }
+
+ return alldadcompleted ? found : 0;
+}
+
static struct rt6 *
find_route6(struct rt6head *rts, const struct rt6 *r)
{