diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2024-11-24 21:57:19 +0200 | 
|---|---|---|
| committer | Donatas Abraitis <donatas@opensourcerouting.org> | 2024-11-24 21:57:19 +0200 | 
| commit | 0a85b1ba04f6463e300aa6d5e064a5e5d79bec53 (patch) | |
| tree | d8c3ee3da2273dc32420d603d5d96b61ce5fa8ac /bgpd/bgp_fsm.c | |
| parent | 28b45fd5535fda325ac1a965280845da0e4fbad9 (diff) | |
bgpd: Fix graceful-restart for peer-groups
Slipped somehow that peer-groups with GR is just completely broken, but it was
working before.
Strikes again, that we MUST have more and more topotests.
Fixes: 15403f521a12b668e87ef8961c78e0ed97c6ff92 ("bgpd: Streamline GR config, act on change immediately")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_fsm.c')
| -rw-r--r-- | bgpd/bgp_fsm.c | 96 | 
1 files changed, 66 insertions, 30 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 4ac8201f74..490451f193 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -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); +			} +		}  	}  } @@ -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; @@ -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;  | 
