From: Donald Sharp Date: Wed, 29 Sep 2021 15:42:19 +0000 (-0400) Subject: bgpd: When removing v6 address being used as a nexthop ensure peer is reset X-Git-Tag: base_8.2~357^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=f3d20a2aa5746ad4b00a53b04df4fd863d8c49b4;p=matthieu%2Ffrr.git bgpd: When removing v6 address being used as a nexthop ensure peer is reset With v6 interface based peering, we send the global as well as the LL address as nexthops to the peer. When either of these were removed on the interface we were not necessarily resetting the connection. Leaving bgp in a state where the peer had reachability for addresses that are no longer in use. Modify the code that when we receive an interface address deletion event. Check to see that we are using the v6 address as nexthops for that peer and if so, tell it to reset. I initially struggled with a hard reset of the peer or a clear but choose to follow other places in the code that we noticed address changes that resulted in hard resets. Ticket: #2799568 Signed-off-by: Donald Sharp --- diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 2a67bb2f8c..09fe399c29 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -338,8 +338,11 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) { + struct listnode *node, *nnode; struct connected *ifc; + struct peer *peer; struct bgp *bgp; + struct prefix *addr; bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -356,6 +359,35 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) bgp_connected_delete(bgp, ifc); } + addr = ifc->address; + + if (bgp) { + /* + * When we are using the v6 global as part of the peering + * nexthops and we are removing it, then we need to + * clear the peer data saved for that nexthop and + * cause a re-announcement of the route. Since + * we do not want the peering to bounce. + */ + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + afi_t afi; + safi_t safi; + + if (addr->family == AF_INET) + continue; + + if (!IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6) + && memcmp(&peer->nexthop.v6_global, + &addr->u.prefix6, 16) + == 0) { + memset(&peer->nexthop.v6_global, 0, 16); + FOREACH_AFI_SAFI (afi, safi) + bgp_announce_route(peer, afi, safi, + true); + } + } + } + connected_free(&ifc); return 0;