diff options
author | Alexander Chernavin <achernavin@netgate.com> | 2022-02-14 12:59:28 +0000 |
---|---|---|
committer | Matthew Smith <mgsmith@netgate.com> | 2022-03-29 13:31:02 +0000 |
commit | 851215a04ff53df2eb153133e3f47f514facde3a (patch) | |
tree | 33a92330d070d9f7319ecdc66f5a67acf838b5a8 | |
parent | 1c5b127d2247b68f362b3caac8ff229406fab4d0 (diff) |
linux-cp: handle ipv4 routes when link goes down on subif
Type: improvement
Currently, the plugin can monitor link state changes on hardware
interfaces for which a linux-cp pair exists. When the link goes down on
one of the hardware interfaces, the plugin processes IPv4 routes that
resolve through that interface according to the configurations:
del-static-on-link-down and del-dynamic-on-link-down.
The problem is that link state changes are not signaled for
subinterfaces and the code that handles IPv4 routes is not triggered.
When the link on a hardware interface goes down, it implies
that subinterfaces added to that interface also will have the link in
the down state.
With this change, when the link goes down on a hardware interface,
iterate over subinterfaces added to the interface and apply the same
logic of routes processing as for hardware interfaces.
Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
Change-Id: I97337d2e328437c73f2d99a00737768778f197a1
-rw-r--r-- | src/plugins/linux-cp/lcp_router.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/src/plugins/linux-cp/lcp_router.c b/src/plugins/linux-cp/lcp_router.c index 4aab148a456..05943e4ca67 100644 --- a/src/plugins/linux-cp/lcp_router.c +++ b/src/plugins/linux-cp/lcp_router.c @@ -512,33 +512,59 @@ lcp_router_link_up_down (vnet_main_t *vnm, u32 hw_if_index, u32 flags) lcp_get_del_dynamic_on_link_down ())) { u32 fib_index; + u32 **fib_index_to_sw_if_index_to_bool = NULL; + u32 id, sw_if_index; lcp_router_table_t *nlt; fib_index = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, hi->sw_if_index); - pool_foreach (nlt, lcp_router_table_pool) + vec_validate_init_empty (fib_index_to_sw_if_index_to_bool, fib_index, + NULL); + vec_validate_init_empty (fib_index_to_sw_if_index_to_bool[fib_index], + hi->sw_if_index, false); + fib_index_to_sw_if_index_to_bool[fib_index][hi->sw_if_index] = true; + + /* clang-format off */ + hash_foreach (id, sw_if_index, hi->sub_interface_sw_if_index_by_id, + ({ + fib_index = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, + sw_if_index); + vec_validate_init_empty (fib_index_to_sw_if_index_to_bool, fib_index, + NULL); + vec_validate_init_empty (fib_index_to_sw_if_index_to_bool[fib_index], + sw_if_index, false); + fib_index_to_sw_if_index_to_bool[fib_index][sw_if_index] = true; + })); + /* clang-format on */ + + vec_foreach_index (fib_index, fib_index_to_sw_if_index_to_bool) { - 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; + u32 *sw_if_index_to_bool; - if (lcp_get_del_static_on_link_down ()) - 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, sw_if_index_to_bool, - lcp_rt_fib_src_dynamic); + sw_if_index_to_bool = fib_index_to_sw_if_index_to_bool[fib_index]; + if (NULL == sw_if_index_to_bool) + continue; - vec_free (sw_if_index_to_bool); - break; + pool_foreach (nlt, lcp_router_table_pool) + { + if (fib_index == nlt->nlt_fib_index && + FIB_PROTOCOL_IP4 == nlt->nlt_proto) + { + if (lcp_get_del_static_on_link_down ()) + 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, sw_if_index_to_bool, + lcp_rt_fib_src_dynamic); + break; + } } + + vec_free (sw_if_index_to_bool); } + + vec_free (fib_index_to_sw_if_index_to_bool); } return 0; |