X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=05b830c503feae6693ace27a2513a04fdf01d097;hb=0c58c0c4da31b554e88be581cca39d314ded9b6b;hp=385c0b81688e62a2d11a0ff6e363ceb5fb23d672;hpb=78857dfb3dd2812d8b3a036a2b5adb46be8d7ae8;p=openvswitch diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 385c0b81..05b830c5 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -516,18 +516,12 @@ netdev_linux_cache_cb(const struct rtnetlink_link_change *change, /* Creates system and internal devices. */ static int -netdev_linux_create(const struct netdev_class *class, - const char *name, const struct shash *args, - struct netdev_dev **netdev_devp) +netdev_linux_create(const struct netdev_class *class, const char *name, + struct netdev_dev **netdev_devp) { struct netdev_dev_linux *netdev_dev; int error; - if (!shash_is_empty(args)) { - VLOG_WARN("%s: arguments for %s devices should be empty", - name, class->type); - } - if (!cache_notifier_refcount) { error = rtnetlink_link_notifier_register(&netdev_linux_cache_notifier, netdev_linux_cache_cb, NULL); @@ -539,7 +533,7 @@ netdev_linux_create(const struct netdev_class *class, netdev_dev = xzalloc(sizeof *netdev_dev); netdev_dev->change_seq = 1; - netdev_dev_init(&netdev_dev->netdev_dev, name, args, class); + netdev_dev_init(&netdev_dev->netdev_dev, name, class); *netdev_devp = &netdev_dev->netdev_dev; return 0; @@ -553,8 +547,7 @@ netdev_linux_create(const struct netdev_class *class, * be unavailable to other reads for tap devices. */ static int netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED, - const char *name, const struct shash *args, - struct netdev_dev **netdev_devp) + const char *name, struct netdev_dev **netdev_devp) { struct netdev_dev_linux *netdev_dev; struct tap_state *state; @@ -562,10 +555,6 @@ netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED, struct ifreq ifr; int error; - if (!shash_is_empty(args)) { - VLOG_WARN("%s: arguments for TAP devices should be empty", name); - } - netdev_dev = xzalloc(sizeof *netdev_dev); state = &netdev_dev->state.tap; @@ -593,7 +582,7 @@ netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED, goto error; } - netdev_dev_init(&netdev_dev->netdev_dev, name, args, &netdev_tap_class); + netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_tap_class); *netdev_devp = &netdev_dev->netdev_dev; return 0; @@ -639,8 +628,7 @@ netdev_linux_destroy(struct netdev_dev *netdev_dev_) } static int -netdev_linux_open(struct netdev_dev *netdev_dev_, int ethertype, - struct netdev **netdevp) +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; @@ -676,54 +664,6 @@ netdev_linux_open(struct netdev_dev *netdev_dev_, int ethertype, * 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; - int ifindex; - - /* Create file descriptor. */ - protocol = (ethertype == NETDEV_ETH_TYPE_ANY ? ETH_P_ALL - : ethertype == NETDEV_ETH_TYPE_802_2 ? ETH_P_802_2 - : ethertype); - netdev->fd = socket(PF_PACKET, SOCK_RAW, - (OVS_FORCE int) htons(protocol)); - if (netdev->fd < 0) { - error = errno; - goto error; - } - - /* Set non-blocking mode. */ - error = set_nonblocking(netdev->fd); - if (error) { - goto error; - } - - /* Get ethernet device index. */ - error = get_ifindex(&netdev->netdev, &ifindex); - if (error) { - goto error; - } - - /* Bind to specific ethernet device. */ - memset(&sll, 0, sizeof sll); - sll.sll_family = AF_PACKET; - sll.sll_ifindex = ifindex; - if (bind(netdev->fd, - (struct sockaddr *) &sll, sizeof sll) < 0) { - error = errno; - VLOG_ERR("bind to %s failed: %s", netdev_dev_get_name(netdev_dev_), - strerror(error)); - goto error; - } - - /* Between the socket() and bind() calls above, the socket receives all - * packets of the requested type on all system interfaces. We do not - * want to receive that data, but there is no way to avoid it. So we - * must now drain out the receive queue. */ - error = drain_rcvbuf(netdev->fd); - if (error) { - goto error; - } } *netdevp = &netdev->netdev; @@ -768,13 +708,68 @@ netdev_linux_enumerate(struct sset *sset) } } +static int +netdev_linux_listen(struct netdev *netdev_) +{ + struct netdev_linux *netdev = netdev_linux_cast(netdev_); + struct sockaddr_ll sll; + int ifindex; + int error; + int fd; + + if (netdev->fd >= 0) { + return 0; + } + + /* Create file descriptor. */ + fd = socket(PF_PACKET, SOCK_RAW, 0); + if (fd < 0) { + error = errno; + VLOG_ERR("failed to create raw socket (%s)", strerror(error)); + goto error; + } + + /* Set non-blocking mode. */ + error = set_nonblocking(fd); + if (error) { + goto error; + } + + /* Get ethernet device index. */ + error = get_ifindex(&netdev->netdev, &ifindex); + if (error) { + goto error; + } + + /* Bind to specific ethernet device. */ + memset(&sll, 0, sizeof sll); + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifindex; + sll.sll_protocol = (OVS_FORCE unsigned short int) htons(ETH_P_ALL); + if (bind(fd, (struct sockaddr *) &sll, sizeof sll) < 0) { + error = errno; + VLOG_ERR("%s: failed to bind raw socket (%s)", + netdev_get_name(netdev_), strerror(error)); + goto error; + } + + netdev->fd = fd; + return 0; + +error: + if (fd >= 0) { + close(fd); + } + return error; +} + static int netdev_linux_recv(struct netdev *netdev_, void *data, size_t size) { struct netdev_linux *netdev = netdev_linux_cast(netdev_); if (netdev->fd < 0) { - /* Device was opened with NETDEV_ETH_TYPE_NONE. */ + /* Device is not listening. */ return -EAGAIN; } @@ -2246,14 +2241,15 @@ netdev_linux_change_seq(const struct netdev *netdev) \ CREATE, \ netdev_linux_destroy, \ + NULL, /* get_config */ \ NULL, /* set_config */ \ - NULL, /* config_equal */ \ \ netdev_linux_open, \ netdev_linux_close, \ \ ENUMERATE, \ \ + netdev_linux_listen, \ netdev_linux_recv, \ netdev_linux_recv_wait, \ netdev_linux_drain, \