aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chernavin <achernavin@netgate.com>2022-02-11 15:25:40 +0000
committerMatthew Smith <mgsmith@netgate.com>2022-03-29 12:49:45 +0000
commit1c5b127d2247b68f362b3caac8ff229406fab4d0 (patch)
tree523635b5135c75003ff70a253463270edad9b51f
parent53e575ce8a495d132b41ef9b2f1f6b70299a8134 (diff)
linux-cp: add support for table flush if multiple interfaces
Type: improvement lcp_router_table_flush() is used to remove routes from the given route table if they are resolved through the given interface with specified FIB source. Currently, if you need to remove routes from a route table that are resolved through one of the interfaces from a vector, the function has to be executed for every interface from the vector. Every execution walks the route table again. With this change, lcp_router_table_flush() accepts a vector of interfaces. Thus, the function can walk a single route table once and delete routes that resolve through one of the interfaces from the vector. Signed-off-by: Alexander Chernavin <achernavin@netgate.com> Change-Id: I6d99384064d279dea24bb4dc1790a1af943be41c
-rw-r--r--src/plugins/linux-cp/lcp_router.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/src/plugins/linux-cp/lcp_router.c b/src/plugins/linux-cp/lcp_router.c
index 4fc824ca5ad..4aab148a456 100644
--- a/src/plugins/linux-cp/lcp_router.c
+++ b/src/plugins/linux-cp/lcp_router.c
@@ -307,7 +307,8 @@ lcp_router_link_addr (struct rtnl_link *rl, lcp_itf_pair_t *lip)
lip->lip_phy_adjs.adj_index[AF_IP6]);
}
-static void lcp_router_table_flush (lcp_router_table_t *nlt, u32 sw_if_index,
+static void lcp_router_table_flush (lcp_router_table_t *nlt,
+ u32 *sw_if_index_to_bool,
fib_source_t source);
static void
@@ -366,10 +367,18 @@ lcp_router_link_add (struct rtnl_link *rl, void *ctx)
if (fib_index == nlt->nlt_fib_index &&
FIB_PROTOCOL_IP4 == nlt->nlt_proto)
{
- lcp_router_table_flush (nlt, lip->lip_phy_sw_if_index,
+ u32 *sw_if_index_to_bool = NULL;
+
+ vec_validate_init_empty (sw_if_index_to_bool,
+ lip->lip_phy_sw_if_index, false);
+ sw_if_index_to_bool[lip->lip_phy_sw_if_index] = true;
+
+ lcp_router_table_flush (nlt, sw_if_index_to_bool,
lcp_rt_fib_src);
- lcp_router_table_flush (nlt, lip->lip_phy_sw_if_index,
+ lcp_router_table_flush (nlt, sw_if_index_to_bool,
lcp_rt_fib_src_dynamic);
+
+ vec_free (sw_if_index_to_bool);
break;
}
}
@@ -513,11 +522,20 @@ lcp_router_link_up_down (vnet_main_t *vnm, u32 hw_if_index, u32 flags)
if (fib_index == nlt->nlt_fib_index &&
FIB_PROTOCOL_IP4 == nlt->nlt_proto)
{
+ u32 *sw_if_index_to_bool = NULL;
+
+ vec_validate_init_empty (sw_if_index_to_bool, hi->sw_if_index,
+ false);
+ sw_if_index_to_bool[hi->sw_if_index] = true;
+
if (lcp_get_del_static_on_link_down ())
- lcp_router_table_flush (nlt, hi->sw_if_index, lcp_rt_fib_src);
+ lcp_router_table_flush (nlt, sw_if_index_to_bool,
+ lcp_rt_fib_src);
if (lcp_get_del_dynamic_on_link_down ())
- lcp_router_table_flush (nlt, hi->sw_if_index,
+ lcp_router_table_flush (nlt, sw_if_index_to_bool,
lcp_rt_fib_src_dynamic);
+
+ vec_free (sw_if_index_to_bool);
break;
}
}
@@ -1208,7 +1226,7 @@ lcp_router_route_sync_end (void)
typedef struct lcp_router_table_flush_ctx_t_
{
fib_node_index_t *lrtf_entries;
- u32 lrtf_sw_if_index;
+ u32 *lrtf_sw_if_index_to_bool;
fib_source_t lrtf_source;
} lcp_router_table_flush_ctx_t;
@@ -1216,9 +1234,13 @@ static fib_table_walk_rc_t
lcp_router_table_flush_cb (fib_node_index_t fib_entry_index, void *arg)
{
lcp_router_table_flush_ctx_t *ctx = arg;
+ u32 sw_if_index;
- if (fib_entry_get_resolving_interface_for_source (
- fib_entry_index, ctx->lrtf_source) == ctx->lrtf_sw_if_index)
+ sw_if_index = fib_entry_get_resolving_interface_for_source (
+ fib_entry_index, ctx->lrtf_source);
+
+ if (sw_if_index < vec_len (ctx->lrtf_sw_if_index_to_bool) &&
+ ctx->lrtf_sw_if_index_to_bool[sw_if_index])
{
vec_add1 (ctx->lrtf_entries, fib_entry_index);
}
@@ -1226,24 +1248,26 @@ lcp_router_table_flush_cb (fib_node_index_t fib_entry_index, void *arg)
}
static void
-lcp_router_table_flush (lcp_router_table_t *nlt, u32 sw_if_index,
+lcp_router_table_flush (lcp_router_table_t *nlt, u32 *sw_if_index_to_bool,
fib_source_t source)
{
fib_node_index_t *fib_entry_index;
lcp_router_table_flush_ctx_t ctx = {
.lrtf_entries = NULL,
- .lrtf_sw_if_index = sw_if_index,
+ .lrtf_sw_if_index_to_bool = sw_if_index_to_bool,
.lrtf_source = source,
};
+ LCP_ROUTER_DBG (
+ "Flush table: proto %U, fib-index %u, max sw_if_index %u, source %U",
+ format_fib_protocol, nlt->nlt_proto, nlt->nlt_fib_index,
+ vec_len (sw_if_index_to_bool) - 1, format_fib_source, source);
+
fib_table_walk (nlt->nlt_fib_index, nlt->nlt_proto,
lcp_router_table_flush_cb, &ctx);
- LCP_ROUTER_DBG (
- "Flush table: proto %U, fib-index %u, resolved via %U for source %U",
- format_fib_protocol, nlt->nlt_proto, nlt->nlt_fib_index,
- format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index,
- format_fib_source, source);
+ LCP_ROUTER_DBG ("Flush table: entries number to delete %u",
+ vec_len (ctx.lrtf_entries));
vec_foreach (fib_entry_index, ctx.lrtf_entries)
{