From 61b999dd6fa3a8942b5002f9392a0068324a80b6 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Tue, 1 Jun 2010 15:27:26 -0700 Subject: [PATCH] netdev-linux: Give tap FD to first opener. Tap devices can have two FDs that allow transmit and receive from different perspectives. We previously would always share one of the FDs among all openers. However, this is confusing to some users (primarily the DHCP client) which expect tap devices to behave like any other device. Now we give the tap FD to the first opener, which knows that it has opened a tap device, and a normal system FD to everyone else for consistency. --- lib/netdev-linux.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index c8d463ae..2fa05b66 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -88,6 +88,7 @@ enum { struct tap_state { int fd; + bool opened; }; struct netdev_dev_linux { @@ -371,8 +372,15 @@ netdev_linux_open(struct netdev_dev *netdev_dev_, int ethertype, goto error; } - if (!strcmp(netdev_dev_get_type(netdev_dev_), "tap")) { + 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; } else if (ethertype != NETDEV_ETH_TYPE_NONE) { struct sockaddr_ll sll; int protocol; -- 2.30.2