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/api_types.hpp"
#include "vom/gbp_endpoint_cmds.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::gbp_endpoint(const interface& itf,
const boost::asio::ip::address& ip_addr,
const mac_address_t& mac,
const gbp_endpoint_group& epg)
: m_hw(false)
gbp_endpoint::gbp_endpoint(
const interface& itf,
const std::vector<boost::asio::ip::address>& ip_addrs,
const mac_address_t& mac,
const gbp_endpoint_group& epg)
: m_hdl(handle_t::INVALID)
, m_itf(itf.singular())
, m_ip(ip_addr)
, m_ips(ip_addrs)
, m_mac(mac)
, m_epg(epg.singular())
{
}
gbp_endpoint::gbp_endpoint(const gbp_endpoint& gbpe)
: m_hw(gbpe.m_hw)
: m_hdl(gbpe.m_hdl)
, m_itf(gbpe.m_itf)
, m_ip(gbpe.m_ip)
, m_ips(gbpe.m_ips)
, m_mac(gbpe.m_mac)
, m_epg(gbpe.m_epg)
{
@ -53,7 +55,7 @@ gbp_endpoint::~gbp_endpoint()
const gbp_endpoint::key_t
gbp_endpoint::key() const
{
return (std::make_pair(m_itf->key(), m_ip));
return (std::make_pair(m_itf->key(), m_mac));
}
bool
@ -65,8 +67,8 @@ gbp_endpoint::operator==(const gbp_endpoint& gbpe) const
void
gbp_endpoint::sweep()
{
if (m_hw) {
HW::enqueue(new gbp_endpoint_cmds::delete_cmd(m_hw, m_itf->handle(), m_ip));
if (m_hdl) {
HW::enqueue(new gbp_endpoint_cmds::delete_cmd(m_hdl));
}
HW::write();
}
@ -74,8 +76,8 @@ gbp_endpoint::sweep()
void
gbp_endpoint::replay()
{
if (m_hw) {
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hw, m_itf->handle(), m_ip,
if (m_hdl) {
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hdl, m_itf->handle(), m_ips,
m_mac, m_epg->id()));
}
}
@ -84,8 +86,12 @@ std::string
gbp_endpoint::to_string() const
{
std::ostringstream s;
s << "gbp-endpoint:[" << m_itf->to_string() << ", " << m_ip.to_string()
<< ", " << m_mac.to_string() << ", epg:" << m_epg->to_string() << "]";
s << "gbp-endpoint:[" << m_itf->to_string() << ", ips:[";
for (auto ip : m_ips)
s << ip.to_string();
s << "], " << m_mac.to_string() << ", epg:" << m_epg->to_string() << "]";
return (s.str());
}
@ -93,8 +99,8 @@ gbp_endpoint::to_string() const
void
gbp_endpoint::update(const gbp_endpoint& r)
{
if (rc_t::OK != m_hw.rc()) {
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hw, m_itf->handle(), m_ip,
if (rc_t::OK != m_hdl.rc()) {
HW::enqueue(new gbp_endpoint_cmds::create_cmd(m_hdl, m_itf->handle(), m_ips,
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) {
auto& payload = record.get_payload();
boost::asio::ip::address address =
from_bytes(payload.endpoint.is_ip6, payload.endpoint.address);
std::vector<boost::asio::ip::address> addresses;
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 =
interface::find(payload.endpoint.sw_if_index);
std::shared_ptr<gbp_endpoint_group> epg =
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;
if (itf && epg) {
gbp_endpoint gbpe(*itf, address, mac, *epg);
gbp_endpoint gbpe(*itf, addresses, mac, *epg);
OM::commit(key, gbpe);
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);
}
std::ostream&
operator<<(std::ostream& os, const gbp_endpoint::key_t& key)
{
os << key.first << "," << key.second;
return os;
}
} // namespace VOM
/*

View File

@ -17,6 +17,7 @@
#define __VOM_GBP_ENDPOINT_H__
#include <ostream>
#include <vector>
#include "vom/gbp_endpoint_group.hpp"
#include "vom/interface.hpp"
@ -32,13 +33,13 @@ public:
/**
* 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
*/
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 gbp_endpoint_group& epg);
@ -151,7 +152,7 @@ private:
/**
* 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.
@ -161,7 +162,7 @@ private:
/**
* 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

View File

@ -14,20 +14,21 @@
*/
#include "vom/gbp_endpoint_cmds.hpp"
#include "vom/api_types.hpp"
DEFINE_VAPI_MSG_IDS_GBP_API_JSON;
namespace VOM {
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 boost::asio::ip::address& ip_addr,
const std::vector<boost::asio::ip::address>& ip_addrs,
const mac_address_t& mac,
epg_id_t epg_id)
: rpc_cmd(item)
, m_itf(itf)
, m_ip_addr(ip_addr)
, m_ip_addrs(ip_addrs)
, m_mac(mac)
, m_epg_id(epg_id)
{
@ -36,50 +37,76 @@ create_cmd::create_cmd(HW::item<bool>& item,
bool
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));
}
rc_t
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();
payload.is_add = 1;
payload.endpoint.sw_if_index = m_itf.value();
payload.endpoint.epg_id = m_epg_id;
to_bytes(m_ip_addr, &payload.endpoint.is_ip6, payload.endpoint.address);
m_mac.to_bytes(payload.endpoint.mac, 6);
payload.endpoint.n_ips = m_ip_addrs.size();
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());
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
create_cmd::to_string() const
{
std::ostringstream s;
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());
}
delete_cmd::delete_cmd(HW::item<bool>& item,
const handle_t& itf,
const boost::asio::ip::address& ip_addr)
delete_cmd::delete_cmd(HW::item<handle_t>& item)
: rpc_cmd(item)
, m_itf(itf)
, m_ip_addr(ip_addr)
{
}
bool
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
@ -88,10 +115,7 @@ delete_cmd::issue(connection& con)
msg_t req(con.ctx(), std::ref(*this));
auto& payload = req.get_request().get_payload();
payload.is_add = 0;
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);
payload.handle = m_hw_item.data().value();
VAPI_CALL(req.execute());
@ -102,8 +126,7 @@ std::string
delete_cmd::to_string() const
{
std::ostringstream s;
s << "gbp-endpoint-delete: " << m_hw_item.to_string() << " itf:" << m_itf
<< " ip:" << m_ip_addr.to_string();
s << "gbp-endpoint-delete: " << m_hw_item.to_string();
return (s.str());
}

