Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgp/bfd backports for stable/10.1 #18137

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions bgpd/bgp_bfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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 &&
Expand Down Expand 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).
Expand Down Expand Up @@ -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);
Expand Down
28 changes: 17 additions & 11 deletions bgpd/bgp_nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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);

Expand All @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions bgpd/bgp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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)
Expand Down
Loading