devices: tap API cleanup 06/21706/19
authorJakub Grajciar <jgrajcia@cisco.com>
Tue, 3 Sep 2019 08:40:01 +0000 (10:40 +0200)
committerOle Trøan <otroan@employees.org>
Wed, 11 Dec 2019 09:39:42 +0000 (09:39 +0000)
Use consistent API types.

Type: fix

Change-Id: I11cc7f6347b7a60e5fd41e54f0c7994e2d81199f
Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
extras/vom/vom/interface_factory.cpp
extras/vom/vom/tap_interface_cmds.cpp
src/vat/api_format.c
src/vnet/devices/tap/cli.c
src/vnet/devices/tap/tap.c
src/vnet/devices/tap/tap.h
src/vnet/devices/tap/tapv2.api
src/vnet/devices/tap/tapv2_api.c
src/vpp/api/custom_dump.c
test/test_tap.py [new file with mode: 0644]
test/vpp_devices.py [new file with mode: 0644]

index a5981fd..f0b25ff 100644 (file)
@@ -175,12 +175,12 @@ interface_factory::new_tap_interface(
   route::prefix_t pfx(route::prefix_t::ZERO);
   boost::asio::ip::address addr;
 
-  if (vd.host_ip4_prefix_len)
-    pfx =
-      route::prefix_t(0, (uint8_t*)vd.host_ip4_addr, vd.host_ip4_prefix_len);
-  else if (vd.host_ip6_prefix_len)
-    pfx =
-      route::prefix_t(1, (uint8_t*)vd.host_ip6_addr, vd.host_ip6_prefix_len);
+  if (vd.host_ip4_prefix.len)
+    pfx = route::prefix_t(
+      0, (uint8_t*)vd.host_ip4_prefix.address, vd.host_ip4_prefix.len);
+  else if (vd.host_ip6_prefix.len)
+    pfx = route::prefix_t(
+      1, (uint8_t*)vd.host_ip6_prefix.address, vd.host_ip6_prefix.len);
 
   l2_address_t l2_address(vd.host_mac_addr, 6);
   sp = tap_interface(name, interface::admin_state_t::UP, pfx, l2_address)
index 1d16aff..16bb065 100644 (file)
@@ -31,8 +31,7 @@ tapv2_create_cmd::tapv2_create_cmd(HW::item<handle_t>& item,
   : interface::create_cmd<vapi::Tap_create_v2>(item, name)
   , m_prefix(prefix)
   , m_l2_address(l2_address)
-{
-}
+{}
 
 rc_t
 tapv2_create_cmd::issue(connection& con)
@@ -41,18 +40,21 @@ tapv2_create_cmd::issue(connection& con)
 
   auto& payload = req.get_request().get_payload();
   memset(payload.host_if_name, 0, sizeof(payload.host_if_name));
-  memcpy(payload.host_if_name, m_name.c_str(),
+  memcpy(payload.host_if_name,
+         m_name.c_str(),
          std::min(m_name.length(), sizeof(payload.host_if_name)));
   payload.host_if_name_set = 1;
 
   if (m_prefix != route::prefix_t::ZERO) {
     if (m_prefix.address().is_v6()) {
-      m_prefix.to_vpp(&payload.host_ip6_addr_set, payload.host_ip6_addr,
-                      &payload.host_ip6_prefix_len);
+      m_prefix.to_vpp((uint8_t*)&payload.host_ip6_prefix_set,
+                      payload.host_ip6_prefix.address,
+                      &payload.host_ip6_prefix.len);
     } else {
-      m_prefix.to_vpp(&payload.host_ip4_addr_set, payload.host_ip4_addr,
-                      &payload.host_ip4_prefix_len);
-      payload.host_ip4_addr_set = 1;
+      m_prefix.to_vpp((uint8_t*)&payload.host_ip4_prefix_set,
+                      payload.host_ip4_prefix.address,
+                      &payload.host_ip4_prefix.len);
+      payload.host_ip4_prefix_set = 1;
     }
   }
 
@@ -89,8 +91,7 @@ tapv2_create_cmd::to_string() const
 
 tapv2_delete_cmd::tapv2_delete_cmd(HW::item<handle_t>& item)
   : interface::delete_cmd<vapi::Tap_delete_v2>(item)
-{
-}
+{}
 
 rc_t
 tapv2_delete_cmd::issue(connection& con)
@@ -119,9 +120,7 @@ tapv2_delete_cmd::to_string() const
   return (s.str());
 }
 
-tapv2_dump_cmd::tapv2_dump_cmd()
-{
-}
+tapv2_dump_cmd::tapv2_dump_cmd() {}
 
 bool
 tapv2_dump_cmd::operator==(const tapv2_dump_cmd& other) const
index 218ae95..6e1ebf9 100644 (file)
@@ -7474,8 +7474,8 @@ api_tap_create_v2 (vat_main_t * vam)
   mp->id = ntohl (id);
   mp->host_namespace_set = host_ns != 0;
   mp->host_bridge_set = host_bridge != 0;
-  mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
-  mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
+  mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
+  mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
   mp->rx_ring_sz = ntohs (rx_ring_sz);
   mp->tx_ring_sz = ntohs (tx_ring_sz);
   mp->host_mtu_set = host_mtu_set;
@@ -7493,9 +7493,9 @@ api_tap_create_v2 (vat_main_t * vam)
   if (host_bridge)
     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
   if (host_ip4_prefix_len)
-    clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
+    clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
   if (host_ip6_prefix_len)
-    clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
+    clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
   if (host_ip4_gw_set)
     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
   if (host_ip6_gw_set)
@@ -11859,10 +11859,12 @@ static void vl_api_sw_interface_tap_v2_details_t_handler
 {
   vat_main_t *vam = &vat_main;
 
-  u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
-                   mp->host_ip4_prefix_len);
-  u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
-                   mp->host_ip6_prefix_len);
+  u8 *ip4 =
+    format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
+           mp->host_ip4_prefix.len);
+  u8 *ip6 =
+    format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
+           mp->host_ip6_prefix.len);
 
   print (vam->ofp,
         "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
@@ -11903,12 +11905,12 @@ static void vl_api_sw_interface_tap_v2_details_t_handler_json
   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
   vat_json_object_add_string_copy (node, "host_ip4_addr",
                                   format (0, "%U/%d", format_ip4_address,
-                                          mp->host_ip4_addr,
-                                          mp->host_ip4_prefix_len));
-  vat_json_object_add_string_copy (node, "host_ip6_addr",
+                                          mp->host_ip4_prefix.address,
+                                          mp->host_ip4_prefix.len));
+  vat_json_object_add_string_copy (node, "host_ip6_prefix",
                                   format (0, "%U/%d", format_ip6_address,
-                                          mp->host_ip6_addr,
-                                          mp->host_ip6_prefix_len));
+                                          mp->host_ip6_prefix.address,
+                                          mp->host_ip6_prefix.len));
 
 }
 
