vom: Add TAPv2 support 53/13353/3
authorMohsin Kazmi <sykazmi@cisco.com>
Wed, 4 Jul 2018 13:17:01 +0000 (15:17 +0200)
committerNeale Ranns <nranns@cisco.com>
Wed, 11 Jul 2018 13:12:12 +0000 (13:12 +0000)
Change-Id: I1fff014dd7d8a66ed3cb063e8c996de4f7e745c2
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
extras/vom/vom/interface.cpp
extras/vom/vom/interface.hpp
extras/vom/vom/interface_cmds.cpp
extras/vom/vom/interface_cmds.hpp
extras/vom/vom/interface_factory.cpp
extras/vom/vom/interface_factory.hpp
extras/vom/vom/interface_types.cpp
extras/vom/vom/tap_interface.cpp
extras/vom/vom/tap_interface.hpp
extras/vom/vom/tap_interface_cmds.cpp
extras/vom/vom/tap_interface_cmds.hpp

index 009e703..4f26ac8 100644 (file)
@@ -23,6 +23,7 @@
 #include "vom/logger.hpp"
 #include "vom/prefix.hpp"
 #include "vom/singular_db_funcs.hpp"
+#include "vom/tap_interface_cmds.hpp"
 
 namespace VOM {
 /**
@@ -286,8 +287,7 @@ interface::mk_create_cmd(std::queue<cmd*>& q)
     q.push(new interface_cmds::af_packet_create_cmd(m_hdl, m_name));
     if (!m_tag.empty())
       q.push(new interface_cmds::set_tag(m_hdl, m_tag));
-  } else if (type_t::TAP == m_type) {
-    q.push(new interface_cmds::tap_create_cmd(m_hdl, m_name));
+  } else if (type_t::TAP == m_type || type_t::TAPV2 == m_type) {
     if (!m_tag.empty())
       q.push(new interface_cmds::set_tag(m_hdl, m_tag));
   } else if (type_t::VHOST == m_type) {
@@ -306,8 +306,6 @@ interface::mk_delete_cmd(std::queue<cmd*>& q)
     q.push(new interface_cmds::loopback_delete_cmd(m_hdl));
   } else if (type_t::AFPACKET == m_type) {
     q.push(new interface_cmds::af_packet_delete_cmd(m_hdl, m_name));
-  } else if (type_t::TAP == m_type) {
-    q.push(new interface_cmds::tap_delete_cmd(m_hdl));
   } else if (type_t::VHOST == m_type) {
     q.push(new interface_cmds::vhost_delete_cmd(m_hdl, m_name));
   }
@@ -491,7 +489,7 @@ void
 interface::event_handler::handle_populate(const client_db::key_t& key)
 {
   /*
-   * dump VPP current states
+   * dump VPP vhost-user interfaces
    */
   std::shared_ptr<interface_cmds::vhost_dump_cmd> vcmd =
     std::make_shared<interface_cmds::vhost_dump_cmd>();
@@ -507,6 +505,9 @@ interface::event_handler::handle_populate(const client_db::key_t& key)
     OM::commit(key, *vitf);
   }
 
+  /*
+   * dump VPP af-packet interfaces
+   */
   std::shared_ptr<interface_cmds::af_packet_dump_cmd> afcmd =
     std::make_shared<interface_cmds::af_packet_dump_cmd>();
 
@@ -521,6 +522,53 @@ interface::event_handler::handle_populate(const client_db::key_t& key)
     OM::commit(key, *afitf);
   }
 
