X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=a27a625f8b1d4af811f732a3e9c77041c21ff8ec;hb=85dcedffa5de44699ff4885a344c70d97aaead32;hp=1ff4d4096af02d91566442bc7faa14857a4d98e8;hpb=782e6111668f5f4bccec2dc9328dc3a83f548fce;p=openvswitch diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 1ff4d409..a27a625f 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; @@ -562,7 +563,7 @@ netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED, /* Create tap device. */ ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); + ovs_strzcpy(ifr.ifr_name, name, sizeof ifr.ifr_name); if (ioctl(state->fd, TUNSETIFF, &ifr) == -1) { VLOG_WARN("%s: creating tap device failed: %s", name, strerror(errno)); @@ -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) { @@ -1937,7 +1924,7 @@ do_set_addr(struct netdev *netdev, int ioctl_nr, const char *ioctl_name, struct in_addr addr) { struct ifreq ifr; - strncpy(ifr.ifr_name, netdev_get_name(netdev), sizeof ifr.ifr_name); + ovs_strzcpy(ifr.ifr_name, netdev_get_name(netdev), sizeof ifr.ifr_name); make_in4_sockaddr(&ifr.ifr_addr, addr); return netdev_linux_do_ioctl(netdev_get_name(netdev), &ifr, ioctl_nr, @@ -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, @@ -2038,13 +2045,14 @@ netdev_linux_arp_lookup(const struct netdev *netdev, int retval; memset(&r, 0, sizeof r); + memset(&sin, 0, sizeof sin); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ip; sin.sin_port = 0; memcpy(&r.arp_pa, &sin, sizeof sin); r.arp_ha.sa_family = ARPHRD_ETHER; r.arp_flags = 0; - strncpy(r.arp_dev, netdev_get_name(netdev), sizeof r.arp_dev); + ovs_strzcpy(r.arp_dev, netdev_get_name(netdev), sizeof r.arp_dev); COVERAGE_INC(netdev_arp_lookup); retval = ioctl(af_inet_sock, SIOCGARP, &r) < 0 ? errno : 0; if (!retval) { @@ -2194,7 +2202,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 +2246,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 +2366,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 +2490,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 +2522,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); @@ -4036,7 +4055,7 @@ do_get_ifindex(const char *netdev_name) { struct ifreq ifr; - strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); + ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); COVERAGE_INC(netdev_get_ifindex); if (ioctl(af_inet_sock, SIOCGIFINDEX, &ifr) < 0) { VLOG_WARN_RL(&rl, "ioctl(SIOCGIFINDEX) on %s device failed: %s", @@ -4071,7 +4090,7 @@ get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN]) int hwaddr_family; memset(&ifr, 0, sizeof ifr); - strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); + ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); COVERAGE_INC(netdev_get_hwaddr); if (ioctl(af_inet_sock, SIOCGIFHWADDR, &ifr) < 0) { VLOG_ERR("ioctl(SIOCGIFHWADDR) on %s device failed: %s", @@ -4094,7 +4113,7 @@ set_etheraddr(const char *netdev_name, int hwaddr_family, struct ifreq ifr; memset(&ifr, 0, sizeof ifr); - strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); + ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name); ifr.ifr_hwaddr.sa_family = hwaddr_family; memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ADDR_LEN); COVERAGE_INC(netdev_set_hwaddr); @@ -4113,7 +4132,7 @@ netdev_linux_do_ethtool(const char *name, struct ethtool_cmd *ecmd, struct ifreq ifr; memset(&ifr, 0, sizeof ifr); - strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); + ovs_strzcpy(ifr.ifr_name, name, sizeof ifr.ifr_name); ifr.ifr_data = (caddr_t) ecmd; ecmd->cmd = cmd; @@ -4136,7 +4155,7 @@ static int netdev_linux_do_ioctl(const char *name, struct ifreq *ifr, int cmd, const char *cmd_name) { - strncpy(ifr->ifr_name, name, sizeof ifr->ifr_name); + ovs_strzcpy(ifr->ifr_name, name, sizeof ifr->ifr_name); if (ioctl(af_inet_sock, cmd, ifr) == -1) { VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s", name, cmd_name, strerror(errno));