aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/gbp/gbp_endpoint_group.c
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2018-10-10 07:22:51 -0700
committerDamjan Marion <dmarion@me.com>2018-11-07 12:00:10 +0000
commit93cc3ee3b3a9c9224a1446625882205f3282a949 (patch)
tree077421ee51238c22181a3b3f4871b648bb1299d3 /src/plugins/gbp/gbp_endpoint_group.c
parentc3df1e9a0ab79c1fe254394748ef441ffe224c43 (diff)
GBP Endpoint Learning
Learning GBP endpoints over vxlan-gbp tunnels Change-Id: I1db9fda5a16802d9ad8b4efd4e475614f3b21502 Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
Diffstat (limited to 'src/plugins/gbp/gbp_endpoint_group.c')
-rw-r--r--src/plugins/gbp/gbp_endpoint_group.c260
1 files changed, 198 insertions, 62 deletions
diff --git a/src/plugins/gbp/gbp_endpoint_group.c b/src/plugins/gbp/gbp_endpoint_group.c
index 095c8fe607b..ee4af2c0060 100644
--- a/src/plugins/gbp/gbp_endpoint_group.c
+++ b/src/plugins/gbp/gbp_endpoint_group.c
@@ -17,11 +17,12 @@
#include <plugins/gbp/gbp_endpoint_group.h>
#include <plugins/gbp/gbp_endpoint.h>
+#include <plugins/gbp/gbp_bridge_domain.h>
+#include <plugins/gbp/gbp_route_domain.h>
#include <vnet/dpo/dvr_dpo.h>
#include <vnet/fib/fib_table.h>
#include <vnet/l2/l2_input.h>
-#include <vnet/l2/feat_bitmap.h>
/**
* Pool of GBP endpoint_groups
@@ -32,106 +33,218 @@ gbp_endpoint_group_t *gbp_endpoint_group_pool;
* DB of endpoint_groups
*/
gbp_endpoint_group_db_t gbp_endpoint_group_db;
+vlib_log_class_t gg_logger;
+
+#define GBP_EPG_DBG(...) \
+ vlib_log_debug (gg_logger, __VA_ARGS__);
gbp_endpoint_group_t *
+gbp_endpoint_group_get (index_t i)
+{
+ return (pool_elt_at_index (gbp_endpoint_group_pool, i));
+}
+
+static void
+gbp_endpoint_group_lock (index_t i)
+{
+ gbp_endpoint_group_t *gg;
+
+ gg = gbp_endpoint_group_get (i);
+ gg->gg_locks++;
+}
+
+index_t
gbp_endpoint_group_find (epg_id_t epg_id)
{
uword *p;
- p = hash_get (gbp_endpoint_group_db.gepg_hash, epg_id);
+ p = hash_get (gbp_endpoint_group_db.gg_hash, epg_id);
if (NULL != p)
- return (pool_elt_at_index (gbp_endpoint_group_pool, p[0]));
+ return p[0];
- return (NULL);
+ return (INDEX_INVALID);
+}
+
+index_t
+gbp_endpoint_group_find_and_lock (epg_id_t epg_id)
+{
+ uword *p;
+
+ p = hash_get (gbp_endpoint_group_db.gg_hash, epg_id);
+
+ if (NULL != p)
+ {
+ gbp_endpoint_group_lock (p[0]);
+ return p[0];
+ }
+ return (INDEX_INVALID);
}
int
-gbp_endpoint_group_add (epg_id_t epg_id,
- u32 bd_id,
- u32 ip4_table_id,
- u32 ip6_table_id, u32 uplink_sw_if_index)
+gbp_endpoint_group_add_and_lock (epg_id_t epg_id,
+ u32 bd_id, u32 rd_id, u32 uplink_sw_if_index)
{
- gbp_endpoint_group_t *gepg;
+ gbp_endpoint_group_t *gg;
+ index_t ggi;
- gepg = gbp_endpoint_group_find (epg_id);
+ ggi = gbp_endpoint_group_find (epg_id);
- if (NULL == gepg)
+ if (INDEX_INVALID == ggi)
{
+ gbp_bridge_domain_t *gb;
fib_protocol_t fproto;
+ index_t gbi, grdi;
+
+ gbi = gbp_bridge_domain_find_and_lock (bd_id);
+
+ if (~0 == gbi)
+ return (VNET_API_ERROR_BD_NOT_MODIFIABLE);
- pool_get (gbp_endpoint_group_pool, gepg);
- clib_memset (gepg, 0, sizeof (*gepg));
+ grdi = gbp_route_domain_find_and_lock (rd_id);
- gepg->gepg_id = epg_id;
- gepg->gepg_bd = bd_id;
- gepg->gepg_rd[FIB_PROTOCOL_IP4] = ip4_table_id;
- gepg->gepg_rd[FIB_PROTOCOL_IP6] = ip6_table_id;
- gepg->gepg_uplink_sw_if_index = uplink_sw_if_index;
+ if (~0 == grdi)
+ {
+ gbp_bridge_domain_unlock (gbi);
+ return (VNET_API_ERROR_NO_SUCH_FIB);
+ }
+
+ gb = gbp_bridge_domain_get (gbi);
+
+ pool_get_zero (gbp_endpoint_group_pool, gg);
+
+ gg->gg_id = epg_id;
+ gg->gg_rd = grdi;
+ gg->gg_gbd = gbi;
+ gg->gg_bd_index = gb->gb_bd_index;
+
+ gg->gg_uplink_sw_if_index = uplink_sw_if_index;
+ gg->gg_locks = 1;
/*
* an egress DVR dpo for internal subnets to use when sending
* on the uplink interface
*/
- FOR_EACH_FIB_IP_PROTOCOL (fproto)
- {
- gepg->gepg_fib_index[fproto] =
- fib_table_find_or_create_and_lock (fproto,
- gepg->gepg_rd[fproto],
- FIB_SOURCE_PLUGIN_HI);
-
- if (~0 == gepg->gepg_fib_index[fproto])
+ if (~0 != gg->gg_uplink_sw_if_index)
+ {
+ FOR_EACH_FIB_IP_PROTOCOL (fproto)
{
- return (VNET_API_ERROR_NO_SUCH_FIB);
+ dvr_dpo_add_or_lock (uplink_sw_if_index,
+ fib_proto_to_dpo (fproto),
+ &gg->gg_dpo[fproto]);
}
- dvr_dpo_add_or_lock (uplink_sw_if_index,
- fib_proto_to_dpo (fproto),
- &gepg->gepg_dpo[fproto]);
- }
-
- /*
- * packets direct from the uplink have had policy applied
- */
- l2input_intf_bitmap_enable (gepg->gepg_uplink_sw_if_index,
- L2INPUT_FEAT_GBP_NULL_CLASSIFY, 1);
+ /*
+ * Add the uplink to the BD
+ * packets direct from the uplink have had policy applied
+ */
+ set_int_l2_mode (vlib_get_main (), vnet_get_main (),
+ MODE_L2_BRIDGE, gg->gg_uplink_sw_if_index,
+ gg->gg_bd_index, L2_BD_PORT_TYPE_NORMAL, 0, 0);
+ l2input_intf_bitmap_enable (gg->gg_uplink_sw_if_index,
+ L2INPUT_FEAT_GBP_NULL_CLASSIFY, 1);
+ }
- hash_set (gbp_endpoint_group_db.gepg_hash,
- gepg->gepg_id, gepg - gbp_endpoint_group_pool);
+ hash_set (gbp_endpoint_group_db.gg_hash,
+ gg->gg_id, gg - gbp_endpoint_group_pool);
}
+ else
+ {
+ gg = gbp_endpoint_group_get (ggi);
+ gg->gg_locks++;
+ }
+
+ GBP_EPG_DBG ("add: %U", format_gbp_endpoint_group, gg);
return (0);
}
void
-gbp_endpoint_group_delete (epg_id_t epg_id)
+gbp_endpoint_group_unlock (index_t ggi)
{
- gbp_endpoint_group_t *gepg;
- uword *p;
+ gbp_endpoint_group_t *gg;
- p = hash_get (gbp_endpoint_group_db.gepg_hash, epg_id);
+ gg = gbp_endpoint_group_get (ggi);
- if (NULL != p)
+ gg->gg_locks--;
+
+ if (0 == gg->gg_locks)
{
fib_protocol_t fproto;
- gepg = pool_elt_at_index (gbp_endpoint_group_pool, p[0]);
+ gg = pool_elt_at_index (gbp_endpoint_group_pool, ggi);
- l2input_intf_bitmap_enable (gepg->gepg_uplink_sw_if_index,
- L2INPUT_FEAT_GBP_NULL_CLASSIFY, 0);
+ if (~0 != gg->gg_uplink_sw_if_index)
+ {
+ set_int_l2_mode (vlib_get_main (), vnet_get_main (),
+ MODE_L3, gg->gg_uplink_sw_if_index,
+ gg->gg_bd_index, L2_BD_PORT_TYPE_NORMAL, 0, 0);
+ l2input_intf_bitmap_enable (gg->gg_uplink_sw_if_index,
+ L2INPUT_FEAT_GBP_NULL_CLASSIFY, 0);
+ }
FOR_EACH_FIB_IP_PROTOCOL (fproto)
{
- dpo_reset (&gepg->gepg_dpo[fproto]);
- fib_table_unlock (gepg->gepg_fib_index[fproto],
- fproto, FIB_SOURCE_PLUGIN_HI);
+ dpo_reset (&gg->gg_dpo[fproto]);
}
+ gbp_bridge_domain_unlock (gg->gg_gbd);
+ gbp_route_domain_unlock (gg->gg_rd);
+
+ hash_unset (gbp_endpoint_group_db.gg_hash, gg->gg_id);
- hash_unset (gbp_endpoint_group_db.gepg_hash, epg_id);
+ pool_put (gbp_endpoint_group_pool, gg);
+ }
+}
+
+int
+gbp_endpoint_group_delete (epg_id_t epg_id)
+{
+ index_t ggi;
+
+ ggi = gbp_endpoint_group_find (epg_id);
- pool_put (gbp_endpoint_group_pool, gepg);
+ if (INDEX_INVALID != ggi)
+ {
+ GBP_EPG_DBG ("del: %U", format_gbp_endpoint_group,
+ gbp_endpoint_group_get (ggi));
+ gbp_endpoint_group_unlock (ggi);
+
+ return (0);
}
+
+ return (VNET_API_ERROR_NO_SUCH_ENTRY);
+}
+
+u32
+gbp_endpoint_group_get_bd_id (const gbp_endpoint_group_t * gg)
+{
+ const gbp_bridge_domain_t *gb;
+
+ gb = gbp_bridge_domain_get (gg->gg_gbd);
+
+ return (gb->gb_bd_id);
+}
+
+index_t
+gbp_endpoint_group_get_fib_index (gbp_endpoint_group_t * gg,
+ fib_protocol_t fproto)
+{
+ const gbp_route_domain_t *grd;
+
+ grd = gbp_route_domain_get (gg->gg_rd);
+
+ return (grd->grd_fib_index[fproto]);
+}
+
+u32
+gbp_endpoint_group_get_bvi (gbp_endpoint_group_t * gg)
+{
+ const gbp_bridge_domain_t *gb;
+
+ gb = gbp_bridge_domain_get (gg->gg_gbd);
+
+ return (gb->gb_bvi_sw_if_index);
}
void
@@ -190,8 +303,8 @@ gbp_endpoint_group_cli (vlib_main_t * vm,
if (~0 == rd_id)
return clib_error_return (0, "route-domain must be specified");
- gbp_endpoint_group_add (epg_id, bd_id, rd_id, rd_id,
- uplink_sw_if_index);
+ gbp_endpoint_group_add_and_lock (epg_id, bd_id, rd_id,
+ uplink_sw_if_index);
}
else
gbp_endpoint_group_delete (epg_id);
@@ -213,19 +326,32 @@ VLIB_CLI_COMMAND (gbp_endpoint_group_cli_node, static) = {
.function = gbp_endpoint_group_cli,
};
-static int
-gbp_endpoint_group_show_one (gbp_endpoint_group_t *gepg, void *ctx)
+u8 *
+format_gbp_endpoint_group (u8 * s, va_list * args)
{
+ gbp_endpoint_group_t *gg = va_arg (*args, gbp_endpoint_group_t*);
vnet_main_t *vnm = vnet_get_main ();
+
+ if (NULL != gg)
+ s = format (s, "%d, bd:[%d,%d], rd:[%d] uplink:%U locks:%d",
+ gg->gg_id,
+ gbp_endpoint_group_get_bd_id(gg), gg->gg_bd_index,
+ gg->gg_rd,
+ format_vnet_sw_if_index_name, vnm, gg->gg_uplink_sw_if_index,
+ gg->gg_locks);
+ else
+ s = format (s, "NULL");
+
+ return (s);
+}
+
+static int
+gbp_endpoint_group_show_one (gbp_endpoint_group_t *gg, void *ctx)
+{
vlib_main_t *vm;
vm = ctx;
- vlib_cli_output (vm, " %d, bd:%d, ip4:%d ip6:%d uplink:%U",
- gepg->gepg_id,
- gepg->gepg_bd,
- gepg->gepg_rd[FIB_PROTOCOL_IP4],
- gepg->gepg_rd[FIB_PROTOCOL_IP6],
- format_vnet_sw_if_index_name, vnm, gepg->gepg_uplink_sw_if_index);
+ vlib_cli_output (vm, " %U",format_gbp_endpoint_group, gg);
return (1);
}
@@ -256,6 +382,16 @@ VLIB_CLI_COMMAND (gbp_endpoint_group_show_node, static) = {
};
/* *INDENT-ON* */
+static clib_error_t *
+gbp_endpoint_group_init (vlib_main_t * vm)
+{
+ gg_logger = vlib_log_register_class ("gbp", "epg");
+
+ return (NULL);
+}
+
+VLIB_INIT_FUNCTION (gbp_endpoint_group_init);
+
/*
* fd.io coding-style-patch-verification: ON
*