X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=b8e8015d47999d622149704d1467e3b64b04546c;hb=efacbce62f4ca3baf305441641ee35aa5b657442;hp=2faffa346011d046b541e9b54b0419c6c512e09e;hpb=edaa959f6b5100361a6af2e5c68ca6abb94bf838;p=sliver-openvswitch.git diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 2faffa346..b8e8015d4 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -239,9 +239,11 @@ netdev_linux_open(const char *name, char *suffix, int ethertype, /* Create tap device. */ ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - error = netdev_linux_do_ioctl(&netdev->netdev, &ifr, - TUNSETIFF, "TUNSETIFF"); - if (error) { + strncpy(ifr.ifr_name, suffix, sizeof ifr.ifr_name); + if (ioctl(netdev->tap_fd, TUNSETIFF, &ifr) == -1) { + VLOG_WARN("%s: creating tap device failed: %s", suffix, + strerror(errno)); + error = errno; goto error; } @@ -368,7 +370,7 @@ netdev_linux_recv(struct netdev *netdev_, void *data, size_t size) if (netdev->tap_fd < 0) { /* Device was opened with NETDEV_ETH_TYPE_NONE. */ - return EAGAIN; + return -EAGAIN; } for (;;) { @@ -380,7 +382,7 @@ netdev_linux_recv(struct netdev *netdev_, void *data, size_t size) VLOG_WARN_RL(&rl, "error receiving Ethernet packet on %s: %s", strerror(errno), netdev_get_name(netdev_)); } - return errno; + return -errno; } } } @@ -490,9 +492,17 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, const uint8_t mac[ETH_ADDR_LEN]) { struct netdev_linux *netdev = netdev_linux_cast(netdev_); - int error = set_etheraddr(netdev_get_name(netdev_), ARPHRD_ETHER, mac); - if (!error) { - memcpy(netdev->cache->etheraddr, mac, ETH_ADDR_LEN); + int error; + + if (!(netdev->cache->valid & VALID_ETHERADDR) + || !eth_addr_equals(netdev->cache->etheraddr, mac)) { + error = set_etheraddr(netdev_get_name(netdev_), ARPHRD_ETHER, mac); + if (!error) { + netdev->cache->valid |= VALID_ETHERADDR; + memcpy(netdev->cache->etheraddr, mac, ETH_ADDR_LEN); + } + } else { + error = 0; } return error; } @@ -538,6 +548,17 @@ netdev_linux_get_mtu(const struct netdev *netdev_, int *mtup) return 0; } +/* Returns the ifindex of 'netdev', if successful, as a positive number. + * On failure, returns a negative errno value. */ +static int +netdev_linux_get_ifindex(const struct netdev *netdev) +{ + int ifindex, error; + + error = get_ifindex(netdev, &ifindex); + return error ? -error : ifindex; +} + static int netdev_linux_get_carrier(const struct netdev *netdev_, bool *carrier) { @@ -710,8 +731,7 @@ netdev_linux_get_stats(const struct netdev *netdev_, struct netdev_stats *stats) /* Stores the features supported by 'netdev' into each of '*current', * '*advertised', '*supported', and '*peer' that are non-null. Each value is a * bitmap of "enum ofp_port_features" bits, in host byte order. Returns 0 if - * successful, otherwise a positive errno value. On failure, all of the - * passed-in values are set to 0. */ + * successful, otherwise a positive errno value. */ static int netdev_linux_get_features(struct netdev *netdev, uint32_t *current, uint32_t *advertised, @@ -1379,6 +1399,7 @@ const struct netdev_class netdev_linux_class = { netdev_linux_set_etheraddr, netdev_linux_get_etheraddr, netdev_linux_get_mtu, + netdev_linux_get_ifindex, netdev_linux_get_carrier, netdev_linux_get_stats, @@ -1423,6 +1444,7 @@ const struct netdev_class netdev_tap_class = { netdev_linux_set_etheraddr, netdev_linux_get_etheraddr, netdev_linux_get_mtu, + netdev_linux_get_ifindex, netdev_linux_get_carrier, netdev_linux_get_stats, @@ -1496,6 +1518,7 @@ get_stats_via_netlink(int ifindex, struct netdev_stats *stats) if (!attrs[IFLA_STATS]) { VLOG_WARN_RL(&rl, "RTM_GETLINK reply lacks stats"); + ofpbuf_delete(reply); return EPROTO; } @@ -1522,6 +1545,8 @@ get_stats_via_netlink(int ifindex, struct netdev_stats *stats) stats->tx_heartbeat_errors = rtnl_stats->tx_heartbeat_errors; stats->tx_window_errors = rtnl_stats->tx_window_errors; + ofpbuf_delete(reply); + return 0; }