summaryrefslogtreecommitdiffstats
path: root/net.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2013-05-17 23:09:36 +0000
committerRoy Marples <roy@marples.name>2013-05-17 23:09:36 +0000
commit5331b839c9a0feac60ae563b051609eba9a066ab (patch)
tree584fe9f5aafc9250c154618e987c49db0579374e /net.c
parent21701103539f281964a5ccd2ba9ff75b497dae04 (diff)
downloaddhcpcd-5331b839c9a0feac60ae563b051609eba9a066ab.tar.xz
Store IPv6 link local addresses per interface.
Listen to kernel messages to account them. If we don't have a local link address, delay IPv6RS as it just won#t work until we have a local link address.
Diffstat (limited to 'net.c')
-rw-r--r--net.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/net.c b/net.c
index b96f09fd..f6e6e846 100644
--- a/net.c
+++ b/net.c
@@ -42,6 +42,12 @@
# include <net/if_media.h>
#endif
+#include <net/route.h>
+#ifdef __linux__
+# include <asm/types.h> /* for systems with broken headers */
+# include <linux/rtnetlink.h>
+#endif
+
#include <ctype.h>
#include <errno.h>
#include <ifaddrs.h>
@@ -127,6 +133,7 @@ free_interface(struct interface *ifp)
if (ifp == NULL)
return;
dhcp_free(ifp);
+ ipv6_free(ifp);
dhcp6_free(ifp);
ipv6rs_free(ifp);
free_options(ifp->options);
@@ -224,6 +231,9 @@ discover_interfaces(int argc, char * const *argv)
#elif AF_PACKET
const struct sockaddr_ll *sll;
#endif
+#ifdef INET6
+ const struct sockaddr_in6 *sin6;
+#endif
if (getifaddrs(&ifaddrs) == -1)
return NULL;
@@ -417,6 +427,22 @@ discover_interfaces(int argc, char * const *argv)
TAILQ_INSERT_TAIL(ifs, ifp, next);
}
+
+#ifdef INET6
+ /* Capture local link addresses */
+ for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr != NULL &&
+ ifa->ifa_addr->sa_family == AF_INET6)
+ {
+ sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+ /* XXX: Check tentative, etc? */
+ ipv6_handleifa(RTM_NEWADDR, ifs, ifa->ifa_name,
+ &sin6->sin6_addr, 0);
+ }
+ }
+#endif
+
freeifaddrs(ifaddrs);
#ifdef IFLR_ACTIVE