summaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2013-05-30 05:38:21 +0000
committerRoy Marples <roy@marples.name>2013-05-30 05:38:21 +0000
commitc5d2e393a55539a2c1efe26af61ee944d7a7ed12 (patch)
tree62a5f9468bcdf9e4c86d11a99f36e0a03af7df6a /if-bsd.c
parent28bae8ce393d0add16b9dd344595de6bb8b6e3b0 (diff)
downloaddhcpcd-c5d2e393a55539a2c1efe26af61ee944d7a7ed12.tar.xz
Move SIOCGIFAFLAG_IN6 into if-bsd as in6_addr_flags
Add pfx_flush to flush ND6 entries when changing routes. Both these functions only work for BSD, just stubs on Linux. This tidies the code a little and fixes changing IPv6 routes on BSD, although the kernel may complain network is down for a few moments.
Diffstat (limited to 'if-bsd.c')
-rw-r--r--if-bsd.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/if-bsd.c b/if-bsd.c
index bc3d82fb..7f313423 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -450,6 +450,20 @@ if_route6(const struct rt6 *rt, int action)
retval = -1;
return retval;
}
+
+int
+pfx_flush(void)
+{
+ int s;
+ char dummy[IFNAMSIZ + 1];
+
+ s = socket(AF_INET6, SOCK_DGRAM, 0);
+ if (s != -1) {
+ strcpy(dummy, "lo0");
+ s = ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummy);
+ }
+ return s;
+}
#endif
static void
@@ -472,6 +486,26 @@ get_addrs(int type, char *cp, struct sockaddr **sa)
}
int
+in6_addr_flags(const char *ifname, const struct in6_addr *addr)
+{
+ int s, flags;
+ struct in6_ifreq ifr6;
+
+ s = socket(AF_INET6, SOCK_DGRAM, 0);
+ flags = -1;
+ if (s != -1) {
+ memset(&ifr6, 0, sizeof(ifr6));
+ strncpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
+ ifr6.ifr_addr.sin6_family = AF_INET6;
+ ifr6.ifr_addr.sin6_addr = *addr;
+ if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) != -1)
+ flags = ifr6.ifr_flags;
+ close(s);
+ }
+ return flags;
+}
+
+int
manage_link(int fd)
{
char *p, *e, *cp;
@@ -491,6 +525,7 @@ manage_link(int fd)
#if defined(INET6) && !defined(LISTEN_DAD)
struct in6_addr ia6;
struct sockaddr_in6 *sin6;
+ int ifa_flags;
#endif
for (;;) {
@@ -620,8 +655,16 @@ manage_link(int fd)
memcpy(ia6.s6_addr,
sin6->sin6_addr.s6_addr,
sizeof(ia6.s6_addr));
+ if (rtm->rtm_type == RTM_NEWADDR) {
+ ifa_flags = in6_addr_flags(
+ ifname,
+ &ia6);
+ if (ifa_flags == -1)
+ break;
+ } else
+ ifa_flags = 0;
ipv6_handleifa(rtm->rtm_type, NULL,
- ifname, &ia6, ifam->ifam_flags);
+ ifname, &ia6, ifa_flags);
break;
#endif
}