diff options
author | Justin Pettit <jpettit@nicira.com> | 2012-12-05 17:02:48 -0800 |
---|---|---|
committer | Justin Pettit <jpettit@nicira.com> | 2012-12-07 15:04:36 -0800 |
commit | 33d82a56df179219ccc3581437ca6e0c2d6b42ee (patch) | |
tree | 48a7c8b5e5ca06ee06fd965585af5e8a6b66e0a9 /lib/netdev-linux.c | |
parent | 2520f4528742decf78a8b375f5389b50977f5e4b (diff) |
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 <jpettit@nicira.com>
Reported-by: Simon Horman <horms@verge.net.au>
Tested-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'lib/netdev-linux.c')
-rw-r--r-- | 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 5b4d1a34..9b59bc9a 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) { |