X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fgbp%2Fgbp_bridge_domain.c;h=f2a56d770b970c95133f871ef5ee6e6f5672f717;hb=59f71132e;hp=298819f87f18730543d265dc2aaece992eafc3cc;hpb=13a08cc0984496d50722ffb75e2f48c5d84fb9a7;p=vpp.git diff --git a/src/plugins/gbp/gbp_bridge_domain.c b/src/plugins/gbp/gbp_bridge_domain.c index 298819f87f1..f2a56d770b9 100644 --- a/src/plugins/gbp/gbp_bridge_domain.c +++ b/src/plugins/gbp/gbp_bridge_domain.c @@ -14,7 +14,10 @@ */ #include +#include #include +#include +#include #include #include @@ -33,6 +36,11 @@ gbp_bridge_domain_t *gbp_bridge_domain_pool; */ gbp_bridge_domain_db_t gbp_bridge_domain_db; +/** + * Map of BD index to contract scope + */ +gbp_scope_t *gbp_scope_by_bd_index; + /** * logger */ @@ -56,6 +64,16 @@ gbp_bridge_domain_lock (index_t i) gb->gb_locks++; } +u32 +gbp_bridge_domain_get_bd_id (index_t gbdi) +{ + gbp_bridge_domain_t *gb; + + gb = gbp_bridge_domain_get (gbdi); + + return (gb->gb_bd_id); +} + static index_t gbp_bridge_domain_find (u32 bd_id) { @@ -102,6 +120,29 @@ gbp_bridge_domain_db_remove (gbp_bridge_domain_t * gb) gbp_bridge_domain_db.gbd_by_bd_index[gb->gb_bd_index] = INDEX_INVALID; } +u8 * +format_gbp_bridge_domain_flags (u8 * s, va_list * args) +{ + gbp_bridge_domain_flags_t gf = va_arg (*args, gbp_bridge_domain_flags_t); + + if (gf) + { + if (gf & GBP_BD_FLAG_DO_NOT_LEARN) + s = format (s, "do-not-learn "); + if (gf & GBP_BD_FLAG_UU_FWD_DROP) + s = format (s, "uu-fwd-drop "); + if (gf & GBP_BD_FLAG_MCAST_DROP) + s = format (s, "mcast-drop "); + if (gf & GBP_BD_FLAG_UCAST_ARP) + s = format (s, "ucast-arp "); + } + else + { + s = format (s, "none"); + } + return (s); +} + static u8 * format_gbp_bridge_domain_ptr (u8 * s, va_list * args) { @@ -109,13 +150,14 @@ format_gbp_bridge_domain_ptr (u8 * s, va_list * args) vnet_main_t *vnm = vnet_get_main (); if (NULL != gb) - s = format (s, "[%d] bd:[%d,%d], bvi:%U uu-flood:%U locks:%d", - gb - gbp_bridge_domain_pool, - gb->gb_bd_id, - gb->gb_bd_index, - format_vnet_sw_if_index_name, vnm, gb->gb_bvi_sw_if_index, - format_vnet_sw_if_index_name, vnm, gb->gb_uu_fwd_sw_if_index, - gb->gb_locks); + s = + format (s, + "[%d] bd:[%d,%d], bvi:%U uu-flood:%U bm-flood:%U flags:%U locks:%d", + gb - gbp_bridge_domain_pool, gb->gb_bd_id, gb->gb_bd_index, + format_vnet_sw_if_index_name, vnm, gb->gb_bvi_sw_if_index, + format_vnet_sw_if_index_name, vnm, gb->gb_uu_fwd_sw_if_index, + format_gbp_itf_hdl, gb->gb_bm_flood_itf, + format_gbp_bridge_domain_flags, gb->gb_flags, gb->gb_locks); else s = format (s, "NULL"); @@ -136,8 +178,11 @@ format_gbp_bridge_domain (u8 * s, va_list * args) int gbp_bridge_domain_add_and_lock (u32 bd_id, + u32 rd_id, gbp_bridge_domain_flags_t flags, - u32 bvi_sw_if_index, u32 uu_fwd_sw_if_index) + u32 bvi_sw_if_index, + u32 uu_fwd_sw_if_index, + u32 bm_flood_sw_if_index) { gbp_bridge_domain_t *gb; index_t gbi; @@ -146,6 +191,7 @@ gbp_bridge_domain_add_and_lock (u32 bd_id, if (INDEX_INVALID == gbi) { + gbp_route_domain_t *gr; u32 bd_index; bd_index = bd_find_index (&bd_main, bd_id); @@ -153,31 +199,62 @@ gbp_bridge_domain_add_and_lock (u32 bd_id, if (~0 == bd_index) return (VNET_API_ERROR_BD_NOT_MODIFIABLE); - /* - * unset learning in the bridge - */ - bd_set_flags (vlib_get_main (), bd_index, L2_LEARN, 0); + bd_flags_t bd_flags = L2_NONE; + if (flags & GBP_BD_FLAG_UU_FWD_DROP) + bd_flags |= L2_UU_FLOOD; + if (flags & GBP_BD_FLAG_MCAST_DROP) + bd_flags |= L2_FLOOD; pool_get (gbp_bridge_domain_pool, gb); memset (gb, 0, sizeof (*gb)); + gbi = gb - gbp_bridge_domain_pool; gb->gb_bd_id = bd_id; gb->gb_bd_index = bd_index; gb->gb_uu_fwd_sw_if_index = uu_fwd_sw_if_index; gb->gb_bvi_sw_if_index = bvi_sw_if_index; + gbp_itf_hdl_reset (&gb->gb_bm_flood_itf); gb->gb_locks = 1; gb->gb_flags = flags; + gb->gb_rdi = gbp_route_domain_find_and_lock (rd_id); + + /* + * set the scope from the BD's RD's scope + */ + gr = gbp_route_domain_get (gb->gb_rdi); + vec_validate (gbp_scope_by_bd_index, gb->gb_bd_index); + gbp_scope_by_bd_index[gb->gb_bd_index] = gr->grd_scope; /* * Set the BVI and uu-flood interfaces into the BD */ - set_int_l2_mode (vlib_get_main (), vnet_get_main (), - MODE_L2_BRIDGE, gb->gb_bvi_sw_if_index, - bd_index, L2_BD_PORT_TYPE_BVI, 0, 0); - if (~0 != gb->gb_uu_fwd_sw_if_index) - set_int_l2_mode (vlib_get_main (), vnet_get_main (), - MODE_L2_BRIDGE, gb->gb_uu_fwd_sw_if_index, - bd_index, L2_BD_PORT_TYPE_UU_FWD, 0, 0); + gbp_bridge_domain_itf_add (gbi, gb->gb_bvi_sw_if_index, + L2_BD_PORT_TYPE_BVI); + + if ((!(flags & GBP_BD_FLAG_UU_FWD_DROP) || + (flags & GBP_BD_FLAG_UCAST_ARP)) && + ~0 != gb->gb_uu_fwd_sw_if_index) + gbp_bridge_domain_itf_add (gbi, gb->gb_uu_fwd_sw_if_index, + L2_BD_PORT_TYPE_UU_FWD); + + if (!(flags & GBP_BD_FLAG_MCAST_DROP) && ~0 != bm_flood_sw_if_index) + { + gb->gb_bm_flood_itf = + gbp_itf_l2_add_and_lock (bm_flood_sw_if_index, gbi); + gbp_itf_l2_set_input_feature (gb->gb_bm_flood_itf, + L2INPUT_FEAT_GBP_LEARN); + } + + /* + * unset any flag(s) set above + */ + bd_set_flags (vlib_get_main (), bd_index, bd_flags, 0); + + if (flags & GBP_BD_FLAG_UCAST_ARP) + { + bd_flags = L2_ARP_UFWD; + bd_set_flags (vlib_get_main (), bd_index, bd_flags, 1); + } /* * Add the BVI's MAC to the L2FIB @@ -202,11 +279,41 @@ gbp_bridge_domain_add_and_lock (u32 bd_id, } void -gbp_bridge_domain_unlock (index_t index) +gbp_bridge_domain_itf_add (index_t gbdi, + u32 sw_if_index, l2_bd_port_type_t type) +{ + gbp_bridge_domain_t *gb; + + gb = gbp_bridge_domain_get (gbdi); + + set_int_l2_mode (vlib_get_main (), vnet_get_main (), MODE_L2_BRIDGE, + sw_if_index, gb->gb_bd_index, type, 0, 0); + /* + * adding an interface to the bridge enables learning on the + * interface. Disable learning on the interface by default for gbp + * interfaces + */ + l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_LEARN, 0); +} + +void +gbp_bridge_domain_itf_del (index_t gbdi, + u32 sw_if_index, l2_bd_port_type_t type) +{ + gbp_bridge_domain_t *gb; + + gb = gbp_bridge_domain_get (gbdi); + + set_int_l2_mode (vlib_get_main (), vnet_get_main (), MODE_L3, sw_if_index, + gb->gb_bd_index, type, 0, 0); +} + +void +gbp_bridge_domain_unlock (index_t gbdi) { gbp_bridge_domain_t *gb; - gb = gbp_bridge_domain_get (index); + gb = gbp_bridge_domain_get (gbdi); gb->gb_locks--; @@ -218,15 +325,15 @@ gbp_bridge_domain_unlock (index_t index) (vnet_get_main (), gb->gb_bvi_sw_if_index), gb->gb_bd_index, gb->gb_bvi_sw_if_index); - set_int_l2_mode (vlib_get_main (), vnet_get_main (), - MODE_L3, gb->gb_bvi_sw_if_index, - gb->gb_bd_index, L2_BD_PORT_TYPE_BVI, 0, 0); + gbp_bridge_domain_itf_del (gbdi, gb->gb_bvi_sw_if_index, + L2_BD_PORT_TYPE_BVI); if (~0 != gb->gb_uu_fwd_sw_if_index) - set_int_l2_mode (vlib_get_main (), vnet_get_main (), - MODE_L3, gb->gb_uu_fwd_sw_if_index, - gb->gb_bd_index, L2_BD_PORT_TYPE_UU_FWD, 0, 0); + gbp_bridge_domain_itf_del (gbdi, gb->gb_uu_fwd_sw_if_index, + L2_BD_PORT_TYPE_UU_FWD); + gbp_itf_unlock (&gb->gb_bm_flood_itf); gbp_bridge_domain_db_remove (gb); + gbp_route_domain_unlock (gb->gb_rdi); pool_put (gbp_bridge_domain_pool, gb); } @@ -270,39 +377,55 @@ gbp_bridge_domain_cli (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { vnet_main_t *vnm = vnet_get_main (); + gbp_bridge_domain_flags_t flags; + u32 bm_flood_sw_if_index = ~0; u32 uu_fwd_sw_if_index = ~0; + u32 bd_id = ~0, rd_id = ~0; u32 bvi_sw_if_index = ~0; - u32 bd_id = ~0; u8 add = 1; + flags = GBP_BD_FLAG_NONE; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "bvi %U", unformat_vnet_sw_interface, vnm, &bvi_sw_if_index)) ; - else if (unformat (input, "uu-flood %U", unformat_vnet_sw_interface, + else if (unformat (input, "uu-fwd %U", unformat_vnet_sw_interface, vnm, &uu_fwd_sw_if_index)) ; + else if (unformat (input, "bm-flood %U", unformat_vnet_sw_interface, + vnm, &bm_flood_sw_if_index)) + ; else if (unformat (input, "add")) add = 1; else if (unformat (input, "del")) add = 0; + else if (unformat (input, "flags %d", &flags)) + ; else if (unformat (input, "bd %d", &bd_id)) ; + else if (unformat (input, "rd %d", &rd_id)) + ; else break; } if (~0 == bd_id) - return clib_error_return (0, "EPG-ID must be specified"); + return clib_error_return (0, "BD-ID must be specified"); + if (~0 == rd_id) + return clib_error_return (0, "RD-ID must be specified"); if (add) { if (~0 == bvi_sw_if_index) return clib_error_return (0, "interface must be specified"); - gbp_bridge_domain_add_and_lock (bd_id, GBP_BD_FLAG_NONE, - bvi_sw_if_index, uu_fwd_sw_if_index); + gbp_bridge_domain_add_and_lock (bd_id, rd_id, + flags, + bvi_sw_if_index, + uu_fwd_sw_if_index, + bm_flood_sw_if_index); } else gbp_bridge_domain_delete (bd_id); @@ -314,13 +437,13 @@ gbp_bridge_domain_cli (vlib_main_t * vm, * Configure a GBP bridge-domain * * @cliexpar - * @cliexstart{set gbp bridge-domain [del] bd bvi uu-flood } + * @cliexstart{gbp bridge-domain [del] bd bvi [uu-fwd ] [bm-flood ] [flags ]} * @cliexend ?*/ /* *INDENT-OFF* */ VLIB_CLI_COMMAND (gbp_bridge_domain_cli_node, static) = { .path = "gbp bridge-domain", - .short_help = "gbp bridge-domain [del] epg bd bvi uu-flood ", + .short_help = "gbp bridge-domain [del] bd bvi [uu-fwd ] [bm-flood ] [flags ]", .function = gbp_bridge_domain_cli, };