summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2021-09-29 17:42:19 +0200
committerDonald Sharp <sharpd@nvidia.com>2021-10-04 14:03:38 +0200
commitf3d20a2aa5746ad4b00a53b04df4fd863d8c49b4 (patch)
treeedbd59e4f31b43fd4e5dd5b659080da4eb6abcc8 /bgpd/bgp_zebra.c
parentbgpd: bgp_announce_route should know if we should force the update or not (diff)
downloadfrr-f3d20a2aa5746ad4b00a53b04df4fd863d8c49b4.tar.xz
frr-f3d20a2aa5746ad4b00a53b04df4fd863d8c49b4.zip
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>
Diffstat (limited to 'bgpd/bgp_zebra.c')
-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 2a67bb2f8..09fe399c2 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;