+  /*
+   * dump VPP tap interfaces
+   */
+  std::shared_ptr<tap_interface_cmds::tap_dump_cmd> tapcmd =
+    std::make_shared<tap_interface_cmds::tap_dump_cmd>();
+
+  HW::enqueue(tapcmd);
+  HW::write();
+
+  for (auto& tap_record : *tapcmd) {
+    std::shared_ptr<tap_interface> tapitf =
+      interface_factory::new_tap_interface(tap_record.get_payload());
+    VOM_LOG(log_level_t::DEBUG) << "tap-dump: " << tapitf->to_string();
+
+    /*
+     * Write each of the discovered interfaces into the OM,
+     * but disable the HW Command q whilst we do, so that no
+     * commands are sent to VPP
+     */
+    OM::commit(key, *tapitf);
+  }
+
+  /*
+   * dump VPP tapv2 interfaces
+   */
+  std::shared_ptr<tap_interface_cmds::tapv2_dump_cmd> tapv2cmd =
+    std::make_shared<tap_interface_cmds::tapv2_dump_cmd>();
+
+  HW::enqueue(tapv2cmd);
+  HW::write();
+
+  for (auto& tapv2_record : *tapv2cmd) {
+    std::shared_ptr<tap_interface> tapv2itf =
+      interface_factory::new_tap_v2_interface(tapv2_record.get_payload());
+    VOM_LOG(log_level_t::DEBUG) << "tapv2-dump: " << tapv2itf->to_string();
+
+    /*
+     * Write each of the discovered interfaces into the OM,
+     * but disable the HW Command q whilst we do, so that no
+     * commands are sent to VPP
+     */
+    OM::commit(key, *tapv2itf);
+  }
+
+  /*
+   * dump VPP interfaces
+   */
   std::shared_ptr<interface_cmds::dump_cmd> cmd =
     std::make_shared<interface_cmds::dump_cmd>();
 
@@ -567,6 +615,9 @@ interface::event_handler::handle_populate(const client_db::key_t& key)
     }
   }
 
+  /*
+   * dump VPP bond interfaces
+   */
   std::shared_ptr<bond_interface_cmds::dump_cmd> bcmd =
     std::make_shared<bond_interface_cmds::dump_cmd>();
 
index f6708b3..92e14a7 100644 (file)
@@ -99,6 +99,11 @@ public:
      */
     const static type_t TAP;
 
+    /**
+     * TAPv2 interface type
+     */
+    const static type_t TAPV2;
+
     /**
      * vhost-user interface type
      */
index fc1d71f..e78ed46 100644 (file)
@@ -19,7 +19,6 @@
 DEFINE_VAPI_MSG_IDS_VPE_API_JSON;
 DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON;
 DEFINE_VAPI_MSG_IDS_AF_PACKET_API_JSON;
-DEFINE_VAPI_MSG_IDS_TAP_API_JSON;
 DEFINE_VAPI_MSG_IDS_VHOST_USER_API_JSON;
 DEFINE_VAPI_MSG_IDS_STATS_API_JSON;
 
@@ -92,44 +91,6 @@ af_packet_create_cmd::to_string() const
   return (s.str());
 }
 
-tap_create_cmd::tap_create_cmd(HW::item<handle_t>& item,
-                               const std::string& name)
-  : create_cmd(item, name)
-{
-}
-
-rc_t
-tap_create_cmd::issue(connection& con)
-{
-  msg_t req(con.ctx(), std::ref(*this));
-
-  auto& payload = req.get_request().get_payload();
-
-  memset(payload.tap_name, 0, sizeof(payload.tap_name));
-  memcpy(payload.tap_name, m_name.c_str(),
-         std::min(m_name.length(), sizeof(payload.tap_name)));
-  payload.use_random_mac = 1;
-
-  VAPI_CALL(req.execute());
-
-  m_hw_item = wait();
-
-  if (m_hw_item.rc() == rc_t::OK) {
-    insert_interface();
-  }
-
-  return rc_t::OK;
-}
-
-std::string
-tap_create_cmd::to_string() const
-{
-  std::ostringstream s;
-  s << "tap-intf-create: " << m_hw_item.to_string() << " name:" << m_name;
-
-  return (s.str());
-}
-
 vhost_create_cmd::vhost_create_cmd(HW::item<handle_t>& item,
                                    const std::string& name,
                                    const std::string& tag)
@@ -242,28 +203,6 @@ af_packet_delete_cmd::to_string() const
   return (s.str());
 }
 
-tap_delete_cmd::tap_delete_cmd(HW::item<handle_t>& item)
-  : delete_cmd(item)
-{
-}
-
-rc_t
-tap_delete_cmd::issue(connection& con)
-{
-  // finally... call VPP
-
-  remove_interface();
-  return rc_t::OK;
-}
-std::string
-tap_delete_cmd::to_string() const
-{
-  std::ostringstream s;
-  s << "tap-itf-delete: " << m_hw_item.to_string();
-
-  return (s.str());
-}
-
 vhost_delete_cmd::vhost_delete_cmd(HW::item<handle_t>& item,
                                    const std::string& name)
   : delete_cmd(item, name)
