aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/gbp/gbp_endpoint.c
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2018-09-05 15:42:26 -0700
committerNeale Ranns <nranns@cisco.com>2018-09-11 16:00:29 +0000
commitc0a93143412b4be7bba087bf633855aeeaee7c56 (patch)
treed3031d3a0af0963f75b54c169299425cd5d63319 /src/plugins/gbp/gbp_endpoint.c
parent0d8cbc1b1503b633fd024e498e7664b489841075 (diff)
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>
Diffstat (limited to 'src/plugins/gbp/gbp_endpoint.c')
-rw-r--r--src/plugins/gbp/gbp_endpoint.c602
1 files changed, 413 insertions, 189 deletions
diff --git a/src/plugins/gbp/gbp_endpoint.c b/src/plugins/gbp/gbp_endpoint.c
index 0522f613f7d..a261527a177 100644
--- a/src/plugins/gbp/gbp_endpoint.c
+++ b/src/plugins/gbp/gbp_endpoint.c
@@ -23,200 +23,340 @@
#include <vnet/l2/l2_output.h>
#include <vnet/l2/feat_bitmap.h>
-/**
- * IP4 destintion address to destination EPG mapping table
- */
-typedef struct gbp_ip4_to_epg_db_t_
-{
- /**
- * use a simple hash table
- */
- uword *g4ie_hash;
-} gbp_ip4_to_epg_db_t;
-
-static gbp_ip4_to_epg_db_t gbp_ip4_to_epg_db;
+gbp_ep_by_itf_db_t gbp_ep_by_itf_db;
+gbp_ep_by_mac_itf_db_t gbp_ep_by_mac_itf_db;
+gbp_ep_by_ip_itf_db_t gbp_ep_by_ip_itf_db;
/**
- * IP6 destintion address to destination EPG mapping table
+ * Pool of GBP endpoints
*/
-typedef struct gbp_ip6_to_epg_db_t_
+gbp_endpoint_t *gbp_endpoint_pool;
+
+/* void */
+/* gbp_itf_epg_update (u32 sw_if_index, epg_id_t src_epg, u8 do_policy) */
+/* { */
+/* vec_validate_init_empty (gbp_itf_to_epg_db.gte_vec, */
+/* sw_if_index, ITF_INVALID); */
+
+/* if (0 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count) */
+/* { */
+/* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY, */
+/* 1); */
+/* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 1); */
+/* if (do_policy) */
+/* l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, */
+/* 1); */
+/* } */
+/* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = src_epg; */
+/* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count++; */
+/* } */
+
+/* void */
+/* gbp_itf_epg_delete (u32 sw_if_index) */
+/* { */
+/* if (vec_len (gbp_itf_to_epg_db.gte_vec) <= sw_if_index) */
+/* return; */
+
+/* if (1 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count) */
+/* { */
+/* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = EPG_INVALID; */
+
+/* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY, */
+/* 0); */
+/* l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 0); */
+/* l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, 0); */
+/* } */
+/* gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count--; */
+/* } */
+
+static void
+gbp_endpoint_mk_key_mac_itf (const mac_address_t * mac,
+ u32 sw_if_index, clib_bihash_kv_16_8_t * key)
{
- /**
- * use a memroy hash table
- */
- uword *g6ie_hash;
-} gbp_ip6_to_epg_db_t;
+ key->key[0] = mac_address_as_u64 (mac);
+ key->key[1] = sw_if_index;
+}
-static gbp_ip6_to_epg_db_t gbp_ip6_to_epg_db;
+static void
+gbp_endpoint_extract_key_mac_itf (const clib_bihash_kv_16_8_t * key,
+ mac_address_t * mac, u32 * sw_if_index)
+{
+ mac_address_from_u64 (key->key[0], mac);
+ *sw_if_index = key->key[1];
+}
+gbp_endpoint_t *
+gbp_endpoint_find_mac_itf (const mac_address_t * mac, u32 sw_if_index)
+{
+ clib_bihash_kv_16_8_t key, value;
+ int rv;
-const static gbp_itf_t ITF_INVALID = {
- .gi_epg = EPG_INVALID,
- .gi_ref_count = 0,
-};
+ gbp_endpoint_mk_key_mac_itf (mac, sw_if_index, &key);
-gbp_itf_to_epg_db_t gbp_itf_to_epg_db;
+ rv =
+ clib_bihash_search_16_8 (&gbp_ep_by_mac_itf_db.gte_table, &key, &value);
-/**
- * Pool of GBP endpoints
- */
-static gbp_endpoint_t *gbp_endpoint_pool;
+ if (0 != rv)
+ return NULL;
-/**
- * DB of endpoints
- */
-static uword *gbp_endpoint_db;
+ return (gbp_endpoint_get (value.value));
+}
static void
-gbp_ip_epg_update (const ip46_address_t * ip, epg_id_t epg_id)
+gbp_endpoint_mk_key_ip_itf (const ip46_address_t * ip,
+ u32 sw_if_index, clib_bihash_kv_24_8_t * key)
{
- /*
- * we are dealing only with addresses here so this limited
- * is_ip4 check is ok
- */
- if (ip46_address_is_ip4 (ip))
- {
- hash_set (gbp_ip4_to_epg_db.g4ie_hash, ip->ip4.as_u32, epg_id);
- }
- else
- {
- hash_set_mem (gbp_ip6_to_epg_db.g6ie_hash, &ip->ip6, epg_id);
- }
+ key->key[0] = ip->as_u64[0];
+ key->key[1] = ip->as_u64[1];
+ key->key[2] = sw_if_index;
}
static void
-gbp_ip_epg_delete (const ip46_address_t * ip)
+gbp_endpoint_extract_key_ip_itf (const clib_bihash_kv_24_8_t * key,
+ ip46_address_t * ip, u32 * sw_if_index)
{
- if (ip46_address_is_ip4 (ip))
- {
- hash_unset (gbp_ip4_to_epg_db.g4ie_hash, ip->ip4.as_u32);
- }
- else
- {
- hash_unset_mem (gbp_ip6_to_epg_db.g6ie_hash, &ip->ip6);
- }
+ ip->as_u64[0] = key->key[0];
+ ip->as_u64[1] = key->key[1];
+ *sw_if_index = key->key[2];
}
-void
-gbp_itf_epg_update (u32 sw_if_index, epg_id_t src_epg, u8 do_policy)
+gbp_endpoint_t *
+gbp_endpoint_find_ip_itf (const ip46_address_t * ip, u32 sw_if_index)
{
- vec_validate_init_empty (gbp_itf_to_epg_db.gte_vec,
- sw_if_index, ITF_INVALID);
+ clib_bihash_kv_24_8_t key, value;
+ int rv;
+
+ gbp_endpoint_mk_key_ip_itf (ip, sw_if_index, &key);
+
+ rv = clib_bihash_search_24_8 (&gbp_ep_by_ip_itf_db.gte_table, &key, &value);
+
+ if (0 != rv)
+ return NULL;
+
+ return (gbp_endpoint_get (value.value));
+}
+
+gbp_endpoint_t *
+gbp_endpoint_find_itf (u32 sw_if_index)
+{
+ /* if (vec_len(gbp_ep_by_itf_db.gte_vec) >= sw_if_index) */
+ /* return NULL; */
+
+ /* vec_search(gbp_ep_by_itf_db.gte_vec[sw_if_index], */
+ /* return (gbp_endpoint_get(gbp_ep_by_itf_db.gte_vec[sw_if_index][0])); */
+ return (NULL);
+}
+
+static bool
+gbp_endpoint_add_mac_itf (const mac_address_t * mac,
+ u32 sw_if_index, index_t gbpei)
+{
+ clib_bihash_kv_16_8_t key;
+ int rv;
+
+ gbp_endpoint_mk_key_mac_itf (mac, sw_if_index, &key);
+ key.value = gbpei;
- if (0 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count)
+ rv = clib_bihash_add_del_16_8 (&gbp_ep_by_mac_itf_db.gte_table, &key, 1);
+
+ return (0 == rv);
+}
+
+static bool
+gbp_endpoint_add_ip_itf (const ip46_address_t * ip,
+ u32 sw_if_index, index_t gbpei)
+{
+ clib_bihash_kv_24_8_t key;
+ int rv;
+
+ gbp_endpoint_mk_key_ip_itf (ip, sw_if_index, &key);
+ key.value = gbpei;
+
+ rv = clib_bihash_add_del_24_8 (&gbp_ep_by_ip_itf_db.gte_table, &key, 1);
+
+ return (0 == rv);
+}
+
+static void
+gbp_endpoint_add_itf (u32 sw_if_index, index_t gbpei)
+{
+ vec_validate_init_empty (gbp_ep_by_itf_db.gte_vec, sw_if_index,
+ INDEX_INVALID);
+
+ if (INDEX_INVALID == gbp_ep_by_itf_db.gte_vec[sw_if_index])
{
l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY,
1);
l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 1);
- if (do_policy)
- l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY,
- 1);
+ l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, 1);
}
- gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = src_epg;
- gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count++;
+ gbp_ep_by_itf_db.gte_vec[sw_if_index] = gbpei;
}
-void
-gbp_itf_epg_delete (u32 sw_if_index)
+static void
+gbp_endpoint_del_mac_itf (const mac_address_t * mac, u32 sw_if_index)
+{
+ clib_bihash_kv_16_8_t key;
+
+ gbp_endpoint_mk_key_mac_itf (mac, sw_if_index, &key);
+
+ clib_bihash_add_del_16_8 (&gbp_ep_by_mac_itf_db.gte_table, &key, 0);
+}
+
+static void
+gbp_endpoint_del_ip_itf (const ip46_address_t * ip, u32 sw_if_index)
+{
+ clib_bihash_kv_24_8_t key;
+
+ gbp_endpoint_mk_key_ip_itf (ip, sw_if_index, &key);
+
+ clib_bihash_add_del_24_8 (&gbp_ep_by_ip_itf_db.gte_table, &key, 0);
+}
+
+static void
+gbp_endpoint_del_itf (u32 sw_if_index)
{
- if (vec_len (gbp_itf_to_epg_db.gte_vec) <= sw_if_index)
+ if (vec_len (gbp_ep_by_itf_db.gte_vec) <= sw_if_index)
return;
- if (1 == gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count)
- {
- gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg = EPG_INVALID;
+ l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY, 0);
+ l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 0);
+ l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, 0);
- l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_SRC_CLASSIFY,
- 0);
- l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_GBP_FWD, 0);
- l2output_intf_bitmap_enable (sw_if_index, L2OUTPUT_FEAT_GBP_POLICY, 0);
- }
- gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_ref_count--;
+ gbp_ep_by_itf_db.gte_vec[sw_if_index] = INDEX_INVALID;
+}
+
+static index_t
+gbp_endpoint_index (const gbp_endpoint_t * gbpe)
+{
+ return (gbpe - gbp_endpoint_pool);
}
int
gbp_endpoint_update (u32 sw_if_index,
- const ip46_address_t * ip, epg_id_t epg_id)
+ const ip46_address_t * ips,
+ const mac_address_t * mac, epg_id_t epg_id, u32 * handle)
{
- gbp_endpoint_key_t key = {
- .gek_ip = *ip,
- .gek_sw_if_index = sw_if_index,
- };
gbp_endpoint_group_t *gepg;
+ const ip46_address_t *ip;
gbp_endpoint_t *gbpe;
- uword *p;
+ gbpe = NULL;
gepg = gbp_endpoint_group_find (epg_id);
if (NULL == gepg)
return (VNET_API_ERROR_NO_SUCH_ENTRY);
- p = hash_get_mem (gbp_endpoint_db, &key);
-
- if (p)
+ /*
+ * find an existing endpoint matching one of the key types
+ */
+ if (NULL != mac)
{
- gbpe = pool_elt_at_index (gbp_endpoint_pool, p[0]);
+ gbpe = gbp_endpoint_find_mac_itf (mac, sw_if_index);
}
- else
+ if (NULL == gbpe && NULL != ips)
{
- pool_get (gbp_endpoint_pool, gbpe);
-
- gbpe->ge_key = clib_mem_alloc (sizeof (gbp_endpoint_key_t));
- clib_memcpy (gbpe->ge_key, &key, sizeof (gbp_endpoint_key_t));
+ vec_foreach (ip, ips)
+ {
+ gbpe = gbp_endpoint_find_ip_itf (ip, sw_if_index);
- hash_set_mem (gbp_endpoint_db, gbpe->ge_key, gbpe - gbp_endpoint_pool);
+ if (NULL != gbpe)
+ break;
+ }
+ }
+ if (NULL == gbpe)
+ {
+ gbpe = gbp_endpoint_find_itf (sw_if_index);
}
- gbpe->ge_epg_id = epg_id;
-
- gbp_itf_epg_update (gbpe->ge_key->gek_sw_if_index, gbpe->ge_epg_id, 1);
-
- if (!ip46_address_is_zero (&gbpe->ge_key->gek_ip))
- gbp_ip_epg_update (&gbpe->ge_key->gek_ip, gbpe->ge_epg_id);
-
- /*
- * send a gratuitous ARP on the EPG's uplink. this is done so that if
- * this EP has moved from some other place in the 'fabric', upstream
- * devices are informed
- */
- if (ip46_address_is_ip4 (&gbpe->ge_key->gek_ip))
- send_ip4_garp_w_addr (vlib_get_main (),
- &gbpe->ge_key->gek_ip.ip4,
- gepg->gepg_uplink_sw_if_index);
+ if (NULL == gbpe)
+ {
+ index_t gbpei;
+ u32 ii;
+ /*
+ * new entry
+ */
+ pool_get (gbp_endpoint_pool, gbpe);
+ gbpei = gbp_endpoint_index (gbpe);
+
+ gbpe->ge_epg_id = epg_id;
+ gbpe->ge_sw_if_index = sw_if_index;
+ gbp_endpoint_add_itf (gbpe->ge_sw_if_index, gbpei);
+
+ if (NULL != mac)
+ {
+ gbpe->ge_mac = *mac;
+
+ // FIXME ERROR
+ gbp_endpoint_add_mac_itf (mac, sw_if_index, gbpei);
+ }
+
+ if (NULL != ips)
+ {
+ vec_validate (gbpe->ge_ips, vec_len (ips) - 1);
+ vec_foreach_index (ii, ips)
+ {
+ ip46_address_copy (&gbpe->ge_ips[ii], &ips[ii]);
+
+ // FIXME ERROR
+ gbp_endpoint_add_ip_itf (&ips[ii], sw_if_index, gbpei);
+
+ /*
+ * send a gratuitous ARP on the EPG's uplink. this is done so
+ * that if this EP has moved from some other place in the
+ * 'fabric', upstream devices are informed
+ */
+ if (ip46_address_is_ip4 (&ips[ii]))
+ send_ip4_garp_w_addr (vlib_get_main (),
+ &ips[ii].ip4,
+ gepg->gepg_uplink_sw_if_index);
+ else
+ send_ip6_na_w_addr (vlib_get_main (),
+ &ips[ii].ip6,
+ gepg->gepg_uplink_sw_if_index);
+ }
+ }
+ }
else
- send_ip6_na_w_addr (vlib_get_main (),
- &gbpe->ge_key->gek_ip.ip6,
- gepg->gepg_uplink_sw_if_index);
+ {
+ /*
+ * update existing entry..
+ */
+ ASSERT (0);
+ }
+
+ *handle = (gbpe - gbp_endpoint_pool);
return (0);
}
void
-gbp_endpoint_delete (u32 sw_if_index, const ip46_address_t * ip)
+gbp_endpoint_delete (u32 handle)
{
- gbp_endpoint_key_t key = {
- .gek_ip = *ip,
- .gek_sw_if_index = sw_if_index,
- };
gbp_endpoint_t *gbpe;
- uword *p;
- p = hash_get_mem (gbp_endpoint_db, &key);
+ if (pool_is_free_index (gbp_endpoint_pool, handle))
+ return;
- if (p)
- {
- gbpe = pool_elt_at_index (gbp_endpoint_pool, p[0]);
+ gbpe = pool_elt_at_index (gbp_endpoint_pool, handle);
- hash_unset_mem (gbp_endpoint_db, gbpe->ge_key);
+ gbp_endpoint_del_itf (gbpe->ge_sw_if_index);
- gbp_itf_epg_delete (gbpe->ge_key->gek_sw_if_index);
- if (!ip46_address_is_zero (&gbpe->ge_key->gek_ip))
- gbp_ip_epg_delete (&gbpe->ge_key->gek_ip);
+ if (!mac_address_is_zero (&gbpe->ge_mac))
+ {
+ gbp_endpoint_del_mac_itf (&gbpe->ge_mac, gbpe->ge_sw_if_index);
+ }
- clib_mem_free (gbpe->ge_key);
+ if (NULL != gbpe->ge_ips)
+ {
+ const ip46_address_t *ip;
- pool_put (gbp_endpoint_pool, gbpe);
+ vec_foreach (ip, gbpe->ge_ips)
+ {
+ gbp_endpoint_del_ip_itf (ip, gbpe->ge_sw_if_index);
+ }
}
+ pool_put (gbp_endpoint_pool, gbpe);
}
void
@@ -237,14 +377,19 @@ static clib_error_t *
gbp_endpoint_cli (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
+ ip46_address_t ip = ip46_address_initializer, *ips = NULL;
+ mac_address_t mac = ZERO_MAC_ADDRESS;
vnet_main_t *vnm = vnet_get_main ();
epg_id_t epg_id = EPG_INVALID;
- ip46_address_t ip = { };
+ u32 handle = INDEX_INVALID;
u32 sw_if_index = ~0;
u8 add = 1;
+ int rv;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
+ ip46_address_reset (&ip);
+
if (unformat (input, "%U", unformat_vnet_sw_interface,
vnm, &sw_if_index))
;
@@ -254,25 +399,41 @@ gbp_endpoint_cli (vlib_main_t * vm,
add = 0;
else if (unformat (input, "epg %d", &epg_id))
;
- else if (unformat (input, "ip %U", unformat_ip4_address, &ip.ip4))
+ else if (unformat (input, "handle %d", &handle))
;
+ else if (unformat (input, "ip %U", unformat_ip4_address, &ip.ip4))
+ vec_add1 (ips, ip);
else if (unformat (input, "ip %U", unformat_ip6_address, &ip.ip6))
+ vec_add1 (ips, ip);
+ else if (unformat (input, "mac %U", unformat_mac_address, &mac))
;
else
break;
}
- if (~0 == sw_if_index)
- return clib_error_return (0, "interface must be specified");
- if (EPG_INVALID == epg_id)
- return clib_error_return (0, "EPG-ID must be specified");
- if (ip46_address_is_zero (&ip))
- return clib_error_return (0, "IP address must be specified");
-
if (add)
- gbp_endpoint_update (sw_if_index, &ip, epg_id);
+ {
+ if (~0 == sw_if_index)
+ return clib_error_return (0, "interface must be specified");
+ if (EPG_INVALID == epg_id)
+ return clib_error_return (0, "EPG-ID must be specified");
+
+ rv = gbp_endpoint_update (sw_if_index, ips, &mac, epg_id, &handle);
+
+ if (rv)
+ return clib_error_return (0, "GBP Endpoint update returned %d", rv);
+ else
+ vlib_cli_output (vm, "handle %d\n", handle);
+ }
else
- gbp_endpoint_delete (sw_if_index, &ip);
+ {
+ if (INDEX_INVALID == handle)
+ return clib_error_return (0, "handle must be specified");
+
+ gbp_endpoint_delete (handle);
+ }
+
+ vec_free (ips);
return (NULL);
}
@@ -288,75 +449,132 @@ gbp_endpoint_cli (vlib_main_t * vm,
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (gbp_endpoint_cli_node, static) = {
.path = "gbp endpoint",
- .short_help = "gbp endpoint [del] <interface> epg <ID> ip <IP>",
+ .short_help = "gbp endpoint [del] <interface> epg <ID> ip <IP> mac <MAC>",
.function = gbp_endpoint_cli,
};
/* *INDENT-ON* */
-static int
-gbp_endpoint_show_one (gbp_endpoint_t * gbpe, void *ctx)
+u8 *
+format_gbp_endpoint (u8 * s, va_list * args)
{
+ index_t gbpei = va_arg (*args, index_t);
vnet_main_t *vnm = vnet_get_main ();
+ const ip46_address_t *ip;
+ gbp_endpoint_t *gbpe;
+
+ gbpe = gbp_endpoint_get (gbpei);
+
+ s = format (s, "[@%d] ", gbpei);
+ s =
+ format (s, "%U", format_vnet_sw_if_index_name, vnm, gbpe->ge_sw_if_index);
+ s = format (s, ", IPs:[");
+
+ vec_foreach (ip, gbpe->ge_ips)
+ {
+ s = format (s, "%U, ", format_ip46_address, ip, IP46_TYPE_ANY);
+ }
+ s = format (s, "]");
+
+ s = format (s, " MAC:%U", format_mac_address_t, &gbpe->ge_mac);
+ s = format (s, " EPG-ID:%d", gbpe->ge_epg_id);
+
+ return s;
+}
+
+static walk_rc_t
+gbp_endpoint_show_one (gbp_endpoint_t * gbpe, void *ctx)
+{
vlib_main_t *vm;
vm = ctx;
- vlib_cli_output (vm, " {%U, %U} -> %d",
- format_vnet_sw_if_index_name, vnm,
- gbpe->ge_key->gek_sw_if_index,
- format_ip46_address, &gbpe->ge_key->gek_ip, IP46_TYPE_ANY,
- gbpe->ge_epg_id);
+ vlib_cli_output (vm, " %U", format_gbp_endpoint, gbp_endpoint_index (gbpe));
- return (1);
+ return (WALK_CONTINUE);
}
-static clib_error_t *
-gbp_endpoint_show (vlib_main_t * vm,
- unformat_input_t * input, vlib_cli_command_t * cmd)
+static void
+gbp_endpoint_walk_ip_itf (const clib_bihash_kv_24_8_t * kvp, void *arg)
{
- vnet_main_t *vnm = vnet_get_main ();
- ip46_address_t ip, *ipp;
- epg_id_t epg_id;
+ ip46_address_t ip;
+ vlib_main_t *vm;
u32 sw_if_index;
- vlib_cli_output (vm, "Endpoints:");
- gbp_endpoint_walk (gbp_endpoint_show_one, vm);
+ vm = arg;
- vlib_cli_output (vm, "\nSource interface to EPG:");
+ gbp_endpoint_extract_key_ip_itf (kvp, &ip, &sw_if_index);
- vec_foreach_index (sw_if_index, gbp_itf_to_epg_db.gte_vec)
- {
- if (EPG_INVALID != gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg)
- {
- vlib_cli_output (vm, " %U -> %d",
- format_vnet_sw_if_index_name, vnm, sw_if_index,
- gbp_itf_to_epg_db.gte_vec[sw_if_index].gi_epg);
- }
- }
+ vlib_cli_output (vm, " {%U, %U} -> %d",
+ format_ip46_address, &ip, IP46_TYPE_ANY,
+ format_vnet_sw_if_index_name, vnet_get_main (),
+ sw_if_index, kvp->value);
+}
- vlib_cli_output (vm, "\nDestination IP4 to EPG:");
+static void
+gbp_endpoint_walk_mac_itf (const clib_bihash_kv_16_8_t * kvp, void *arg)
+{
+ mac_address_t mac;
+ vlib_main_t *vm;
+ u32 sw_if_index;
- /* *INDENT-OFF* */
- hash_foreach (ip.ip4.as_u32, epg_id, gbp_ip4_to_epg_db.g4ie_hash,
- {
- vlib_cli_output (vm, " %U -> %d", format_ip46_address, &ip,
- IP46_TYPE_IP4, epg_id);
- });
- /* *INDENT-ON* */
+ vm = arg;
- vlib_cli_output (vm, "\nDestination IP6 to EPG:");
+ gbp_endpoint_extract_key_mac_itf (kvp, &mac, &sw_if_index);
- /* *INDENT-OFF* */
- hash_foreach_mem (ipp, epg_id, gbp_ip6_to_epg_db.g6ie_hash,
- {
- vlib_cli_output (vm, " %U -> %d", format_ip46_address, ipp,
- IP46_TYPE_IP6, epg_id);
- });
- /* *INDENT-ON* */
+ vlib_cli_output (vm, " {%U, %U} -> %d",
+ format_mac_address_t, &mac,
+ format_vnet_sw_if_index_name, vnet_get_main (),
+ sw_if_index, kvp->value);
+}
+
+static clib_error_t *
+gbp_endpoint_show (vlib_main_t * vm,
+ unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+ u32 sw_if_index, show_dbs, handle;
+
+ handle = INDEX_INVALID;
+ show_dbs = 0;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "%d", &handle))
+ ;
+ else if (unformat (input, "db", &handle))
+ show_dbs = 1;
+ else
+ break;
+ }
+
+ if (INDEX_INVALID != handle)
+ {
+ vlib_cli_output (vm, "%U", format_gbp_endpoint, handle);
+ }
+ else if (show_dbs)
+ {
+ vlib_cli_output (vm, "\nDatabases:");
+ clib_bihash_foreach_key_value_pair_24_8 (&gbp_ep_by_ip_itf_db.gte_table,
+ gbp_endpoint_walk_ip_itf, vm);
+ clib_bihash_foreach_key_value_pair_16_8
+ (&gbp_ep_by_mac_itf_db.gte_table, gbp_endpoint_walk_mac_itf, vm);
+
+ vec_foreach_index (sw_if_index, gbp_ep_by_itf_db.gte_vec)
+ {
+ if (INDEX_INVALID != gbp_ep_by_itf_db.gte_vec[sw_if_index])
+ vlib_cli_output (vm, " {%U} -> %d",
+ format_vnet_sw_if_index_name, vnet_get_main (),
+ sw_if_index,
+ gbp_ep_by_itf_db.gte_vec[sw_if_index]);
+ }
+ }
+ else
+ {
+ vlib_cli_output (vm, "Endpoints:");
+ gbp_endpoint_walk (gbp_endpoint_show_one, vm);
+ }
return (NULL);
}
-
/*?
* Show Group Based Policy Endpoints and derived information
*
@@ -372,15 +590,21 @@ VLIB_CLI_COMMAND (gbp_endpoint_show_node, static) = {
};
/* *INDENT-ON* */
+#define GBP_EP_HASH_NUM_BUCKETS (2 * 1024)
+#define GBP_EP_HASH_MEMORY_SIZE (1 << 20)
+
static clib_error_t *
gbp_endpoint_init (vlib_main_t * vm)
{
- gbp_endpoint_db = hash_create_mem (0,
- sizeof (gbp_endpoint_key_t),
- sizeof (u32));
- gbp_ip6_to_epg_db.g6ie_hash =
- hash_create_mem (0, sizeof (ip6_address_t), sizeof (u32));
- return 0;
+ clib_bihash_init_24_8 (&gbp_ep_by_ip_itf_db.gte_table,
+ "GBP Endpoints - IP/Interface",
+ GBP_EP_HASH_NUM_BUCKETS, GBP_EP_HASH_MEMORY_SIZE);
+
+ clib_bihash_init_16_8 (&gbp_ep_by_mac_itf_db.gte_table,
+ "GBP Endpoints - MAC/Interface",
+ GBP_EP_HASH_NUM_BUCKETS, GBP_EP_HASH_MEMORY_SIZE);
+
+ return (NULL);
}
VLIB_INIT_FUNCTION (gbp_endpoint_init);