X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=c0e0c40c5d2df63ef950da1b27192c150c9d43fc;hb=077996afd9aabcbd29a5ca72629b01dcc2fb1793;hp=4471778e7c79390b72a72c781a08caade4045c4b;hpb=275707c33f8f5463154bc3e2f561181a2060ab57;p=sliver-openvswitch.git diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 4471778e7..c0e0c40c5 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -18,7 +18,6 @@ #include "netdev-linux.h" -#include #include #include #include @@ -56,18 +55,19 @@ #include "hmap.h" #include "netdev-provider.h" #include "netdev-vport.h" -#include "netlink.h" #include "netlink-notifier.h" #include "netlink-socket.h" +#include "netlink.h" #include "ofpbuf.h" #include "openflow/openflow.h" #include "packets.h" #include "poll-loop.h" #include "rtnetlink-link.h" -#include "socket-util.h" #include "shash.h" +#include "socket-util.h" #include "sset.h" #include "timer.h" +#include "unaligned.h" #include "vlog.h" VLOG_DEFINE_THIS_MODULE(netdev_linux); @@ -444,7 +444,7 @@ static struct netdev_dev_linux * netdev_dev_linux_cast(const struct netdev_dev *netdev_dev) { const struct netdev_class *netdev_class = netdev_dev_get_class(netdev_dev); - assert(is_netdev_linux_class(netdev_class)); + ovs_assert(is_netdev_linux_class(netdev_class)); return CONTAINER_OF(netdev_dev, struct netdev_dev_linux, netdev_dev); } @@ -454,7 +454,7 @@ netdev_linux_cast(const struct netdev *netdev) { struct netdev_dev *netdev_dev = netdev_get_dev(netdev); const struct netdev_class *netdev_class = netdev_dev_get_class(netdev_dev); - assert(is_netdev_linux_class(netdev_class)); + ovs_assert(is_netdev_linux_class(netdev_class)); return CONTAINER_OF(netdev, struct netdev_linux, netdev); } @@ -583,7 +583,7 @@ static int cache_notifier_ref(void) { if (!cache_notifier_refcount) { - assert(!netdev_linux_cache_notifier); + ovs_assert(!netdev_linux_cache_notifier); netdev_linux_cache_notifier = rtnetlink_link_notifier_create(netdev_linux_cache_cb, NULL); @@ -600,9 +600,9 @@ cache_notifier_ref(void) static void cache_notifier_unref(void) { - assert(cache_notifier_refcount > 0); + ovs_assert(cache_notifier_refcount > 0); if (!--cache_notifier_refcount) { - assert(netdev_linux_cache_notifier); + ovs_assert(netdev_linux_cache_notifier); rtnetlink_link_notifier_destroy(netdev_linux_cache_notifier); netdev_linux_cache_notifier = NULL; } @@ -916,7 +916,7 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size) sock = af_packet_sock(); if (sock < 0) { - return sock; + return -sock; } error = get_ifindex(netdev_, &ifindex); @@ -1310,6 +1310,58 @@ swap_uint64(uint64_t *a, uint64_t *b) *b = tmp; } +/* Copies 'src' into 'dst', performing format conversion in the process. + * + * 'src' is allowed to be misaligned. */ +static void +netdev_stats_from_ovs_vport_stats(struct netdev_stats *dst, + const struct ovs_vport_stats *src) +{ + dst->rx_packets = get_unaligned_u64(&src->rx_packets); + dst->tx_packets = get_unaligned_u64(&src->tx_packets); + dst->rx_bytes = get_unaligned_u64(&src->rx_bytes); + dst->tx_bytes = get_unaligned_u64(&src->tx_bytes); + dst->rx_errors = get_unaligned_u64(&src->rx_errors); + dst->tx_errors = get_unaligned_u64(&src->tx_errors); + dst->rx_dropped = get_unaligned_u64(&src->rx_dropped); + dst->tx_dropped = get_unaligned_u64(&src->tx_dropped); + dst->multicast = 0; + dst->collisions = 0; + dst->rx_length_errors = 0; + dst->rx_over_errors = 0; + dst->rx_crc_errors = 0; + dst->rx_frame_errors = 0; + dst->rx_fifo_errors = 0; + dst->rx_missed_errors = 0; + dst->tx_aborted_errors = 0; + dst->tx_carrier_errors = 0; + dst->tx_fifo_errors = 0; + dst->tx_heartbeat_errors = 0; + dst->tx_window_errors = 0; +} + +static int +get_stats_via_vport__(const struct netdev *netdev, struct netdev_stats *stats) +{ + struct dpif_linux_vport reply; + struct ofpbuf *buf; + int error; + + error = dpif_linux_vport_get(netdev_get_name(netdev), &reply, &buf); + if (error) { + return error; + } else if (!reply.stats) { + ofpbuf_delete(buf); + return EOPNOTSUPP; + } + + netdev_stats_from_ovs_vport_stats(stats, reply.stats); + + ofpbuf_delete(buf); + + return 0; +} + static void get_stats_via_vport(const struct netdev *netdev_, struct netdev_stats *stats) @@ -1321,7 +1373,7 @@ get_stats_via_vport(const struct netdev *netdev_, !(netdev_dev->cache_valid & VALID_VPORT_STAT_ERROR)) { int error; - error = netdev_vport_get_stats(netdev_, stats); + error = get_stats_via_vport__(netdev_, stats); if (error && error != ENOENT) { VLOG_WARN_RL(&rl, "%s: obtaining netdev stats via vport failed " "(%s)", netdev_get_name(netdev_), strerror(error)); @@ -1919,11 +1971,11 @@ netdev_linux_set_qos(struct netdev *netdev, if (error) { return error; } - assert(netdev_dev->tc == NULL); + ovs_assert(netdev_dev->tc == NULL); /* Install new qdisc. */ error = new_ops->tc_install(netdev, details); - assert((error == 0) == (netdev_dev->tc != NULL)); + ovs_assert((error == 0) == (netdev_dev->tc != NULL)); return error; } @@ -2433,6 +2485,7 @@ netdev_linux_change_seq(const struct netdev *netdev) netdev_linux_destroy, \ NULL, /* get_config */ \ NULL, /* set_config */ \ + NULL, /* get_tunnel_config */ \ \ netdev_linux_open, \ netdev_linux_close, \ @@ -3730,7 +3783,7 @@ tc_add_policer(struct netdev *netdev, int kbits_rate, int kbits_burst) memset(&tc_police, 0, sizeof tc_police); tc_police.action = TC_POLICE_SHOT; tc_police.mtu = mtu; - tc_fill_rate(&tc_police.rate, kbits_rate/8 * 1000, mtu); + tc_fill_rate(&tc_police.rate, (kbits_rate * 1000)/8, mtu); tc_police.burst = tc_bytes_to_ticks(tc_police.rate.rate, kbits_burst * 1024); @@ -4144,7 +4197,7 @@ tc_query_qdisc(const struct netdev *netdev) /* Instantiate it. */ load_error = ops->tc_load(CONST_CAST(struct netdev *, netdev), qdisc); - assert((load_error == 0) == (netdev_dev->tc != NULL)); + ovs_assert((load_error == 0) == (netdev_dev->tc != NULL)); ofpbuf_delete(qdisc); return error ? error : load_error; @@ -4586,7 +4639,11 @@ af_packet_sock(void) if (sock == INT_MIN) { sock = socket(AF_PACKET, SOCK_RAW, 0); if (sock >= 0) { - set_nonblocking(sock); + int error = set_nonblocking(sock); + if (error) { + close(sock); + sock = -error; + } } else { sock = -errno; VLOG_ERR("failed to create packet socket: %s", strerror(errno));