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:
Neale Ranns
2018-09-05 15:42:26 -07:00
committed by Neale Ranns
parent 0d8cbc1b15
commit c0a9314341
39 changed files with 1133 additions and 690 deletions

View File

@ -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
/* /*

View File

@ -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

View File

@ -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());
} }

View File

@ -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;
}; };
/** /**

View File

@ -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);

View File

@ -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;

View File

@ -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
*/ */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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,
}; };

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 *

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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