vom: Add TAPv2 support
Change-Id: I1fff014dd7d8a66ed3cb063e8c996de4f7e745c2 Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
This commit is contained in:
Mohsin Kazmi
committed by
Neale Ranns
parent
858151ff84
commit
9aca7b5ee9
@ -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>();
|
||||
|
||||
|
@ -99,6 +99,11 @@ public:
|
||||
*/
|
||||
const static type_t TAP;
|
||||
|
||||
/**
|
||||
* TAPv2 interface type
|
||||
*/
|
||||
const static type_t TAPV2;
|
||||
|
||||
/**
|
||||
* vhost-user interface type
|
||||
*/
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user