X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=412a92debf0d0758ffcdb2fe0e7fa70c1ee0e7d3;hb=7186aaa9dc9562a1090356ca428a58624f432748;hp=a8d74381407a994deb77b26994c923470b6fb0bd;hpb=5a965e4eaea12e6d4404194a2ebc9a1d81b6516f;p=sliver-openvswitch.git diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index a8d743814..412a92deb 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks. + * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,7 +69,6 @@ #include "sset.h" #include "timer.h" #include "vlog.h" -#include "tunalloc.h" VLOG_DEFINE_THIS_MODULE(netdev_linux); @@ -78,7 +77,8 @@ COVERAGE_DEFINE(netdev_arp_lookup); COVERAGE_DEFINE(netdev_get_ifindex); COVERAGE_DEFINE(netdev_get_hwaddr); COVERAGE_DEFINE(netdev_set_hwaddr); -COVERAGE_DEFINE(netdev_ethtool); +COVERAGE_DEFINE(netdev_get_ethtool); +COVERAGE_DEFINE(netdev_set_ethtool); /* These were introduced in Linux 2.6.14, so they might be missing if we have @@ -182,7 +182,7 @@ struct tc_ops { * * (This function is null for tc_ops_other, which cannot be installed. For * other TC classes it should always be nonnull.) */ - int (*tc_install)(struct netdev *netdev, const struct shash *details); + int (*tc_install)(struct netdev *netdev, const struct smap *details); /* Called when the netdev code determines (through a Netlink query) that * this TC class's qdisc is installed on 'netdev', but we didn't install @@ -222,7 +222,7 @@ struct tc_ops { * * This function may be null if 'tc' is not configurable. */ - int (*qdisc_get)(const struct netdev *netdev, struct shash *details); + int (*qdisc_get)(const struct netdev *netdev, struct smap *details); /* Reconfigures 'netdev->tc' according to 'details', performing any * required Netlink calls to complete the reconfiguration. @@ -233,7 +233,7 @@ struct tc_ops { * * This function may be null if 'tc' is not configurable. */ - int (*qdisc_set)(struct netdev *, const struct shash *details); + int (*qdisc_set)(struct netdev *, const struct smap *details); /* Retrieves details of 'queue' on 'netdev->tc' into 'details'. 'queue' is * one of the 'struct tc_queue's within 'netdev->tc->queues'. @@ -249,7 +249,7 @@ struct tc_ops { * This function may be null if 'tc' does not have queues ('n_queues' is * 0). */ int (*class_get)(const struct netdev *netdev, const struct tc_queue *queue, - struct shash *details); + struct smap *details); /* Configures or reconfigures 'queue_id' on 'netdev->tc' according to * 'details', perfoming any required Netlink calls to complete the @@ -263,7 +263,7 @@ struct tc_ops { * This function may be null if 'tc' does not have queues or its queues are * not configurable. */ int (*class_set)(struct netdev *, unsigned int queue_id, - const struct shash *details); + const struct smap *details); /* Deletes 'queue' from 'netdev->tc'. 'queue' is one of the 'struct * tc_queue's within 'netdev->tc->queues'. @@ -507,6 +507,7 @@ netdev_linux_get_drvinfo(struct netdev_dev_linux *netdev_dev) return 0; } + COVERAGE_INC(netdev_get_ethtool); memset(&netdev_dev->drvinfo, 0, sizeof netdev_dev->drvinfo); error = netdev_linux_do_ethtool(netdev_dev->netdev_dev.name, (struct ethtool_cmd *)&netdev_dev->drvinfo, @@ -767,7 +768,7 @@ netdev_linux_open(struct netdev_dev *netdev_dev_, struct netdev **netdevp) } } - if (!strncmp(netdev_dev_get_type(netdev_dev_), "tap", 3) && + 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 @@ -792,7 +793,7 @@ netdev_linux_close(struct netdev *netdev_) { struct netdev_linux *netdev = netdev_linux_cast(netdev_); - if (netdev->fd > 0 && strncmp(netdev_get_type(netdev_), "tap", 3)) { + if (netdev->fd > 0 && strcmp(netdev_get_type(netdev_), "tap")) { close(netdev->fd); } free(netdev); @@ -899,7 +900,7 @@ netdev_linux_drain(struct netdev *netdev_) struct netdev_linux *netdev = netdev_linux_cast(netdev_); if (netdev->fd < 0) { return 0; - } else if (!strncmp(netdev_get_type(netdev_), "tap", 3)) { + } else if (!strcmp(netdev_get_type(netdev_), "tap")) { struct ifreq ifr; int error = netdev_linux_do_ioctl(netdev_get_name(netdev_), &ifr, SIOCGIFTXQLEN, "SIOCGIFTXQLEN"); @@ -954,7 +955,7 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size) sll.sll_family = AF_PACKET; sll.sll_ifindex = ifindex; - iov.iov_base = (void *) data; + iov.iov_base = CONST_CAST(void *, data); iov.iov_len = size; msg.msg_name = &sll; @@ -1010,7 +1011,7 @@ netdev_linux_send_wait(struct netdev *netdev_) struct netdev_linux *netdev = netdev_linux_cast(netdev_); if (netdev->fd < 0) { /* Nothing to do. */ - } else if (strncmp(netdev_get_type(netdev_), "tap", 3)) { + } else if (strcmp(netdev_get_type(netdev_), "tap")) { poll_fd_wait(netdev->fd, POLLOUT); } else { /* TAP device always accepts packets.*/ @@ -1204,6 +1205,7 @@ netdev_linux_get_miimon(const char *name, bool *miimon) VLOG_DBG_RL(&rl, "%s: failed to query MII, falling back to ethtool", name); + COVERAGE_INC(netdev_get_ethtool); memset(&ecmd, 0, sizeof ecmd); error = netdev_linux_do_ethtool(name, &ecmd, ETHTOOL_GLINK, "ETHTOOL_GLINK"); @@ -1497,6 +1499,7 @@ netdev_linux_read_features(struct netdev_dev_linux *netdev_dev) return; } + COVERAGE_INC(netdev_get_ethtool); memset(&ecmd, 0, sizeof ecmd); error = netdev_linux_do_ethtool(netdev_dev->netdev_dev.name, &ecmd, ETHTOOL_GSET, "ETHTOOL_GSET"); @@ -1653,6 +1656,7 @@ netdev_linux_set_advertisements(struct netdev *netdev, struct ethtool_cmd ecmd; int error; + COVERAGE_INC(netdev_get_ethtool); memset(&ecmd, 0, sizeof ecmd); error = netdev_linux_do_ethtool(netdev_get_name(netdev), &ecmd, ETHTOOL_GSET, "ETHTOOL_GSET"); @@ -1697,6 +1701,7 @@ netdev_linux_set_advertisements(struct netdev *netdev, if (advertise & NETDEV_F_PAUSE_ASYM) { ecmd.advertising |= ADVERTISED_Asym_Pause; } + COVERAGE_INC(netdev_set_ethtool); return netdev_linux_do_ethtool(netdev_get_name(netdev), &ecmd, ETHTOOL_SSET, "ETHTOOL_SSET"); } @@ -1781,51 +1786,6 @@ netdev_linux_get_qos_types(const struct netdev *netdev OVS_UNUSED, return 0; } -static int -netdev_linux_create_tap_pl(const struct netdev_class *class OVS_UNUSED, - const char *name, struct netdev_dev **netdev_devp) -{ - struct netdev_dev_linux *netdev_dev; - struct tap_state *state; - char real_name[IFNAMSIZ]; - int error; - - netdev_dev = xzalloc(sizeof *netdev_dev); - state = &netdev_dev->state.tap; - - error = cache_notifier_ref(); - if (error) { - goto error; - } - - /* Open tap device. */ - state->fd = tun_alloc(IFF_TAP, real_name); - if (state->fd < 0) { - error = errno; - VLOG_WARN("tun_alloc(IFF_TAP, %s) failed: %s", name, strerror(error)); - goto error_unref_notifier; - } - if (strcmp(name, real_name)) { - VLOG_WARN("tap_pl: requested %s, created %s", name, real_name); - } - - /* Make non-blocking. */ - error = set_nonblocking(state->fd); - if (error) { - goto error_unref_notifier; - } - - netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_tap_pl_class); - *netdev_devp = &netdev_dev->netdev_dev; - return 0; - -error_unref_notifier: - cache_notifier_unref(); -error: - free(netdev_dev); - return error; -} - static const struct tc_ops * tc_lookup_ovs_name(const char *name) { @@ -1891,7 +1851,7 @@ netdev_linux_get_qos_capabilities(const struct netdev *netdev OVS_UNUSED, static int netdev_linux_get_qos(const struct netdev *netdev, - const char **typep, struct shash *details) + const char **typep, struct smap *details) { struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); @@ -1910,7 +1870,7 @@ netdev_linux_get_qos(const struct netdev *netdev, static int netdev_linux_set_qos(struct netdev *netdev, - const char *type, const struct shash *details) + const char *type, const struct smap *details) { struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); @@ -1947,7 +1907,7 @@ netdev_linux_set_qos(struct netdev *netdev, static int netdev_linux_get_queue(const struct netdev *netdev, - unsigned int queue_id, struct shash *details) + unsigned int queue_id, struct smap *details) { struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); @@ -1966,7 +1926,7 @@ netdev_linux_get_queue(const struct netdev *netdev, static int netdev_linux_set_queue(struct netdev *netdev, - unsigned int queue_id, const struct shash *details) + unsigned int queue_id, const struct smap *details) { struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); @@ -2048,7 +2008,7 @@ netdev_linux_dump_queues(const struct netdev *netdev, struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); struct tc_queue *queue, *next_queue; - struct shash details; + struct smap details; int last_error; int error; @@ -2060,10 +2020,10 @@ netdev_linux_dump_queues(const struct netdev *netdev, } last_error = 0; - shash_init(&details); + smap_init(&details); HMAP_FOR_EACH_SAFE (queue, next_queue, hmap_node, &netdev_dev->tc->queues) { - shash_clear(&details); + smap_clear(&details); error = netdev_dev->tc->ops->class_get(netdev, queue, &details); if (!error) { @@ -2072,7 +2032,7 @@ netdev_linux_dump_queues(const struct netdev *netdev, last_error = error; } } - shash_destroy(&details); + smap_destroy(&details); return last_error; } @@ -2317,7 +2277,7 @@ netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop, } static int -netdev_linux_get_drv_info(const struct netdev *netdev, struct shash *sh) +netdev_linux_get_drv_info(const struct netdev *netdev, struct smap *smap) { int error; struct netdev_dev_linux *netdev_dev = @@ -2325,17 +2285,18 @@ netdev_linux_get_drv_info(const struct netdev *netdev, struct shash *sh) error = netdev_linux_get_drvinfo(netdev_dev); if (!error) { - shash_add(sh, "driver_name", xstrdup(netdev_dev->drvinfo.driver)); - shash_add(sh, "driver_version", xstrdup(netdev_dev->drvinfo.version)); - shash_add(sh, "firmware_version", xstrdup(netdev_dev->drvinfo.fw_version)); + smap_add(smap, "driver_name", netdev_dev->drvinfo.driver); + smap_add(smap, "driver_version", netdev_dev->drvinfo.version); + smap_add(smap, "firmware_version", netdev_dev->drvinfo.fw_version); } return error; } static int -netdev_internal_get_drv_info(const struct netdev *netdev OVS_UNUSED, struct shash *sh) +netdev_internal_get_drv_info(const struct netdev *netdev OVS_UNUSED, + struct smap *smap) { - shash_add(sh, "driver_name", xstrdup("openvswitch")); + smap_add(smap, "driver_name", "openvswitch"); return 0; } @@ -2416,13 +2377,6 @@ netdev_linux_update_flags(struct netdev *netdev, enum netdev_flags off, return error; } -static int -netdev_tap_pl_update_flags(struct netdev *netdev, enum netdev_flags off, - enum netdev_flags on, enum netdev_flags *old_flagsp) -{ - return 0; -} - static unsigned int netdev_linux_change_seq(const struct netdev *netdev) { @@ -2430,8 +2384,7 @@ netdev_linux_change_seq(const struct netdev *netdev) } #define NETDEV_LINUX_CLASS(NAME, CREATE, GET_STATS, SET_STATS, \ - GET_FEATURES, GET_STATUS, \ - UPDATE_FLAGS) \ + GET_FEATURES, GET_STATUS) \ { \ NAME, \ \ @@ -2489,7 +2442,7 @@ netdev_linux_change_seq(const struct netdev *netdev) GET_STATUS, \ netdev_linux_arp_lookup, \ \ - UPDATE_FLAGS, \ + netdev_linux_update_flags, \ \ netdev_linux_change_seq \ } @@ -2501,8 +2454,7 @@ const struct netdev_class netdev_linux_class = netdev_linux_get_stats, NULL, /* set_stats */ netdev_linux_get_features, - netdev_linux_get_drv_info, - netdev_linux_update_flags); + netdev_linux_get_drv_info); const struct netdev_class netdev_tap_class = NETDEV_LINUX_CLASS( @@ -2511,8 +2463,7 @@ const struct netdev_class netdev_tap_class = netdev_tap_get_stats, NULL, /* set_stats */ netdev_linux_get_features, - netdev_linux_get_drv_info, - netdev_linux_update_flags); + netdev_linux_get_drv_info); const struct netdev_class netdev_internal_class = NETDEV_LINUX_CLASS( @@ -2521,18 +2472,7 @@ const struct netdev_class netdev_internal_class = netdev_internal_get_stats, netdev_vport_set_stats, NULL, /* get_features */ - netdev_internal_get_drv_info, - netdev_linux_update_flags); - -const struct netdev_class netdev_tap_pl_class = - NETDEV_LINUX_CLASS( - "tap_pl", - netdev_linux_create_tap_pl, - netdev_tap_get_stats, - NULL, /* set_stats */ - netdev_linux_get_features, - netdev_linux_get_drv_info, - netdev_tap_pl_update_flags); + netdev_internal_get_drv_info); /* HTB traffic control class. */ @@ -2718,11 +2658,11 @@ htb_parse_tcmsg__(struct ofpbuf *tcmsg, unsigned int *queue_id, static void htb_parse_qdisc_details__(struct netdev *netdev, - const struct shash *details, struct htb_class *hc) + const struct smap *details, struct htb_class *hc) { const char *max_rate_s; - max_rate_s = shash_find_data(details, "max-rate"); + max_rate_s = smap_get(details, "max-rate"); hc->max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0; if (!hc->max_rate) { enum netdev_features current; @@ -2737,13 +2677,13 @@ htb_parse_qdisc_details__(struct netdev *netdev, static int htb_parse_class_details__(struct netdev *netdev, - const struct shash *details, struct htb_class *hc) + const struct smap *details, struct htb_class *hc) { const struct htb *htb = htb_get__(netdev); - const char *min_rate_s = shash_find_data(details, "min-rate"); - const char *max_rate_s = shash_find_data(details, "max-rate"); - const char *burst_s = shash_find_data(details, "burst"); - const char *priority_s = shash_find_data(details, "priority"); + const char *min_rate_s = smap_get(details, "min-rate"); + const char *max_rate_s = smap_get(details, "max-rate"); + const char *burst_s = smap_get(details, "burst"); + const char *priority_s = smap_get(details, "priority"); int mtu, error; error = netdev_get_mtu(netdev, &mtu); @@ -2801,7 +2741,7 @@ htb_query_class__(const struct netdev *netdev, unsigned int handle, } static int -htb_tc_install(struct netdev *netdev, const struct shash *details) +htb_tc_install(struct netdev *netdev, const struct smap *details) { int error; @@ -2893,15 +2833,15 @@ htb_tc_destroy(struct tc *tc) } static int -htb_qdisc_get(const struct netdev *netdev, struct shash *details) +htb_qdisc_get(const struct netdev *netdev, struct smap *details) { const struct htb *htb = htb_get__(netdev); - shash_add(details, "max-rate", xasprintf("%llu", 8ULL * htb->max_rate)); + smap_add_format(details, "max-rate", "%llu", 8ULL * htb->max_rate); return 0; } static int -htb_qdisc_set(struct netdev *netdev, const struct shash *details) +htb_qdisc_set(struct netdev *netdev, const struct smap *details) { struct htb_class hc; int error; @@ -2917,24 +2857,24 @@ htb_qdisc_set(struct netdev *netdev, const struct shash *details) static int htb_class_get(const struct netdev *netdev OVS_UNUSED, - const struct tc_queue *queue, struct shash *details) + const struct tc_queue *queue, struct smap *details) { const struct htb_class *hc = htb_class_cast__(queue); - shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate)); + smap_add_format(details, "min-rate", "%llu", 8ULL * hc->min_rate); if (hc->min_rate != hc->max_rate) { - shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate)); + smap_add_format(details, "max-rate", "%llu", 8ULL * hc->max_rate); } - shash_add(details, "burst", xasprintf("%llu", 8ULL * hc->burst)); + smap_add_format(details, "burst", "%llu", 8ULL * hc->burst); if (hc->priority) { - shash_add(details, "priority", xasprintf("%u", hc->priority)); + smap_add_format(details, "priority", "%u", hc->priority); } return 0; } static int htb_class_set(struct netdev *netdev, unsigned int queue_id, - const struct shash *details) + const struct smap *details) { struct htb_class hc; int error; @@ -3194,13 +3134,13 @@ hfsc_query_class__(const struct netdev *netdev, unsigned int handle, } static void -hfsc_parse_qdisc_details__(struct netdev *netdev, const struct shash *details, +hfsc_parse_qdisc_details__(struct netdev *netdev, const struct smap *details, struct hfsc_class *class) { uint32_t max_rate; const char *max_rate_s; - max_rate_s = shash_find_data(details, "max-rate"); + max_rate_s = smap_get(details, "max-rate"); max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0; if (!max_rate) { @@ -3216,7 +3156,7 @@ hfsc_parse_qdisc_details__(struct netdev *netdev, const struct shash *details, static int hfsc_parse_class_details__(struct netdev *netdev, - const struct shash *details, + const struct smap *details, struct hfsc_class * class) { const struct hfsc *hfsc; @@ -3224,8 +3164,8 @@ hfsc_parse_class_details__(struct netdev *netdev, const char *min_rate_s, *max_rate_s; hfsc = hfsc_get__(netdev); - min_rate_s = shash_find_data(details, "min-rate"); - max_rate_s = shash_find_data(details, "max-rate"); + min_rate_s = smap_get(details, "min-rate"); + max_rate_s = smap_get(details, "max-rate"); min_rate = min_rate_s ? strtoull(min_rate_s, NULL, 10) / 8 : 0; min_rate = MAX(min_rate, 1); @@ -3326,7 +3266,7 @@ hfsc_setup_class__(struct netdev *netdev, unsigned int handle, } static int -hfsc_tc_install(struct netdev *netdev, const struct shash *details) +hfsc_tc_install(struct netdev *netdev, const struct smap *details) { int error; struct hfsc_class class; @@ -3394,16 +3334,16 @@ hfsc_tc_destroy(struct tc *tc) } static int -hfsc_qdisc_get(const struct netdev *netdev, struct shash *details) +hfsc_qdisc_get(const struct netdev *netdev, struct smap *details) { const struct hfsc *hfsc; hfsc = hfsc_get__(netdev); - shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hfsc->max_rate)); + smap_add_format(details, "max-rate", "%llu", 8ULL * hfsc->max_rate); return 0; } static int -hfsc_qdisc_set(struct netdev *netdev, const struct shash *details) +hfsc_qdisc_set(struct netdev *netdev, const struct smap *details) { int error; struct hfsc_class class; @@ -3421,21 +3361,21 @@ hfsc_qdisc_set(struct netdev *netdev, const struct shash *details) static int hfsc_class_get(const struct netdev *netdev OVS_UNUSED, - const struct tc_queue *queue, struct shash *details) + const struct tc_queue *queue, struct smap *details) { const struct hfsc_class *hc; hc = hfsc_class_cast__(queue); - shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate)); + smap_add_format(details, "min-rate", "%llu", 8ULL * hc->min_rate); if (hc->min_rate != hc->max_rate) { - shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate)); + smap_add_format(details, "max-rate", "%llu", 8ULL * hc->max_rate); } return 0; } static int hfsc_class_set(struct netdev *netdev, unsigned int queue_id, - const struct shash *details) + const struct smap *details) { int error; struct hfsc_class class; @@ -3540,7 +3480,7 @@ default_install__(struct netdev *netdev) static int default_tc_install(struct netdev *netdev, - const struct shash *details OVS_UNUSED) + const struct smap *details OVS_UNUSED) { default_install__(netdev); return 0; @@ -4166,7 +4106,7 @@ tc_query_qdisc(const struct netdev *netdev) } /* Instantiate it. */ - load_error = ops->tc_load((struct netdev *) netdev, qdisc); + load_error = ops->tc_load(CONST_CAST(struct netdev *, netdev), qdisc); assert((load_error == 0) == (netdev_dev->tc != NULL)); ofpbuf_delete(qdisc); @@ -4263,6 +4203,7 @@ netdev_linux_ethtool_set_flag(struct netdev *netdev, uint32_t flag, uint32_t new_flags; int error; + COVERAGE_INC(netdev_get_ethtool); memset(&evalue, 0, sizeof evalue); error = netdev_linux_do_ethtool(netdev_name, (struct ethtool_cmd *)&evalue, @@ -4271,6 +4212,7 @@ netdev_linux_ethtool_set_flag(struct netdev *netdev, uint32_t flag, return error; } + COVERAGE_INC(netdev_set_ethtool); evalue.data = new_flags = (evalue.data & ~flag) | (enable ? flag : 0); error = netdev_linux_do_ethtool(netdev_name, (struct ethtool_cmd *)&evalue, @@ -4279,6 +4221,7 @@ netdev_linux_ethtool_set_flag(struct netdev *netdev, uint32_t flag, return error; } + COVERAGE_INC(netdev_get_ethtool); memset(&evalue, 0, sizeof evalue); error = netdev_linux_do_ethtool(netdev_name, (struct ethtool_cmd *)&evalue, @@ -4554,7 +4497,6 @@ netdev_linux_do_ethtool(const char *name, struct ethtool_cmd *ecmd, ifr.ifr_data = (caddr_t) ecmd; ecmd->cmd = cmd; - COVERAGE_INC(netdev_ethtool); if (ioctl(af_inet_sock, SIOCETHTOOL, &ifr) == 0) { return 0; } else {