From 424fe0bf809c1d84f16aba3f5e5f8249af29083b Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 11:11:05 +0100 Subject: [PATCH] bgpd: fix sending ipv6 local nexthop if global present bgpd keeps on advertising IPv6 prefixes with a IPv6 link-local nexthop after a valid IPv6 global appears. At bgpd startup, the IPv6 global is announced by zebra after the link-local. Only the link-local is advertised. Clearing the BGP sessions make the global to to be announced. Update the nexthops with the global IPv6 when available. Signed-off-by: Louis Scalbert --- bgpd/bgp_zebra.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 5977180ce5..5c0a6a09c3 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -303,11 +303,12 @@ static int bgp_ifp_down(struct interface *ifp) static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) { - struct connected *ifc; + struct connected *ifc, *connected; struct bgp *bgp; struct peer *peer; struct prefix *addr; struct listnode *node, *nnode; + bool v6_ll_in_nh_global; afi_t afi; safi_t safi; @@ -342,6 +343,27 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) addr = ifc->address; for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + v6_ll_in_nh_global = false; + + if (IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global)) { + frr_each (if_connected, ifc->ifp->connected, + connected) { + if (connected->address->family != + AF_INET6) + continue; + if (!IPV6_ADDR_SAME(&connected->address + ->u.prefix6, + &peer->nexthop + .v6_global)) + continue; + /* peer->nexthop.v6_global contains a link-local address + * that needs to be replaced by the global address. + */ + v6_ll_in_nh_global = true; + break; + } + } + /* * If the Peer's interface name matches the * interface name for which BGP received the @@ -352,10 +374,11 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) * into peer's v6_global and send updates out * with new nexthop addr. */ - if ((peer->conf_if && - (strcmp(peer->conf_if, ifc->ifp->name) == 0)) && - ((IS_MAPPED_IPV6(&peer->nexthop.v6_global)) || - IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global))) { + if (v6_ll_in_nh_global || + (peer->conf_if && + strcmp(peer->conf_if, ifc->ifp->name) == 0 && + (IS_MAPPED_IPV6(&peer->nexthop.v6_global) || + IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global)))) { if (bgp_debug_zebra(ifc->address)) { zlog_debug("Update peer %pBP's current intf global addr from %pI6 to %pI6 and send updates", peer,