- error = nl_sock_recv(notify_sock, &buf, false);
- if (!error) {
- if (nl_policy_parse(buf, NLMSG_HDRLEN + sizeof(struct ifinfomsg),
- rtnlgrp_link_policy,
- attrs, ARRAY_SIZE(rtnlgrp_link_policy))) {
- struct ifinfomsg *ifinfo;
-
- ifinfo = (void *) ((char *) buf->data + NLMSG_HDRLEN);
- linux_netdev_report_change(buf->data, ifinfo, attrs);
- } else {
- VLOG_WARN_RL(&rl, "received bad rtnl message");
- linux_netdev_report_notify_error();
- }
- ofpbuf_delete(buf);
- } else if (error == EAGAIN) {
- return;
- } else {
- if (error == ENOBUFS) {
- VLOG_WARN_RL(&rl, "rtnetlink receive buffer overflowed");
- } else {
- VLOG_WARN_RL(&rl, "error reading rtnetlink socket: %s",
- strerror(error));
- }
- linux_netdev_report_notify_error();
- }
- }
-}
-
-void
-linux_netdev_notifier_wait(void)
-{
- if (notify_sock) {
- nl_sock_wait(notify_sock, POLLIN);
- }
-}
-
-static void
-linux_netdev_report_change(const struct nlmsghdr *nlmsg,
- const struct ifinfomsg *ifinfo,
- struct nlattr *attrs[])
-{
- struct linux_netdev_notifier *notifier;
- struct linux_netdev_change change;
-
- COVERAGE_INC(linux_netdev_changed);
-
- change.nlmsg_type = nlmsg->nlmsg_type;
- change.ifi_index = ifinfo->ifi_index;
- change.ifname = nl_attr_get_string(attrs[IFLA_IFNAME]);
- change.master_ifindex = (attrs[IFLA_MASTER]
- ? nl_attr_get_u32(attrs[IFLA_MASTER]) : 0);
-
- LIST_FOR_EACH (notifier, struct linux_netdev_notifier, node,
- &all_notifiers) {
- notifier->cb(&change, notifier->aux);
- }
-}
-
-static void
-linux_netdev_report_notify_error(void)