View File

@ -27,15 +27,15 @@ namespace gbp_endpoint_cmds {
/**
* 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:
/**
* Constructor
*/
create_cmd(HW::item<bool>& item,
create_cmd(HW::item<handle_t>& item,
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,
epg_id_t epg_id);
@ -49,6 +49,8 @@ public:
*/
std::string to_string() const;
virtual vapi_error_e operator()(vapi::Gbp_endpoint_add& reply);
/**
* Comparison operator - only used for UT
*/
@ -56,7 +58,7 @@ public:
private:
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 epg_id_t m_epg_id;
};
@ -64,15 +66,13 @@ private:
/**
* 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:
/**
* Constructor
*/
delete_cmd(HW::item<bool>& item,
const handle_t& itf,
const boost::asio::ip::address& ip_addr);
delete_cmd(HW::item<handle_t>& item);
/**
* Issue the command to VPP/HW
@ -90,8 +90,7 @@ public:
bool operator==(const delete_cmd& i) const;
private:
const handle_t m_itf;
const boost::asio::ip::address m_ip_addr;
const handle_t m_hdl;
};
/**

View File

@ -14,6 +14,7 @@
*/
#include "vom/gbp_subnet.hpp"
#include "vom/api_types.hpp"
#include "vom/gbp_subnet_cmds.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) {
auto& payload = record.get_payload();
route::prefix_t pfx(payload.subnet.is_ip6, payload.subnet.address,
payload.subnet.address_length);
route::prefix_t pfx = from_api(payload.subnet.prefix);
std::shared_ptr<route_domain> rd =
route_domain::find(payload.subnet.table_id);

View File

@ -14,6 +14,7 @@
*/
#include "vom/gbp_subnet_cmds.hpp"
#include "vom/api_types.hpp"
namespace VOM {
namespace gbp_subnet_cmds {
@ -52,8 +53,7 @@ create_cmd::issue(connection& con)
payload.subnet.table_id = m_rd;
payload.subnet.sw_if_index = m_itf.value();
payload.subnet.epg_id = m_epg_id;
m_prefix.to_vpp(&payload.subnet.is_ip6, payload.subnet.address,
&payload.subnet.address_length);
payload.subnet.prefix = to_api(m_prefix);
VAPI_CALL(req.execute());
@ -94,8 +94,7 @@ delete_cmd::issue(connection& con)
auto& payload = req.get_request().get_payload();
payload.is_add = 0;
payload.subnet.table_id = m_rd;
m_prefix.to_vpp(&payload.subnet.is_ip6, payload.subnet.address,
&payload.subnet.address_length);
payload.subnet.prefix = to_api(m_prefix);
payload.subnet.is_internal = 0;
payload.subnet.sw_if_index = ~0;

View File

@ -16,9 +16,8 @@
#ifndef __VOM_PREFIX_H__
#define __VOM_PREFIX_H__
#include <boost/asio/ip/address.hpp>
#include "vom/enum_base.hpp"
#include <boost/asio/ip/address.hpp>
namespace VOM {
/**
@ -111,10 +110,12 @@ public:
* Constructor with string and length
*/
prefix_t(const std::string& s, uint8_t len);
/**
* Copy Constructor
*/
prefix_t(const prefix_t&);
/**
* Constructor with VPP API prefix representation
*/

View File

@ -14,30 +14,46 @@
* 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
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
*/
typeonly define gbp_endpoint
typedef gbp_endpoint
{
u32 sw_if_index;
u16 epg_id;
u8 is_ip6;
u8 address[16];
u8 mac[6];
vl_api_mac_address_t mac;
u8 n_ips;
vl_api_address_t ips[n_ips];
};
autoreply define gbp_endpoint_add_del
define gbp_endpoint_add
{
u32 client_index;
u32 context;
u8 is_add;
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
{
u32 client_index;
@ -111,10 +127,8 @@ typeonly define gbp_subnet
u32 table_id;
u32 sw_if_index;
u16 epg_id;
u8 is_ip6;
u8 is_internal;
u8 address_length;
u8 address[16];
vl_api_prefix_t prefix;
};
autoreply define gbp_subnet_add_del

View File

@ -20,6 +20,8 @@
#include <vnet/interface.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 <gbp/gbp.h>
@ -52,7 +54,8 @@
#include <vlibapi/api_helper_macros.h>
#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_SUBNET_ADD_DEL, gbp_subnet_add_del) \
_(GBP_SUBNET_DUMP, gbp_subnet_dump) \
@ -70,39 +73,55 @@ static u16 msg_id_base;
#define GBP_MSG_BASE msg_id_base
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;
ip46_address_t ip = { };
u32 sw_if_index;
int rv = 0;
vl_api_gbp_endpoint_add_reply_t *rmp;
u32 sw_if_index, handle;
ip46_address_t *ips;
mac_address_t mac;
int rv = 0, ii;
VALIDATE_SW_IF_INDEX (&(mp->endpoint));
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)
{
clib_memcpy (&ip.ip6, mp->endpoint.address, sizeof (ip.ip6));
}
else
{
clib_memcpy (&ip.ip4, mp->endpoint.address, sizeof (ip.ip4));
}
ips = NULL;
if (mp->is_add)
if (mp->endpoint.n_ips)
{
rv =
gbp_endpoint_update (sw_if_index, &ip, ntohs (mp->endpoint.epg_id));
}
else
{
gbp_endpoint_delete (sw_if_index, &ip);
vec_validate (ips, mp->endpoint.n_ips - 1);
vec_foreach_index (ii, ips)
{
ip_address_decode (&mp->endpoint.ips[ii], &ips[ii]);
}
}
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;
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_
@ -111,14 +130,16 @@ typedef struct gbp_walk_ctx_t_
u32 context;
} gbp_walk_ctx_t;
static int
static walk_rc_t
gbp_endpoint_send_details (gbp_endpoint_t * gbpe, void *args)
{
vl_api_gbp_endpoint_details_t *mp;
gbp_walk_ctx_t *ctx;
u8 n_ips, ii;
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)
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->context = ctx->context;
mp->endpoint.sw_if_index = ntohl (gbpe->ge_key->gek_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.sw_if_index = ntohl (gbpe->ge_sw_if_index);
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);
return (1);
return (WALK_CONTINUE);
}
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_reply_t *rmp;
fib_prefix_t pfx;
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)
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));
ip_prefix_decode (&mp->subnet.prefix, &pfx);
rv = gbp_subnet_add_del (ntohl (mp->subnet.table_id),
&pfx,
@ -238,16 +249,8 @@ gbp_subnet_send_details (u32 table_id,
mp->subnet.is_internal = is_internal;
mp->subnet.sw_if_index = ntohl (sw_if_index);
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);
if (mp->subnet.is_ip6)
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));
ip_prefix_encode (pfx, &mp->subnet.prefix);
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)
{
u32 next0, bi0, src_epg, sw_if_index0;
const gbp_endpoint_t *gep0;
vlib_buffer_t *b0;
bi0 = from[0];
@ -97,7 +98,8 @@ gbp_classify_inline (vlib_main_t * vm,
}
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)
{
/*

File diff suppressed because it is too large Load Diff

View File

@ -18,86 +18,110 @@
#include <plugins/gbp/gbp_types.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_
{
/**
* The interface on which the EP is connected
*/
u32 gek_sw_if_index;
/**
* The IP[46] address of the endpoint
*/
ip46_address_t gek_ip;
} gbp_endpoint_key_t;
GBP_ENDPOINT_FLAG_NONE = 0,
GBP_ENDPOINT_FLAG_BOUNCE = (1 << 0),
GBP_ENDPOINT_FLAG_DYNAMIC = (1 << 1),
} gbp_endpoint_flags_t;
/**
* A Group Based Policy Endpoint.
* This is typcially a VM on the local compute node for which policy must be
* locally applied
* This is typcially a VM or container. If the endpoint is local (i.e. on
* 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_
{
/**
* 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
*/
epg_id_t ge_epg_id;
/**
* Endpoint flags
*/
gbp_endpoint_flags_t ge_flags;
} gbp_endpoint_t;
/**
* 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;
extern u8 *format_gbp_endpoint (u8 * s, va_list * args);
/**
* 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;
} gbp_itf_to_epg_db_t;
index_t *gte_vec;
} 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,
const ip46_address_t * ip, epg_id_t epg_id);
extern void gbp_endpoint_delete (u32 sw_if_index, const ip46_address_t * ip);
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);
/**
* 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
*/
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
gbp_port_to_epg (u32 sw_if_index)
always_inline gbp_endpoint_t *
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

