GBP Endpoint Updates
- common types on the API - endpoints keyed in various ways for DP lookup - conparison functions for VPP IP address types Change-Id: If7ec0bbc5cea71fd0983fe78987d147ec1bd7ec8 Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
This commit is contained in:
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vom/gbp_endpoint.hpp"
|
#include "vom/gbp_endpoint.hpp"
|
||||||
|
#include "vom/api_types.hpp"
|
||||||
#include "vom/gbp_endpoint_cmds.hpp"
|
#include "vom/gbp_endpoint_cmds.hpp"
|
||||||
#include "vom/singular_db_funcs.hpp"
|
#include "vom/singular_db_funcs.hpp"
|
||||||
|
|
||||||
@ -23,22 +24,23 @@ singular_db<gbp_endpoint::key_t, gbp_endpoint> gbp_endpoint::m_db;
|
|||||||
|
|
||||||
gbp_endpoint::event_handler gbp_endpoint::m_evh;
|
gbp_endpoint::event_handler gbp_endpoint::m_evh;
|
||||||
|
|
||||||
gbp_endpoint::gbp_endpoint(const interface& itf,
|
gbp_endpoint::gbp_endpoint(
|
||||||
const boost::asio::ip::address& ip_addr,
|
const interface& itf,
|
||||||
const mac_address_t& mac,
|
const std::vector<boost::asio::ip::address>& ip_addrs,
|
||||||
const gbp_endpoint_group& epg)
|
const mac_address_t& mac,
|
||||||
: m_hw(false)
|
const gbp_endpoint_group& epg)
|
||||||
|
: m_hdl(handle_t::INVALID)
|
||||||
, m_itf(itf.singular())
|
, m_itf(itf.singular())
|
||||||
, m_ip(ip_addr)
|
, m_ips(ip_addrs)
|
||||||
, m_mac(mac)
|
, m_mac(mac)
|
||||||
, m_epg(epg.singular())
|
, m_epg(epg.singular())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
gbp_endpoint::gbp_endpoint(const gbp_endpoint& gbpe)
|
gbp_endpoint::gbp_endpoint(const gbp_endpoint& gbpe)
|
||||||
: m_hw(gbpe.m_hw)
|
: m_hdl(gbpe.m_hdl)
|
||||||
, m_itf(gbpe.m_itf)
|
, m_itf(gbpe.m_itf)
|
||||||
, m_ip(gbpe.m_ip)
|
, m_ips(gbpe.m_ips)
|
||||||
, m_mac(gbpe.m_mac)
|
, m_mac(gbpe.m_mac)
|
||||||
, m_epg(gbpe.m_epg)
|
, m_epg(gbpe.m_epg)
|
||||||
{
|
{
|
||||||
@ -53,7 +55,7 @@ gbp_endpoint::~gbp_endpoint()
|
|||||||
const gbp_endpoint::key_t
|
const gbp_endpoint::key_t
|
||||||
gbp_endpoint::key() const
|
gbp_endpoint::key() const
|
||||||
{
|
{
|
||||||
return (std::make_pair(m_itf->key(), m_ip));
|
return (std::make_pair(m_itf->key(), m_mac));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -65,8 +67,8 @@ gbp_endpoint::operator==(const gbp_endpoint& gbpe) const
|
|||||||
void
|
void
|
||||||
gbp_endpoint::sweep()
|
gbp_endpoint::sweep()
|
||||||
{
|
{
|
||||||
if (m_hw) {
|
if (m_hdl) {
|
||||||
HW::enqueue(new gbp_endpoint_cmds::delete_cmd(m_hw, m_itf->handle(), m_ip));
|
HW::enqueue(new gbp_endpoint_cmds::delete_cmd(m_hdl));
|
||||||
}
|
}
|
||||||
HW::write();
|
HW::write();
|
||||||
}
|
}
|
||||||
@ -74,8 +76,8 @@ gbp_endpoint::sweep()
|
|||||||
void
|
void
|
||||||
gbp_endpoint::replay()
|
gbp_endpoint::replay()
|
||||||
{
|
{
|
||||||
if (m_hw) {
|
if (m_hdl) {
|
||||||
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hw, m_itf->handle(), m_ip,
|
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hdl, m_itf->handle(), m_ips,
|
||||||
m_mac, m_epg->id()));
|
m_mac, m_epg->id()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,8 +86,12 @@ std::string
|
|||||||
gbp_endpoint::to_string() const
|
gbp_endpoint::to_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << "gbp-endpoint:[" << m_itf->to_string() << ", " << m_ip.to_string()
|
s << "gbp-endpoint:[" << m_itf->to_string() << ", ips:[";
|
||||||
<< ", " << m_mac.to_string() << ", epg:" << m_epg->to_string() << "]";
|
|
||||||
|
for (auto ip : m_ips)
|
||||||
|
s << ip.to_string();
|
||||||
|
|
||||||
|
s << "], " << m_mac.to_string() << ", epg:" << m_epg->to_string() << "]";
|
||||||
|
|
||||||
return (s.str());
|
return (s.str());
|
||||||
}
|
}
|
||||||
@ -93,8 +99,8 @@ gbp_endpoint::to_string() const
|
|||||||
void
|
void
|
||||||
gbp_endpoint::update(const gbp_endpoint& r)
|
gbp_endpoint::update(const gbp_endpoint& r)
|
||||||
{
|
{
|
||||||
if (rc_t::OK != m_hw.rc()) {
|
if (rc_t::OK != m_hdl.rc()) {
|
||||||
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hw, m_itf->handle(), m_ip,
|
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hdl, m_itf->handle(), m_ips,
|
||||||
m_mac, m_epg->id()));
|
m_mac, m_epg->id()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,18 +153,20 @@ gbp_endpoint::event_handler::handle_populate(const client_db::key_t& key)
|
|||||||
for (auto& record : *cmd) {
|
for (auto& record : *cmd) {
|
||||||
auto& payload = record.get_payload();
|
auto& payload = record.get_payload();
|
||||||
|
|
||||||
boost::asio::ip::address address =
|
std::vector<boost::asio::ip::address> addresses;
|
||||||
from_bytes(payload.endpoint.is_ip6, payload.endpoint.address);
|
|
||||||
|
for (uint8_t n = 0; n < payload.endpoint.n_ips; n++)
|
||||||
|
addresses.push_back(from_api(payload.endpoint.ips[n]));
|
||||||
std::shared_ptr<interface> itf =
|
std::shared_ptr<interface> itf =
|
||||||
interface::find(payload.endpoint.sw_if_index);
|
interface::find(payload.endpoint.sw_if_index);
|
||||||
std::shared_ptr<gbp_endpoint_group> epg =
|
std::shared_ptr<gbp_endpoint_group> epg =
|
||||||
gbp_endpoint_group::find(payload.endpoint.epg_id);
|
gbp_endpoint_group::find(payload.endpoint.epg_id);
|
||||||
mac_address_t mac(payload.endpoint.mac);
|
mac_address_t mac = from_api(payload.endpoint.mac);
|
||||||
|
|
||||||
VOM_LOG(log_level_t::DEBUG) << "data: " << payload.endpoint.sw_if_index;
|
VOM_LOG(log_level_t::DEBUG) << "data: " << payload.endpoint.sw_if_index;
|
||||||
|
|
||||||
if (itf && epg) {
|
if (itf && epg) {
|
||||||
gbp_endpoint gbpe(*itf, address, mac, *epg);
|
gbp_endpoint gbpe(*itf, addresses, mac, *epg);
|
||||||
OM::commit(key, gbpe);
|
OM::commit(key, gbpe);
|
||||||
|
|
||||||
VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string();
|
VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string();
|
||||||
@ -177,6 +185,15 @@ gbp_endpoint::event_handler::show(std::ostream& os)
|
|||||||
{
|
{
|
||||||
db_dump(m_db, os);
|
db_dump(m_db, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& os, const gbp_endpoint::key_t& key)
|
||||||
|
{
|
||||||
|
os << key.first << "," << key.second;
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace VOM
|
} // namespace VOM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#define __VOM_GBP_ENDPOINT_H__
|
#define __VOM_GBP_ENDPOINT_H__
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "vom/gbp_endpoint_group.hpp"
|
#include "vom/gbp_endpoint_group.hpp"
|
||||||
#include "vom/interface.hpp"
|
#include "vom/interface.hpp"
|
||||||
@ -32,13 +33,13 @@ public:
|
|||||||
/**
|
/**
|
||||||
* The key for a GBP endpoint; interface and IP
|
* The key for a GBP endpoint; interface and IP
|
||||||
*/
|
*/
|
||||||
typedef std::pair<interface::key_t, boost::asio::ip::address> key_t;
|
typedef std::pair<interface::key_t, mac_address_t> key_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a GBP endpoint
|
* Construct a GBP endpoint
|
||||||
*/
|
*/
|
||||||
gbp_endpoint(const interface& itf,
|
gbp_endpoint(const interface& itf,
|
||||||
const boost::asio::ip::address& ip_addr,
|
const std::vector<boost::asio::ip::address>& ip_addr,
|
||||||
const mac_address_t& mac,
|
const mac_address_t& mac,
|
||||||
const gbp_endpoint_group& epg);
|
const gbp_endpoint_group& epg);
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* HW configuration for the result of creating the endpoint
|
* HW configuration for the result of creating the endpoint
|
||||||
*/
|
*/
|
||||||
HW::item<bool> m_hw;
|
HW::item<handle_t> m_hdl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface the endpoint is attached to.
|
* The interface the endpoint is attached to.
|
||||||
@ -161,7 +162,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* The IP address of the endpoint
|
* The IP address of the endpoint
|
||||||
*/
|
*/
|
||||||
boost::asio::ip::address m_ip;
|
std::vector<boost::asio::ip::address> m_ips;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MAC address of the endpoint
|
* The MAC address of the endpoint
|
||||||
|
@ -14,20 +14,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vom/gbp_endpoint_cmds.hpp"
|
#include "vom/gbp_endpoint_cmds.hpp"
|
||||||
|
#include "vom/api_types.hpp"
|
||||||
|
|
||||||
DEFINE_VAPI_MSG_IDS_GBP_API_JSON;
|
DEFINE_VAPI_MSG_IDS_GBP_API_JSON;
|
||||||
|
|
||||||
namespace VOM {
|
namespace VOM {
|
||||||
namespace gbp_endpoint_cmds {
|
namespace gbp_endpoint_cmds {
|
||||||
|
|
||||||
create_cmd::create_cmd(HW::item<bool>& item,
|
create_cmd::create_cmd(HW::item<handle_t>& item,
|
||||||
const handle_t& itf,
|
const handle_t& itf,
|
||||||
const boost::asio::ip::address& ip_addr,
|
const std::vector<boost::asio::ip::address>& ip_addrs,
|
||||||
const mac_address_t& mac,
|
const mac_address_t& mac,
|
||||||
epg_id_t epg_id)
|
epg_id_t epg_id)
|
||||||
: rpc_cmd(item)
|
: rpc_cmd(item)
|
||||||
, m_itf(itf)
|
, m_itf(itf)
|
||||||
, m_ip_addr(ip_addr)
|
, m_ip_addrs(ip_addrs)
|
||||||
, m_mac(mac)
|
, m_mac(mac)
|
||||||
, m_epg_id(epg_id)
|
, m_epg_id(epg_id)
|
||||||
{
|
{
|
||||||
@ -36,50 +37,76 @@ create_cmd::create_cmd(HW::item<bool>& item,
|
|||||||
bool
|
bool
|
||||||
create_cmd::operator==(const create_cmd& other) const
|
create_cmd::operator==(const create_cmd& other) const
|
||||||
{
|
{
|
||||||
return ((m_itf == other.m_itf) && (m_ip_addr == other.m_ip_addr) &&
|
return ((m_itf == other.m_itf) && (m_ip_addrs == other.m_ip_addrs) &&
|
||||||
(m_mac == other.m_mac) && (m_epg_id == other.m_epg_id));
|
(m_mac == other.m_mac) && (m_epg_id == other.m_epg_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t
|
rc_t
|
||||||
create_cmd::issue(connection& con)
|
create_cmd::issue(connection& con)
|
||||||
{
|
{
|
||||||
msg_t req(con.ctx(), std::ref(*this));
|
msg_t req(con.ctx(), m_ip_addrs.size() * sizeof(vapi_type_address),
|
||||||
|
std::ref(*this));
|
||||||
|
uint8_t n;
|
||||||
|
|
||||||
auto& payload = req.get_request().get_payload();
|
auto& payload = req.get_request().get_payload();
|
||||||
payload.is_add = 1;
|
|
||||||
payload.endpoint.sw_if_index = m_itf.value();
|
payload.endpoint.sw_if_index = m_itf.value();
|
||||||
payload.endpoint.epg_id = m_epg_id;
|
payload.endpoint.epg_id = m_epg_id;
|
||||||
to_bytes(m_ip_addr, &payload.endpoint.is_ip6, payload.endpoint.address);
|
payload.endpoint.n_ips = m_ip_addrs.size();
|
||||||
m_mac.to_bytes(payload.endpoint.mac, 6);
|
|
||||||
|
for (n = 0; n < payload.endpoint.n_ips; n++) {
|
||||||
|
payload.endpoint.ips[n] = to_api(m_ip_addrs[n]);
|
||||||
|
}
|
||||||
|
payload.endpoint.mac = to_api(m_mac);
|
||||||
|
|
||||||
VAPI_CALL(req.execute());
|
VAPI_CALL(req.execute());
|
||||||
|
|
||||||
return (wait());
|
return (wait());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vapi_error_e
|
||||||
|
create_cmd::operator()(vapi::Gbp_endpoint_add& reply)
|
||||||
|
{
|
||||||
|
int handle = reply.get_response().get_payload().handle;
|
||||||
|
int retval = reply.get_response().get_payload().retval;
|
||||||
|
|
||||||
|
VOM_LOG(log_level_t::DEBUG) << this->to_string() << " " << retval;
|
||||||
|
|
||||||
|
rc_t rc = rc_t::from_vpp_retval(retval);
|
||||||
|
handle_t hdl = handle_t::INVALID;
|
||||||
|
|
||||||
|
if (rc_t::OK == rc) {
|
||||||
|
hdl = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->fulfill(HW::item<handle_t>(hdl, rc));
|
||||||
|
|
||||||
|
return (VAPI_OK);
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
create_cmd::to_string() const
|
create_cmd::to_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << "gbp-endpoint-create: " << m_hw_item.to_string() << " itf:" << m_itf
|
s << "gbp-endpoint-create: " << m_hw_item.to_string() << " itf:" << m_itf
|
||||||
<< " ip:" << m_ip_addr.to_string() << " epg-id:" << m_epg_id;
|
<< " ips:[";
|
||||||
|
for (auto ip : m_ip_addrs)
|
||||||
|
s << ip.to_string();
|
||||||
|
|
||||||
|
s << "] mac:" << m_mac;
|
||||||
|
s << " epg-id:" << m_epg_id;
|
||||||
|
|
||||||
return (s.str());
|
return (s.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_cmd::delete_cmd(HW::item<bool>& item,
|
delete_cmd::delete_cmd(HW::item<handle_t>& item)
|
||||||
const handle_t& itf,
|
|
||||||
const boost::asio::ip::address& ip_addr)
|
|
||||||
: rpc_cmd(item)
|
: rpc_cmd(item)
|
||||||
, m_itf(itf)
|
|
||||||
, m_ip_addr(ip_addr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
delete_cmd::operator==(const delete_cmd& other) const
|
delete_cmd::operator==(const delete_cmd& other) const
|
||||||
{
|
{
|
||||||
return ((m_itf == other.m_itf) && (m_ip_addr == other.m_ip_addr));
|
return (m_hw_item == other.m_hw_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t
|
rc_t
|
||||||
@ -88,10 +115,7 @@ delete_cmd::issue(connection& con)
|
|||||||
msg_t req(con.ctx(), std::ref(*this));
|
msg_t req(con.ctx(), std::ref(*this));
|
||||||
|
|
||||||
auto& payload = req.get_request().get_payload();
|
auto& payload = req.get_request().get_payload();
|
||||||
payload.is_add = 0;
|
payload.handle = m_hw_item.data().value();
|
||||||
payload.endpoint.sw_if_index = m_itf.value();
|
|
||||||
payload.endpoint.epg_id = ~0;
|
|
||||||
to_bytes(m_ip_addr, &payload.endpoint.is_ip6, payload.endpoint.address);
|
|
||||||
|
|
||||||
VAPI_CALL(req.execute());
|
VAPI_CALL(req.execute());
|
||||||
|
|
||||||
@ -102,8 +126,7 @@ std::string
|
|||||||
delete_cmd::to_string() const
|
delete_cmd::to_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << "gbp-endpoint-delete: " << m_hw_item.to_string() << " itf:" << m_itf
|
s << "gbp-endpoint-delete: " << m_hw_item.to_string();
|
||||||
<< " ip:" << m_ip_addr.to_string();
|
|
||||||
|
|
||||||
return (s.str());
|
return (s.str());
|
||||||
}
|
}
|
||||||
|
@ -27,15 +27,15 @@ namespace gbp_endpoint_cmds {
|
|||||||
/**
|
/**
|
||||||
* A command class that creates or updates the GBP endpoint
|
* A command class that creates or updates the GBP endpoint
|
||||||
*/
|
*/
|
||||||
class create_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_endpoint_add_del>
|
class create_cmd : public rpc_cmd<HW::item<handle_t>, vapi::Gbp_endpoint_add>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
create_cmd(HW::item<bool>& item,
|
create_cmd(HW::item<handle_t>& item,
|
||||||
const handle_t& itf,
|
const handle_t& itf,
|
||||||
const boost::asio::ip::address& ip_addr,
|
const std::vector<boost::asio::ip::address>& ip_addrs,
|
||||||
const mac_address_t& mac,
|
const mac_address_t& mac,
|
||||||
epg_id_t epg_id);
|
epg_id_t epg_id);
|
||||||
|
|
||||||
@ -49,6 +49,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
|
|
||||||
|
virtual vapi_error_e operator()(vapi::Gbp_endpoint_add& reply);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comparison operator - only used for UT
|
* Comparison operator - only used for UT
|
||||||
*/
|
*/
|
||||||
@ -56,7 +58,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const handle_t m_itf;
|
const handle_t m_itf;
|
||||||
const boost::asio::ip::address m_ip_addr;
|
const std::vector<boost::asio::ip::address> m_ip_addrs;
|
||||||
const mac_address_t m_mac;
|
const mac_address_t m_mac;
|
||||||
const epg_id_t m_epg_id;
|
const epg_id_t m_epg_id;
|
||||||
};
|
};
|
||||||
@ -64,15 +66,13 @@ private:
|
|||||||
/**
|
/**
|
||||||
* A cmd class that deletes a GBP endpoint
|
* A cmd class that deletes a GBP endpoint
|
||||||
*/
|
*/
|
||||||
class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_endpoint_add_del>
|
class delete_cmd : public rpc_cmd<HW::item<handle_t>, vapi::Gbp_endpoint_del>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
delete_cmd(HW::item<bool>& item,
|
delete_cmd(HW::item<handle_t>& item);
|
||||||
const handle_t& itf,
|
|
||||||
const boost::asio::ip::address& ip_addr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issue the command to VPP/HW
|
* Issue the command to VPP/HW
|
||||||
@ -90,8 +90,7 @@ public:
|
|||||||
bool operator==(const delete_cmd& i) const;
|
bool operator==(const delete_cmd& i) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const handle_t m_itf;
|
const handle_t m_hdl;
|
||||||
const boost::asio::ip::address m_ip_addr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vom/gbp_subnet.hpp"
|
#include "vom/gbp_subnet.hpp"
|
||||||
|
#include "vom/api_types.hpp"
|
||||||
#include "vom/gbp_subnet_cmds.hpp"
|
#include "vom/gbp_subnet_cmds.hpp"
|
||||||
#include "vom/singular_db_funcs.hpp"
|
#include "vom/singular_db_funcs.hpp"
|
||||||
|
|
||||||
@ -190,8 +191,7 @@ gbp_subnet::event_handler::handle_populate(const client_db::key_t& key)
|
|||||||
for (auto& record : *cmd) {
|
for (auto& record : *cmd) {
|
||||||
auto& payload = record.get_payload();
|
auto& payload = record.get_payload();
|
||||||
|
|
||||||
route::prefix_t pfx(payload.subnet.is_ip6, payload.subnet.address,
|
route::prefix_t pfx = from_api(payload.subnet.prefix);
|
||||||
payload.subnet.address_length);
|
|
||||||
std::shared_ptr<route_domain> rd =
|
std::shared_ptr<route_domain> rd =
|
||||||
route_domain::find(payload.subnet.table_id);
|
route_domain::find(payload.subnet.table_id);
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vom/gbp_subnet_cmds.hpp"
|
#include "vom/gbp_subnet_cmds.hpp"
|
||||||
|
#include "vom/api_types.hpp"
|
||||||
|
|
||||||
namespace VOM {
|
namespace VOM {
|
||||||
namespace gbp_subnet_cmds {
|
namespace gbp_subnet_cmds {
|
||||||
@ -52,8 +53,7 @@ create_cmd::issue(connection& con)
|
|||||||
payload.subnet.table_id = m_rd;
|
payload.subnet.table_id = m_rd;
|
||||||
payload.subnet.sw_if_index = m_itf.value();
|
payload.subnet.sw_if_index = m_itf.value();
|
||||||
payload.subnet.epg_id = m_epg_id;
|
payload.subnet.epg_id = m_epg_id;
|
||||||
m_prefix.to_vpp(&payload.subnet.is_ip6, payload.subnet.address,
|
payload.subnet.prefix = to_api(m_prefix);
|
||||||
&payload.subnet.address_length);
|
|
||||||
|
|
||||||
VAPI_CALL(req.execute());
|
VAPI_CALL(req.execute());
|
||||||
|
|
||||||
@ -94,8 +94,7 @@ delete_cmd::issue(connection& con)
|
|||||||
auto& payload = req.get_request().get_payload();
|
auto& payload = req.get_request().get_payload();
|
||||||
payload.is_add = 0;
|
payload.is_add = 0;
|
||||||
payload.subnet.table_id = m_rd;
|
payload.subnet.table_id = m_rd;
|
||||||
m_prefix.to_vpp(&payload.subnet.is_ip6, payload.subnet.address,
|
payload.subnet.prefix = to_api(m_prefix);
|
||||||
&payload.subnet.address_length);
|
|
||||||
|
|
||||||
payload.subnet.is_internal = 0;
|
payload.subnet.is_internal = 0;
|
||||||
payload.subnet.sw_if_index = ~0;
|
payload.subnet.sw_if_index = ~0;
|
||||||
|
@ -16,9 +16,8 @@
|
|||||||
#ifndef __VOM_PREFIX_H__
|
#ifndef __VOM_PREFIX_H__
|
||||||
#define __VOM_PREFIX_H__
|
#define __VOM_PREFIX_H__
|
||||||
|
|
||||||
#include <boost/asio/ip/address.hpp>
|
|
||||||
|
|
||||||
#include "vom/enum_base.hpp"
|
#include "vom/enum_base.hpp"
|
||||||
|
#include <boost/asio/ip/address.hpp>
|
||||||
|
|
||||||
namespace VOM {
|
namespace VOM {
|
||||||
/**
|
/**
|
||||||
@ -111,10 +110,12 @@ public:
|
|||||||
* Constructor with string and length
|
* Constructor with string and length
|
||||||
*/
|
*/
|
||||||
prefix_t(const std::string& s, uint8_t len);
|
prefix_t(const std::string& s, uint8_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy Constructor
|
* Copy Constructor
|
||||||
*/
|
*/
|
||||||
prefix_t(const prefix_t&);
|
prefix_t(const prefix_t&);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor with VPP API prefix representation
|
* Constructor with VPP API prefix representation
|
||||||
*/
|
*/
|
||||||
|
@ -14,30 +14,46 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
option version = "1.0.0";
|
option version = "2.0.0";
|
||||||
|
|
||||||
|
import "vnet/ip/ip_types.api";
|
||||||
|
import "vnet/ethernet/ethernet_types.api";
|
||||||
|
|
||||||
/** \brief Endpoint
|
/** \brief Endpoint
|
||||||
@param client_index - opaque cookie to identify the sender
|
@param client_index - opaque cookie to identify the sender
|
||||||
@param context - sender context, to match reply w/ request
|
@param context - sender context, to match reply w/ request
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typeonly define gbp_endpoint
|
typedef gbp_endpoint
|
||||||
{
|
{
|
||||||
u32 sw_if_index;
|
u32 sw_if_index;
|
||||||
u16 epg_id;
|
u16 epg_id;
|
||||||
u8 is_ip6;
|
vl_api_mac_address_t mac;
|
||||||
u8 address[16];
|
u8 n_ips;
|
||||||
u8 mac[6];
|
vl_api_address_t ips[n_ips];
|
||||||
};
|
};
|
||||||
|
|
||||||
autoreply define gbp_endpoint_add_del
|
define gbp_endpoint_add
|
||||||
{
|
{
|
||||||
u32 client_index;
|
u32 client_index;
|
||||||
u32 context;
|
u32 context;
|
||||||
u8 is_add;
|
|
||||||
vl_api_gbp_endpoint_t endpoint;
|
vl_api_gbp_endpoint_t endpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
define gbp_endpoint_add_reply
|
||||||
|
{
|
||||||
|
u32 context;
|
||||||
|
i32 retval;
|
||||||
|
u32 handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
autoreply define gbp_endpoint_del
|
||||||
|
{
|
||||||
|
u32 client_index;
|
||||||
|
u32 context;
|
||||||
|
u32 handle;
|
||||||
|
};
|
||||||
|
|
||||||
define gbp_endpoint_dump
|
define gbp_endpoint_dump
|
||||||
{
|
{
|
||||||
u32 client_index;
|
u32 client_index;
|
||||||
@ -111,10 +127,8 @@ typeonly define gbp_subnet
|
|||||||
u32 table_id;
|
u32 table_id;
|
||||||
u32 sw_if_index;
|
u32 sw_if_index;
|
||||||
u16 epg_id;
|
u16 epg_id;
|
||||||
u8 is_ip6;
|
|
||||||
u8 is_internal;
|
u8 is_internal;
|
||||||
u8 address_length;
|
vl_api_prefix_t prefix;
|
||||||
u8 address[16];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
autoreply define gbp_subnet_add_del
|
autoreply define gbp_subnet_add_del
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <vnet/interface.h>
|
#include <vnet/interface.h>
|
||||||
#include <vnet/api_errno.h>
|
#include <vnet/api_errno.h>
|
||||||
|
#include <vnet/ip/ip_types_api.h>
|
||||||
|
#include <vnet/ethernet/ethernet_types_api.h>
|
||||||
#include <vpp/app/version.h>
|
#include <vpp/app/version.h>
|
||||||
|
|
||||||
#include <gbp/gbp.h>
|
#include <gbp/gbp.h>
|
||||||
@ -52,7 +54,8 @@
|
|||||||
#include <vlibapi/api_helper_macros.h>
|
#include <vlibapi/api_helper_macros.h>
|
||||||
|
|
||||||
#define foreach_gbp_api_msg \
|
#define foreach_gbp_api_msg \
|
||||||
_(GBP_ENDPOINT_ADD_DEL, gbp_endpoint_add_del) \
|
_(GBP_ENDPOINT_ADD, gbp_endpoint_add) \
|
||||||
|
_(GBP_ENDPOINT_DEL, gbp_endpoint_del) \
|
||||||
_(GBP_ENDPOINT_DUMP, gbp_endpoint_dump) \
|
_(GBP_ENDPOINT_DUMP, gbp_endpoint_dump) \
|
||||||
_(GBP_SUBNET_ADD_DEL, gbp_subnet_add_del) \
|
_(GBP_SUBNET_ADD_DEL, gbp_subnet_add_del) \
|
||||||
_(GBP_SUBNET_DUMP, gbp_subnet_dump) \
|
_(GBP_SUBNET_DUMP, gbp_subnet_dump) \
|
||||||
@ -70,39 +73,55 @@ static u16 msg_id_base;
|
|||||||
#define GBP_MSG_BASE msg_id_base
|
#define GBP_MSG_BASE msg_id_base
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vl_api_gbp_endpoint_add_del_t_handler (vl_api_gbp_endpoint_add_del_t * mp)
|
vl_api_gbp_endpoint_add_t_handler (vl_api_gbp_endpoint_add_t * mp)
|
||||||
{
|
{
|
||||||
vl_api_gbp_endpoint_add_del_reply_t *rmp;
|
vl_api_gbp_endpoint_add_reply_t *rmp;
|
||||||
ip46_address_t ip = { };
|
u32 sw_if_index, handle;
|
||||||
u32 sw_if_index;
|
ip46_address_t *ips;
|
||||||
int rv = 0;
|
mac_address_t mac;
|
||||||
|
int rv = 0, ii;
|
||||||
|
|
||||||
|
VALIDATE_SW_IF_INDEX (&(mp->endpoint));
|
||||||
|
|
||||||
sw_if_index = ntohl (mp->endpoint.sw_if_index);
|
sw_if_index = ntohl (mp->endpoint.sw_if_index);
|
||||||
if (!vnet_sw_if_index_is_api_valid (sw_if_index))
|
|
||||||
goto bad_sw_if_index;
|
|
||||||
|
|
||||||
if (mp->endpoint.is_ip6)
|
ips = NULL;
|
||||||
{
|
|
||||||
clib_memcpy (&ip.ip6, mp->endpoint.address, sizeof (ip.ip6));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clib_memcpy (&ip.ip4, mp->endpoint.address, sizeof (ip.ip4));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp->is_add)
|
if (mp->endpoint.n_ips)
|
||||||
{
|
{
|
||||||
rv =
|
vec_validate (ips, mp->endpoint.n_ips - 1);
|
||||||
gbp_endpoint_update (sw_if_index, &ip, ntohs (mp->endpoint.epg_id));
|
|
||||||
}
|
vec_foreach_index (ii, ips)
|
||||||
else
|
{
|
||||||
{
|
ip_address_decode (&mp->endpoint.ips[ii], &ips[ii]);
|
||||||
gbp_endpoint_delete (sw_if_index, &ip);
|
}
|
||||||
}
|
}
|
||||||
|
mac_address_decode (&mp->endpoint.mac, &mac);
|
||||||
|
|
||||||
|
rv = gbp_endpoint_update (sw_if_index, ips, &mac,
|
||||||
|
ntohs (mp->endpoint.epg_id), &handle);
|
||||||
|
|
||||||
|
vec_free (ips);
|
||||||
|
|
||||||
BAD_SW_IF_INDEX_LABEL;
|
BAD_SW_IF_INDEX_LABEL;
|
||||||
|
|
||||||
REPLY_MACRO (VL_API_GBP_ENDPOINT_ADD_DEL_REPLY + GBP_MSG_BASE);
|
/* *INDENT-OFF* */
|
||||||
|
REPLY_MACRO2 (VL_API_GBP_ENDPOINT_ADD_REPLY + GBP_MSG_BASE,
|
||||||
|
({
|
||||||
|
rmp->handle = htonl (handle);
|
||||||
|
}));
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vl_api_gbp_endpoint_del_t_handler (vl_api_gbp_endpoint_del_t * mp)
|
||||||
|
{
|
||||||
|
vl_api_gbp_endpoint_del_reply_t *rmp;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
gbp_endpoint_delete (ntohl (mp->handle));
|
||||||
|
|
||||||
|
REPLY_MACRO (VL_API_GBP_ENDPOINT_DEL_REPLY + GBP_MSG_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct gbp_walk_ctx_t_
|
typedef struct gbp_walk_ctx_t_
|
||||||
@ -111,14 +130,16 @@ typedef struct gbp_walk_ctx_t_
|
|||||||
u32 context;
|
u32 context;
|
||||||
} gbp_walk_ctx_t;
|
} gbp_walk_ctx_t;
|
||||||
|
|
||||||
static int
|
static walk_rc_t
|
||||||
gbp_endpoint_send_details (gbp_endpoint_t * gbpe, void *args)
|
gbp_endpoint_send_details (gbp_endpoint_t * gbpe, void *args)
|
||||||
{
|
{
|
||||||
vl_api_gbp_endpoint_details_t *mp;
|
vl_api_gbp_endpoint_details_t *mp;
|
||||||
gbp_walk_ctx_t *ctx;
|
gbp_walk_ctx_t *ctx;
|
||||||
|
u8 n_ips, ii;
|
||||||
|
|
||||||
ctx = args;
|
ctx = args;
|
||||||
mp = vl_msg_api_alloc (sizeof (*mp));
|
n_ips = vec_len (gbpe->ge_ips);
|
||||||
|
mp = vl_msg_api_alloc (sizeof (*mp) + (sizeof (*mp->endpoint.ips) * n_ips));
|
||||||
if (!mp)
|
if (!mp)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -126,22 +147,20 @@ gbp_endpoint_send_details (gbp_endpoint_t * gbpe, void *args)
|
|||||||
mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_DETAILS + GBP_MSG_BASE);
|
mp->_vl_msg_id = ntohs (VL_API_GBP_ENDPOINT_DETAILS + GBP_MSG_BASE);
|
||||||
mp->context = ctx->context;
|
mp->context = ctx->context;
|
||||||
|
|
||||||
mp->endpoint.sw_if_index = ntohl (gbpe->ge_key->gek_sw_if_index);
|
mp->endpoint.sw_if_index = ntohl (gbpe->ge_sw_if_index);
|
||||||
mp->endpoint.is_ip6 = !ip46_address_is_ip4 (&gbpe->ge_key->gek_ip);
|
|
||||||
if (mp->endpoint.is_ip6)
|
|
||||||
clib_memcpy (&mp->endpoint.address,
|
|
||||||
&gbpe->ge_key->gek_ip.ip6,
|
|
||||||
sizeof (gbpe->ge_key->gek_ip.ip6));
|
|
||||||
else
|
|
||||||
clib_memcpy (&mp->endpoint.address,
|
|
||||||
&gbpe->ge_key->gek_ip.ip4,
|
|
||||||
sizeof (gbpe->ge_key->gek_ip.ip4));
|
|
||||||
|
|
||||||
mp->endpoint.epg_id = ntohs (gbpe->ge_epg_id);
|
mp->endpoint.epg_id = ntohs (gbpe->ge_epg_id);
|
||||||
|
mp->endpoint.n_ips = n_ips;
|
||||||
|
mac_address_encode (&gbpe->ge_mac, &mp->endpoint.mac);
|
||||||
|
|
||||||
|
vec_foreach_index (ii, gbpe->ge_ips)
|
||||||
|
{
|
||||||
|
ip_address_encode (&gbpe->ge_ips[ii], IP46_TYPE_ANY,
|
||||||
|
&mp->endpoint.ips[ii]);
|
||||||
|
}
|
||||||
|
|
||||||
vl_api_send_msg (ctx->reg, (u8 *) mp);
|
vl_api_send_msg (ctx->reg, (u8 *) mp);
|
||||||
|
|
||||||
return (1);
|
return (WALK_CONTINUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -195,18 +214,10 @@ static void
|
|||||||
vl_api_gbp_subnet_add_del_t_handler (vl_api_gbp_subnet_add_del_t * mp)
|
vl_api_gbp_subnet_add_del_t_handler (vl_api_gbp_subnet_add_del_t * mp)
|
||||||
{
|
{
|
||||||
vl_api_gbp_subnet_add_del_reply_t *rmp;
|
vl_api_gbp_subnet_add_del_reply_t *rmp;
|
||||||
|
fib_prefix_t pfx;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
fib_prefix_t pfx = {
|
|
||||||
.fp_len = mp->subnet.address_length,
|
|
||||||
.fp_proto = (mp->subnet.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (mp->subnet.is_ip6)
|
ip_prefix_decode (&mp->subnet.prefix, &pfx);
|
||||||
clib_memcpy (&pfx.fp_addr.ip6, mp->subnet.address,
|
|
||||||
sizeof (pfx.fp_addr.ip6));
|
|
||||||
else
|
|
||||||
clib_memcpy (&pfx.fp_addr.ip4, mp->subnet.address,
|
|
||||||
sizeof (pfx.fp_addr.ip4));
|
|
||||||
|
|
||||||
rv = gbp_subnet_add_del (ntohl (mp->subnet.table_id),
|
rv = gbp_subnet_add_del (ntohl (mp->subnet.table_id),
|
||||||
&pfx,
|
&pfx,
|
||||||
@ -238,16 +249,8 @@ gbp_subnet_send_details (u32 table_id,
|
|||||||
mp->subnet.is_internal = is_internal;
|
mp->subnet.is_internal = is_internal;
|
||||||
mp->subnet.sw_if_index = ntohl (sw_if_index);
|
mp->subnet.sw_if_index = ntohl (sw_if_index);
|
||||||
mp->subnet.epg_id = ntohs (epg);
|
mp->subnet.epg_id = ntohs (epg);
|
||||||
mp->subnet.is_ip6 = (pfx->fp_proto == FIB_PROTOCOL_IP6);
|
|
||||||
mp->subnet.address_length = pfx->fp_len;
|
|
||||||
mp->subnet.table_id = ntohl (table_id);
|
mp->subnet.table_id = ntohl (table_id);
|
||||||
if (mp->subnet.is_ip6)
|
ip_prefix_encode (pfx, &mp->subnet.prefix);
|
||||||
clib_memcpy (&mp->subnet.address,
|
|
||||||
&pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
|
|
||||||
else
|
|
||||||
clib_memcpy (&mp->subnet.address,
|
|
||||||
&pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
|
|
||||||
|
|
||||||
|
|
||||||
vl_api_send_msg (ctx->reg, (u8 *) mp);
|
vl_api_send_msg (ctx->reg, (u8 *) mp);
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ gbp_classify_inline (vlib_main_t * vm,
|
|||||||
while (n_left_from > 0 && n_left_to_next > 0)
|
while (n_left_from > 0 && n_left_to_next > 0)
|
||||||
{
|
{
|
||||||
u32 next0, bi0, src_epg, sw_if_index0;
|
u32 next0, bi0, src_epg, sw_if_index0;
|
||||||
|
const gbp_endpoint_t *gep0;
|
||||||
vlib_buffer_t *b0;
|
vlib_buffer_t *b0;
|
||||||
|
|
||||||
bi0 = from[0];
|
bi0 = from[0];
|
||||||
@ -97,7 +98,8 @@ gbp_classify_inline (vlib_main_t * vm,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
src_epg = gbp_port_to_epg (sw_if_index0);
|
gep0 = gbp_endpoint_get_itf (sw_if_index0);
|
||||||
|
src_epg = gep0->ge_epg_id;
|
||||||
if (is_l3)
|
if (is_l3)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,86 +18,110 @@
|
|||||||
|
|
||||||
#include <plugins/gbp/gbp_types.h>
|
#include <plugins/gbp/gbp_types.h>
|
||||||
#include <vnet/ip/ip.h>
|
#include <vnet/ip/ip.h>
|
||||||
|
#include <vnet/ethernet/mac_address.h>
|
||||||
|
|
||||||
|
#include <vppinfra/bihash_16_8.h>
|
||||||
|
#include <vppinfra/bihash_template.h>
|
||||||
|
#include <vppinfra/bihash_24_8.h>
|
||||||
|
#include <vppinfra/bihash_template.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The key for an Endpoint
|
* Flags for each endpoint
|
||||||
*/
|
*/
|
||||||
typedef struct gbp_endpoint_key_t_
|
typedef enum gbp_endpoint_flags_t_
|
||||||
{
|
{
|
||||||
/**
|
GBP_ENDPOINT_FLAG_NONE = 0,
|
||||||
* The interface on which the EP is connected
|
GBP_ENDPOINT_FLAG_BOUNCE = (1 << 0),
|
||||||
*/
|
GBP_ENDPOINT_FLAG_DYNAMIC = (1 << 1),
|
||||||
u32 gek_sw_if_index;
|
} gbp_endpoint_flags_t;
|
||||||
|
|
||||||
/**
|
|
||||||
* The IP[46] address of the endpoint
|
|
||||||
*/
|
|
||||||
ip46_address_t gek_ip;
|
|
||||||
} gbp_endpoint_key_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Group Based Policy Endpoint.
|
* A Group Based Policy Endpoint.
|
||||||
* This is typcially a VM on the local compute node for which policy must be
|
* This is typcially a VM or container. If the endpoint is local (i.e. on
|
||||||
* locally applied
|
* the smae compute node as VPP) then there is one interface per-endpoint.
|
||||||
|
* If the EP is remote,e.g. reachable onver a [vxlan] tunnel, then there
|
||||||
|
* will be multiple EPs reachable over the tunnel and they can be distingusihed
|
||||||
|
* via either their MAC or IP Address[es].
|
||||||
*/
|
*/
|
||||||
typedef struct gbp_endpoint_t_
|
typedef struct gbp_endpoint_t_
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The endpoint's interface and IP address
|
* The interface on which the EP is connected
|
||||||
*/
|
*/
|
||||||
gbp_endpoint_key_t *ge_key;
|
u32 ge_sw_if_index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A vector of ip addresses that below to the endpoint
|
||||||
|
*/
|
||||||
|
ip46_address_t *ge_ips;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MAC address of the endpoint
|
||||||
|
*/
|
||||||
|
mac_address_t ge_mac;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The endpoint's designated EPG
|
* The endpoint's designated EPG
|
||||||
*/
|
*/
|
||||||
epg_id_t ge_epg_id;
|
epg_id_t ge_epg_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint flags
|
||||||
|
*/
|
||||||
|
gbp_endpoint_flags_t ge_flags;
|
||||||
} gbp_endpoint_t;
|
} gbp_endpoint_t;
|
||||||
|
|
||||||
/**
|
extern u8 *format_gbp_endpoint (u8 * s, va_list * args);
|
||||||
* Result of a interface to EPG mapping.
|
|
||||||
* multiple Endpoints can occur on the same interface, so this
|
|
||||||
* mapping needs to be reference counted.
|
|
||||||
*/
|
|
||||||
typedef struct gbp_itf_t_
|
|
||||||
{
|
|
||||||
epg_id_t gi_epg;
|
|
||||||
u32 gi_ref_count;
|
|
||||||
} gbp_itf_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to source EPG DB - a per-interface vector
|
* Interface to source EPG DB - a per-interface vector
|
||||||
*/
|
*/
|
||||||
typedef struct gbp_itf_to_epg_db_t_
|
typedef struct gbp_ep_by_itf_db_t_
|
||||||
{
|
{
|
||||||
gbp_itf_t *gte_vec;
|
index_t *gte_vec;
|
||||||
} gbp_itf_to_epg_db_t;
|
} gbp_ep_by_itf_db_t;
|
||||||
|
|
||||||
|
typedef struct gbp_ep_by_ip_itf_db_t_
|
||||||
|
{
|
||||||
|
clib_bihash_24_8_t gte_table;
|
||||||
|
} gbp_ep_by_ip_itf_db_t;
|
||||||
|
|
||||||
|
typedef struct gbp_ep_by_mac_itf_db_t_
|
||||||
|
{
|
||||||
|
clib_bihash_16_8_t gte_table;
|
||||||
|
} gbp_ep_by_mac_itf_db_t;
|
||||||
|
|
||||||
extern int gbp_endpoint_update (u32 sw_if_index,
|
extern int gbp_endpoint_update (u32 sw_if_index,
|
||||||
const ip46_address_t * ip, epg_id_t epg_id);
|
const ip46_address_t * ip,
|
||||||
extern void gbp_endpoint_delete (u32 sw_if_index, const ip46_address_t * ip);
|
const mac_address_t * mac,
|
||||||
|
epg_id_t epg_id, u32 * handle);
|
||||||
|
extern void gbp_endpoint_delete (u32 handle);
|
||||||
|
|
||||||
typedef int (*gbp_endpoint_cb_t) (gbp_endpoint_t * gbpe, void *ctx);
|
typedef walk_rc_t (*gbp_endpoint_cb_t) (gbp_endpoint_t * gbpe, void *ctx);
|
||||||
extern void gbp_endpoint_walk (gbp_endpoint_cb_t cb, void *ctx);
|
extern void gbp_endpoint_walk (gbp_endpoint_cb_t cb, void *ctx);
|
||||||
|
|
||||||
/**
|
|
||||||
* Port to EPG mapping management
|
|
||||||
*/
|
|
||||||
extern void gbp_itf_epg_update (u32 sw_if_index, epg_id_t src_epg,
|
|
||||||
u8 do_policy);
|
|
||||||
extern void gbp_itf_epg_delete (u32 sw_if_index);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DP functions and databases
|
* DP functions and databases
|
||||||
*/
|
*/
|
||||||
extern gbp_itf_to_epg_db_t gbp_itf_to_epg_db;
|
extern gbp_ep_by_itf_db_t gbp_ep_by_itf_db;
|
||||||
|
extern gbp_ep_by_mac_itf_db_t gbp_ep_by_mac_itf_db;
|
||||||
|
extern gbp_ep_by_ip_itf_db_t gbp_ep_by_ip_itf_db;
|
||||||
|
extern gbp_endpoint_t *gbp_endpoint_pool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the source EPG for a port/interface
|
* Get the endpoint from a port/interface
|
||||||
*/
|
*/
|
||||||
always_inline u32
|
always_inline gbp_endpoint_t *
|
||||||
gbp_port_to_epg (u32 sw_if_index)
|
gbp_endpoint_get (index_t gbpei)
|
||||||
{
|
{
|
||||||
return (gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg);
|
return (pool_elt_at_index (gbp_endpoint_pool, gbpei));
|
||||||
|
}
|
||||||
|
|
||||||
|
always_inline gbp_endpoint_t *
|
||||||
|
gbp_endpoint_get_itf (u32 sw_if_index)
|
||||||
|
{
|
||||||
|
return (gbp_endpoint_get (gbp_ep_by_itf_db.gte_vec[sw_if_index]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -209,7 +209,7 @@ gbp_endpoint_group_cli (vlib_main_t * vm,
|
|||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
VLIB_CLI_COMMAND (gbp_endpoint_group_cli_node, static) = {
|
VLIB_CLI_COMMAND (gbp_endpoint_group_cli_node, static) = {
|
||||||
.path = "gbp endpoint-group",
|
.path = "gbp endpoint-group",
|
||||||
.short_help = "gbp endpoint-group [del] epg <ID> bd <ID> <interface>",
|
.short_help = "gbp endpoint-group [del] epg <ID> bd <ID> rd <ID> <interface>",
|
||||||
.function = gbp_endpoint_group_cli,
|
.function = gbp_endpoint_group_cli,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ gbp_policy (vlib_main_t * vm,
|
|||||||
|
|
||||||
while (n_left_from > 0 && n_left_to_next > 0)
|
while (n_left_from > 0 && n_left_to_next > 0)
|
||||||
{
|
{
|
||||||
|
const gbp_endpoint_t *gep0;
|
||||||
gbp_policy_next_t next0;
|
gbp_policy_next_t next0;
|
||||||
gbp_contract_key_t key0;
|
gbp_contract_key_t key0;
|
||||||
gbp_contract_value_t value0 = {
|
gbp_contract_value_t value0 = {
|
||||||
@ -107,7 +108,8 @@ gbp_policy (vlib_main_t * vm,
|
|||||||
* determine the src and dst EPG
|
* determine the src and dst EPG
|
||||||
*/
|
*/
|
||||||
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
|
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
|
||||||
key0.gck_dst = gbp_port_to_epg (sw_if_index0);
|
gep0 = gbp_endpoint_get_itf (sw_if_index0);
|
||||||
|
key0.gck_dst = gep0->ge_epg_id;
|
||||||
key0.gck_src = vnet_buffer2 (b0)->gbp.src_epg;
|
key0.gck_src = vnet_buffer2 (b0)->gbp.src_epg;
|
||||||
|
|
||||||
if (EPG_INVALID != key0.gck_src)
|
if (EPG_INVALID != key0.gck_src)
|
||||||
|
@ -85,7 +85,8 @@ gbp_recirc_add (u32 sw_if_index, epg_id_t epg_id, u8 is_ext)
|
|||||||
* the external EPG, these are classified to the NAT EPG
|
* the external EPG, these are classified to the NAT EPG
|
||||||
* based on its port
|
* based on its port
|
||||||
*/
|
*/
|
||||||
gbp_itf_epg_update (gr->gr_sw_if_index, gr->gr_epg, 0);
|
gbp_endpoint_update (gr->gr_sw_if_index,
|
||||||
|
NULL, NULL, gr->gr_epg, &gr->gr_ep);
|
||||||
vnet_feature_enable_disable ("ip4-unicast",
|
vnet_feature_enable_disable ("ip4-unicast",
|
||||||
"ip4-gbp-src-classify",
|
"ip4-gbp-src-classify",
|
||||||
gr->gr_sw_if_index, 1, 0, 0);
|
gr->gr_sw_if_index, 1, 0, 0);
|
||||||
@ -128,7 +129,7 @@ gbp_recirc_delete (u32 sw_if_index)
|
|||||||
|
|
||||||
if (gr->gr_is_ext)
|
if (gr->gr_is_ext)
|
||||||
{
|
{
|
||||||
gbp_itf_epg_delete (gr->gr_sw_if_index);
|
gbp_endpoint_delete (gr->gr_ep);
|
||||||
vnet_feature_enable_disable ("ip4-unicast",
|
vnet_feature_enable_disable ("ip4-unicast",
|
||||||
"ip4-gbp-src-classify",
|
"ip4-gbp-src-classify",
|
||||||
gr->gr_sw_if_index, 0, 0, 0);
|
gr->gr_sw_if_index, 0, 0, 0);
|
||||||
|
@ -44,6 +44,10 @@ typedef struct gpb_recirc_t_
|
|||||||
*/
|
*/
|
||||||
u32 gr_sw_if_index;
|
u32 gr_sw_if_index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The endpoint created to represent the reric interface
|
||||||
|
*/
|
||||||
|
index_t gr_ep;
|
||||||
} gbp_recirc_t;
|
} gbp_recirc_t;
|
||||||
|
|
||||||
extern int gbp_recirc_add (u32 sw_if_index, epg_id_t epg_id, u8 is_ext);
|
extern int gbp_recirc_add (u32 sw_if_index, epg_id_t epg_id, u8 is_ext);
|
||||||
|
@ -93,6 +93,13 @@ typedef CLIB_PACKED (union {
|
|||||||
#define ip46_address_is_zero(ip46) (((ip46)->as_u64[0] == 0) && ((ip46)->as_u64[1] == 0))
|
#define ip46_address_is_zero(ip46) (((ip46)->as_u64[0] == 0) && ((ip46)->as_u64[1] == 0))
|
||||||
#define ip46_address_is_equal(a1, a2) (((a1)->as_u64[0] == (a2)->as_u64[0]) \
|
#define ip46_address_is_equal(a1, a2) (((a1)->as_u64[0] == (a2)->as_u64[0]) \
|
||||||
&& ((a1)->as_u64[1] == (a2)->as_u64[1]))
|
&& ((a1)->as_u64[1] == (a2)->as_u64[1]))
|
||||||
|
static_always_inline void
|
||||||
|
ip46_address_copy (ip46_address_t * dst, const ip46_address_t * src)
|
||||||
|
{
|
||||||
|
dst->as_u64[0] = src->as_u64[0];
|
||||||
|
dst->as_u64[1] = src->as_u64[1];
|
||||||
|
}
|
||||||
|
|
||||||
#define ip46_address_initializer {{{ 0 }}}
|
#define ip46_address_initializer {{{ 0 }}}
|
||||||
|
|
||||||
always_inline ip46_address_t
|
always_inline ip46_address_t
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
from vpp_udp_encap import *
|
from vpp_udp_encap import *
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, DpoProto
|
from vpp_ip import DpoProto
|
||||||
|
from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable
|
||||||
|
|
||||||
from scapy.packet import Raw
|
from scapy.packet import Raw
|
||||||
from scapy.layers.l2 import Ether, ARP
|
from scapy.layers.l2 import Ether, ARP
|
||||||
|
@ -20,7 +20,8 @@ from vpp_pg_interface import CaptureTimeoutError, is_ipv6_misc
|
|||||||
from vpp_lo_interface import VppLoInterface
|
from vpp_lo_interface import VppLoInterface
|
||||||
from util import ppp
|
from util import ppp
|
||||||
from vpp_papi_provider import UnexpectedApiReturnValueError
|
from vpp_papi_provider import UnexpectedApiReturnValueError
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto
|
from vpp_ip import DpoProto
|
||||||
|
from vpp_ip_route import VppIpRoute, VppRoutePath
|
||||||
|
|
||||||
USEC_IN_SEC = 1000000
|
USEC_IN_SEC = 1000000
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ import unittest
|
|||||||
import socket
|
import socket
|
||||||
|
|
||||||
from framework import VppTestCase, VppTestRunner, running_extended_tests
|
from framework import VppTestCase, VppTestRunner, running_extended_tests
|
||||||
|
from vpp_ip import DpoProto
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
|
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
|
||||||
VppMplsTable, VppIpMRoute, VppMRoutePath, VppIpTable, \
|
VppMplsTable, VppIpMRoute, VppMRoutePath, VppIpTable, \
|
||||||
MRouteEntryFlags, MRouteItfFlags, MPLS_LABEL_INVALID, DpoProto, \
|
MRouteEntryFlags, MRouteItfFlags, MPLS_LABEL_INVALID, \
|
||||||
VppMplsLabel
|
VppMplsLabel
|
||||||
from vpp_bier import *
|
from vpp_bier import *
|
||||||
from vpp_udp_encap import *
|
from vpp_udp_encap import *
|
||||||
|
488
test/test_gbp.py
488
test/test_gbp.py
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,8 @@ from logging import *
|
|||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
from vpp_sub_interface import VppDot1QSubint
|
from vpp_sub_interface import VppDot1QSubint
|
||||||
from vpp_gre_interface import VppGreInterface, VppGre6Interface
|
from vpp_gre_interface import VppGreInterface, VppGre6Interface
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto, VppIpTable
|
from vpp_ip import DpoProto
|
||||||
|
from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable
|
||||||
from vpp_papi_provider import L2_VTR_OP
|
from vpp_papi_provider import L2_VTR_OP
|
||||||
|
|
||||||
from scapy.packet import Raw
|
from scapy.packet import Raw
|
||||||
|
@ -7,9 +7,10 @@ from framework import VppTestCase, VppTestRunner
|
|||||||
from util import ppp, ip6_normalize
|
from util import ppp, ip6_normalize
|
||||||
from vpp_sub_interface import VppSubInterface, VppDot1QSubint
|
from vpp_sub_interface import VppSubInterface, VppDot1QSubint
|
||||||
from vpp_pg_interface import is_ipv6_misc
|
from vpp_pg_interface import is_ipv6_misc
|
||||||
|
from vpp_ip import DpoProto
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
|
from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
|
||||||
VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \
|
VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \
|
||||||
VppMplsRoute, DpoProto, VppMplsTable, VppIpTable
|
VppMplsRoute, VppMplsTable, VppIpTable
|
||||||
from vpp_neighbor import find_nbr, VppNeighbor
|
from vpp_neighbor import find_nbr, VppNeighbor
|
||||||
|
|
||||||
from scapy.packet import Raw
|
from scapy.packet import Raw
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
|
from vpp_ip import DpoProto
|
||||||
from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal, \
|
from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal, \
|
||||||
MRouteItfFlags, MRouteEntryFlags, VppIpTable, DpoProto
|
MRouteItfFlags, MRouteEntryFlags, VppIpTable
|
||||||
|
|
||||||
from scapy.packet import Raw
|
from scapy.packet import Raw
|
||||||
from scapy.layers.l2 import Ether
|
from scapy.layers.l2 import Ether
|
||||||
|
@ -5,7 +5,8 @@ import unittest
|
|||||||
from scapy.layers.inet6 import IPv6, Ether, IP, UDP
|
from scapy.layers.inet6 import IPv6, Ether, IP, UDP
|
||||||
from scapy.all import fragment, RandShort
|
from scapy.all import fragment, RandShort
|
||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto, VppIpTable
|
from vpp_ip import DpoProto
|
||||||
|
from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable
|
||||||
from socket import AF_INET, AF_INET6, inet_pton
|
from socket import AF_INET, AF_INET6, inet_pton
|
||||||
import StringIO
|
import StringIO
|
||||||
|
|
||||||
|
@ -4,7 +4,8 @@ import unittest
|
|||||||
import socket
|
import socket
|
||||||
|
|
||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto
|
from vpp_ip import DpoProto
|
||||||
|
from vpp_ip_route import VppIpRoute, VppRoutePath
|
||||||
|
|
||||||
from scapy.layers.l2 import Ether, Raw
|
from scapy.layers.l2 import Ether, Raw
|
||||||
from scapy.layers.inet import IP, UDP, ICMP
|
from scapy.layers.inet import IP, UDP, ICMP
|
||||||
|
@ -4,9 +4,10 @@ import unittest
|
|||||||
import socket
|
import socket
|
||||||
|
|
||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
|
from vpp_ip import DpoProto
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
|
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
|
||||||
VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
|
VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
|
||||||
MRouteItfFlags, MRouteEntryFlags, DpoProto, VppIpTable, VppMplsTable, \
|
MRouteItfFlags, MRouteEntryFlags, VppIpTable, VppMplsTable, \
|
||||||
VppMplsLabel, MplsLspMode
|
VppMplsLabel, MplsLspMode
|
||||||
from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
|
from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ import unittest
|
|||||||
from scapy.layers.inet6 import IPv6, Ether, IP, UDP, ICMPv6PacketTooBig
|
from scapy.layers.inet6 import IPv6, Ether, IP, UDP, ICMPv6PacketTooBig
|
||||||
from scapy.layers.inet import ICMP
|
from scapy.layers.inet import ICMP
|
||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto
|
from vpp_ip import DpoProto
|
||||||
|
from vpp_ip_route import VppIpRoute, VppRoutePath
|
||||||
from socket import AF_INET, AF_INET6, inet_pton
|
from socket import AF_INET, AF_INET6, inet_pton
|
||||||
import StringIO
|
import StringIO
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ from scapy.layers.inet6 import IPv6
|
|||||||
|
|
||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
from vpp_sub_interface import VppP2PSubint
|
from vpp_sub_interface import VppP2PSubint
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto
|
from vpp_ip import DpoProto
|
||||||
|
from vpp_ip_route import VppIpRoute, VppRoutePath
|
||||||
from util import mactobinary
|
from util import mactobinary
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,8 +5,9 @@ import unittest
|
|||||||
from framework import VppTestCase, VppTestRunner
|
from framework import VppTestCase, VppTestRunner
|
||||||
from vpp_papi_provider import QOS_SOURCE
|
from vpp_papi_provider import QOS_SOURCE
|
||||||
from vpp_sub_interface import VppDot1QSubint
|
from vpp_sub_interface import VppDot1QSubint
|
||||||
|
from vpp_ip import DpoProto
|
||||||
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
|
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
|
||||||
VppMplsLabel, VppMplsTable, DpoProto
|
VppMplsLabel, VppMplsTable
|
||||||
|
|
||||||
from scapy.packet import Raw
|
from scapy.packet import Raw
|
||||||
from scapy.layers.l2 import Ether, Dot1Q
|
from scapy.layers.l2 import Ether, Dot1Q
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user