summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_aspath.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 02:57:34 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 02:57:34 +0200
commit5000f21c25dd13d12c3a00b5e702d6f79685a77e (patch)
treee1bb0e2f2630fddb88e589db8cbacdeed61d657c /bgpd/bgp_aspath.c
parentSend CEASE NOTIFICATIONS to all peers on "no router bgp" (diff)
downloadfrr-5000f21c25dd13d12c3a00b5e702d6f79685a77e.tar.xz
frr-5000f21c25dd13d12c3a00b5e702d6f79685a77e.zip
Add replace-as option to remove-private-as
Diffstat (limited to 'bgpd/bgp_aspath.c')
-rw-r--r--bgpd/bgp_aspath.c116
1 files changed, 105 insertions, 11 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 8fe528028..b8bd71b99 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -463,13 +463,11 @@ aspath_highest (struct aspath *aspath)
struct assegment *seg = aspath->segments;
as_t highest = 0;
unsigned int i;
-
+
while (seg)
{
for (i = 0; i < seg->length; i++)
- if (seg->as[i] > highest
- && (seg->as[i] < BGP_PRIVATE_AS_MIN
- || seg->as[i] > BGP_PRIVATE_AS_MAX))
+ if (seg->as[i] > highest && !BGP_AS_IS_PRIVATE(seg->as[i]))
highest = seg->as[i];
seg = seg->next;
}
@@ -1128,22 +1126,19 @@ int
aspath_private_as_check (struct aspath *aspath)
{
struct assegment *seg;
-
+
if ( !(aspath && aspath->segments) )
return 0;
-
+
seg = aspath->segments;
while (seg)
{
int i;
-
+
for (i = 0; i < seg->length; i++)
{
- if ( (seg->as[i] < BGP_PRIVATE_AS_MIN)
- || (seg->as[i] > BGP_PRIVATE_AS_MAX &&
- seg->as[i] < BGP_PRIVATE_AS4_MIN)
- || (seg->as[i] > BGP_PRIVATE_AS4_MAX))
+ if (!BGP_AS_IS_PRIVATE(seg->as[i]))
return 0;
}
seg = seg->next;
@@ -1151,6 +1146,105 @@ aspath_private_as_check (struct aspath *aspath)
return 1;
}
+/* Replace all private ASNs with our own ASN */
+struct aspath *
+aspath_replace_private_asns (struct aspath *aspath, as_t asn)
+{
+ struct aspath *new;
+ struct assegment *seg;
+
+ new = aspath_dup(aspath);
+ seg = new->segments;
+
+ while (seg)
+ {
+ int i;
+
+ for (i = 0; i < seg->length; i++)
+ {
+ if (BGP_AS_IS_PRIVATE(seg->as[i]))
+ seg->as[i] = asn;
+ }
+ seg = seg->next;
+ }
+
+ aspath_str_update(new);
+ return new;
+}
+
+/* Remove all private ASNs */
+struct aspath *
+aspath_remove_private_asns (struct aspath *aspath)
+{
+ struct aspath *new;
+ struct assegment *seg;
+ struct assegment *new_seg;
+ struct assegment *last_new_seg;
+ int i;
+ int j;
+ int public = 0;
+
+ new = XCALLOC (MTYPE_AS_PATH, sizeof (struct aspath));
+
+ new_seg = NULL;
+ last_new_seg = NULL;
+ seg = aspath->segments;
+ while (seg)
+ {
+ public = 0;
+ for (i = 0; i < seg->length; i++)
+ {
+ // ASN is public
+ if (!BGP_AS_IS_PRIVATE(seg->as[i]))
+ {
+ public++;
+ }
+ }
+
+ // 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)
+ {
+ new_seg = assegment_dup (seg);
+ }
+
+ // The segment is a mix of public and private ASNs. Copy as many spots as
+ // there are public ASNs then come back and fill in only the public ASNs.
+ else
+ {
+ 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]))
+ {
+ new_seg->as[j] = seg->as[i];
+ j++;
+ }
+ }
+ }
+
+ // This is the first segment so set the aspath segments pointer to this one
+ if (!last_new_seg)
+ new->segments = new_seg;
+ else
+ last_new_seg->next = new_seg;
+
+ last_new_seg = new_seg;
+ seg = seg->next;
+ }
+
+ aspath_str_update(new);
+ return new;
+}
+
/* AS path confed check. If aspath contains confed set or sequence then return 1. */
int
aspath_confed_check (struct aspath *aspath)