summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <donaldsharp72@gmail.com>2025-02-13 11:18:33 -0500
committerGitHub <noreply@github.com>2025-02-13 11:18:33 -0500
commit92046523bfebd67bfa0ec4cc97901c72e53f0815 (patch)
tree369de2ccaedee1fefab3c03ddb8c28275aba1bd4
parent07e44e0aadcf9afccb25b7911a9eeea841aa979f (diff)
parent1f9ca9e1591f03810f7321ebb0cc47da0fc5020c (diff)
Merge pull request #18137 from opensourcerouting/fix/backport_bgp_bfd_10.1
bgp/bfd backports for stable/10.1
-rw-r--r--bgpd/bgp_bfd.c59
-rw-r--r--bgpd/bgp_nexthop.c28
-rw-r--r--bgpd/bgp_zebra.c4
3 files changed, 68 insertions, 23 deletions
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index 14ff5f2e11..add93d3a5f 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -26,6 +26,7 @@
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_packet.h"
+#include "bgpd/bgp_network.h"
DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data");
@@ -53,14 +54,23 @@ static void bfd_session_status_update(struct bfd_session_params *bsp,
peer->host);
return;
}
- peer->last_reset = PEER_DOWN_BFD_DOWN;
- /* rfc9384 */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_BFD_DOWN);
-
- BGP_EVENT_ADD(peer->connection, BGP_Stop);
+ /* Once the BFD session is UP, and later BGP session is UP,
+ * BFD notices that peer->su_local changed, and BFD session goes down.
+ * We should trigger BGP session reset if BFD session is UP
+ * only when BGP session is UP already.
+ * Otherwise, we end up resetting BGP session when BFD session is UP,
+ * when the source address is changed, e.g. 0.0.0.0 -> 10.0.0.1.
+ */
+ if (bss->last_event > peer->uptime) {
+ peer->last_reset = PEER_DOWN_BFD_DOWN;
+ /* rfc9384 */
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
+ bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_BFD_DOWN);
+
+ BGP_EVENT_ADD(peer->connection, BGP_Stop);
+ }
}
if (bss->state == BSS_UP && bss->previous_state != BSS_UP &&
@@ -104,6 +114,10 @@ void bgp_peer_config_apply(struct peer *p, struct peer_group *pg)
*/
gconfig = pg->conf;
+ if (CHECK_FLAG(gconfig->flags, PEER_FLAG_UPDATE_SOURCE) ||
+ CHECK_FLAG(p->flags_override, PEER_FLAG_UPDATE_SOURCE))
+ bgp_peer_bfd_update_source(p);
+
/*
* If using default control plane independent configuration,
* then prefer group's (e.g. it means it wasn't manually configured).
@@ -141,24 +155,45 @@ void bgp_peer_config_apply(struct peer *p, struct peer_group *pg)
void bgp_peer_bfd_update_source(struct peer *p)
{
- struct bfd_session_params *session = p->bfd_config->session;
- const union sockunion *source;
+ struct bfd_session_params *session;
+ const union sockunion *source = NULL;
bool changed = false;
int family;
union {
struct in_addr v4;
struct in6_addr v6;
} src, dst;
+ struct interface *ifp;
+ union sockunion addr;
+
+ if (!p->bfd_config)
+ return;
+ session = p->bfd_config->session;
/* Nothing to do for groups. */
if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP))
return;
/* Figure out the correct source to use. */
- if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE) && p->update_source)
- source = p->update_source;
- else
+ if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE)) {
+ if (p->update_source) {
+ source = p->update_source;
+ } else if (p->update_if) {
+ ifp = if_lookup_by_name(p->update_if, p->bgp->vrf_id);
+ if (ifp) {
+ sockunion_init(&addr);
+ if (bgp_update_address(ifp, &p->connection->su, &addr)) {
+ if (BGP_DEBUG(bfd, BFD_LIB))
+ zlog_debug("%s: can't find the source address for interface %s",
+ __func__, p->update_if);
+ }
+
+ source = &addr;
+ }
+ }
+ } else {
source = p->su_local;
+ }
/* Update peer's source/destination addresses. */
bfd_sess_addresses(session, &family, &src.v6, &dst.v6);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index ba6d707109..68a1b85806 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -32,6 +32,7 @@
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_rd.h"
#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_bfd.h"
DEFINE_MTYPE_STATIC(BGPD, MARTIAN_STRING, "BGP Martian Addr Intf String");
@@ -409,17 +410,6 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc)
bgp_dest_set_bgp_connected_ref_info(dest, bc);
}
- for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- if (peer->conf_if &&
- (strcmp(peer->conf_if, ifc->ifp->name) == 0) &&
- !peer_established(peer->connection) &&
- !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) {
- connection = peer->connection;
- if (peer_active(peer))
- BGP_EVENT_ADD(connection, BGP_Stop);
- BGP_EVENT_ADD(connection, BGP_Start);
- }
- }
} else if (addr->family == AF_INET6) {
apply_mask_ipv6((struct prefix_ipv6 *)&p);
@@ -443,6 +433,22 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc)
bgp_dest_set_bgp_connected_ref_info(dest, bc);
}
}
+
+ /*
+ * Iterate over all the peers and attempt to set the bfd session
+ * data and if it's a bgp unnumbered get her flowing if necessary
+ */
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+ bgp_peer_bfd_update_source(peer);
+ if (peer->conf_if && (strcmp(peer->conf_if, ifc->ifp->name) == 0) &&
+ !peer_established(peer->connection) &&
+ !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) {
+ connection = peer->connection;
+ if (peer_active(peer))
+ BGP_EVENT_ADD(connection, BGP_Stop);
+ BGP_EVENT_ADD(connection, BGP_Start);
+ }
+ }
}
void bgp_connected_delete(struct bgp *bgp, struct connected *ifc)
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 2e9c54e126..10e823c14f 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -744,6 +744,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
int ret = 0;
struct interface *ifp = NULL;
bool v6_ll_avail = true;
+ bool shared_network_original = peer->shared_network;
memset(nexthop, 0, sizeof(struct bgp_nexthop));
@@ -908,6 +909,9 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
peer->shared_network = 0;
}
+ if (shared_network_original != peer->shared_network)
+ bgp_peer_bfd_update_source(peer);
+
/* KAME stack specific treatment. */
#ifdef KAME
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->v6_global)