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

bgpd: Fix Graceful-Restart for peer-groups #17501

Merged
merged 3 commits into from
Nov 26, 2024
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
96 changes: 66 additions & 30 deletions bgpd/bgp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2726,33 +2726,55 @@ static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp,
struct listnode *node = {0};
struct listnode *nnode = {0};
enum peer_mode peer_old_state = PEER_INVALID;

/* TODO: Need to handle peer-groups. */
struct peer_group *group;
struct peer *member;

for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
peer_old_state = bgp_peer_gr_mode_get(peer);
if (peer_old_state != PEER_GLOBAL_INHERIT)
continue;
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer_old_state = bgp_peer_gr_mode_get(peer);
if (peer_old_state != PEER_GLOBAL_INHERIT)
continue;

bgp_peer_inherit_global_gr_mode(peer, global_new_state);
bgp_peer_gr_flags_update(peer);
bgp_peer_inherit_global_gr_mode(peer, global_new_state);
bgp_peer_gr_flags_update(peer);

if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("%pBP: Inherited Global GR mode, GR flags 0x%x peer flags 0x%" PRIx64
"...resetting session",
peer, peer->peer_gr_new_status_flag,
peer->flags);
if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("%pBP: Inherited Global GR mode, GR flags 0x%x peer flags 0x%" PRIx64
"...resetting session",
peer, peer->peer_gr_new_status_flag, peer->flags);

peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;

/* Reset session to match with behavior for other peer
* configs that require the session to be re-setup.
*/
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
bgp_session_reset_safe(peer, &nnode);
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
bgp_session_reset_safe(peer, &nnode);
} else {
group = peer->group;
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, member)) {
peer_old_state = bgp_peer_gr_mode_get(member);
if (peer_old_state != PEER_GLOBAL_INHERIT)
continue;

bgp_peer_inherit_global_gr_mode(member, global_new_state);
bgp_peer_gr_flags_update(member);

if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
zlog_debug("%pBP: Inherited Global GR mode, GR flags 0x%x peer flags 0x%" PRIx64
"...resetting session",
member, member->peer_gr_new_status_flag,
member->flags);

member->last_reset = PEER_DOWN_CAPABILITY_CHANGE;

if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
bgp_session_reset(member);
}
}
}
}

Expand Down Expand Up @@ -2911,6 +2933,9 @@ unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state,
{
enum global_mode global_gr_mode;
bool session_reset = true;
struct peer_group *group;
struct peer *member;
struct listnode *node, *nnode;

if (old_state == new_state)
return BGP_GR_NO_OPERATION;
Expand Down Expand Up @@ -2945,16 +2970,27 @@ unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state,
bgp_peer_move_to_gr_mode(peer, new_state);

if (session_reset) {
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;

/* Reset session to match with behavior for other peer
* configs that require the session to be re-setup.
*/
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
bgp_session_reset(peer);
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
bgp_session_reset(peer);
} else {
group = peer->group;
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, member)) {
member->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
bgp_peer_move_to_gr_mode(member, new_state);

if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
bgp_session_reset(member);
}
}
}

return BGP_GR_SUCCESS;
Expand Down
49 changes: 14 additions & 35 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -3519,11 +3519,6 @@ DEFUN (bgp_neighbor_graceful_restart_set,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
vty_out(vty,
"Per peer-group graceful-restart configuration is not yet supported\n");
return CMD_WARNING_CONFIG_FAILED;
}