index abec8f0..a85fcbf 100644 (file)
@@ -90,7 +90,7 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
          else if (unformat (line_input, "gso"))
            args.tap_flags |= TAP_FLAG_GSO;
          else if (unformat (line_input, "hw-addr %U",
-                            unformat_ethernet_address, args.mac_addr))
+                            unformat_ethernet_address, args.mac_addr.bytes))
            args.mac_addr_set = 1;
          else
            {
index 38f0605..061c6ac 100644 (file)
@@ -170,9 +170,9 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
   vif->num_rxqs = args->num_rx_queues;
   num_q_pairs = clib_max (vif->num_rxqs, vif->num_txqs);
 
-  if (ethernet_mac_address_is_zero (args->host_mac_addr))
-    ethernet_mac_address_generate (args->host_mac_addr);
-  clib_memcpy (vif->host_mac_addr, args->host_mac_addr, 6);
+  if (ethernet_mac_address_is_zero (args->host_mac_addr.bytes))
+    ethernet_mac_address_generate (args->host_mac_addr.bytes);
+  clib_memcpy (vif->host_mac_addr, args->host_mac_addr.bytes, 6);
 
   if ((vif->tap_fd = tfd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
     {
@@ -345,6 +345,17 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
        }
     }
 
+  if (!ethernet_mac_address_is_zero (args->host_mac_addr.bytes))
+    {
+      args->error = vnet_netlink_set_link_addr (vif->ifindex,
+                                               args->host_mac_addr.bytes);
+      if (args->error)
+       {
+         args->rv = VNET_API_ERROR_NETLINK_ERROR;
+         goto error;
+       }
+    }
+
   if (args->host_bridge)
     {
       args->error = vnet_netlink_set_link_master (vif->ifindex,
@@ -547,14 +558,15 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
     }
 
   if (!args->mac_addr_set)
-    ethernet_mac_address_generate (args->mac_addr);
+    ethernet_mac_address_generate (args->mac_addr.bytes);
 
-  clib_memcpy (vif->mac_addr, args->mac_addr, 6);
+  clib_memcpy (vif->mac_addr, args->mac_addr.bytes, 6);
 
   vif->host_if_name = format (0, "%s%c", host_if_name, 0);
   vif->net_ns = format (0, "%s%c", args->host_namespace, 0);
   vif->host_bridge = format (0, "%s%c", args->host_bridge, 0);
   vif->host_mtu_size = args->host_mtu_size;
+  clib_memcpy (vif->host_mac_addr, args->host_mac_addr.bytes, 6);
   vif->host_ip4_prefix_len = args->host_ip4_prefix_len;
   vif->host_ip6_prefix_len = args->host_ip6_prefix_len;
   if (args->host_ip4_prefix_len)
@@ -726,7 +738,7 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
     tapid->rx_ring_sz = vring->size;
     vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS(0));
     tapid->tx_ring_sz = vring->size;
-    clib_memcpy(tapid->host_mac_addr, vif->host_mac_addr, 6);
+    clib_memcpy(&tapid->host_mac_addr, vif->host_mac_addr, 6);
     if (vif->host_if_name)
       {
         clib_memcpy(tapid->host_if_name, vif->host_if_name,
@@ -746,10 +758,10 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
                     strlen ((const char *) vif->host_bridge)));
       }
     if (vif->host_ip4_prefix_len)
-      clib_memcpy(tapid->host_ip4_addr, &vif->host_ip4_addr, 4);
+      clib_memcpy(tapid->host_ip4_addr.as_u8, &vif->host_ip4_addr, 4);
     tapid->host_ip4_prefix_len = vif->host_ip4_prefix_len;
     if (vif->host_ip6_prefix_len)
-      clib_memcpy(tapid->host_ip6_addr, &vif->host_ip6_addr, 16);
+      clib_memcpy(tapid->host_ip6_addr.as_u8, &vif->host_ip6_addr, 16);
     tapid->host_ip6_prefix_len = vif->host_ip6_prefix_len;
     tapid->host_mtu_size = vif->host_mtu_size;
   );
