diff options
Diffstat (limited to 'src/plugins/gbp/gbp_itf.c')
-rw-r--r-- | src/plugins/gbp/gbp_itf.c | 574 |
1 files changed, 0 insertions, 574 deletions
diff --git a/src/plugins/gbp/gbp_itf.c b/src/plugins/gbp/gbp_itf.c deleted file mode 100644 index 738a7ac2e39..00000000000 --- a/src/plugins/gbp/gbp_itf.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Copyright (c) 2018 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <plugins/gbp/gbp_itf.h> -#include <plugins/gbp/gbp_bridge_domain.h> -#include <plugins/gbp/gbp_route_domain.h> - -#include <vnet/ip/ip.h> - -#define foreach_gbp_itf_mode \ - _(L2, "l2") \ - _(L3, "L3") - -typedef enum gbp_ift_mode_t_ -{ -#define _(s,v) GBP_ITF_MODE_##s, - foreach_gbp_itf_mode -#undef _ -} gbp_itf_mode_t; - -/** - * Attributes and configurations attached to interfaces by GBP - */ -typedef struct gbp_itf_t_ -{ - /** - * Number of references to this interface - */ - u32 gi_locks; - - /** - * The interface this wrapper is managing - */ - u32 gi_sw_if_index; - - /** - * The mode of the interface - */ - gbp_itf_mode_t gi_mode; - - /** - * Users of this interface - this is encoded in the user's handle - */ - u32 *gi_users; - - /** - * L2/L3 Features configured by each user - */ - u32 *gi_input_fbs; - u32 gi_input_fb; - u32 *gi_output_fbs; - u32 gi_output_fb; - - /** - * function to call when the interface is deleted. - */ - gbp_itf_free_fn_t gi_free_fn; - - union - { - /** - * GBP BD or RD index - */ - u32 gi_gbi; - index_t gi_gri; - }; -} gbp_itf_t; - -static gbp_itf_t *gbp_itf_pool; -static uword *gbp_itf_db; - -static const char *gbp_itf_feat_bit_pos_to_arc[] = { -#define _(s,v,a) [GBP_ITF_L3_FEAT_POS_##s] = a, - foreach_gdb_l3_feature -#undef _ -}; - -static const char *gbp_itf_feat_bit_pos_to_feat[] = { -#define _(s,v,a) [GBP_ITF_L3_FEAT_POS_##s] = v, - foreach_gdb_l3_feature -#undef _ -}; - -u8 * -format_gbp_itf_l3_feat (u8 * s, va_list * args) -{ - gbp_itf_l3_feat_t flags = va_arg (*args, gbp_itf_l3_feat_t); - -#define _(a, b, c) \ - if (flags & GBP_ITF_L3_FEAT_##a) \ - s = format (s, "%s ", b); - foreach_gdb_l3_feature -#undef _ - return (s); -} - -void -gbp_itf_hdl_reset (gbp_itf_hdl_t * gh) -{ - *gh = GBP_ITF_HDL_INVALID; -} - -bool -gbp_itf_hdl_is_valid (gbp_itf_hdl_t gh) -{ - return (gh.gh_which != GBP_ITF_HDL_INVALID.gh_which); -} - -static gbp_itf_t * -gbp_itf_get (index_t gii) -{ - if (pool_is_free_index (gbp_itf_pool, gii)) - return (NULL); - - return (pool_elt_at_index (gbp_itf_pool, gii)); -} - -static gbp_itf_t * -gbp_itf_find (u32 sw_if_index) -{ - uword *p; - - p = hash_get (gbp_itf_db, sw_if_index); - - if (NULL != p) - return (gbp_itf_get (p[0])); - - return (NULL); -} - -static gbp_itf_t * -gbp_itf_find_hdl (gbp_itf_hdl_t gh) -{ - return (gbp_itf_find (gh.gh_which)); -} - -u32 -gbp_itf_get_sw_if_index (gbp_itf_hdl_t hdl) -{ - return (hdl.gh_which); -} - -static gbp_itf_hdl_t -gbp_itf_mk_hdl (gbp_itf_t * gi) -{ - gbp_itf_hdl_t gh; - u32 *useri; - - pool_get (gi->gi_users, useri); - *useri = 0; - - gh.gh_who = useri - gi->gi_users; - gh.gh_which = gi->gi_sw_if_index; - - return (gh); -} - -static gbp_itf_hdl_t -gbp_itf_l2_add_and_lock_i (u32 sw_if_index, index_t gbi, gbp_itf_free_fn_t ff) -{ - gbp_itf_t *gi; - - gi = gbp_itf_find (sw_if_index); - - if (NULL == gi) - { - pool_get_zero (gbp_itf_pool, gi); - - gi->gi_sw_if_index = sw_if_index; - gi->gi_gbi = gbi; - gi->gi_mode = GBP_ITF_MODE_L2; - gi->gi_free_fn = ff; - - gbp_bridge_domain_itf_add (gi->gi_gbi, gi->gi_sw_if_index, - L2_BD_PORT_TYPE_NORMAL); - - hash_set (gbp_itf_db, gi->gi_sw_if_index, gi - gbp_itf_pool); - } - - gi->gi_locks++; - - return (gbp_itf_mk_hdl (gi)); -} - -gbp_itf_hdl_t -gbp_itf_l2_add_and_lock (u32 sw_if_index, index_t gbi) -{ - return (gbp_itf_l2_add_and_lock_i (sw_if_index, gbi, NULL)); -} - -gbp_itf_hdl_t -gbp_itf_l2_add_and_lock_w_free (u32 sw_if_index, - index_t gbi, gbp_itf_free_fn_t ff) -{ - return (gbp_itf_l2_add_and_lock_i (sw_if_index, gbi, ff)); -} - -gbp_itf_hdl_t -gbp_itf_l3_add_and_lock_i (u32 sw_if_index, index_t gri, gbp_itf_free_fn_t ff) -{ - gbp_itf_t *gi; - - gi = gbp_itf_find (sw_if_index); - - if (NULL == gi) - { - const gbp_route_domain_t *grd; - fib_protocol_t fproto; - - pool_get_zero (gbp_itf_pool, gi); - - gi->gi_sw_if_index = sw_if_index; - gi->gi_mode = GBP_ITF_MODE_L3; - gi->gi_gri = gri; - gi->gi_free_fn = ff; - - grd = gbp_route_domain_get (gi->gi_gri); - - ip4_sw_interface_enable_disable (gi->gi_sw_if_index, 1); - ip6_sw_interface_enable_disable (gi->gi_sw_if_index, 1); - - FOR_EACH_FIB_IP_PROTOCOL (fproto) - ip_table_bind (fproto, gi->gi_sw_if_index, grd->grd_table_id[fproto]); - - hash_set (gbp_itf_db, gi->gi_sw_if_index, gi - gbp_itf_pool); - } - - gi->gi_locks++; - - return (gbp_itf_mk_hdl (gi)); -} - -gbp_itf_hdl_t -gbp_itf_l3_add_and_lock (u32 sw_if_index, index_t gri) -{ - return (gbp_itf_l3_add_and_lock_i (sw_if_index, gri, NULL)); -} - -gbp_itf_hdl_t -gbp_itf_l3_add_and_lock_w_free (u32 sw_if_index, - index_t gri, gbp_itf_free_fn_t ff) -{ - return (gbp_itf_l3_add_and_lock_i (sw_if_index, gri, ff)); -} - -void -gbp_itf_lock (gbp_itf_hdl_t gh) -{ - gbp_itf_t *gi; - - if (!gbp_itf_hdl_is_valid (gh)) - return; - - gi = gbp_itf_find_hdl (gh); - - gi->gi_locks++; -} - -gbp_itf_hdl_t -gbp_itf_clone_and_lock (gbp_itf_hdl_t gh) -{ - gbp_itf_t *gi; - - if (!gbp_itf_hdl_is_valid (gh)) - return (GBP_ITF_HDL_INVALID); - - gi = gbp_itf_find_hdl (gh); - - gi->gi_locks++; - - return (gbp_itf_mk_hdl (gi)); -} - -void -gbp_itf_unlock (gbp_itf_hdl_t * gh) -{ - gbp_itf_t *gi; - - if (!gbp_itf_hdl_is_valid (*gh)) - return; - - gi = gbp_itf_find_hdl (*gh); - ASSERT (gi->gi_locks > 0); - gi->gi_locks--; - - if (0 == gi->gi_locks) - { - if (GBP_ITF_MODE_L2 == gi->gi_mode) - { - gbp_itf_l2_set_input_feature (*gh, L2INPUT_FEAT_NONE); - gbp_itf_l2_set_output_feature (*gh, L2OUTPUT_FEAT_NONE); - gbp_bridge_domain_itf_del (gi->gi_gbi, - gi->gi_sw_if_index, - L2_BD_PORT_TYPE_NORMAL); - } - else - { - fib_protocol_t fproto; - - gbp_itf_l3_set_input_feature (*gh, GBP_ITF_L3_FEAT_NONE); - FOR_EACH_FIB_IP_PROTOCOL (fproto) - ip_table_bind (fproto, gi->gi_sw_if_index, 0); - - ip4_sw_interface_enable_disable (gi->gi_sw_if_index, 0); - ip6_sw_interface_enable_disable (gi->gi_sw_if_index, 0); - } - - hash_unset (gbp_itf_db, gi->gi_sw_if_index); - - if (gi->gi_free_fn) - gi->gi_free_fn (gi->gi_sw_if_index); - - pool_free (gi->gi_users); - vec_free (gi->gi_input_fbs); - vec_free (gi->gi_output_fbs); - - memset (gi, 0, sizeof (*gi)); - } - - gbp_itf_hdl_reset (gh); -} - -void -gbp_itf_l3_set_input_feature (gbp_itf_hdl_t gh, gbp_itf_l3_feat_t feats) -{ - u32 diff_fb, new_fb, *fb, feat; - gbp_itf_t *gi; - - gi = gbp_itf_find_hdl (gh); - - if (NULL == gi || GBP_ITF_MODE_L3 != gi->gi_mode) - return; - - vec_validate (gi->gi_input_fbs, gh.gh_who); - gi->gi_input_fbs[gh.gh_who] = feats; - - new_fb = 0; - vec_foreach (fb, gi->gi_input_fbs) - { - new_fb |= *fb; - } - - /* add new features */ - diff_fb = (gi->gi_input_fb ^ new_fb) & new_fb; - - /* *INDENT-OFF* */ - foreach_set_bit (feat, diff_fb, - ({ - vnet_feature_enable_disable (gbp_itf_feat_bit_pos_to_arc[feat], - gbp_itf_feat_bit_pos_to_feat[feat], - gi->gi_sw_if_index, 1, 0, 0); - })); - /* *INDENT-ON* */ - - /* remove unneeded features */ - diff_fb = (gi->gi_input_fb ^ new_fb) & gi->gi_input_fb; - - /* *INDENT-OFF* */ - foreach_set_bit (feat, diff_fb, - ({ - vnet_feature_enable_disable (gbp_itf_feat_bit_pos_to_arc[feat], - gbp_itf_feat_bit_pos_to_feat[feat], - gi->gi_sw_if_index, 0, 0, 0); - })); - /* *INDENT-ON* */ - - gi->gi_input_fb = new_fb; -} - -void -gbp_itf_l2_set_input_feature (gbp_itf_hdl_t gh, l2input_feat_masks_t feats) -{ - u32 diff_fb, new_fb, *fb, feat; - gbp_itf_t *gi; - - gi = gbp_itf_find_hdl (gh); - - if (NULL == gi || GBP_ITF_MODE_L2 != gi->gi_mode) - { - ASSERT (0); - return; - } - - vec_validate (gi->gi_input_fbs, gh.gh_who); - gi->gi_input_fbs[gh.gh_who] = feats; - - new_fb = 0; - vec_foreach (fb, gi->gi_input_fbs) - { - new_fb |= *fb; - } - - /* add new features */ - diff_fb = (gi->gi_input_fb ^ new_fb) & new_fb; - - /* *INDENT-OFF* */ - foreach_set_bit (feat, diff_fb, - ({ - l2input_intf_bitmap_enable (gi->gi_sw_if_index, (1 << feat), 1); - })); - /* *INDENT-ON* */ - - /* remove unneeded features */ - diff_fb = (gi->gi_input_fb ^ new_fb) & gi->gi_input_fb; - - /* *INDENT-OFF* */ - foreach_set_bit (feat, diff_fb, - ({ - l2input_intf_bitmap_enable (gi->gi_sw_if_index, (1 << feat), 0); - })); - /* *INDENT-ON* */ - - gi->gi_input_fb = new_fb; -} - -void -gbp_itf_l2_set_output_feature (gbp_itf_hdl_t gh, l2output_feat_masks_t feats) -{ - u32 diff_fb, new_fb, *fb, feat; - gbp_itf_t *gi; - - gi = gbp_itf_find_hdl (gh); - - if (NULL == gi || GBP_ITF_MODE_L2 != gi->gi_mode) - { - ASSERT (0); - return; - } - - vec_validate (gi->gi_output_fbs, gh.gh_who); - gi->gi_output_fbs[gh.gh_who] = feats; - - new_fb = 0; - vec_foreach (fb, gi->gi_output_fbs) - { - new_fb |= *fb; - } - - /* add new features */ - diff_fb = (gi->gi_output_fb ^ new_fb) & new_fb; - - /* *INDENT-OFF* */ - foreach_set_bit (feat, diff_fb, - ({ - l2output_intf_bitmap_enable (gi->gi_sw_if_index, (1 << feat), 1); - })); - /* *INDENT-ON* */ - - /* remove unneeded features */ - diff_fb = (gi->gi_output_fb ^ new_fb) & gi->gi_output_fb; - - /* *INDENT-OFF* */ - foreach_set_bit (feat, diff_fb, - ({ - l2output_intf_bitmap_enable (gi->gi_sw_if_index, (1 << feat), 0); - })); - /* *INDENT-ON* */ - - gi->gi_output_fb = new_fb; -} - -static u8 * -format_gbp_itf_mode (u8 * s, va_list * args) -{ - gbp_itf_mode_t mode = va_arg (*args, gbp_itf_mode_t); - - switch (mode) - { -#define _(a,v) \ - case GBP_ITF_MODE_##a: \ - return format(s, "%s", v); - foreach_gbp_itf_mode -#undef _ - } - return (s); -} - -static u8 * -format_gbp_itf (u8 * s, va_list * args) -{ - index_t gii = va_arg (*args, index_t); - gbp_itf_t *gi; - - if (INDEX_INVALID == gii) - return (format (s, "unset")); - - gi = gbp_itf_get (gii); - - s = format (s, "%U locks:%d mode:%U ", - format_vnet_sw_if_index_name, vnet_get_main (), - gi->gi_sw_if_index, gi->gi_locks, - format_gbp_itf_mode, gi->gi_mode); - - if (GBP_ITF_MODE_L2 == gi->gi_mode) - s = format (s, "gbp-bd:%d input-feats:[%U] output-feats:[%U]", - gi->gi_gbi, - format_l2_input_features, gi->gi_input_fb, 0, - format_l2_output_features, gi->gi_output_fb, 0); - else - s = format (s, "gbp-rd:%d input-feats:[%U] output-feats:[%U]", - gi->gi_gbi, - format_gbp_itf_l3_feat, gi->gi_input_fb, - format_gbp_itf_l3_feat, gi->gi_output_fb); - - return (s); -} - -u8 * -format_gbp_itf_hdl (u8 * s, va_list * args) -{ - gbp_itf_hdl_t gh = va_arg (*args, gbp_itf_hdl_t); - gbp_itf_t *gi; - - gi = gbp_itf_find_hdl (gh); - - if (NULL == gi) - return format (s, "INVALID"); - - return (format (s, "%U", format_gbp_itf, gi - gbp_itf_pool)); -} - -static clib_error_t * -gbp_itf_show (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - u32 gii; - - vlib_cli_output (vm, "Interfaces:"); - - /* *INDENT-OFF* */ - pool_foreach_index (gii, gbp_itf_pool) - { - vlib_cli_output (vm, " [%d] %U", gii, format_gbp_itf, gii); - } - /* *INDENT-ON* */ - - return (NULL); -} - -/*? - * Show Group Based Interfaces - * - * @cliexpar - * @cliexstart{show gbp contract} - * @cliexend - ?*/ -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (gbp_contract_show_node, static) = { - .path = "show gbp interface", - .short_help = "show gbp interface\n", - .function = gbp_itf_show, -}; -/* *INDENT-ON* */ - - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |