From 62196fbd1919f98a8cf36ebdd1f48d31a404ed9f Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 6 Aug 2023 20:42:47 +0300 Subject: [PATCH] zebra: Enable `nht resolve-via-default` by default for traditional profile Lots of questions raising regarding unresolved nht, I think it's time to relax this and make it a default ON. Here is an example list of issues when `nht resolvia-via-default` solved the problem: https://github.com/FRRouting/frr/issues/3241 https://github.com/FRRouting/frr/issues/7420 https://github.com/FRRouting/frr/issues/3474 https://github.com/FRRouting/frr/issues/5023 https://github.com/FRRouting/frr/issues/6504 https://github.com/FRRouting/frr/issues/6680 https://github.com/FRRouting/frr/issues/7049 https://github.com/FRRouting/frr/issues/7862 https://github.com/FRRouting/frr/issues/7999 https://github.com/FRRouting/frr/issues/13215 https://github.com/FRRouting/frr/issues/14098 TL;DR; The BGP session does not come up if using multihop sessions and/or the peer(nexthop) is not accessible from the RIB, but only via default route. This is even valid for iBGP, and not only for eBGP peering. Adding a static /32, /128 route for the peer would do the trick, but it's a workaround. If the route has a nexthop marked as invalid, most likely this is due to it can't be resolved from the current RIB, but only via default route. For instance, Cisco allows this by default (can't find even a knob to turn it off or I'm blind). For eBGP sessions it might be also combined with `disable-ebgp-connected-route-check`. Some people asked if this could be a default, also for instance MetalLB is adding this by default for all the configs it generates. Signed-off-by: Donatas Abraitis --- doc/user/zebra.rst | 4 ++++ zebra/zebra_vrf.c | 39 +++++++++++++++++++++++++++++++-------- zebra/zebra_vrf.h | 6 ++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 39add2235f..ee9dabbf12 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -328,11 +328,15 @@ the default route. Allow IPv4 nexthop tracking to resolve via the default route. This parameter is configured per-VRF, so the command is also available in the VRF subnode. + This is enabled by default for a traditional profile. + .. clicmd:: ipv6 nht resolve-via-default Allow IPv6 nexthop tracking to resolve via the default route. This parameter is configured per-VRF, so the command is also available in the VRF subnode. + This is enabled by default for a traditional profile. + .. clicmd:: show ip nht [vrf NAME] [A.B.C.D|X:X::X:X] [mrib] [json] Show nexthop tracking status for address resolution. If vrf is not specified diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index b246d445da..c13b3071e9 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -373,6 +373,12 @@ struct zebra_vrf *zebra_vrf_alloc(struct vrf *vrf) zebra_pw_init(zvrf); zvrf->table_id = RT_TABLE_MAIN; /* by default table ID is default one */ + + if (DFLT_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) { + zvrf->zebra_rnh_ip_default_route = true; + zvrf->zebra_rnh_ipv6_default_route = true; + } + return zvrf; } @@ -456,11 +462,20 @@ static int vrf_config_write(struct vty *vty) zvrf->l3vni) ? " prefix-routes-only" : ""); - if (zvrf->zebra_rnh_ip_default_route) - vty_out(vty, "ip nht resolve-via-default\n"); - if (zvrf->zebra_rnh_ipv6_default_route) - vty_out(vty, "ipv6 nht resolve-via-default\n"); + if (zvrf->zebra_rnh_ip_default_route != + SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) + vty_out(vty, "%sip nht resolve-via-default\n", + zvrf->zebra_rnh_ip_default_route + ? "" + : "no "); + + if (zvrf->zebra_rnh_ipv6_default_route != + SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) + vty_out(vty, "%sipv6 nht resolve-via-default\n", + zvrf->zebra_rnh_ipv6_default_route + ? "" + : "no "); if (zvrf->tbl_mgr && (zvrf->tbl_mgr->start || zvrf->tbl_mgr->end)) @@ -476,11 +491,19 @@ static int vrf_config_write(struct vty *vty) ? " prefix-routes-only" : ""); zebra_ns_config_write(vty, (struct ns *)vrf->ns_ctxt); - if (zvrf->zebra_rnh_ip_default_route) - vty_out(vty, " ip nht resolve-via-default\n"); + if (zvrf->zebra_rnh_ip_default_route != + SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) + vty_out(vty, " %sip nht resolve-via-default\n", + zvrf->zebra_rnh_ip_default_route + ? "" + : "no "); - if (zvrf->zebra_rnh_ipv6_default_route) - vty_out(vty, " ipv6 nht resolve-via-default\n"); + if (zvrf->zebra_rnh_ipv6_default_route != + SAVE_ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT) + vty_out(vty, " %sipv6 nht resolve-via-default\n", + zvrf->zebra_rnh_ipv6_default_route + ? "" + : "no "); if (zvrf->tbl_mgr && vrf_is_backend_netns() && (zvrf->tbl_mgr->start || zvrf->tbl_mgr->end)) diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index aef83cd8f1..5cbfab1ddc 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -13,11 +13,17 @@ #include #include #include +#include "defaults.h" #ifdef __cplusplus extern "C" { #endif +FRR_CFG_DEFAULT_BOOL(ZEBRA_IP_NHT_RESOLVE_VIA_DEFAULT, + { .val_bool = true, .match_profile = "traditional", }, + { .val_bool = false }, +); + /* MPLS (Segment Routing) global block */ struct mpls_srgb { uint32_t start_label;