From: Justin Pettit Date: Thu, 6 Dec 2012 01:02:48 +0000 (-0800) Subject: netdev-linux: Use underlying tap device on netdev_linux_listen(). X-Git-Tag: sliver-openvswitch-1.9.90-3~10^2~105 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=33d82a56df179219ccc3581437ca6e0c2d6b42ee;p=sliver-openvswitch.git netdev-linux: Use underlying tap device on netdev_linux_listen(). 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 Reported-by: Simon Horman Tested-by: Simon Horman --- diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 5b4d1a342..9b59bc9ad 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) {