aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2018-07-04 15:17:01 +0200
committerNeale Ranns <nranns@cisco.com>2018-07-11 13:12:12 +0000
commit9aca7b5ee915b8035fb5b690b7520ab155fcb36e (patch)
treeb83cb84f64cffc16701f234f93957c213bbf6a73
parent858151ff84848b3803f37983e4fe8bc450cb45ce (diff)
vom: Add TAPv2 support
Change-Id: I1fff014dd7d8a66ed3cb063e8c996de4f7e745c2 Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
-rw-r--r--extras/vom/vom/interface.cpp61
-rw-r--r--extras/vom/vom/interface.hpp5
-rw-r--r--extras/vom/vom/interface_cmds.cpp73
-rw-r--r--extras/vom/vom/interface_cmds.hpp45
-rw-r--r--extras/vom/vom/interface_factory.cpp48
-rw-r--r--extras/vom/vom/interface_factory.hpp9
-rw-r--r--extras/vom/vom/interface_types.cpp10
-rw-r--r--extras/vom/vom/tap_interface.cpp46
-rw-r--r--extras/vom/vom/tap_interface.hpp7
-rw-r--r--extras/vom/vom/tap_interface_cmds.cpp171
-rw-r--r--extras/vom/vom/tap_interface_cmds.hpp84
11 files changed, 383 insertions, 176 deletions
diff --git a/extras/vom/vom/interface.cpp b/extras/vom/vom/interface.cpp
index 009e703000f..4f26ac80313 100644
--- a/extras/vom/vom/interface.cpp
+++ b/extras/vom/vom/interface.cpp
@@ -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>();
diff --git a/extras/vom/vom/interface.hpp b/extras/vom/vom/interface.hpp
index f6708b30176..92e14a791d6 100644
--- a/extras/vom/vom/interface.hpp
+++ b/extras/vom/vom/interface.hpp
@@ -100,6 +100,11 @@ public:
const static type_t TAP;
/**
+ * TAPv2 interface type
+ */
+ const static type_t TAPV2;
+
+ /**
* vhost-user interface type
*/
const static type_t VHOST;
diff --git a/extras/vom/vom/interface_cmds.cpp b/extras/vom/vom/interface_cmds.cpp
index fc1d71fa2d9..e78ed46272d 100644
--- a/extras/vom/vom/interface_cmds.cpp
+++ b/extras/vom/vom/interface_cmds.cpp
@@ -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();
diff --git a/extras/vom/vom/interface_cmds.hpp b/extras/vom/vom/interface_cmds.hpp
index d5c161dd113..1d0c4f543bc 100644
--- a/extras/vom/vom/interface_cmds.hpp
+++ b/extras/vom/vom/interface_cmds.hpp
@@ -87,30 +87,6 @@ public:
};
/**
-* 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
*/
class vhost_create_cmd
@@ -179,27 +155,6 @@ public:
};
/**
-* 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
*/
class vhost_delete_cmd
diff --git a/extras/vom/vom/interface_factory.cpp b/extras/vom/vom/interface_factory.cpp
index 715c3b6f4db..c417c1cc3de 100644
--- a/extras/vom/vom/interface_factory.cpp
+++ b/extras/vom/vom/interface_factory.cpp
@@ -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)
diff --git a/extras/vom/vom/interface_factory.hpp b/extras/vom/vom/interface_factory.hpp
index 613c26e98b5..1bb60a899f0 100644
--- a/extras/vom/vom/interface_factory.hpp
+++ b/extras/vom/vom/interface_factory.hpp
@@ -20,10 +20,13 @@
#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);
diff --git a/extras/vom/vom/interface_types.cpp b/extras/vom/vom/interface_types.cpp
index 139bdd52f9b..b20a3857146 100644
--- a/extras/vom/vom/interface_types.cpp
+++ b/extras/vom/vom/interface_types.cpp
@@ -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;
}
diff --git a/extras/vom/vom/tap_interface.cpp b/extras/vom/vom/tap_interface.cpp
index d7f16f5c132..4054e26466c 100644
--- a/extras/vom/vom/tap_interface.cpp
+++ b/extras/vom/vom/tap_interface.cpp
@@ -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()
diff --git a/extras/vom/vom/tap_interface.hpp b/extras/vom/vom/tap_interface.hpp
index d9df9a92a8d..3b0072d4a7d 100644
--- a/extras/vom/vom/tap_interface.hpp
+++ b/extras/vom/vom/tap_interface.hpp
@@ -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;
/**
diff --git a/extras/vom/vom/tap_interface_cmds.cpp b/extras/vom/vom/tap_interface_cmds.cpp
index b0885607742..763ded56bdc 100644
--- a/extras/vom/vom/tap_interface_cmds.cpp
+++ b/extras/vom/vom/tap_interface_cmds.cpp
@@ -16,13 +16,17 @@
#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
diff --git a/extras/vom/vom/tap_interface_cmds.hpp b/extras/vom/vom/tap_interface_cmds.hpp
index 1c1a3468c9b..5651b7cf193 100644
--- a/extras/vom/vom/tap_interface_cmds.hpp
+++ b/extras/vom/vom/tap_interface_cmds.hpp
@@ -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