result = bgp_neighbor_graceful_restart(peer, PEER_GR_CMD);
if (result == BGP_GR_SUCCESS) {
Expand Down Expand Up @@ -3554,11 +3549,6 @@ DEFUN (no_bgp_neighbor_graceful_restart,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
vty_out(vty,
"Per peer-group graceful-restart configuration is not yet supported\n");
return CMD_WARNING_CONFIG_FAILED;
}

result = bgp_neighbor_graceful_restart(peer, NO_PEER_GR_CMD);
if (ret == BGP_GR_SUCCESS) {
Expand Down Expand Up @@ -3588,11 +3578,6 @@ DEFUN (bgp_neighbor_graceful_restart_helper_set,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
vty_out(vty,
"Per peer-group graceful-restart configuration is not yet supported\n");
return CMD_WARNING_CONFIG_FAILED;
}

ret = bgp_neighbor_graceful_restart(peer, PEER_HELPER_CMD);
if (ret == BGP_GR_SUCCESS) {
Expand Down Expand Up @@ -3623,11 +3608,6 @@ DEFUN (no_bgp_neighbor_graceful_restart_helper,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
vty_out(vty,
"Per peer-group graceful-restart configuration is not yet supported\n");
return CMD_WARNING_CONFIG_FAILED;
}

ret = bgp_neighbor_graceful_restart(peer, NO_PEER_HELPER_CMD);
if (ret == BGP_GR_SUCCESS) {
Expand Down Expand Up @@ -3657,11 +3637,6 @@ DEFUN (bgp_neighbor_graceful_restart_disable_set,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
vty_out(vty,
"Per peer-group graceful-restart configuration is not yet supported\n");
return CMD_WARNING_CONFIG_FAILED;
}

ret = bgp_neighbor_graceful_restart(peer, PEER_DISABLE_CMD);
if (ret == BGP_GR_SUCCESS) {
Expand Down Expand Up @@ -3693,11 +3668,6 @@ DEFUN (no_bgp_neighbor_graceful_restart_disable,
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
vty_out(vty,
"Per peer-group graceful-restart configuration is not yet supported\n");
return CMD_WARNING_CONFIG_FAILED;
}

ret = bgp_neighbor_graceful_restart(peer, NO_PEER_DISABLE_CMD);
if (ret == BGP_GR_SUCCESS) {
Expand Down Expand Up @@ -14927,22 +14897,31 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV) ||
CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV)) {
if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV) &&
CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV))
CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
json_object_string_add(
json_cap, "gracefulRestart",
"advertisedAndReceived");
else if (CHECK_FLAG(p->cap,
PEER_CAP_RESTART_ADV))
} else if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV)) {
json_object_string_add(json_cap, "gracefulRestart",
"advertised");
#if CONFDATE > 20250525
CPP_NOTICE("Remove `gracefulRestartCapability` JSON field")
#endif
json_object_string_add(
json_cap,
"gracefulRestartCapability",
"advertised");
else if (CHECK_FLAG(p->cap,
PEER_CAP_RESTART_RCV))
} else if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
json_object_string_add(json_cap, "gracefulRestart",
"received");
#if CONFDATE > 20250525
CPP_NOTICE("Remove `gracefulRestartCapability` JSON field")
#endif
json_object_string_add(
json_cap,
"gracefulRestartCapability",
"received");
}

if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
int restart_af_count = 0;
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3022,6 +3022,7 @@ static void peer_group2peer_config_copy(struct peer_group *group,
PEER_ATTR_INHERIT(peer, group, local_role);

/* Update GR flags for the peer. */
PEER_ATTR_INHERIT(peer, group, peer_gr_new_status_flag);
bgp_peer_gr_flags_update(peer);

/* Apply BFD settings from group to peer if it exists. */
Expand Down
12 changes: 0 additions & 12 deletions tests/topotests/bgp_peer_group/r1/bgpd.conf

This file was deleted.

21 changes: 21 additions & 0 deletions tests/topotests/bgp_peer_group/r1/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
!
interface r1-eth0
ip address 192.168.255.1/24
!
interface r1-eth1
ip address 192.168.251.1/30
!
ip forwarding
!
router bgp 65001
neighbor PG peer-group
neighbor PG remote-as external
neighbor PG timers 3 10
neighbor 192.168.255.3 peer-group PG
neighbor r1-eth0 interface peer-group PG
neighbor PG1 peer-group
neighbor PG1 remote-as external
neighbor PG1 timers 3 20
neighbor PG1 graceful-restart-disable
neighbor 192.168.251.2 peer-group PG1
!
9 changes: 0 additions & 9 deletions tests/topotests/bgp_peer_group/r1/zebra.conf

This file was deleted.

11 changes: 0 additions & 11 deletions tests/topotests/bgp_peer_group/r2/bgpd.conf

This file was deleted.

19 changes: 19 additions & 0 deletions tests/topotests/bgp_peer_group/r2/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
!
interface r2-eth0
ip address 192.168.255.2/24
!
interface r2-eth1
ip address 192.168.251.2/30
!
ip forwarding
!
router bgp 65002
neighbor PG peer-group
neighbor PG remote-as external
neighbor PG timers 3 10
neighbor r2-eth0 interface peer-group PG
neighbor PG1 peer-group
neighbor PG1 remote-as external
neighbor PG1 timers 3 20
neighbor 192.168.251.1 peer-group PG1
!
9 changes: 0 additions & 9 deletions tests/topotests/bgp_peer_group/r2/zebra.conf

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
!
interface r3-eth0
ip address 192.168.255.3/24
!
ip forwarding
!
router bgp 65003
no bgp ebgp-requires-policy
neighbor PG peer-group
Expand Down
6 changes: 0 additions & 6 deletions tests/topotests/bgp_peer_group/r3/zebra.conf

This file was deleted.

Loading
Loading