index 46edf02..6eba7af 100644 (file)
@@ -26,7 +26,7 @@ typedef struct
 {
   u32 id;
   u8 mac_addr_set;
-  u8 mac_addr[6];
+  mac_address_t mac_addr;
   u8 num_rx_queues;
   u16 rx_ring_sz;
   u16 tx_ring_sz;
@@ -34,7 +34,7 @@ typedef struct
 #define TAP_FLAG_GSO (1 << 0)
   u8 *host_namespace;
   u8 *host_if_name;
-  u8 host_mac_addr[6];
+  mac_address_t host_mac_addr;
   u8 *host_bridge;
   ip4_address_t host_ip4_addr;
   u8 host_ip4_prefix_len;
@@ -61,13 +61,13 @@ typedef struct
   u8 dev_name[64];
   u16 tx_ring_sz;
   u16 rx_ring_sz;
-  u8 host_mac_addr[6];
+  mac_address_t host_mac_addr;
   u8 host_if_name[64];
   u8 host_namespace[64];
   u8 host_bridge[64];
-  u8 host_ip4_addr[4];
+  ip4_address_t host_ip4_addr;
   u8 host_ip4_prefix_len;
-  u8 host_ip6_addr[16];
+  ip6_address_t host_ip6_addr;
   u8 host_ip6_prefix_len;
   u32 host_mtu_size;
 } tap_interface_details_t;
