diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2024-03-09 22:17:27 +0200 | 
|---|---|---|
| committer | Donatas Abraitis <donatas@opensourcerouting.org> | 2024-03-09 22:23:37 +0200 | 
| commit | 77102e853ec1856f8dccaa61a74ce2f78452d5a5 (patch) | |
| tree | f409b1d4ef6fc11bd647c887d60ce432638842e2 /bgpd/bgp_packet.c | |
| parent | aa6ceeeb5b1f92280ee79716e68d31c9a8686230 (diff) | |
bgpd: Unset advertised capabilities if capability is disabled
When using dynamic capabilities, do not forget to unset advertised capabilities.
Otherwise, it's kept as advertised.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_packet.c')
| -rw-r--r-- | bgpd/bgp_packet.c | 92 | 
1 files changed, 47 insertions, 45 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 55d3efde23..47aa19c249 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1240,7 +1240,6 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  	/* Encode MP_EXT capability. */  	switch (capability_code) {  	case CAPABILITY_CODE_SOFT_VERSION: -		SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_ADV);  		stream_putc(s, action);  		stream_putc(s, CAPABILITY_CODE_SOFT_VERSION);  		cap_len = stream_get_endp(s); @@ -1271,6 +1270,9 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  					   : "Removing",  				   capability, iana_afi2str(pkt_afi),  				   iana_safi2str(pkt_safi)); + +		COND_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_ADV, +			  action == CAPABILITY_ACTION_SET);  		break;  	case CAPABILITY_CODE_MP:  		stream_putc(s, action); @@ -1294,7 +1296,6 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  		    !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))  			return; -		SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);  		stream_putc(s, action);  		stream_putc(s, CAPABILITY_CODE_RESTART);  		cap_len = stream_get_endp(s); @@ -1343,13 +1344,13 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  				   capability, iana_afi2str(pkt_afi),  				   iana_safi2str(pkt_safi)); +		COND_FLAG(peer->cap, PEER_CAP_RESTART_ADV, +			  action == CAPABILITY_ACTION_SET);  		break;  	case CAPABILITY_CODE_LLGR:  		if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV))  			return; -		SET_FLAG(peer->cap, PEER_CAP_LLGR_ADV); -  		stream_putc(s, action);  		stream_putc(s, CAPABILITY_CODE_LLGR);  		cap_len = stream_get_endp(s); @@ -1381,10 +1382,11 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  					   : "Removing",  				   capability, iana_afi2str(pkt_afi),  				   iana_safi2str(pkt_safi)); + +		COND_FLAG(peer->cap, PEER_CAP_LLGR_ADV, +			  action == CAPABILITY_ACTION_SET);  		break;  	case CAPABILITY_CODE_ADDPATH: -		SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV); -  		FOREACH_AFI_SAFI (afi, safi) {  			if (peer->afc[afi][safi]) {  				addpath_afi_safi_count++; @@ -1462,10 +1464,10 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  				   capability, iana_afi2str(pkt_afi),  				   iana_safi2str(pkt_safi)); +		COND_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV, +			  action == CAPABILITY_ACTION_SET);  		break;  	case CAPABILITY_CODE_PATHS_LIMIT: -		SET_FLAG(peer->cap, PEER_CAP_PATHS_LIMIT_ADV); -  		FOREACH_AFI_SAFI (afi, safi) {  			if (!peer->afc[afi][safi])  				continue; @@ -1505,6 +1507,8 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  						   .send);  		} +		COND_FLAG(peer->cap, PEER_CAP_PATHS_LIMIT_ADV, +			  action == CAPABILITY_ACTION_SET);  		break;  	case CAPABILITY_CODE_ORF:  		/* Convert AFI, SAFI to values for packet. */ @@ -1578,43 +1582,42 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  				   iana_safi2str(pkt_safi));  		break;  	case CAPABILITY_CODE_FQDN: -		if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_FQDN) && -		    hostname) { -			SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV); -			stream_putc(s, action); -			stream_putc(s, CAPABILITY_CODE_FQDN); -			cap_len = stream_get_endp(s); -			stream_putc(s, 0); /* Capability Length */ - -			len = strlen(hostname); +		stream_putc(s, action); +		stream_putc(s, CAPABILITY_CODE_FQDN); +		cap_len = stream_get_endp(s); +		stream_putc(s, 0); /* Capability Length */ + +		len = strlen(hostname); +		if (len > BGP_MAX_HOSTNAME) +			len = BGP_MAX_HOSTNAME; + +		stream_putc(s, len); +		stream_put(s, hostname, len); + +		if (domainname) { +			len = strlen(domainname);  			if (len > BGP_MAX_HOSTNAME)  				len = BGP_MAX_HOSTNAME;  			stream_putc(s, len); -			stream_put(s, hostname, len); - -			if (domainname) { -				len = strlen(domainname); -				if (len > BGP_MAX_HOSTNAME) -					len = BGP_MAX_HOSTNAME; +			stream_put(s, domainname, len); +		} else +			stream_putc(s, 0); -				stream_putc(s, len); -				stream_put(s, domainname, len); -			} else -				stream_putc(s, 0); +		len = stream_get_endp(s) - cap_len - 1; +		stream_putc_at(s, cap_len, len); -			len = stream_get_endp(s) - cap_len - 1; -			stream_putc_at(s, cap_len, len); +		if (bgp_debug_neighbor_events(peer)) +			zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s", +				   peer, +				   action == CAPABILITY_ACTION_SET +					   ? "Advertising" +					   : "Removing", +				   capability, iana_afi2str(pkt_afi), +				   iana_safi2str(pkt_safi)); -			if (bgp_debug_neighbor_events(peer)) -				zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s", -					   peer, -					   action == CAPABILITY_ACTION_SET -						   ? "Advertising" -						   : "Removing", -					   capability, iana_afi2str(pkt_afi), -					   iana_safi2str(pkt_safi)); -		} +		COND_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV, +			  action == CAPABILITY_ACTION_SET);  		break;  	case CAPABILITY_CODE_REFRESH:  	case CAPABILITY_CODE_AS4: @@ -1624,13 +1627,12 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  	case CAPABILITY_CODE_EXT_MESSAGE:  		break;  	case CAPABILITY_CODE_ROLE: -		if (peer->local_role != ROLE_UNDEFINED) { -			SET_FLAG(peer->cap, PEER_CAP_ROLE_ADV); -			stream_putc(s, action); -			stream_putc(s, CAPABILITY_CODE_ROLE); -			stream_putc(s, CAPABILITY_CODE_ROLE_LEN); -			stream_putc(s, peer->local_role); -		} +		stream_putc(s, action); +		stream_putc(s, CAPABILITY_CODE_ROLE); +		stream_putc(s, CAPABILITY_CODE_ROLE_LEN); +		stream_putc(s, peer->local_role); +		COND_FLAG(peer->cap, PEER_CAP_ROLE_ADV, +			  action == CAPABILITY_ACTION_SET);  		break;  	default:  		break;  | 