View File

@ -209,7 +209,7 @@ gbp_endpoint_group_cli (vlib_main_t * vm,
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (gbp_endpoint_group_cli_node, static) = {
.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,
};

View File

@ -85,6 +85,7 @@ gbp_policy (vlib_main_t * vm,
while (n_left_from > 0 && n_left_to_next > 0)
{
const gbp_endpoint_t *gep0;
gbp_policy_next_t next0;
gbp_contract_key_t key0;
gbp_contract_value_t value0 = {
@ -107,7 +108,8 @@ gbp_policy (vlib_main_t * vm,
* determine the src and dst EPG
*/
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;
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
* 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",
"ip4-gbp-src-classify",
gr->gr_sw_if_index, 1, 0, 0);
@ -128,7 +129,7 @@ gbp_recirc_delete (u32 sw_if_index)
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",
"ip4-gbp-src-classify",
gr->gr_sw_if_index, 0, 0, 0);

View File

@ -44,6 +44,10 @@ typedef struct gpb_recirc_t_
*/
u32 gr_sw_if_index;
/**
* The endpoint created to represent the reric interface
*/
index_t gr_ep;
} gbp_recirc_t;
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_equal(a1, a2) (((a1)->as_u64[0] == (a2)->as_u64[0]) \
&& ((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 }}}
always_inline ip46_address_t

View File

@ -2,7 +2,8 @@
from framework import VppTestCase, VppTestRunner
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.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 util import ppp
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

View File

@ -4,9 +4,10 @@ import unittest
import socket
from framework import VppTestCase, VppTestRunner, running_extended_tests
from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
VppMplsTable, VppIpMRoute, VppMRoutePath, VppIpTable, \
MRouteEntryFlags, MRouteItfFlags, MPLS_LABEL_INVALID, DpoProto, \
MRouteEntryFlags, MRouteItfFlags, MPLS_LABEL_INVALID, \
VppMplsLabel
from vpp_bier 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 vpp_sub_interface import VppDot1QSubint
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 scapy.packet import Raw

View File

@ -7,9 +7,10 @@ from framework import VppTestCase, VppTestRunner
from util import ppp, ip6_normalize
from vpp_sub_interface import VppSubInterface, VppDot1QSubint
from vpp_pg_interface import is_ipv6_misc
from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \
VppMplsRoute, DpoProto, VppMplsTable, VppIpTable
VppMplsRoute, VppMplsTable, VppIpTable
from vpp_neighbor import find_nbr, VppNeighbor
from scapy.packet import Raw

View File

@ -3,8 +3,9 @@
import unittest
from framework import VppTestCase, VppTestRunner
from vpp_ip import DpoProto
from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal, \
MRouteItfFlags, MRouteEntryFlags, VppIpTable, DpoProto
MRouteItfFlags, MRouteEntryFlags, VppIpTable
from scapy.packet import Raw
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.all import fragment, RandShort
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
import StringIO

View File

@ -4,7 +4,8 @@ import unittest
import socket
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.inet import IP, UDP, ICMP

View File

@ -4,9 +4,10 @@ import unittest
import socket
from framework import VppTestCase, VppTestRunner
from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
MRouteItfFlags, MRouteEntryFlags, DpoProto, VppIpTable, VppMplsTable, \
MRouteItfFlags, MRouteEntryFlags, VppIpTable, VppMplsTable, \
VppMplsLabel, MplsLspMode
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.inet import ICMP
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
import StringIO

View File

@ -11,7 +11,8 @@ from scapy.layers.inet6 import IPv6
from framework import VppTestCase, VppTestRunner
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

View File

@ -5,8 +5,9 @@ import unittest
from framework import VppTestCase, VppTestRunner
from vpp_papi_provider import QOS_SOURCE
from vpp_sub_interface import VppDot1QSubint
from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
VppMplsLabel, VppMplsTable, DpoProto
VppMplsLabel, VppMplsTable
from scapy.packet import Raw
from scapy.layers.l2 import Ether, Dot1Q

Some files were not shown because too many files have changed in this diff Show More