index c11a07c..ec8bd45 100644 (file)
     the Linux kernel TAP device driver
 */
 
-option version = "2.1.0";
+option version = "3.0.0";
+
+import "vnet/interface_types.api";
+import "vnet/ethernet/ethernet_types.api";
+import "vnet/ip/ip_types.api";
+
+enum tap_flags {
+        TAP_FLAG_GSO = 1,
+};
 
 /** \brief Initialize a new tap interface with the given parameters
     @param client_index - opaque cookie to identify the sender
@@ -27,61 +35,60 @@ option version = "2.1.0";
     @param id - interface id, 0xffffffff means auto
     @param use_random_mac - let the system generate a unique mac address
     @param mac_address - mac addr to assign to the interface if use_random not set
+    @param num_rx_queues - number of rx queues
     @param tx_ring_sz - the number of entries of TX ring
     @param rx_ring_sz - the number of entries of RX ring
+    @param host_mtu_set - host MTU should be set
+    @param host_mtu_size - host MTU size
     @param host_mac_addr_set - host side interface mac address should be set
     @param host_mac_addr - host side interface mac address
-    @param host_if_name_set - host side interface name should be set
-    @param host_if_name - host side interface name
-    @param host_namespace_set - host namespace should be set
-    @param host_namespace - host namespace to attach interface to
-    @param host_bridge_set - host bridge should be set
-    @param host_bridge - host bridge to attach interface to
-    @param host_ip4_addr_set - host IPv4 ip address should be set
-    @param host_ip4_addr - host IPv4 ip address
-    @param host_ip4_prefix_len - host IPv4 ip address prefix length
-    @param host_ip6_addr_set - host IPv6 ip address should be set
-    @param host_ip6_addr - host IPv6 ip address
-    @param host_ip6_prefix_len - host IPv6 ip address prefix length
+    @param host_ip4_prefix_set - host IPv4 ip address should be set
+    @param host_ip4_prefix - host IPv4 ip address
+    @param host_ip6_prefix_set - host IPv6 ip address should be set
+    @param host_ip6_prefix - host IPv6 ip address
     @param host_ip4_gw_set - host IPv4 default gateway should be set
     @param host_ip4_gw - host IPv4 default gateway
     @param host_ip6_gw_set - host IPv6 default gateway should be set
     @param host_ip6_gw - host IPv6 default gateway
-    @param host_mtu_set - host MTU should be set
-    @param host_mtu_size - host MTU size
     @param tap_flags - flags for the TAP interface creation
+    @param host_if_name_set - host side interface name should be set
+    @param host_if_name - host side interface name
+    @param host_namespace_set - host namespece should be set
+    @param host_namespace - host namespace to attach interface to
+    @param host_bridge_set - host bridge should be set
+    @param host_bridge - host bridge to attach interface to
+    @param tag - tag
 */
 define tap_create_v2
 {
   u32 client_index;
   u32 context;
-  u32 id [default= 0xffffffff] ;
-  u8 use_random_mac;
-  u8 mac_address[6];
+  u32 id [default=0xffffffff];
+  bool use_random_mac [default=true];
+  vl_api_mac_address_t mac_address;
+  u8 num_rx_queues [default=1];
   u16 tx_ring_sz; /* optional, default is 256 entries, must be power of 2 */
   u16 rx_ring_sz; /* optional, default is 256 entries, must be power of 2 */
-  u8 host_namespace_set;
-  u8 host_namespace[64];
-  u8 host_mac_addr_set;
-  u8 host_mac_addr[6];
-  u8 host_if_name_set;
-  u8 host_if_name[64];
-  u8 host_bridge_set;
-  u8 host_bridge[64];
-  u8 host_ip4_addr_set;
-  u8 host_ip4_addr[4];
-  u8 host_ip4_prefix_len;
-  u8 host_ip6_addr_set;
-  u8 host_ip6_addr[16];
-  u8 host_ip6_prefix_len;
-  u8 host_ip4_gw_set;
-  u8 host_ip4_gw[4];
-  u8 host_ip6_gw_set;
-  u8 host_ip6_gw[16];
-  u8 host_mtu_set;
+  bool host_mtu_set;
   u32 host_mtu_size;
-  u8 tag[64];
-  u32 tap_flags;
+  bool host_mac_addr_set;
+  vl_api_mac_address_t host_mac_addr;
+  bool host_ip4_prefix_set;
+  vl_api_ip4_address_with_prefix_t host_ip4_prefix;
+  bool host_ip6_prefix_set;
+  vl_api_ip6_address_with_prefix_t host_ip6_prefix;
+  bool host_ip4_gw_set;
+  vl_api_ip4_address_t host_ip4_gw;
+  bool host_ip6_gw_set;
+  vl_api_ip6_address_t host_ip6_gw;
+  vl_api_tap_flags_t tap_flags;
+  bool host_namespace_set;
+  string host_namespace[64];
+  bool host_if_name_set;
+  string host_if_name[64];
+  bool host_bridge_set;
+  string host_bridge[64];
+  string tag[];
 };
 
 /** \brief Reply for tap create reply
@@ -93,7 +100,7 @@ define tap_create_v2_reply
 {
   u32 context;
   i32 retval;
-  u32 sw_if_index;
+  vl_api_interface_index_t sw_if_index;
 };
 
 /** \brief Delete tap interface
@@ -105,50 +112,50 @@ autoreply define tap_delete_v2
 {
   u32 client_index;
   u32 context;
-  u32 sw_if_index;
+  vl_api_interface_index_t sw_if_index;
 };
 
-/** \brief Dump tap interfaces request */
+/** \brief Dump tap interfaces request
+    @param sw_if_index - filter by sw_if_index UNIMPLEMENTED
+*/
 define sw_interface_tap_v2_dump
 {
   u32 client_index;
   u32 context;
+  vl_api_interface_index_t sw_if_index [default=0xffffffff];
 };
 
 /** \brief Reply for tap dump request
     @param sw_if_index - software index of tap interface
     @param id - interface id
-    @param dev_name - Linux tap device name
     @param tx_ring_sz - the number of entries of TX ring
     @param rx_ring_sz - the number of entries of RX ring
+    @param host_mtu_size - host mtu size
     @param host_mac_addr - mac address assigned to the host side of the interface
+    @param host_ip4_prefix - host IPv4 ip address
+    @param host_ip6_prefix - host IPv6 ip address
+    @param tap_flags - flags for the TAP interface creation
+    @param dev_name - Linux tap device name
     @param host_if_name - host side interface name
     @param host_namespace - host namespace the interface is attached into
     @param host_bridge - host bridge the interface is attached into
-    @param host_ip4_addr - host IPv4 ip address
-    @param host_ip4_prefix_len - host IPv4 ip address prefix length; 0 if unset
-    @param host_ip6_addr - host IPv6 ip address
-    @param host_ip6_prefix_len - host IPv6 ip address prefix length; 0 if unset
-    @param host_mtu_size - host mtu size
 */
 define sw_interface_tap_v2_details
 {
   u32 context;
   u32 sw_if_index;
   u32 id;
-  u8 dev_name[64];
   u16 tx_ring_sz;
   u16 rx_ring_sz;
-  u8 host_mac_addr[6];
-  u8 host_if_name[64];
-  u8 host_namespace[64];
-  u8 host_bridge[64];
-  u8 host_ip4_addr[4];
-  u8 host_ip4_prefix_len;
-  u8 host_ip6_addr[16];
-  u8 host_ip6_prefix_len;
   u32 host_mtu_size;
-  u32 tap_flags;
+  vl_api_mac_address_t host_mac_addr;
+  vl_api_ip4_address_with_prefix_t host_ip4_prefix;
+  vl_api_ip6_address_with_prefix_t host_ip6_prefix;
+  vl_api_tap_flags_t tap_flags;
+  string dev_name[64];
+  string host_if_name[64];
+  string host_namespace[64];
+  string host_bridge[64];
 };
 
 /*
index af3c276..1f1e18a 100644 (file)
@@ -25,6 +25,9 @@
 #include <vnet/ethernet/ethernet.h>
 #include <vnet/ip/ip.h>
 
+#include <vnet/ethernet/ethernet_types_api.h>
+#include <vnet/ip/ip_types_api.h>
+
 #include <vnet/vnet_msg_enum.h>
 
 #define vl_typedefs            /* define message structures */
