X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=4471778e7c79390b72a72c781a08caade4045c4b;hb=b0aa8146bf9ebb0794cf7ea39894f18db946da98;hp=3dd5c8af08241650df4af613a262e17cd72bdcd0;hpb=a00ca915ff30a5cb7372cdf145205e339873cd4a;p=sliver-openvswitch.git diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 3dd5c8af0..4471778e7 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, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -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'. @@ -497,27 +497,6 @@ netdev_linux_wait(void) netdev_linux_miimon_wait(); } -static int -netdev_linux_get_drvinfo(struct netdev_dev_linux *netdev_dev) -{ - - int error; - - if (netdev_dev->cache_valid & VALID_DRVINFO) { - return 0; - } - - 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, - ETHTOOL_GDRVINFO, - "ETHTOOL_GDRVINFO"); - if (!error) { - netdev_dev->cache_valid |= VALID_DRVINFO; - } - return error; -} - static void netdev_dev_linux_changed(struct netdev_dev_linux *dev, unsigned int ifi_flags, @@ -742,7 +721,6 @@ netdev_linux_destroy(struct netdev_dev *netdev_dev_) static int 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; enum netdev_flags flags; int error; @@ -767,17 +745,6 @@ netdev_linux_open(struct netdev_dev *netdev_dev_, struct netdev **netdevp) } } - 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 - * and give them the tap FD. Subsequent users probably just expect - * this to be a system device so open it normally to avoid send/receive - * directions appearing to be reversed. */ - netdev->fd = netdev_dev->state.tap.fd; - netdev_dev->state.tap.opened = true; - } - *netdevp = &netdev->netdev; return 0; @@ -802,6 +769,8 @@ static int netdev_linux_listen(struct netdev *netdev_) { struct netdev_linux *netdev = netdev_linux_cast(netdev_); + struct netdev_dev_linux *netdev_dev = + netdev_dev_linux_cast(netdev_get_dev(netdev_)); struct sockaddr_ll sll; int ifindex; int error; @@ -811,6 +780,13 @@ netdev_linux_listen(struct netdev *netdev_) return 0; } + if (!strcmp(netdev_get_type(netdev_), "tap") + && !netdev_dev->state.tap.opened) { + netdev->fd = netdev_dev->state.tap.fd; + netdev_dev->state.tap.opened = true; + return 0; + } + /* Create file descriptor. */ fd = socket(PF_PACKET, SOCK_RAW, 0); if (fd < 0) { @@ -954,7 +930,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; @@ -1027,6 +1003,7 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev_)); int error; + bool up_again = false; if (netdev_dev->cache_valid & VALID_ETHERADDR) { if (netdev_dev->ether_addr_error) { @@ -1038,6 +1015,15 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, netdev_dev->cache_valid &= ~VALID_ETHERADDR; } + /* Tap devices must be brought down before setting the address. */ + if (!strcmp(netdev_get_type(netdev_), "tap")) { + enum netdev_flags flags; + + if (!netdev_get_flags(netdev_, &flags) && (flags & NETDEV_UP)) { + netdev_turn_flags_off(netdev_, NETDEV_UP, false); + up_again = true; + } + } error = set_etheraddr(netdev_get_name(netdev_), mac); if (!error || error == ENODEV) { netdev_dev->ether_addr_error = error; @@ -1047,6 +1033,10 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, } } + if (up_again) { + netdev_turn_flags_on(netdev_, NETDEV_UP, false); + } + return error; } @@ -1204,6 +1194,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"); @@ -1331,7 +1322,7 @@ get_stats_via_vport(const struct netdev *netdev_, int error; error = netdev_vport_get_stats(netdev_, stats); - if (error) { + if (error && error != ENOENT) { VLOG_WARN_RL(&rl, "%s: obtaining netdev stats via vport failed " "(%s)", netdev_get_name(netdev_), strerror(error)); } @@ -1486,6 +1477,41 @@ netdev_internal_get_stats(const struct netdev *netdev_, return netdev_dev->vport_stats_error; } +static int +netdev_internal_set_stats(struct netdev *netdev, + const struct netdev_stats *stats) +{ + struct ovs_vport_stats vport_stats; + struct dpif_linux_vport vport; + int err; + + vport_stats.rx_packets = stats->rx_packets; + vport_stats.tx_packets = stats->tx_packets; + vport_stats.rx_bytes = stats->rx_bytes; + vport_stats.tx_bytes = stats->tx_bytes; + vport_stats.rx_errors = stats->rx_errors; + vport_stats.tx_errors = stats->tx_errors; + vport_stats.rx_dropped = stats->rx_dropped; + vport_stats.tx_dropped = stats->tx_dropped; + + dpif_linux_vport_init(&vport); + vport.cmd = OVS_VPORT_CMD_SET; + vport.name = netdev_get_name(netdev); + vport.stats = &vport_stats; + + err = dpif_linux_vport_transact(&vport, NULL, NULL); + + /* If the vport layer doesn't know about the device, that doesn't mean it + * doesn't exist (after all were able to open it when netdev_open() was + * called), it just means that it isn't attached and we'll be getting + * stats a different way. */ + if (err == ENODEV) { + err = EOPNOTSUPP; + } + + return err; +} + static void netdev_linux_read_features(struct netdev_dev_linux *netdev_dev) { @@ -1497,6 +1523,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 +1680,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 +1725,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"); } @@ -1846,7 +1875,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)); @@ -1865,7 +1894,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)); @@ -1902,7 +1931,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)); @@ -1921,7 +1950,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)); @@ -2002,8 +2031,8 @@ 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; - struct shash details; + struct tc_queue *queue, *next_queue; + struct smap details; int last_error; int error; @@ -2015,9 +2044,10 @@ netdev_linux_dump_queues(const struct netdev *netdev, } last_error = 0; - shash_init(&details); - HMAP_FOR_EACH (queue, hmap_node, &netdev_dev->tc->queues) { - shash_clear(&details); + smap_init(&details); + HMAP_FOR_EACH_SAFE (queue, next_queue, hmap_node, + &netdev_dev->tc->queues) { + smap_clear(&details); error = netdev_dev->tc->ops->class_get(netdev, queue, &details); if (!error) { @@ -2026,7 +2056,7 @@ netdev_linux_dump_queues(const struct netdev *netdev, last_error = error; } } - shash_destroy(&details); + smap_destroy(&details); return last_error; } @@ -2271,25 +2301,39 @@ netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop, } static int -netdev_linux_get_status(const struct netdev *netdev, struct shash *sh) +netdev_linux_get_status(const struct netdev *netdev, struct smap *smap) { - int error; - struct netdev_dev_linux *netdev_dev = - netdev_dev_linux_cast(netdev_get_dev(netdev)); + struct netdev_dev_linux *netdev_dev; + int error = 0; + + netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev)); + if (!(netdev_dev->cache_valid & VALID_DRVINFO)) { + struct ethtool_cmd *cmd = (struct ethtool_cmd *) &netdev_dev->drvinfo; + + COVERAGE_INC(netdev_get_ethtool); + memset(&netdev_dev->drvinfo, 0, sizeof netdev_dev->drvinfo); + error = netdev_linux_do_ethtool(netdev_dev->netdev_dev.name, + cmd, + ETHTOOL_GDRVINFO, + "ETHTOOL_GDRVINFO"); + if (!error) { + netdev_dev->cache_valid |= VALID_DRVINFO; + } + } - 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_status(const struct netdev *netdev OVS_UNUSED, struct shash *sh) +netdev_internal_get_status(const struct netdev *netdev OVS_UNUSED, + struct smap *smap) { - shash_add(sh, "driver_name", xstrdup("openvswitch")); + smap_add(smap, "driver_name", "openvswitch"); return 0; } @@ -2320,7 +2364,7 @@ netdev_linux_arp_lookup(const struct netdev *netdev, memcpy(mac, r.arp_ha.sa_data, ETH_ADDR_LEN); } else if (retval != ENXIO) { VLOG_WARN_RL(&rl, "%s: could not look up ARP entry for "IP_FMT": %s", - netdev_get_name(netdev), IP_ARGS(&ip), strerror(retval)); + netdev_get_name(netdev), IP_ARGS(ip), strerror(retval)); } return retval; } @@ -2463,7 +2507,7 @@ const struct netdev_class netdev_internal_class = "internal", netdev_linux_create, netdev_internal_get_stats, - netdev_vport_set_stats, + netdev_internal_set_stats, NULL, /* get_features */ netdev_internal_get_status); @@ -2651,17 +2695,17 @@ 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; netdev_get_features(netdev, ¤t, NULL, NULL, NULL); - hc->max_rate = netdev_features_to_bps(current) / 8; + hc->max_rate = netdev_features_to_bps(current, 100 * 1000 * 1000) / 8; } hc->min_rate = hc->max_rate; hc->burst = 0; @@ -2670,13 +2714,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); @@ -2734,7 +2778,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; @@ -2826,15 +2870,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; @@ -2850,24 +2894,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; @@ -3127,20 +3171,20 @@ 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) { enum netdev_features current; netdev_get_features(netdev, ¤t, NULL, NULL, NULL); - max_rate = netdev_features_to_bps(current) / 8; + max_rate = netdev_features_to_bps(current, 100 * 1000 * 1000) / 8; } class->min_rate = max_rate; @@ -3149,7 +3193,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; @@ -3157,8 +3201,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); @@ -3259,7 +3303,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; @@ -3327,16 +3371,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; @@ -3354,21 +3398,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; @@ -3473,7 +3517,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; @@ -4099,7 +4143,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); @@ -4196,6 +4240,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, @@ -4204,6 +4249,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, @@ -4212,6 +4258,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, @@ -4487,7 +4534,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 {