summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_aspath.c
diff options
context:
space:
mode:
authorDon Slice <dslice@cumulusnetworks.com>2019-07-25 17:35:06 +0200
committerDon Slice <dslice@cumulusnetworks.com>2019-07-29 21:27:03 +0200
commitbf26b80eba15278f45ec6060dd209fc6c22f3369 (patch)
tree3d107a6a8c822c959aa46b5445a35c3f51c1acf3 /bgpd/bgp_aspath.c
parentMerge pull request #4728 from ton31337/fix/next-hop-self_force_alias_for_ipv6 (diff)
downloadfrr-bf26b80eba15278f45ec6060dd209fc6c22f3369.tar.xz
frr-bf26b80eba15278f45ec6060dd209fc6c22f3369.zip
bgpd: stop removing and replacing private asn if it matches the peer
Problems reported that if multiple peers have "remove-private-AS replace-AS" with each other and all are using private asns, the as-path gets hosed and continues to grow when a prefix is removed. This fix disallows removing and replacing the private asn if it matches the peer's ASN so that normal as-path loop prevention will operate correctly. Ticket: CM-25489 Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Diffstat (limited to 'bgpd/bgp_aspath.c')
-rw-r--r--bgpd/bgp_aspath.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 05577cb8b..cf0d28887 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -1232,7 +1232,8 @@ struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
}
/* Replace all private ASNs with our own ASN */
-struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn)
+struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn,
+ as_t peer_asn)
{
struct aspath *new;
struct assegment *seg;
@@ -1244,7 +1245,9 @@ struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn)
int i;
for (i = 0; i < seg->length; i++) {
- if (BGP_AS_IS_PRIVATE(seg->as[i]))
+ /* Don't replace if public ASN or peer's ASN */
+ if (BGP_AS_IS_PRIVATE(seg->as[i])
+ && (seg->as[i] != peer_asn))
seg->as[i] = asn;
}
seg = seg->next;
@@ -1255,7 +1258,7 @@ struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn)
}
/* Remove all private ASNs */
-struct aspath *aspath_remove_private_asns(struct aspath *aspath)
+struct aspath *aspath_remove_private_asns(struct aspath *aspath, as_t peer_asn)
{
struct aspath *new;
struct assegment *seg;
@@ -1282,16 +1285,9 @@ struct aspath *aspath_remove_private_asns(struct aspath *aspath)
}
}
- // The entire segment is private so skip it
- if (!public) {
- seg = seg->next;
- continue;
- }
-
// The entire segment is public so copy it
- else if (public == seg->length) {
+ if (public == seg->length)
new_seg = assegment_dup(seg);
- }
// The segment is a mix of public and private ASNs. Copy as many
// spots as
@@ -1301,8 +1297,9 @@ struct aspath *aspath_remove_private_asns(struct aspath *aspath)
new_seg = assegment_new(seg->type, public);
j = 0;
for (i = 0; i < seg->length; i++) {
- // ASN is public
- if (!BGP_AS_IS_PRIVATE(seg->as[i])) {
+ // keep ASN if public or matches peer's ASN
+ if (!BGP_AS_IS_PRIVATE(seg->as[i])
+ || (seg->as[i] == peer_asn)) {
new_seg->as[j] = seg->as[i];
j++;
}