@@ -470,13 +409,13 @@ rc_t
 events_cmd::issue(connection& con)
 {
   /*
- * First set the call back to handle the interface events
- */
  * First set the call back to handle the interface events
  */
   m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast<event_cmd*>(this)))));
 
   /*
- * then send the request to enable them
- */
  * then send the request to enable them
  */
   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
 
   auto& payload = req.get_request().get_payload();
@@ -494,8 +433,8 @@ void
 events_cmd::retire(connection& con)
 {
   /*
- * disable interface events.
- */
  * disable interface events.
  */
   msg_t req(con.ctx(), std::ref(*(static_cast<rpc_cmd*>(this))));
 
   auto& payload = req.get_request().get_payload();
index d5c161d..1d0c4f5 100644 (file)
@@ -86,30 +86,6 @@ public:
   std::string to_string() const;
 };
 
-/**
-* A command class to create TAP interfaces in VPP
-*/
-class tap_create_cmd : public interface::create_cmd<vapi::Tap_connect>
-{
-public:
-  /**
-   * Constructor taking the HW::item to update
-   * and the name of the interface to create
-   */
-  tap_create_cmd(HW::item<handle_t>& item, const std::string& name);
-  ~tap_create_cmd() = default;
-
-  /**
-   * Issue the command to VPP/HW
-   */
-  rc_t issue(connection& con);
-
-  /**
- * convert to string format for debug purposes
- */
-  std::string to_string() const;
-};
-
 /**
  * A functor class that creates an interface
  */
@@ -178,27 +154,6 @@ public:
   std::string to_string() const;
 };
 
-/**
-* A command class to delete TAP interfaces in VPP
-*/
-class tap_delete_cmd : public interface::delete_cmd<vapi::Tap_delete>
-{
-public:
-  /**
-   * Constructor taking the HW::item to update
-   */
-  tap_delete_cmd(HW::item<handle_t>& item);
-
-  /**
-   * Issue the command to VPP/HW
-   */
-  rc_t issue(connection& con);
-  /**
-   * convert to string format for debug purposes
-   */
-  std::string to_string() const;
-};
-
 /**
  * A functor class that deletes a Vhost interface
  */
index 715c3b6..c417c1c 100644 (file)
@@ -72,11 +72,11 @@ interface_factory::new_interface(const vapi_payload_sw_interface_details& vd)
   /*
    * pull out the other special cases
    */
