}
}
+/**
+ * Process an RTM_IFANNOUNCE message from the kernel
+ */
+static void process_announce(private_kernel_pfroute_net_t *this,
+ struct if_announcemsghdr *msg)
+{
+ enumerator_t *enumerator;
+ iface_entry_t *iface;
+
+ if (msg->ifan_what != IFAN_DEPARTURE)
+ {
+ /* we handle new interfaces in process_link() */
+ return;
+ }
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->ifaces->create_enumerator(this->ifaces);
+ while (enumerator->enumerate(enumerator, &iface))
+ {
+ if (iface->ifindex == msg->ifan_index)
+ {
+ DBG1(DBG_KNL, "interface %s disappeared", iface->ifname);
+ this->ifaces->remove_at(this->ifaces, enumerator);
+ iface_entry_destroy(iface);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+}
+
/**
* Process an RTM_*ROUTE message from the kernel
*/
struct rt_msghdr rtm;
struct if_msghdr ifm;
struct ifa_msghdr ifam;
+ struct if_announcemsghdr ifanm;
};
char buf[sizeof(struct sockaddr_storage) * RTAX_MAX];
} msg;
case RTM_IFINFO:
hdrlen = sizeof(msg.ifm);
break;
+ case RTM_IFANNOUNCE:
+ hdrlen = sizeof(msg.ifanm);
+ break;
case RTM_ADD:
case RTM_DELETE:
case RTM_GET:
case RTM_IFINFO:
process_link(this, &msg.ifm);
break;
+ case RTM_IFANNOUNCE:
+ process_announce(this, &msg.ifanm);
+ break;
case RTM_ADD:
case RTM_DELETE:
process_route(this, &msg.rtm);