aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/gbp/gbp_itf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gbp/gbp_itf.c')
-rw-r--r--src/plugins/gbp/gbp_itf.c574
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:
- */