@@ -68,20 +71,28 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
   ap->id = ntohl (mp->id);
   if (!mp->use_random_mac)
     {
-      clib_memcpy (ap->mac_addr, mp->mac_address, 6);
+      mac_address_decode (mp->mac_address, &ap->mac_addr);
       ap->mac_addr_set = 1;
     }
   ap->rx_ring_sz = ntohs (mp->rx_ring_sz);
   ap->tx_ring_sz = ntohs (mp->tx_ring_sz);
   ap->sw_if_index = (u32) ~ 0;
 
+  if (mp->num_rx_queues < 1)
+    {
+      ap->rv = VNET_API_ERROR_INVALID_ARGUMENT;
+      ap->sw_if_index = ~0;
+      goto done;
+    }
+
+  ap->num_rx_queues = mp->num_rx_queues;
+
   if (mp->host_if_name_set)
     ap->host_if_name = mp->host_if_name;
 
   if (mp->host_mac_addr_set)
     {
-      clib_memcpy (ap->host_mac_addr, mp->host_mac_addr, 6);
-      ap->mac_addr_set = 1;
+      mac_address_decode (mp->host_mac_addr, &ap->host_mac_addr);
     }
 
   if (mp->host_namespace_set)
@@ -90,27 +101,27 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
   if (mp->host_bridge_set)
     ap->host_bridge = mp->host_bridge;
 
