aboutsummaryrefslogtreecommitdiff
path: root/lib/netdev-linux.c
diff options
context:
space:
mode:
authorJustin Pettit <jpettit@nicira.com>2012-12-05 17:02:48 -0800
committerJustin Pettit <jpettit@nicira.com>2012-12-07 15:04:36 -0800
commit33d82a56df179219ccc3581437ca6e0c2d6b42ee (patch)
tree48a7c8b5e5ca06ee06fd965585af5e8a6b66e0a9 /lib/netdev-linux.c
parent2520f4528742decf78a8b375f5389b50977f5e4b (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.c21
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) {