Skip to content

Commit

Permalink
Merge pull request #16099 from Pdoijode/pdoijode/bgp-gr2
Browse files Browse the repository at this point in the history
Implement BGP-wide configuration for graceful restart
  • Loading branch information
ton31337 authored Jul 2, 2024
2 parents 410947f + b5682ff commit 9ab4186
Show file tree
Hide file tree
Showing 27 changed files with 1,289 additions and 599 deletions.
395 changes: 143 additions & 252 deletions bgpd/bgp_fsm.c

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions bgpd/bgp_fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ int bgp_neighbor_graceful_restart(struct peer *peer,
enum peer_gr_command peer_gr_cmd);
unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_peer_state,
enum peer_mode new_peer_state);
void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state);
void bgp_peer_move_to_gr_mode(struct peer *peer, enum peer_mode new_state);
unsigned int bgp_peer_gr_helper_enable(struct peer *peer);
unsigned int bgp_peer_gr_enable(struct peer *peer);
unsigned int bgp_peer_gr_global_inherit(struct peer *peer);
Expand All @@ -160,9 +160,6 @@ enum peer_mode bgp_peer_gr_mode_get(struct peer *peer);
enum global_mode bgp_global_gr_mode_get(struct bgp *bgp);
enum peer_mode bgp_get_peer_gr_mode_from_flags(struct peer *peer);
unsigned int bgp_peer_gr_global_inherit_unset(struct peer *peer);
int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
enum global_mode global_new_state,
enum global_mode global_old_state);
void bgp_peer_gr_flags_update(struct peer *peer);
const char *print_peer_gr_mode(enum peer_mode pr_mode);
const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd);
Expand Down
4 changes: 4 additions & 0 deletions bgpd/bgp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,13 +511,17 @@ int main(int argc, char **argv)

/* BGP master init. */
bgp_master_init(frr_init(), buffer_size, addresses);
bm->startup_time = monotime(NULL);
bm->port = bgp_port;
if (bgp_port == 0)
bgp_option_set(BGP_OPT_NO_LISTEN);
if (no_fib_flag || no_zebra_flag)
bgp_option_set(BGP_OPT_NO_FIB);
if (no_zebra_flag)
bgp_option_set(BGP_OPT_NO_ZEBRA);
if (bgpd_di.graceful_restart)
SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART);

bgp_error_init();
/* Initializations. */
libagentx_init();
Expand Down
93 changes: 44 additions & 49 deletions bgpd/bgp_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,20 +519,17 @@ static int bgp_capability_restart(struct peer *peer,
UNSET_FLAG(restart_flag_time, 0xF000);
peer->v_gr_restart = restart_flag_time;

if (bgp_debug_neighbor_events(peer)) {
zlog_debug(
"%s Peer has%srestarted. Restart Time: %d, N-bit set: %s",
peer->host,
CHECK_FLAG(peer->cap,
PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)
? " "
: " not ",
peer->v_gr_restart,
CHECK_FLAG(peer->cap,
PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV)
? "yes"
: "no");
}
if (bgp_debug_neighbor_events(peer))
zlog_debug("%pBP OPEN has GR capability, Restart time %d R-bit %s N-bit %s",
peer, peer->v_gr_restart,
CHECK_FLAG(peer->cap,
PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)
? "SET"
: "NOT-SET",
CHECK_FLAG(peer->cap,
PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV)
? "SET"
: "NOT-SET");

while (stream_get_getp(s) + 4 <= end) {
afi_t afi;
Expand All @@ -556,14 +553,12 @@ static int bgp_capability_restart(struct peer *peer,
iana_safi2str(pkt_safi));
} else {
if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%s Address family %s is%spreserved",
peer->host, get_afi_safi_str(afi, safi, false),
CHECK_FLAG(
peer->af_cap[afi][safi],
PEER_CAP_RESTART_AF_PRESERVE_RCV)
? " "
: " not ");
zlog_debug("%pBP F-bit %s for %s", peer,
CHECK_FLAG(peer->af_cap[afi][safi],
PEER_CAP_RESTART_AF_PRESERVE_RCV)
? "SET"
: "NOT-SET",
get_afi_safi_str(afi, safi, false));

SET_FLAG(peer->af_cap[afi][safi],
PEER_CAP_RESTART_AF_RCV);
Expand Down Expand Up @@ -1587,15 +1582,12 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
uint32_t restart_time;
unsigned long capp = 0;
unsigned long rcapp = 0;
struct bgp *bgp = peer->bgp;

if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
&& !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))
return;

if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :",
peer->host);

SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
stream_putc(s, BGP_OPEN_OPT_CAP);
capp = stream_get_endp(s); /* Set Capability Len Pointer */
Expand All @@ -1605,54 +1597,57 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
/* Set Restart Capability Len Pointer */
rcapp = stream_get_endp(s);
stream_putc(s, 0);
restart_time = peer->bgp->restart_time;
if (peer->bgp->t_startup) {
restart_time = bgp->restart_time;
if (peer->bgp->t_startup || bgp_in_graceful_restart()) {
SET_FLAG(restart_time, GRACEFUL_RESTART_R_BIT);
SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV);
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("[BGP_GR] Sending R-Bit for peer: %s",
peer->host);
}

if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION)) {
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION)) {
SET_FLAG(restart_time, GRACEFUL_RESTART_N_BIT);
SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV);
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("[BGP_GR] Sending N-Bit for peer: %s",
peer->host);
}

stream_putw(s, restart_time);

if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("%s: Sending GR Capability, Restart time %d R-bit %s, N-bit %s",
peer->host, bgp->restart_time,
CHECK_FLAG(peer->cap,
PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV)
? "SET"
: "NOT-SET",
CHECK_FLAG(peer->cap,
PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV)
? "SET"
: "NOT-SET");

/* Send address-family specific graceful-restart capability
* only when GR config is present
*/
if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)
&& BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("[BGP_GR] F bit Set");

FOREACH_AFI_SAFI (afi, safi) {
bool f_bit = false;

if (!peer->afc[afi][safi])
continue;

if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug(
"[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:",
afi, safi);

/* Convert AFI, SAFI to values for
* packet.
*/
bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
&pkt_safi);
stream_putw(s, pkt_afi);
stream_putc(s, pkt_safi);
if (CHECK_FLAG(peer->bgp->flags,
BGP_FLAG_GR_PRESERVE_FWD))
stream_putc(s, GRACEFUL_RESTART_F_BIT);
else
stream_putc(s, 0);

f_bit = bgp_gr_is_forwarding_preserved(bgp);

if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("... F-bit %s for %s",
f_bit ? "SET" : "NOT-SET",
get_afi_safi_str(afi, safi, false));

stream_putc(s, f_bit ? GRACEFUL_RESTART_F_BIT : 0);
}
}

Expand Down
9 changes: 4 additions & 5 deletions bgpd/bgp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,10 +696,9 @@ void bgp_open_send(struct peer_connection *connection)
bgp_packet_set_size(s);

if (bgp_debug_neighbor_events(peer))
zlog_debug(
"%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4",
peer->host, BGP_VERSION_4, local_as, send_holdtime,
&peer->local_id);
zlog_debug("%pBP fd %d sending OPEN, version %d, my as %u, holdtime %d, id %pI4",
peer, peer->connection->fd, BGP_VERSION_4, local_as,
send_holdtime, &peer->local_id);

/* Dump packet if debug option is set. */
/* bgp_packet_dump (s); */
Expand Down Expand Up @@ -1296,7 +1295,7 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
stream_putc(s, 0);
gr_restart_time = peer->bgp->restart_time;

if (peer->bgp->t_startup) {
if (peer->bgp->t_startup || bgp_in_graceful_restart()) {
SET_FLAG(gr_restart_time, GRACEFUL_RESTART_R_BIT);
SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV);
}
Expand Down
18 changes: 17 additions & 1 deletion bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -3877,6 +3877,7 @@ void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
struct bgp_dest *dest;
int cnt = 0;
struct afi_safi_info *thread_info;
bool route_sync_pending = false;

if (bgp->gr_info[afi][safi].t_route_select) {
struct event *t = bgp->gr_info[afi][safi].t_route_select;
Expand All @@ -3886,7 +3887,7 @@ void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
}

if (BGP_DEBUG(update, UPDATE_OUT)) {
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) {
zlog_debug("%s: processing route for %s : cnt %d", __func__,
get_afi_safi_str(afi, safi, false),
bgp->gr_info[afi][safi].gr_deferred);
Expand Down Expand Up @@ -3919,6 +3920,21 @@ void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
/* Send route processing complete message to RIB */
bgp_zebra_update(bgp, afi, safi,
ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
bgp->gr_info[afi][safi].route_sync = true;

/* If this instance is all done, check for GR completion overall */
FOREACH_AFI_SAFI_NSF (afi, safi) {
if (bgp->gr_info[afi][safi].af_enabled &&
!bgp->gr_info[afi][safi].route_sync) {
route_sync_pending = true;
break;
}
}

if (!route_sync_pending) {
bgp->gr_route_sync_pending = false;
bgp_update_gr_completion();
}
return;
}

Expand Down
Loading

0 comments on commit 9ab4186

Please sign in to comment.