diff options
Diffstat (limited to 'src/plugins/gbp/gbp_ext_itf.c')
-rw-r--r-- | src/plugins/gbp/gbp_ext_itf.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/plugins/gbp/gbp_ext_itf.c b/src/plugins/gbp/gbp_ext_itf.c index be2d614e1fa..89bcb3da49e 100644 --- a/src/plugins/gbp/gbp_ext_itf.c +++ b/src/plugins/gbp/gbp_ext_itf.c @@ -130,6 +130,120 @@ gbp_ext_itf_delete (u32 sw_if_index) return (VNET_API_ERROR_NO_SUCH_ENTRY); } +int +gbp_ext_itf_anon_add (u32 sw_if_index, u32 bd_id, u32 rd_id) +{ + int rv = gbp_ext_itf_add (sw_if_index, bd_id, rd_id); + if (rv) + return rv; + /* 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); + return 0; +} + +int +gbp_ext_itf_anon_delete (u32 sw_if_index) +{ + int rv = gbp_ext_itf_delete (sw_if_index); + if (rv) + return rv; + gbp_itf_unlock (sw_if_index); + return 0; +} + +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; + int add = 1, anon = 0; + 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")) + anon = 1; + 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"); + if (anon) + rv = gbp_ext_itf_anon_add (sw_if_index, bd_id, rd_id); + else + rv = gbp_ext_itf_add (sw_if_index, bd_id, rd_id); + } + else + { + if (anon) + rv = gbp_ext_itf_anon_delete (sw_if_index); + 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 <interface> bd <ID>} + * @cliexend + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (gbp_itf_anon_l3out_add_del_node, static) = { + .path = "gbp ext-itf", + .short_help = "gbp ext-itf [del] <interface> bd <ID> rd <ID> [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) { |