ofpbuf: Fix trivial spelling typo.
[cascardo/ovs.git] / lib / netdev-dummy.c
index 285f544..ccd4a0a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, 2012, 2013, 2015 Nicira, Inc.
+ * Copyright (c) 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -105,7 +105,7 @@ struct netdev_dummy {
     /* Protects all members below. */
     struct ovs_mutex mutex OVS_ACQ_AFTER(dummy_list_mutex);
 
-    uint8_t hwaddr[ETH_ADDR_LEN] OVS_GUARDED;
+    struct eth_addr hwaddr OVS_GUARDED;
     int mtu OVS_GUARDED;
     struct netdev_stats stats OVS_GUARDED;
     enum netdev_flags flags OVS_GUARDED;
@@ -116,6 +116,7 @@ struct netdev_dummy {
     FILE *tx_pcap, *rxq_pcap OVS_GUARDED;
 
     struct in_addr address, netmask;
+    struct in6_addr ipv6;
     struct ovs_list rxes OVS_GUARDED; /* List of child "netdev_rxq_dummy"s. */
 };
 
@@ -651,12 +652,12 @@ netdev_dummy_construct(struct netdev *netdev_)
 
     ovs_mutex_init(&netdev->mutex);
     ovs_mutex_lock(&netdev->mutex);
-    netdev->hwaddr[0] = 0xaa;
-    netdev->hwaddr[1] = 0x55;
-    netdev->hwaddr[2] = n >> 24;
-    netdev->hwaddr[3] = n >> 16;
-    netdev->hwaddr[4] = n >> 8;
-    netdev->hwaddr[5] = n;
+    netdev->hwaddr.ea[0] = 0xaa;
+    netdev->hwaddr.ea[1] = 0x55;
+    netdev->hwaddr.ea[2] = n >> 24;
+    netdev->hwaddr.ea[3] = n >> 16;
+    netdev->hwaddr.ea[4] = n >> 8;
+    netdev->hwaddr.ea[5] = n;
     netdev->mtu = 1500;
     netdev->flags = 0;
     netdev->ifindex = -EOPNOTSUPP;
@@ -729,6 +730,18 @@ netdev_dummy_get_in4(const struct netdev *netdev_,
     return address->s_addr ? 0 : EADDRNOTAVAIL;
 }
 
+static int
+netdev_dummy_get_in6(const struct netdev *netdev_, struct in6_addr *in6)
+{
+    struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+
+    ovs_mutex_lock(&netdev->mutex);
+    *in6 = netdev->ipv6;
+    ovs_mutex_unlock(&netdev->mutex);
+
+    return ipv6_addr_is_set(in6) ? 0 : EADDRNOTAVAIL;
+}
+
 static int
 netdev_dummy_set_in4(struct netdev *netdev_, struct in_addr address,
                      struct in_addr netmask)
@@ -743,6 +756,18 @@ netdev_dummy_set_in4(struct netdev *netdev_, struct in_addr address,
     return 0;
 }
 
+static int
+netdev_dummy_set_in6(struct netdev *netdev_, struct in6_addr *in6)
+{
+    struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+
+    ovs_mutex_lock(&netdev->mutex);
+    netdev->ipv6 = *in6;
+    ovs_mutex_unlock(&netdev->mutex);
+
+    return 0;
+}
+
 static int
 netdev_dummy_set_config(struct netdev *netdev_, const struct smap *args)
 {
@@ -855,7 +880,7 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet **arr,
     ovs_mutex_unlock(&netdev->mutex);
 
     dp_packet_pad(packet);
-    dp_packet_set_rss_hash(packet, 0);
+    dp_packet_rss_invalidate(packet);
 
     arr[0] = packet;
     *c = 1;
@@ -970,14 +995,13 @@ netdev_dummy_send(struct netdev *netdev, int qid OVS_UNUSED,
 }
 
 static int
-netdev_dummy_set_etheraddr(struct netdev *netdev,
-                           const uint8_t mac[ETH_ADDR_LEN])
+netdev_dummy_set_etheraddr(struct netdev *netdev, const struct eth_addr mac)
 {
     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
 
     ovs_mutex_lock(&dev->mutex);
     if (!eth_addr_equals(dev->hwaddr, mac)) {
-        memcpy(dev->hwaddr, mac, ETH_ADDR_LEN);
+        dev->hwaddr = mac;
         netdev_change_seq_changed(netdev);
     }
     ovs_mutex_unlock(&dev->mutex);
@@ -986,13 +1010,12 @@ netdev_dummy_set_etheraddr(struct netdev *netdev,
 }
 
 static int
-netdev_dummy_get_etheraddr(const struct netdev *netdev,
-                           uint8_t mac[ETH_ADDR_LEN])
+netdev_dummy_get_etheraddr(const struct netdev *netdev, struct eth_addr *mac)
 {
     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
 
     ovs_mutex_lock(&dev->mutex);
-    memcpy(mac, dev->hwaddr, ETH_ADDR_LEN);
+    *mac = dev->hwaddr;
     ovs_mutex_unlock(&dev->mutex);
 
     return 0;
@@ -1034,6 +1057,92 @@ netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
     return 0;
 }
 
+static int
+netdev_dummy_get_queue(const struct netdev *netdev OVS_UNUSED,
+                       unsigned int queue_id, struct smap *details OVS_UNUSED)
+{
+    if (queue_id == 0) {
+        return 0;
+    } else {
+        return EINVAL;
+    }
+}
+
+static void
+netdev_dummy_init_queue_stats(struct netdev_queue_stats *stats)
+{
+    *stats = (struct netdev_queue_stats) {
+        .tx_bytes = UINT64_MAX,
+        .tx_packets = UINT64_MAX,
+        .tx_errors = UINT64_MAX,
+        .created = LLONG_MIN,
+    };
+}
+
+static int
+netdev_dummy_get_queue_stats(const struct netdev *netdev OVS_UNUSED,
+                             unsigned int queue_id,
+                             struct netdev_queue_stats *stats)
+{
+    if (queue_id == 0) {
+        netdev_dummy_init_queue_stats(stats);
+        return 0;
+    } else {
+        return EINVAL;
+    }
+}
+
+struct netdev_dummy_queue_state {
+    unsigned int next_queue;
+};
+
+static int
+netdev_dummy_queue_dump_start(const struct netdev *netdev OVS_UNUSED,
+                              void **statep)
+{
+    struct netdev_dummy_queue_state *state = xmalloc(sizeof *state);
+    state->next_queue = 0;
+    *statep = state;
+    return 0;
+}
+
+static int
+netdev_dummy_queue_dump_next(const struct netdev *netdev OVS_UNUSED,
+                             void *state_,
+                             unsigned int *queue_id,
+                             struct smap *details OVS_UNUSED)
+{
+    struct netdev_dummy_queue_state *state = state_;
+    if (state->next_queue == 0) {
+        *queue_id = 0;
+        state->next_queue++;
+        return 0;
+    } else {
+        return EOF;
+    }
+}
+
+static int
+netdev_dummy_queue_dump_done(const struct netdev *netdev OVS_UNUSED,
+                             void *state)
+{
+    free(state);
+    return 0;
+}
+
+static int
+netdev_dummy_dump_queue_stats(const struct netdev *netdev OVS_UNUSED,
+                              void (*cb)(unsigned int queue_id,
+                                         struct netdev_queue_stats *,
+                                         void *aux),
+                              void *aux)
+{
+    struct netdev_queue_stats stats;
+    netdev_dummy_init_queue_stats(&stats);
+    cb(0, &stats, aux);
+    return 0;
+}
+
 static int
 netdev_dummy_get_ifindex(const struct netdev *netdev)
 {
@@ -1124,18 +1233,18 @@ static const struct netdev_class dummy_class = {
     NULL,                       /* get_qos_capabilities */
     NULL,                       /* get_qos */
     NULL,                       /* set_qos */
-    NULL,                       /* get_queue */
+    netdev_dummy_get_queue,
     NULL,                       /* set_queue */
     NULL,                       /* delete_queue */
-    NULL,                       /* get_queue_stats */
-    NULL,                       /* queue_dump_start */
-    NULL,                       /* queue_dump_next */
-    NULL,                       /* queue_dump_done */
-    NULL,                       /* dump_queue_stats */
+    netdev_dummy_get_queue_stats,
+    netdev_dummy_queue_dump_start,
+    netdev_dummy_queue_dump_next,
+    netdev_dummy_queue_dump_done,
+    netdev_dummy_dump_queue_stats,
 
     netdev_dummy_get_in4,       /* get_in4 */
     NULL,                       /* set_in4 */
-    NULL,                       /* get_in6 */
+    netdev_dummy_get_in6,       /* get_in6 */
     NULL,                       /* add_router */
     NULL,                       /* get_next_hop */
     NULL,                       /* get_status */
@@ -1403,29 +1512,50 @@ netdev_dummy_ip4addr(struct unixctl_conn *conn, int argc OVS_UNUSED,
     struct netdev *netdev = netdev_from_name(argv[1]);
 
     if (netdev && is_dummy_class(netdev->netdev_class)) {
-        struct in_addr ip;
-        uint16_t plen;
-
-        if (ovs_scan(argv[2], IP_SCAN_FMT"/%"SCNi16,
-                     IP_SCAN_ARGS(&ip.s_addr), &plen)) {
-            struct in_addr mask;
+        struct in_addr ip, mask;
+        char *error;
 
-            mask.s_addr = be32_prefix_mask(plen);
+        error = ip_parse_masked(argv[2], &ip.s_addr, &mask.s_addr);
+        if (!error) {
             netdev_dummy_set_in4(netdev, ip, mask);
             unixctl_command_reply(conn, "OK");
         } else {
-            unixctl_command_reply(conn, "Invalid parameters");
+            unixctl_command_reply_error(conn, error);
+            free(error);
         }
+    } else {
+        unixctl_command_reply_error(conn, "Unknown Dummy Interface");
+    }
+
+    netdev_close(netdev);
+}
+
+static void
+netdev_dummy_ip6addr(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                     const char *argv[], void *aux OVS_UNUSED)
+{
+    struct netdev *netdev = netdev_from_name(argv[1]);
+
+    if (netdev && is_dummy_class(netdev->netdev_class)) {
+        char ip6_s[IPV6_SCAN_LEN + 1];
+        struct in6_addr ip6;
 
+        if (ovs_scan(argv[2], IPV6_SCAN_FMT, ip6_s) &&
+            inet_pton(AF_INET6, ip6_s, &ip6) == 1) {
+            netdev_dummy_set_in6(netdev, &ip6);
+            unixctl_command_reply(conn, "OK");
+        } else {
+            unixctl_command_reply_error(conn, "Invalid parameters");
+        }
         netdev_close(netdev);
     } else {
         unixctl_command_reply_error(conn, "Unknown Dummy Interface");
-        netdev_close(netdev);
-        return;
     }
 
+    netdev_close(netdev);
 }
 
+
 static void
 netdev_dummy_override(const char *type)
 {
@@ -1459,6 +1589,9 @@ netdev_dummy_register(enum dummy_level level)
     unixctl_command_register("netdev-dummy/ip4addr",
                              "[netdev] ipaddr/mask-prefix-len", 2, 2,
                              netdev_dummy_ip4addr, NULL);
+    unixctl_command_register("netdev-dummy/ip6addr",
+                             "[netdev] ip6addr", 2, 2,
+                             netdev_dummy_ip6addr, NULL);
 
     if (level == DUMMY_OVERRIDE_ALL) {
         struct sset types;