[ovs-dev,4/8] netdev: update device info only if netns matches.

Message ID 20171102190509.2688-5-fbl@redhat.com
State New
Headers show
Series
  • Add minimum network namespace support.
Related show

Commit Message

Flavio Leitner Nov. 2, 2017, 7:05 p.m.
A network device in another network namespace could have the
same name, so once the socket starts listening to other network
namespaces, it is necessary to confirm the netns id.

Signed-off-by: Flavio Leitner <fbl@redhat.com>
---
 lib/netdev-linux.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 7 deletions(-)

Patch

diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 8ddaa8b39..7f9387c0e 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -573,7 +573,7 @@  netdev_rxq_linux_cast(const struct netdev_rxq *rx)
 }
 
 static int
-netdev_linux_netns_update(struct netdev_linux *netdev)
+netdev_linux_netns_update__(struct netdev_linux *netdev)
 {
     struct netns *dev_netns = &netdev->netns;
     struct dpif_netlink_vport reply;
@@ -591,7 +591,31 @@  netdev_linux_netns_update(struct netdev_linux *netdev)
     return 0;
 }
 
-static void netdev_linux_update(struct netdev_linux *netdev,
+static int
+netdev_linux_netns_update(struct netdev_linux *netdev)
+{
+    if (netns_is_invalid(&netdev->netns)) {
+        return netdev_linux_netns_update__(netdev);
+    }
+
+    return 0;
+}
+
+static bool
+netdev_linux_netns_is_remote(struct netdev_linux *netdev)
+{
+    netdev_linux_netns_update(netdev);
+    return netns_is_remote(&netdev->netns);
+}
+
+static bool
+netdev_linux_netns_is_eq(struct netdev_linux *netdev, struct netns *ns)
+{
+    netdev_linux_netns_update(netdev);
+    return netns_eq(&netdev->netns, ns);
+}
+
+static void netdev_linux_update(struct netdev_linux *netdev, struct netns *,
                                 const struct rtnetlink_change *)
     OVS_REQUIRES(netdev->mutex);
 static void netdev_linux_changed(struct netdev_linux *netdev,
@@ -655,10 +679,11 @@  netdev_linux_run(const struct netdev_class *netdev_class OVS_UNUSED)
     do {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
         uint64_t buf_stub[4096 / 8];
+        struct netns ns;
         struct ofpbuf buf;
 
         ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub);
-        error = nl_sock_recv(sock, &buf, NULL, false);
+        error = nl_sock_recv(sock, &buf, &ns, false);
         if (!error) {
             struct rtnetlink_change change;
 
@@ -677,7 +702,7 @@  netdev_linux_run(const struct netdev_class *netdev_class OVS_UNUSED)
                     struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
                     ovs_mutex_lock(&netdev->mutex);
-                    netdev_linux_update(netdev, &change);
+                    netdev_linux_update(netdev, &ns, &change);
                     ovs_mutex_unlock(&netdev->mutex);
                 }
                 netdev_close(netdev_);
@@ -744,11 +769,11 @@  netdev_linux_changed(struct netdev_linux *dev,
 }
 
 static void
-netdev_linux_update(struct netdev_linux *dev,
-                    const struct rtnetlink_change *change)
+netdev_linux_update__(struct netdev_linux *dev,
+                      const struct rtnetlink_change *change)
     OVS_REQUIRES(dev->mutex)
 {
-    if (rtnetlink_type_is_rtnlgrp_link(change->nlmsg_type)){
+    if (rtnetlink_type_is_rtnlgrp_link(change->nlmsg_type)) {
         if (change->nlmsg_type == RTM_NEWLINK) {
             /* Keep drv-info, and ip addresses. */
             netdev_linux_changed(dev, change->ifi_flags,
@@ -772,6 +797,7 @@  netdev_linux_update(struct netdev_linux *dev,
             dev->get_ifindex_error = 0;
         } else {
             netdev_linux_changed(dev, change->ifi_flags, 0);
+            netns_set_invalid(&dev->netns);
         }
     } else if (rtnetlink_type_is_rtnlgrp_addr(change->nlmsg_type)) {
         /* Invalidates in4, in6. */
@@ -781,6 +807,16 @@  netdev_linux_update(struct netdev_linux *dev,
     }
 }
 
+static void
+netdev_linux_update(struct netdev_linux *dev, struct netns *ns,
+                    const struct rtnetlink_change *change)
+    OVS_REQUIRES(dev->mutex)
+{
+    if (netdev_linux_netns_is_eq(dev, ns)) {
+        netdev_linux_update__(dev, change);
+    }
+}
+
 static struct netdev *
 netdev_linux_alloc(void)
 {