summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2021-09-29 11:42:19 -0400
committerDonald Sharp <sharpd@nvidia.com>2021-10-04 08:03:38 -0400
commitf3d20a2aa5746ad4b00a53b04df4fd863d8c49b4 (patch)
treeedbd59e4f31b43fd4e5dd5b659080da4eb6abcc8
parente1a32ec1c5a4468a8ab7f7d92febfdbebe475d79 (diff)
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 <sharpd@nvidia.com>
-rw-r--r--bgpd/bgp_zebra.c32
1 files changed, 32 insertions, 0 deletions
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;