Commit acf608 (ofproto-dpif: Use a single underlying datapath across
multiple bridges.) broke connectivity to userspace datapath devices.
The code assumed the first caller to open a tap device with
netdev_linux_open() wanted to write to it.  This commit moves that logic
to when netdev_linux_listen() is called.

Thanks to Ben Pfaff for helping debug the issue.

Signed-off-by: Justin Pettit <[email protected]>
Reported-by: Simon Horman <[email protected]>
---
 lib/netdev-linux.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 5b4d1a3..9b59bc9 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -743,7 +743,6 @@ netdev_linux_destroy(struct netdev_dev *netdev_dev_)
 static int
 netdev_linux_open(struct netdev_dev *netdev_dev_, struct netdev **netdevp)
 {
-    struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_dev_);
     struct netdev_linux *netdev;
     enum netdev_flags flags;
     int error;
@@ -768,17 +767,6 @@ netdev_linux_open(struct netdev_dev *netdev_dev_, struct 
netdev **netdevp)
         }
     }
 
-    if (!strcmp(netdev_dev_get_type(netdev_dev_), "tap") &&
-        !netdev_dev->state.tap.opened) {
-
-        /* We assume that the first user of the tap device is the primary user
-         * and give them the tap FD.  Subsequent users probably just expect
-         * this to be a system device so open it normally to avoid send/receive
-         * directions appearing to be reversed. */
-        netdev->fd = netdev_dev->state.tap.fd;
-        netdev_dev->state.tap.opened = true;
-    }
-
     *netdevp = &netdev->netdev;
     return 0;
 
@@ -803,6 +791,8 @@ static int
 netdev_linux_listen(struct netdev *netdev_)
 {
     struct netdev_linux *netdev = netdev_linux_cast(netdev_);
+    struct netdev_dev_linux *netdev_dev =
+                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
     struct sockaddr_ll sll;
     int ifindex;
     int error;
@@ -812,6 +802,13 @@ netdev_linux_listen(struct netdev *netdev_)
         return 0;
     }
 
+    if (!strcmp(netdev_get_type(netdev_), "tap")
+        && !netdev_dev->state.tap.opened) {
+        netdev->fd = netdev_dev->state.tap.fd;
+        netdev_dev->state.tap.opened = true;
+        return 0;
+    }
+
     /* Create file descriptor. */
     fd = socket(PF_PACKET, SOCK_RAW, 0);
     if (fd < 0) {
-- 
1.7.5.4

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to