-  if (interface::type_t::TAP == type) {
+  if (interface::type_t::TAP == type || interface::type_t::TAPV2 == type) {
     /*
-     * TAP interface
+     * TAP interfaces
      */
-    sp = tap_interface(name, state, route::prefix_t()).singular();
+    sp = interface::find(hdl);
     if (sp && !tag.empty())
       sp->set(tag);
   } else if ((name.find(".") != std::string::npos) && (0 != vd.sub_id)) {
@@ -153,6 +153,48 @@ interface_factory::new_af_packet_interface(
   return (sp);
 }
 
+std::shared_ptr<tap_interface>
+interface_factory::new_tap_interface(
+  const vapi_payload_sw_interface_tap_details& vd)
+{
+  std::shared_ptr<tap_interface> sp;
+  std::string name = reinterpret_cast<const char*>(vd.dev_name);
+  handle_t hdl(vd.sw_if_index);
+
+  sp = tap_interface(name, interface::type_t::TAP, interface::admin_state_t::UP,
+                     route::prefix_t::ZERO)
+         .singular();
+  sp->set(hdl);
+  return (sp);
+}
+
+std::shared_ptr<tap_interface>
+interface_factory::new_tap_v2_interface(
+  const vapi_payload_sw_interface_tap_v2_details& vd)
+{
+  std::shared_ptr<tap_interface> sp;
+  handle_t hdl(vd.sw_if_index);
+  std::string name = reinterpret_cast<const char*>(vd.host_if_name);
+  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);
+
+  l2_address_t l2_address(vd.host_mac_addr, 6);
+  sp = tap_interface(name, interface::type_t::TAPV2,
+                     interface::admin_state_t::UP, pfx, l2_address)
+         .singular();
+
+  sp->set(hdl);
+
+  return (sp);
+}
+
 std::shared_ptr<bond_interface>
 interface_factory::new_bond_interface(
   const vapi_payload_sw_interface_bond_details& vd)
index 613c26e..1bb60a8 100644 (file)
 
 #include "vom/bond_member.hpp"
 #include "vom/interface.hpp"
+#include "vom/tap_interface.hpp"
 
 #include <vapi/af_packet.api.vapi.hpp>
 #include <vapi/bond.api.vapi.hpp>
 #include <vapi/interface.api.vapi.hpp>
+#include <vapi/tap.api.vapi.hpp>
+#include <vapi/tapv2.api.vapi.hpp>
 #include <vapi/vhost_user.api.vapi.hpp>
 
 namespace VOM {
@@ -43,6 +46,12 @@ public:
   static std::shared_ptr<interface> new_af_packet_interface(
     const vapi_payload_af_packet_details& vd);
 
+  static std::shared_ptr<tap_interface> new_tap_interface(
+    const vapi_payload_sw_interface_tap_details& vd);
+
+  static std::shared_ptr<tap_interface> new_tap_v2_interface(
+    const vapi_payload_sw_interface_tap_v2_details& vd);
+
   static std::shared_ptr<bond_interface> new_bond_interface(
     const vapi_payload_sw_interface_bond_details& vd);
 
index 139bdd5..b20a385 100644 (file)
@@ -26,8 +26,9 @@ const interface::type_t interface::type_t::AFPACKET(4, "AFPACKET");
 const interface::type_t interface::type_t::LOOPBACK(5, "LOOPBACK");
 const interface::type_t interface::type_t::LOCAL(6, "LOCAL");
 const interface::type_t interface::type_t::TAP(7, "TAP");
-const interface::type_t interface::type_t::VHOST(8, "VHOST");
-const interface::type_t interface::type_t::BOND(9, "Bond");
+const interface::type_t interface::type_t::TAPV2(8, "TAPV2");
+const interface::type_t interface::type_t::VHOST(9, "VHOST");
+const interface::type_t interface::type_t::BOND(10, "Bond");
 
 const interface::oper_state_t interface::oper_state_t::DOWN(0, "down");
 const interface::oper_state_t interface::oper_state_t::UP(1, "up");
@@ -58,8 +59,11 @@ interface::type_t::from_string(const std::string& str)
     return interface::type_t::AFPACKET;
   } else if (str.find("local") != std::string::npos) {
     return interface::type_t::LOCAL;
-  } else if (str.find("tap") != std::string::npos) {
+  } else if ((str.find("tapcli") != std::string::npos) ||
+             (str.find("tuntap") != std::string::npos)) {
     return interface::type_t::TAP;
+  } else if (str.find("tap") != std::string::npos) {
+    return interface::type_t::TAPV2;
   } else if (str.find("bvi") != std::string::npos) {
     return interface::type_t::BVI;
   }
index d7f16f5..4054e26 100644 (file)
@@ -25,19 +25,21 @@ tap_interface::event_handler tap_interface::m_evh;
  * Construct a new object matching the desried state
  */
 tap_interface::tap_interface(const std::string& name,
+                             type_t type,
                              admin_state_t state,
                              route::prefix_t prefix)
-  : interface(name, type_t::TAP, state)
+  : interface(name, type, state)
   , m_prefix(prefix)
   , m_l2_address(l2_address_t::ZERO)
 {
 }
 
 tap_interface::tap_interface(const std::string& name,
+                             type_t type,
                              admin_state_t state,
                              route::prefix_t prefix,
                              const l2_address_t& l2_address)
-  : interface(name, type_t::TAP, state)
+  : interface(name, type, state)
   , m_prefix(prefix)
   , m_l2_address(l2_address)
 {
@@ -59,8 +61,12 @@ tap_interface::tap_interface(const tap_interface& o)
 std::queue<cmd*>&
 tap_interface::mk_create_cmd(std::queue<cmd*>& q)
 {
-  q.push(
-    new tap_interface_cmds::create_cmd(m_hdl, name(), m_prefix, m_l2_address));
+  if (type_t::TAPV2 == type())
+    q.push(new tap_interface_cmds::tapv2_create_cmd(m_hdl, name(), m_prefix,
+                                                    m_l2_address));
+  else
+    q.push(new tap_interface_cmds::tap_create_cmd(m_hdl, name(), m_prefix,
+                                                  m_l2_address));
 
   return (q);
 }
@@ -68,7 +74,10 @@ tap_interface::mk_create_cmd(std::queue<cmd*>& q)
 std::queue<cmd*>&
 tap_interface::mk_delete_cmd(std::queue<cmd*>& q)
 {
-  q.push(new tap_interface_cmds::delete_cmd(m_hdl));
+  if (type_t::TAPV2 == type())
+    q.push(new tap_interface_cmds::tapv2_delete_cmd(m_hdl));
+  else
+    q.push(new tap_interface_cmds::tap_delete_cmd(m_hdl));
 
   return (q);
 }
@@ -88,32 +97,7 @@ tap_interface::singular_i() const
 void
 tap_interface::event_handler::handle_populate(const client_db::key_t& key)
 {
-  /*
-   * dump VPP current states
-   */
-  std::shared_ptr<tap_interface_cmds::dump_cmd> cmd =
-    std::make_shared<tap_interface_cmds::dump_cmd>();
-
-  HW::enqueue(cmd);
-  HW::write();
-
-  for (auto& record : *cmd) {
-    auto& payload = record.get_payload();
-
-    std::string name = reinterpret_cast<const char*>(payload.dev_name);
-
-    tap_interface itf(name, interface::admin_state_t::UP,
-                      route::prefix_t::ZERO);
-
-    VOM_LOG(log_level_t::DEBUG) << "tap-dump: " << itf.to_string();
-
-    /*
-     * Write each of the discovered interfaces into the OM,
-     * but disable the HW Command q whilst we do, so that no
-     * commands are sent to VPP
-     */
-    OM::commit(key, itf);
-  }
+  // It will be polulate by interface handler
 }
 
 tap_interface::event_handler::event_handler()
index d9df9a9..3b0072d 100644 (file)
@@ -26,10 +26,12 @@ class tap_interface : public interface
 {
 public:
   tap_interface(const std::string& name,
+                type_t type,
                 admin_state_t state,
                 route::prefix_t prefix);
 
   tap_interface(const std::string& name,
+                type_t type,
                 admin_state_t state,
                 route::prefix_t prefix,
                 const l2_address_t& l2_address);
@@ -75,10 +77,13 @@ private:
   static event_handler m_evh;
 
   /**
-   * Ip Prefix
+   * host Ip Prefix
    */
   route::prefix_t m_prefix;
 
+  /**
+   * host mac address
+   */
   l2_address_t m_l2_address;
 
   /**
index b088560..763ded5 100644 (file)
 #include "vom/tap_interface_cmds.hpp"
 
 #include <vapi/tap.api.vapi.hpp>
+#include <vapi/tapv2.api.vapi.hpp>
+
+DEFINE_VAPI_MSG_IDS_TAP_API_JSON;
+DEFINE_VAPI_MSG_IDS_TAPV2_API_JSON;
 
 namespace VOM {
 namespace tap_interface_cmds {
-create_cmd::create_cmd(HW::item<handle_t>& item,
-                       const std::string& name,
-                       route::prefix_t& prefix,
-                       const l2_address_t& l2_address)
+tap_create_cmd::tap_create_cmd(HW::item<handle_t>& item,
+                               const std::string& name,
+                               route::prefix_t& prefix,
+                               const l2_address_t& l2_address)
   : interface::create_cmd<vapi::Tap_connect>(item, name)
   , m_prefix(prefix)
   , m_l2_address(l2_address)
@@ -30,7 +34,7 @@ create_cmd::create_cmd(HW::item<handle_t>& item,
 }
 
 rc_t
-create_cmd::issue(connection& con)
+tap_create_cmd::issue(connection& con)
 {
   msg_t req(con.ctx(), std::ref(*this));
 
@@ -58,12 +62,15 @@ create_cmd::issue(connection& con)
   VAPI_CALL(req.execute());
 
   m_hw_item = wait();
+  if (m_hw_item.rc() == rc_t::OK) {
+    insert_interface();
+  }
 
   return rc_t::OK;
 }
 
 std::string
-create_cmd::to_string() const
+tap_create_cmd::to_string() const
 {
   std::ostringstream s;
   s << "tap-intf-create: " << m_hw_item.to_string()
@@ -72,20 +79,30 @@ create_cmd::to_string() const
   return (s.str());
 }
 
-delete_cmd::delete_cmd(HW::item<handle_t>& item)
+tap_delete_cmd::tap_delete_cmd(HW::item<handle_t>& item)
   : interface::delete_cmd<vapi::Tap_delete>(item)
 {
 }
 
 rc_t
-delete_cmd::issue(connection& con)
+tap_delete_cmd::issue(connection& con)
 {
-  // finally... call VPP
+  msg_t req(con.ctx(), std::ref(*this));
+
+  auto& payload = req.get_request().get_payload();
+  payload.sw_if_index = m_hw_item.data().value();
+
+  VAPI_CALL(req.execute());
 
+  wait();
+  m_hw_item.set(rc_t::NOOP);
+
+  remove_interface();
   return rc_t::OK;
 }
+
 std::string
-delete_cmd::to_string() const
+tap_delete_cmd::to_string() const
 {
   std::ostringstream s;
   s << "tap-itf-delete: " << m_hw_item.to_string();
@@ -93,18 +110,18 @@ delete_cmd::to_string() const
   return (s.str());
 }
 
-dump_cmd::dump_cmd()
+tap_dump_cmd::tap_dump_cmd()
 {
 }
 
 bool
-dump_cmd::operator==(const dump_cmd& other) const
+tap_dump_cmd::operator==(const tap_dump_cmd& other) const
 {
   return (true);
 }
 
 rc_t
-dump_cmd::issue(connection& con)
+tap_dump_cmd::issue(connection& con)
 {
   m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
 
@@ -116,10 +133,136 @@ dump_cmd::issue(connection& con)
 }
 
 std::string
-dump_cmd::to_string() const
+tap_dump_cmd::to_string() const
 {
   return ("tap-itf-dump");
 }
+
+/*
+ * TAPV2
+ */
+tapv2_create_cmd::tapv2_create_cmd(HW::item<handle_t>& item,
+                                   const std::string& name,
+                                   route::prefix_t& prefix,
+                                   const l2_address_t& l2_address)
+  : 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)
+{
+  msg_t req(con.ctx(), std::ref(*this));
+
+  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(),
+         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);
+    } 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;
+    }
+  }
+
+  if (m_l2_address != l2_address_t::ZERO) {
+    m_l2_address.to_bytes(payload.host_mac_addr, 6);
+    payload.host_mac_addr_set = 1;
+  }
+
+  payload.id = 0xffffffff;
+  payload.use_random_mac = 1;
+  payload.tx_ring_sz = 1024;
+  payload.rx_ring_sz = 1024;
+
+  VAPI_CALL(req.execute());
+
+  m_hw_item = wait();
+  if (m_hw_item.rc() == rc_t::OK) {
+    insert_interface();
+  }
+
+  return rc_t::OK;
+}
+
+std::string
+tapv2_create_cmd::to_string() const
+{
+  std::ostringstream s;
+  s << "tapv2-intf-create: " << m_hw_item.to_string()
+    << " ip-prefix:" << m_prefix.to_string();
+
+  return (s.str());
+}
+
+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)
+{
+
+  msg_t req(con.ctx(), std::ref(*this));
+
+  auto& payload = req.get_request().get_payload();
+
+  payload.sw_if_index = m_hw_item.data().value();
+
+  VAPI_CALL(req.execute());
+
+  wait();
+  m_hw_item.set(rc_t::NOOP);
+
+  remove_interface();
+  return rc_t::OK;
+}
+std::string
+tapv2_delete_cmd::to_string() const
+{
+  std::ostringstream s;
+  s << "tapv2-itf-delete: " << m_hw_item.to_string();
+
+  return (s.str());
+}
+
+tapv2_dump_cmd::tapv2_dump_cmd()
+{
+}
+
+bool
+tapv2_dump_cmd::operator==(const tapv2_dump_cmd& other) const
+{
+  return (true);
+}
+
+rc_t
+tapv2_dump_cmd::issue(connection& con)
+{
+  m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
+
+  VAPI_CALL(m_dump->execute());
+
+  wait();
+
+  return rc_t::OK;
+}
+
+std::string
+tapv2_dump_cmd::to_string() const
+{
+  return ("tapv2-itf-dump");
+}
+
 } // namespace tap_interface_cmds
 } // namespace VOM
 
