X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=1428ce6617fc76647ae60d4b105e1a3aa1966a56;hb=9591fefeea4b475ee0d1387486a410bbb592b050;hp=1ff4d4096af02d91566442bc7faa14857a4d98e8;hpb=782e6111668f5f4bccec2dc9328dc3a83f548fce;p=openvswitch diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 1ff4d409..1428ce66 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -47,6 +47,7 @@ #include #include "coverage.h" +#include "dpif-linux.h" #include "dynamic-string.h" #include "fatal-signal.h" #include "hash.h" @@ -446,7 +447,7 @@ netdev_linux_init(void) /* Create rtnetlink socket. */ if (!status) { - status = nl_sock_create(NETLINK_ROUTE, 0, 0, 0, &rtnl_sock); + status = nl_sock_create(NETLINK_ROUTE, &rtnl_sock); if (status) { VLOG_ERR_RL(&rl, "failed to create rtnetlink socket: %s", strerror(status)); @@ -522,7 +523,7 @@ netdev_linux_create(const struct netdev_class *class, cache_notifier_refcount++; netdev_dev = xzalloc(sizeof *netdev_dev); - netdev_dev_init(&netdev_dev->netdev_dev, name, class); + netdev_dev_init(&netdev_dev->netdev_dev, name, args, class); *netdev_devp = &netdev_dev->netdev_dev; return 0; @@ -576,7 +577,7 @@ netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED, goto error; } - netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_tap_class); + netdev_dev_init(&netdev_dev->netdev_dev, name, args, &netdev_tap_class); *netdev_devp = &netdev_dev->netdev_dev; return 0; @@ -1105,22 +1106,8 @@ netdev_linux_update_is_pseudo(struct netdev_dev_linux *netdev_dev) const char *type = netdev_dev_get_type(&netdev_dev->netdev_dev); netdev_dev->is_tap = !strcmp(type, "tap"); - netdev_dev->is_internal = false; - if (!netdev_dev->is_tap) { - struct ethtool_drvinfo drvinfo; - int error; - - memset(&drvinfo, 0, sizeof drvinfo); - error = netdev_linux_do_ethtool(name, - (struct ethtool_cmd *)&drvinfo, - ETHTOOL_GDRVINFO, - "ETHTOOL_GDRVINFO"); - - if (!error && !strcmp(drvinfo.driver, "openvswitch")) { - netdev_dev->is_internal = true; - } - } - + netdev_dev->is_internal = (!netdev_dev->is_tap + && dpif_linux_is_internal_device(name)); netdev_dev->cache_valid |= VALID_IS_PSEUDO; } } @@ -1201,7 +1188,7 @@ netdev_linux_get_stats(const struct netdev *netdev_, * bitmap of "enum ofp_port_features" bits, in host byte order. Returns 0 if * successful, otherwise a positive errno value. */ static int -netdev_linux_get_features(struct netdev *netdev, +netdev_linux_get_features(const struct netdev *netdev, uint32_t *current, uint32_t *advertised, uint32_t *supported, uint32_t *peer) { @@ -2025,6 +2012,26 @@ netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop, return ENXIO; } +static int +netdev_linux_get_status(const struct netdev *netdev, struct shash *sh) +{ + struct ethtool_drvinfo drvinfo; + int error; + + memset(&drvinfo, 0, sizeof drvinfo); + error = netdev_linux_do_ethtool(netdev_get_name(netdev), + (struct ethtool_cmd *)&drvinfo, + ETHTOOL_GDRVINFO, + "ETHTOOL_GDRVINFO"); + if (!error) { + shash_add(sh, "driver_name", xstrdup(drvinfo.driver)); + shash_add(sh, "driver_version", xstrdup(drvinfo.version)); + shash_add(sh, "firmware_version", xstrdup(drvinfo.fw_version)); + } + + return error; +} + /* Looks up the ARP table entry for 'ip' on 'netdev'. If one exists and can be * successfully retrieved, it stores the corresponding MAC address in 'mac' and * returns 0. Otherwise, it returns a positive errno value; in particular, @@ -2194,7 +2201,7 @@ netdev_linux_poll_remove(struct netdev_notifier *notifier_) \ CREATE, \ netdev_linux_destroy, \ - NULL, /* reconfigure */ \ + NULL, /* set_config */ \ \ netdev_linux_open, \ netdev_linux_close, \ @@ -2238,7 +2245,7 @@ netdev_linux_poll_remove(struct netdev_notifier *notifier_) netdev_linux_get_in6, \ netdev_linux_add_router, \ netdev_linux_get_next_hop, \ - NULL, /* get_status */ \ + netdev_linux_get_status, \ netdev_linux_arp_lookup, \ \ netdev_linux_update_flags, \ @@ -2358,6 +2365,11 @@ htb_setup_class__(struct netdev *netdev, unsigned int handle, int mtu; netdev_get_mtu(netdev, &mtu); + if (mtu == INT_MAX) { + VLOG_WARN_RL(&rl, "cannot set up HTB on device %s that lacks MTU", + netdev_get_name(netdev)); + return EINVAL; + } memset(&opt, 0, sizeof opt); tc_fill_rate(&opt.rate, class->min_rate, mtu); @@ -2477,6 +2489,13 @@ htb_parse_class_details__(struct netdev *netdev, const char *priority_s = shash_find_data(details, "priority"); int mtu; + netdev_get_mtu(netdev, &mtu); + if (mtu == INT_MAX) { + VLOG_WARN_RL(&rl, "cannot parse HTB class on device %s that lacks MTU", + netdev_get_name(netdev)); + return EINVAL; + } + /* min-rate. Don't allow a min-rate below 1500 bytes/s. */ if (!min_rate_s) { /* min-rate is required. */ @@ -2502,7 +2521,6 @@ htb_parse_class_details__(struct netdev *netdev, * doesn't include the Ethernet header, we need to add at least 14 (18?) to * the MTU. We actually add 64, instead of 14, as a guard against * additional headers get tacked on somewhere that we're not aware of. */ - netdev_get_mtu(netdev, &mtu); hc->burst = burst_s ? strtoull(burst_s, NULL, 10) / 8 : 0; hc->burst = MAX(hc->burst, mtu + 64);