-  if (mp->host_ip4_addr_set)
+  if (mp->host_ip4_prefix_set)
     {
-      clib_memcpy (&ap->host_ip4_addr.as_u8, mp->host_ip4_addr, 4);
-      ap->host_ip4_prefix_len = mp->host_ip4_prefix_len;
+      ip4_address_decode (mp->host_ip4_prefix.address, &ap->host_ip4_addr);
+      ap->host_ip4_prefix_len = mp->host_ip4_prefix.len;
     }
 
-  if (mp->host_ip6_addr_set)
+  if (mp->host_ip6_prefix_set)
     {
-      clib_memcpy (&ap->host_ip6_addr, mp->host_ip6_addr, 16);
-      ap->host_ip6_prefix_len = mp->host_ip6_prefix_len;
+      ip6_address_decode (mp->host_ip6_prefix.address, &ap->host_ip6_addr);
+      ap->host_ip6_prefix_len = mp->host_ip6_prefix.len;
     }
 
   if (mp->host_ip4_gw_set)
     {
-      clib_memcpy (&ap->host_ip4_gw, mp->host_ip4_gw, 4);
+      ip4_address_decode (mp->host_ip4_gw, &ap->host_ip4_gw);
       ap->host_ip4_gw_set = 1;
     }
 
   if (mp->host_ip6_gw_set)
     {
-      clib_memcpy (&ap->host_ip6_gw, mp->host_ip6_gw, 16);
+      ip6_address_decode (mp->host_ip6_gw, &ap->host_ip6_gw);
       ap->host_ip6_gw_set = 1;
     }
 
@@ -126,15 +137,13 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
 
 
   /* If a tag was supplied... */
-  if (mp->tag[0])
+  if (vl_api_string_len (&mp->tag))
     {
-      /* Make sure it's a proper C-string */
-      mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
-      u8 *tag = format (0, "%s%c", mp->tag, 0);
+      u8 *tag = format (0, "%s%c", vl_api_from_api_string (&mp->tag), 0);
       vnet_set_sw_interface_tag (vnm, tag, ap->sw_if_index);
     }
 
-
+done:
   rmp = vl_msg_api_alloc (sizeof (*rmp));
   rmp->_vl_msg_id = ntohs (VL_API_TAP_CREATE_V2_REPLY);
   rmp->context = mp->context;
@@ -191,7 +200,7 @@ tap_send_sw_interface_details (vpe_api_main_t * am,
                    strlen ((const char *) tap_if->dev_name)));
   mp->rx_ring_sz = htons (tap_if->rx_ring_sz);
   mp->tx_ring_sz = htons (tap_if->tx_ring_sz);
-  clib_memcpy (mp->host_mac_addr, tap_if->host_mac_addr, 6);
+  mac_address_encode (&tap_if->host_mac_addr, mp->host_mac_addr);
   clib_memcpy (mp->host_if_name, tap_if->host_if_name,
               MIN (ARRAY_LEN (mp->host_if_name) - 1,
                    strlen ((const char *) tap_if->host_if_name)));
@@ -202,12 +211,14 @@ tap_send_sw_interface_details (vpe_api_main_t * am,
               MIN (ARRAY_LEN (mp->host_bridge) - 1,
                    strlen ((const char *) tap_if->host_bridge)));
   mp->host_mtu_size = htonl (tap_if->host_mtu_size);
+  mac_address_encode (&tap_if->host_mac_addr, mp->host_mac_addr);
+
   if (tap_if->host_ip4_prefix_len)
-    clib_memcpy (&mp->host_ip4_addr, &tap_if->host_ip4_addr, 4);
-  mp->host_ip4_prefix_len = tap_if->host_ip4_prefix_len;
+    ip4_address_encode (&tap_if->host_ip4_addr, mp->host_ip4_prefix.address);
+  mp->host_ip4_prefix.len = tap_if->host_ip4_prefix_len;
   if (tap_if->host_ip6_prefix_len)
-    clib_memcpy (&mp->host_ip6_addr, &tap_if->host_ip6_addr, 16);
-  mp->host_ip6_prefix_len = tap_if->host_ip6_prefix_len;
+    ip6_address_encode (&tap_if->host_ip6_addr, mp->host_ip6_prefix.address);
+  mp->host_ip6_prefix.len = tap_if->host_ip6_prefix_len;
 
   mp->context = context;
   vl_api_send_msg (reg, (u8 *) mp);
@@ -222,11 +233,16 @@ vl_api_sw_interface_tap_v2_dump_t_handler (vl_api_sw_interface_tap_v2_dump_t *
   vl_api_registration_t *reg;
   tap_interface_details_t *tapifs = NULL;
   tap_interface_details_t *tap_if = NULL;
+  u32 filter_sw_if_index;
 
   reg = vl_api_client_index_to_registration (mp->client_index);
   if (!reg)
     return;
 
+  filter_sw_if_index = htonl (mp->sw_if_index);
+  if (filter_sw_if_index != ~0)
+    return;                    /* UNIMPLEMENTED */
+
   rv = tap_dump_ifs (&tapifs);
   if (rv)
     return;
index 982d66d..7284d80 100644 (file)
@@ -557,16 +557,20 @@ static void *vl_api_tap_create_v2_t_print
     s = format (s, "host-ns %s ", mp->host_namespace);
   if (mp->host_bridge_set)
     s = format (s, "host-bridge %s ", mp->host_bridge);
-  if (mp->host_ip4_addr_set)
+  if (mp->host_ip4_prefix_set)
     s = format (s, "host-ip4-addr %U/%d ", format_ip4_address,
-               mp->host_ip4_addr, mp->host_ip4_prefix_len);
-  if (mp->host_ip6_addr_set)
+               mp->host_ip4_prefix.address, mp->host_ip4_prefix.len);
+  if (mp->host_ip6_prefix_set)
     s = format (s, "host-ip6-addr %U/%d ", format_ip6_address,
-               mp->host_ip6_addr, mp->host_ip6_prefix_len);
+               mp->host_ip6_prefix.address, mp->host_ip6_prefix.len);
   if (mp->host_ip4_gw_set)
