diff options
| author | Roy Marples <roy@marples.name> | 2013-09-06 09:38:24 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2013-09-06 09:38:24 +0000 |
| commit | 27f61373d14c2e44b06f6f2ce26baf899ad8c283 (patch) | |
| tree | 28ad48c84866b297888e026ed08d14bd1e85176e /net.c | |
| parent | ef0f1a1ce3b58afd8b45b689c369b42a5d4c9206 (diff) | |
| download | dhcpcd-27f61373d14c2e44b06f6f2ce26baf899ad8c283.tar.xz | |
It seems that FreeBSD will send RTM_DELADDR + RTM_NEWADDR when
replacing an existing IPv4 address with the same values.
As such, we need to maintain a list of configured IPv4 addresses
for each interface so we know when to add it and when to skip it
to avoid receiving bogus RTM_DELADDR messages from ourself.
Diffstat (limited to 'net.c')
| -rw-r--r-- | net.c | 34 |
1 files changed, 30 insertions, 4 deletions
@@ -70,6 +70,7 @@ #include "dhcp.h" #include "dhcp6.h" #include "if-options.h" +#include "ipv4.h" #include "ipv6nd.h" #include "net.h" @@ -138,6 +139,7 @@ free_interface(struct interface *ifp) if (ifp == NULL) return; + ipv4_free(ifp); dhcp_free(ifp); ipv6_free(ifp); dhcp6_free(ifp); @@ -223,6 +225,10 @@ discover_interfaces(int argc, char * const *argv) #ifdef __linux__ char ifn[IF_NAMESIZE]; #endif +#ifdef INET + const struct sockaddr_in *addr; + const struct sockaddr_in *net; + const struct sockaddr_in *dst; #ifdef INET6 const struct sockaddr_in6 *sin6; int ifa_flags; @@ -441,11 +447,29 @@ discover_interfaces(int argc, char * const *argv) TAILQ_INSERT_TAIL(ifs, ifp, next); } -#ifdef INET6 for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr != NULL && - ifa->ifa_addr->sa_family == AF_INET6) - { + if (ifa->ifa_addr == NULL) + continue; + switch(ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + addr = (const struct sockaddr_in *) + (void *)ifa->ifa_addr; + net = (const struct sockaddr_in *) + (void *)ifa->ifa_netmask; + if (ifa->ifa_flags & IFF_POINTOPOINT) + dst = (const struct sockaddr_in *) + (void *)ifa->ifa_dstaddr; + else + dst = NULL; + ipv4_handleifa(RTM_NEWADDR, ifs, ifa->ifa_name, + &addr->sin_addr, + &net->sin_addr, + dst ? &dst->sin_addr : NULL); + break; +#endif +#ifdef INET6 + case AF_INET6: sin6 = (const struct sockaddr_in6 *) (void *)ifa->ifa_addr; ifa_flags = in6_addr_flags(ifa->ifa_name, @@ -454,6 +478,8 @@ discover_interfaces(int argc, char * const *argv) ipv6_handleifa(RTM_NEWADDR, ifs, ifa->ifa_name, &sin6->sin6_addr, ifa_flags); + break; +#endif } } #endif |
