diff options
author | Pim van Pelt <pim@ipng.nl> | 2023-05-21 08:35:26 +0200 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2023-06-09 19:34:36 +0000 |
commit | 63e76fad7e369746f71305a3c9a88d035ec5cb58 (patch) | |
tree | d9fdd7312b8b09c9695e088d9a15a17e2e3fcfc1 /src/plugins/linux-cp/lcp_router.c | |
parent | 1a67c82c843b41d61bd50298597a119ac13174ab (diff) |
linux-cp: Fix add vs update on routes
Linux uses NLM_F_REPLACE in the netlink message to signal a FIB update
The code invariably does a FIB update for IPv4 and a addition for IPv6.
Without this fix, the following:
ip route add 2001:db8::/48 via 2001:db8::1
ip route replace 2001:db8::/48 via 2001:db8::2
ends up as two separate FIB entries in VPP. With the fix, there will be one FIB entry (the second one with nexthop ::2).
Type: fix
Change-Id: I8f98d6ded52ae0c60bfddaa7fc39acbbaa19d34a
Signed-off-by: Pim van Pelt <pim@ipng.nl>
(cherry picked from commit af4fa965e909db69ecde9deb6b7f9a53553aeccb)
Diffstat (limited to 'src/plugins/linux-cp/lcp_router.c')
-rw-r--r-- | src/plugins/linux-cp/lcp_router.c | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/src/plugins/linux-cp/lcp_router.c b/src/plugins/linux-cp/lcp_router.c index c5846cfca3c..8148f9bde56 100644 --- a/src/plugins/linux-cp/lcp_router.c +++ b/src/plugins/linux-cp/lcp_router.c @@ -1167,7 +1167,7 @@ lcp_router_route_del (struct rtnl_route *rr) } static void -lcp_router_route_add (struct rtnl_route *rr) +lcp_router_route_add (struct rtnl_route *rr, int is_replace) { fib_entry_flag_t entry_flags; uint32_t table_id; @@ -1196,71 +1196,71 @@ lcp_router_route_add (struct rtnl_route *rr) LCP_ROUTER_DBG ("route skip: %d:%U %U", rtnl_route_get_table (rr), format_fib_prefix, &pfx, format_fib_entry_flags, entry_flags); + return; } - else - { - LCP_ROUTER_DBG ("route add: %d:%U %U", rtnl_route_get_table (rr), - format_fib_prefix, &pfx, format_fib_entry_flags, - entry_flags); + LCP_ROUTER_DBG ("route %s: %d:%U %U", is_replace ? "replace" : "add", + rtnl_route_get_table (rr), format_fib_prefix, &pfx, + format_fib_entry_flags, entry_flags); - lcp_router_route_path_parse_t np = { - .route_proto = pfx.fp_proto, - .is_mcast = (rtype == RTN_MULTICAST), - .type_flags = lcp_router_route_type_frpflags[rtype], - .preference = (u8) rtnl_route_get_priority (rr), - }; + lcp_router_route_path_parse_t np = { + .route_proto = pfx.fp_proto, + .is_mcast = (rtype == RTN_MULTICAST), + .type_flags = lcp_router_route_type_frpflags[rtype], + .preference = (u8) rtnl_route_get_priority (rr), + }; - rtnl_route_foreach_nexthop (rr, lcp_router_route_path_parse, &np); - lcp_router_route_path_add_special (rr, &np); + rtnl_route_foreach_nexthop (rr, lcp_router_route_path_parse, &np); + lcp_router_route_path_add_special (rr, &np); - if (0 != vec_len (np.paths)) + if (0 != vec_len (np.paths)) + { + if (rtype == RTN_MULTICAST) { - if (rtype == RTN_MULTICAST) - { - /* it's not clear to me how linux expresses the RPF paramters - * so we'll allow from all interfaces and hope for the best */ - mfib_prefix_t mpfx = {}; + /* it's not clear to me how linux expresses the RPF paramters + * so we'll allow from all interfaces and hope for the best */ + mfib_prefix_t mpfx = {}; - lcp_router_route_mk_mprefix (rr, &mpfx); + lcp_router_route_mk_mprefix (rr, &mpfx); - mfib_table_entry_update ( - nlt->nlt_mfib_index, &mpfx, MFIB_SOURCE_PLUGIN_LOW, - MFIB_RPF_ID_NONE, MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF); + mfib_table_entry_update (nlt->nlt_mfib_index, &mpfx, + MFIB_SOURCE_PLUGIN_LOW, MFIB_RPF_ID_NONE, + MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF); - mfib_table_entry_paths_update (nlt->nlt_mfib_index, &mpfx, - MFIB_SOURCE_PLUGIN_LOW, - MFIB_ENTRY_FLAG_NONE, np.paths); - } - else - { - fib_source_t fib_src; - const fib_route_path_t *rpath; + mfib_table_entry_paths_update (nlt->nlt_mfib_index, &mpfx, + MFIB_SOURCE_PLUGIN_LOW, + MFIB_ENTRY_FLAG_NONE, np.paths); + } + else + { + fib_source_t fib_src; + const fib_route_path_t *rpath; - vec_foreach (rpath, np.paths) + vec_foreach (rpath, np.paths) + { + if (fib_route_path_is_attached (rpath)) { - if (fib_route_path_is_attached (rpath)) - { - entry_flags |= FIB_ENTRY_FLAG_ATTACHED; - break; - } + entry_flags |= FIB_ENTRY_FLAG_ATTACHED; + break; } + } - fib_src = lcp_router_proto_fib_source (rproto); + fib_src = lcp_router_proto_fib_source (rproto); - if (pfx.fp_proto == FIB_PROTOCOL_IP6) - fib_table_entry_path_add2 (nlt->nlt_fib_index, &pfx, fib_src, - entry_flags, np.paths); - else - fib_table_entry_update (nlt->nlt_fib_index, &pfx, fib_src, - entry_flags, np.paths); - } + if (is_replace) + fib_table_entry_update (nlt->nlt_fib_index, &pfx, fib_src, + entry_flags, np.paths); + else + fib_table_entry_path_add2 (nlt->nlt_fib_index, &pfx, fib_src, + entry_flags, np.paths); } - else - LCP_ROUTER_DBG ("no paths for route add: %d:%U %U", - rtnl_route_get_table (rr), format_fib_prefix, &pfx, - format_fib_entry_flags, entry_flags); - vec_free (np.paths); } + else + { + LCP_ROUTER_DBG ("no paths for route: %d:%U %U", + rtnl_route_get_table (rr), format_fib_prefix, &pfx, + format_fib_entry_flags, entry_flags); + } + vec_free (np.paths); } static void |