X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fgbp%2Fgbp_ext_itf.c;h=6462eca9eaf1e37d7b97ab5162bb787aed83fed8;hb=3918bdbcb;hp=16cdaa87b77b137b2fe82f4a3a43161255bd34fd;hpb=5f4eb24287c02be6f694f6698472ef4978a5e300;p=vpp.git diff --git a/src/plugins/gbp/gbp_ext_itf.c b/src/plugins/gbp/gbp_ext_itf.c index 16cdaa87b77..6462eca9eaf 100644 --- a/src/plugins/gbp/gbp_ext_itf.c +++ b/src/plugins/gbp/gbp_ext_itf.c @@ -43,13 +43,14 @@ format_gbp_ext_itf (u8 * s, va_list * args) { gbp_ext_itf_t *gx = va_arg (*args, gbp_ext_itf_t *); - return (format (s, "%U in %U", + return (format (s, "%U%s in %U", format_gbp_itf, gx->gx_itf, + (gx->gx_flags & GBP_EXT_ITF_F_ANON) ? " [anon]" : "", format_gbp_bridge_domain, gx->gx_bd)); } int -gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id) +gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id, u32 flags) { gbp_ext_itf_t *gx; index_t gxi; @@ -60,7 +61,6 @@ gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id) if (INDEX_INVALID == gxi) { - gbp_bridge_domain_t *gb; gbp_route_domain_t *gr; fib_protocol_t fproto; index_t gbi, gri; @@ -81,11 +81,11 @@ gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id) pool_get_zero (gbp_ext_itf_pool, gx); gxi = gx - gbp_ext_itf_pool; - gb = gbp_bridge_domain_get (gbi); gr = gbp_route_domain_get (gri); gx->gx_bd = gbi; gx->gx_rd = gri; + gx->gx_itf = sw_if_index; FOR_EACH_FIB_IP_PROTOCOL (fproto) { @@ -93,9 +93,19 @@ gbp_ext_itf_add (u32 sw_if_index, u32 bd_id, u32 rd_id) gr->grd_fib_index[fib_proto_to_dpo (fproto)]; } - gx->gx_itf = gbp_itf_add_and_lock (sw_if_index, gb->gb_bd_index); - gbp_itf_set_l2_input_feature (gx->gx_itf, (gxi | GBP_EXT_ITF_ID), - L2INPUT_FEAT_GBP_LPM_CLASSIFY); + if (flags & GBP_EXT_ITF_F_ANON) + { + /* add interface to the BD */ + index_t itf = gbp_itf_add_and_lock (sw_if_index, bd_id); + /* setup GBP L2 features on this interface */ + gbp_itf_set_l2_input_feature (itf, 0, + L2INPUT_FEAT_GBP_LPM_ANON_CLASSIFY | + L2INPUT_FEAT_LEARN); + gbp_itf_set_l2_output_feature (itf, 0, + L2OUTPUT_FEAT_GBP_POLICY_LPM); + } + + gx->gx_flags = flags; gbp_ext_itf_db[sw_if_index] = gxi; @@ -124,10 +134,8 @@ gbp_ext_itf_delete (u32 sw_if_index) GBP_EXT_ITF_DBG ("del: %U", format_gbp_ext_itf, gx); - gbp_itf_set_l2_input_feature (gx->gx_itf, - (gxi | GBP_EXT_ITF_ID), - L2INPUT_FEAT_NONE); - gbp_itf_unlock (gx->gx_itf); + if (gx->gx_flags & GBP_EXT_ITF_F_ANON) + gbp_itf_unlock (gx->gx_itf); gbp_route_domain_unlock (gx->gx_rd); gbp_bridge_domain_unlock (gx->gx_bd); @@ -140,6 +148,86 @@ gbp_ext_itf_delete (u32 sw_if_index) return (VNET_API_ERROR_NO_SUCH_ENTRY); } +static clib_error_t * +gbp_ext_itf_add_del_cli (vlib_main_t * vm, + unformat_input_t * input, vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + u32 sw_if_index = ~0, bd_id = ~0, rd_id = ~0, flags = 0; + int add = 1; + int rv; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "del")) + add = 0; + else + if (unformat + (line_input, "%U", unformat_vnet_sw_interface, vnet_get_main (), + &sw_if_index)) + ; + else if (unformat (line_input, "bd %d", &bd_id)) + ; + else if (unformat (line_input, "rd %d", &rd_id)) + ; + else if (unformat (line_input, "anon-l3-out")) + flags |= GBP_EXT_ITF_F_ANON; + else + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + } + unformat_free (line_input); + + if (~0 == sw_if_index) + return clib_error_return (0, "interface must be specified"); + + if (add) + { + if (~0 == bd_id) + return clib_error_return (0, "BD-ID must be specified"); + if (~0 == rd_id) + return clib_error_return (0, "RD-ID must be specified"); + rv = gbp_ext_itf_add (sw_if_index, bd_id, rd_id, flags); + } + else + rv = gbp_ext_itf_delete (sw_if_index); + + switch (rv) + { + case 0: + return 0; + case VNET_API_ERROR_ENTRY_ALREADY_EXISTS: + return clib_error_return (0, "interface already exists"); + case VNET_API_ERROR_NO_SUCH_ENTRY: /* fallthrough */ + case VNET_API_ERROR_INVALID_SW_IF_INDEX: + return clib_error_return (0, "unknown interface"); + default: + return clib_error_return (0, "error %d", rv); + } + + /* never reached */ + return 0; +} + +/*? + * Add Group Based Interface as anonymous L3out interface + * + * @cliexpar + * @cliexstart{gbp interface [del] anon-l3out bd } + * @cliexend + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (gbp_itf_anon_l3out_add_del_node, static) = { + .path = "gbp ext-itf", + .short_help = "gbp ext-itf [del] bd rd [anon-l3-out]\n", + .function = gbp_ext_itf_add_del_cli, +}; +/* *INDENT-ON* */ + void gbp_ext_itf_walk (gbp_ext_itf_cb_t cb, void *ctx) {