index 1c1a346..5651b7c 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <vapi/interface.api.vapi.hpp>
 #include <vapi/tap.api.vapi.hpp>
+#include <vapi/tapv2.api.vapi.hpp>
 
 namespace VOM {
 namespace tap_interface_cmds {
@@ -30,10 +31,10 @@ namespace tap_interface_cmds {
 /**
  * A functor class that creates an interface
  */
-class create_cmd : public interface::create_cmd<vapi::Tap_connect>
+class tap_create_cmd : public interface::create_cmd<vapi::Tap_connect>
 {
 public:
-  create_cmd(HW::item<handle_t>& item,
+  tap_create_cmd(HW::item<handle_t>& item,
              const std::string& name,
              route::prefix_t& prefix,
              const l2_address_t& l2_address);
@@ -55,10 +56,10 @@ private:
 /**
  * A functor class that deletes a Tap interface
  */
-class delete_cmd : public interface::delete_cmd<vapi::Tap_delete>
+class tap_delete_cmd : public interface::delete_cmd<vapi::Tap_delete>
 {
 public:
-  delete_cmd(HW::item<handle_t>& item);
+  tap_delete_cmd(HW::item<handle_t>& item);
 
   /**
    * Issue the command to VPP/HW
@@ -73,13 +74,13 @@ public:
 /**
  * A cmd class that Dumps all the Vpp Interfaces
  */
-class dump_cmd : public VOM::dump_cmd<vapi::Sw_interface_tap_dump>
+class tap_dump_cmd : public VOM::dump_cmd<vapi::Sw_interface_tap_dump>
 {
 public:
   /**
    * Default Constructor
    */
-  dump_cmd();
+  tap_dump_cmd();
 
   /**
    * Issue the command to VPP/HW
@@ -93,7 +94,76 @@ public:
   /**
    * Comparison operator - only used for UT
    */
-  bool operator==(const dump_cmd& i) const;
+  bool operator==(const tap_dump_cmd& i) const;
+};
+
+/**
+ * A functor class that creates an interface
+ */
+class tapv2_create_cmd : public interface::create_cmd<vapi::Tap_create_v2>
+{
+public:
+  tapv2_create_cmd(HW::item<handle_t>& item,
+             const std::string& name,
+             route::prefix_t& prefix,
+             const l2_address_t& l2_address);
+
+  /**
+   * Issue the command to VPP/HW
+   */
+  rc_t issue(connection& con);
+  /**
+   * convert to string format for debug purposes
+   */
+  std::string to_string() const;
+
+private:
+  route::prefix_t& m_prefix;
+  const l2_address_t& m_l2_address;
+};
+
+/**
+ * A functor class that deletes a Tap interface
+ */
+class tapv2_delete_cmd : public interface::delete_cmd<vapi::Tap_delete_v2>
+{
+public:
+  tapv2_delete_cmd(HW::item<handle_t>& item);
+
+  /**
+   * Issue the command to VPP/HW
+   */
+  rc_t issue(connection& con);
+  /**
+   * convert to string format for debug purposes
+   */
+  std::string to_string() const;
+};
+
+/**
+ * A cmd class that Dumps all the Vpp Interfaces
+ */
+class tapv2_dump_cmd : public VOM::dump_cmd<vapi::Sw_interface_tap_v2_dump>
+{
+public:
+  /**
+   * Default Constructor
+   */
+  tapv2_dump_cmd();
+
+  /**
+   * Issue the command to VPP/HW
+   */
+  rc_t issue(connection& con);
+  /**
+   * convert to string format for debug purposes
+   */
+  std::string to_string() const;
+
+  /**
+   * Comparison operator - only used for UT
+   */
+  bool operator==(const tapv2_dump_cmd& i) const;
 };
 
 }; // namespace tap_interface_cmds