-    s = format (s, "host-ip4-gw %U ", format_ip4_address, mp->host_ip4_addr);
+    s =
+      format (s, "host-ip4-gw %U ", format_ip4_address,
+             mp->host_ip4_prefix.address);
   if (mp->host_ip6_gw_set)
-    s = format (s, "host-ip6-gw %U ", format_ip6_address, mp->host_ip6_addr);
+    s =
+      format (s, "host-ip6-gw %U ", format_ip6_address,
+             mp->host_ip6_prefix.address);
   if (mp->tx_ring_sz)
     s = format (s, "tx-ring-size %u ", (mp->tx_ring_sz));
   if (mp->rx_ring_sz)
diff --git a/test/test_tap.py b/test/test_tap.py
new file mode 100644 (file)
index 0000000..9258978
--- /dev/null
@@ -0,0 +1,24 @@
+import unittest
+import os
+
+from framework import VppTestCase, VppTestRunner
+from vpp_devices import VppTAPInterface
+
+
+def check_tuntap_driver_access():
+    return os.access("/dev/net/tun", os.R_OK or os.W_OK)
+
+
+@unittest.skipUnless(check_tuntap_driver_access(), "Permission denied")
+class TestTAP(VppTestCase):
+    """ TAP Test Case """
+
+    def test_tap_add_del(self):
+        """Create TAP interface"""
+        tap0 = VppTAPInterface(self, tap_id=0)
+        tap0.add_vpp_config()
+        self.assertTrue(tap0.query_vpp_config())
+
+
+if __name__ == '__main__':
+    unittest.main(testRunner=VppTestRunner)
diff --git a/test/vpp_devices.py b/test/vpp_devices.py
new file mode 100644 (file)
index 0000000..7e18eca
--- /dev/null
@@ -0,0 +1,41 @@
+from vpp_interface import VppInterface
+
+
+class VppTAPInterface(VppInterface):
+
+    @property
+    def tap_id(self):
+        """TAP id"""
+        return self._tap_id
+
+    def __init__(self, test, tap_id=0xffffffff, mac_addr=None):
+        self._test = test
+        self._tap_id = tap_id
+        self._mac_addr = mac_addr
+
+    def get_vpp_dump(self):
+        dump = self._test.vapi.sw_interface_tap_v2_dump()
+        for entry in dump:
+            if entry.sw_if_index == self.sw_if_index:
+                return entry
+
+    def add_vpp_config(self):
+        use_random_mac = True if self._mac_addr else False
+        reply = self._test.vapi.tap_create_v2(
+            id=self._tap_id,
+            use_random_mac=use_random_mac,
+            mac_address=self._mac_addr)
+        self.set_sw_if_index(reply.sw_if_index)
+        self._test.registry.register(self, self.test.logger)
+
+    def remove_vpp_config(self):
+        self._test.vapi.tap_delete_v2(sw_if_index=self.sw_if_index)
+
+    def query_vpp_config(self):
+        dump = self.get_vpp_dump()
+        if dump:
+            return True
+        return False
+
+    def object_id(self):
+        return "tap-%s" % self._tap_id