mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 23:53:28 +00:00
bgpd: Pass global ASN for confederation peers if not AS_SPECIFIED
When we specify remote-as as external/internal, we need to set local_as to bgp->as, instead of bgp->confed_id. Before this patch, (bgp->as != *as) is always valid for such a case because *as is always 0. Also, append peer->local_as as CONFED_SEQ to avoid other side withdrawing the routes due to confederation own AS received and/or malformed as-path. Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This commit is contained in:
parent
12906cb1c8
commit
db5a5ee6e4
@ -1645,6 +1645,14 @@ static enum bgp_attr_parse_ret bgp_attr_aspath_check(struct peer *const peer,
|
|||||||
*/
|
*/
|
||||||
struct aspath *aspath;
|
struct aspath *aspath;
|
||||||
|
|
||||||
|
/* Refresh peer's type. If we set e.g.: AS_EXTERNAL/AS_INTERNAL,
|
||||||
|
* then peer->sort remains BGP_PEER_EBGP/IBGP, hence we need to
|
||||||
|
* have an actual type before checking.
|
||||||
|
* This is especially a case for BGP confederation peers, to avoid
|
||||||
|
* receiving and treating AS_PATH as malformed.
|
||||||
|
*/
|
||||||
|
(void)peer_sort(peer);
|
||||||
|
|
||||||
/* Confederation sanity check. */
|
/* Confederation sanity check. */
|
||||||
if ((peer->sort == BGP_PEER_CONFED
|
if ((peer->sort == BGP_PEER_CONFED
|
||||||
&& !aspath_left_confed_check(attr->aspath))
|
&& !aspath_left_confed_check(attr->aspath))
|
||||||
@ -4295,8 +4303,22 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
|||||||
aspath = aspath_delete_confed_seq(aspath);
|
aspath = aspath_delete_confed_seq(aspath);
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
|
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
|
||||||
|
/* A confed member, so we need to do the
|
||||||
|
* AS_CONFED_SEQUENCE thing if it's outside a common
|
||||||
|
* administration.
|
||||||
|
* Configured confederation peers MUST be validated
|
||||||
|
* under BGP_PEER_CONFED, but if we have configured
|
||||||
|
* remote-as as AS_EXTERNAL, we need to check again
|
||||||
|
* if the peer belongs to us.
|
||||||
|
*/
|
||||||
|
if (bgp_confederation_peers_check(bgp, peer->as)) {
|
||||||
|
aspath = aspath_dup(attr->aspath);
|
||||||
|
aspath = aspath_add_confed_seq(aspath,
|
||||||
|
peer->local_as);
|
||||||
|
} else {
|
||||||
/* Stuff our path CONFED_ID on the front */
|
/* Stuff our path CONFED_ID on the front */
|
||||||
aspath = aspath_add_seq(aspath, bgp->confed_id);
|
aspath = aspath_add_seq(aspath, bgp->confed_id);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (peer->change_local_as) {
|
if (peer->change_local_as) {
|
||||||
/* If replace-as is specified, we only use the
|
/* If replace-as is specified, we only use the
|
||||||
|
@ -2041,9 +2041,9 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
|
|||||||
|
|
||||||
/* If the peer is not part of our confederation, and its not an
|
/* If the peer is not part of our confederation, and its not an
|
||||||
iBGP peer then spoof the source AS */
|
iBGP peer then spoof the source AS */
|
||||||
if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)
|
if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION) &&
|
||||||
&& !bgp_confederation_peers_check(bgp, *as)
|
!bgp_confederation_peers_check(bgp, *as) && *as &&
|
||||||
&& bgp->as != *as)
|
bgp->as != *as)
|
||||||
local_as = bgp->confed_id;
|
local_as = bgp->confed_id;
|
||||||
else
|
else
|
||||||
local_as = bgp->as;
|
local_as = bgp->as;
|
||||||
|
Loading…
Reference in New Issue
Block a user