From: Martin Willi Date: Fri, 19 Apr 2013 08:47:34 +0000 (+0200) Subject: kernel-pfroute: rescan address list for an interface if its state changes X-Git-Tag: 5.1.0dr1~153^2~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e879a59fc41a65b28037e538b8f093eb8f0ac32;p=thirdparty%2Fstrongswan.git kernel-pfroute: rescan address list for an interface if its state changes It seems that we don't get address notifications if the interface is down on OS X. --- diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c index 0d12a875bb..2fda4aebb7 100644 --- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -464,6 +464,47 @@ static void process_addr(private_kernel_pfroute_net_t *this, } } +/** + * Re-initialize address list of an interface if it changes state + */ +static void repopulate_iface(private_kernel_pfroute_net_t *this, + iface_entry_t *iface) +{ + struct ifaddrs *ifap, *ifa; + addr_entry_t *addr; + + while (iface->addrs->remove_last(iface->addrs, (void**)&addr) == SUCCESS) + { + addr_map_entry_remove(addr, iface, this); + addr_entry_destroy(addr); + } + + if (getifaddrs(&ifap) == 0) + { + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr && streq(ifa->ifa_name, iface->ifname)) + { + switch (ifa->ifa_addr->sa_family) + { + case AF_INET: + case AF_INET6: + INIT(addr, + .ip = host_create_from_sockaddr(ifa->ifa_addr), + .refcount = 1, + ); + iface->addrs->insert_last(iface->addrs, addr); + addr_map_entry_add(this, addr, iface); + break; + default: + break; + } + } + } + freeifaddrs(ifap); + } +} + /** * Process an RTM_IFINFO message from the kernel */ @@ -494,6 +535,7 @@ static void process_link(private_kernel_pfroute_net_t *this, } } iface->flags = msg->ifm_flags; + repopulate_iface(this, iface); found = TRUE; break; } @@ -512,6 +554,7 @@ static void process_link(private_kernel_pfroute_net_t *this, DBG1(DBG_KNL, "interface %s appeared", iface->ifname); iface->usable = hydra->kernel_interface->is_interface_usable( hydra->kernel_interface, iface->ifname); + repopulate_iface(this, iface); this->ifaces->insert_last(this->ifaces, iface); } else