summaryrefslogtreecommitdiff
path: root/bgpd/bgp_aspath.c
diff options
context:
space:
mode:
authorFrancois Dumontet <francois.dumontet@6wind.com>2023-07-11 10:03:04 +0200
committerFrancois Dumontet <francois.dumontet@6wind.com>2023-08-07 12:30:34 +0200
commit958340e935350f840e31a0405b492e6ac7dfe13b (patch)
tree7b37d33110cacc7043d811916074d1e13953c5ff /bgpd/bgp_aspath.c
parent529203905b6bbb1c78cf806d1f808eed41a182d7 (diff)
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able to replace an unwanted as segments by another one. unwanted as segment are based on an AS path access-list. The below configuration illustrates the case: router bgp 65001 address-family ipv4 unicast neighbor 192.168.1.2 route-map rule_2 in exit-address-family bgp as-path access-list RULE permit ^65 route-map rule_2 permit 10 set as-path replace as-path-access-list RULE 6000 ``` BGP routing table entry for 10.10.10.10/32, version 13 Paths: (1 available, best #1, table default) Advertised to non peer-group peers: 192.168.10.65 65000 1 2 3 123 192.168.10.65 from 192.168.10.65 (10.10.10.11) Origin IGP, metric 0, valid, external, best (First path received) ``` After: ``` do show ip bgp 10.10.10.10/32 BGP routing table entry for 10.10.10.10/32, version 15 Paths: (1 available, best #1, table default) Advertised to non peer-group peers: 192.168.10.65 6000 1 2 3 123 192.168.10.65 from 192.168.10.65 (10.10.10.11) Origin IGP, metric 0, valid, external, best (First path received) ``` Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
Diffstat (limited to 'bgpd/bgp_aspath.c')
-rw-r--r--bgpd/bgp_aspath.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 4ea81216bf..2e2248cd72 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -1231,6 +1231,46 @@ bool aspath_private_as_check(struct aspath *aspath)
return true;
}
+/* Replace all ASN instances of the regex rule with our own ASN */
+struct aspath *aspath_replace_regex_asn(struct aspath *aspath,
+ struct as_list *acl_list, as_t our_asn)
+{
+ struct aspath *new;
+ struct assegment *cur_seg;
+ struct as_list *cur_as_list;
+ struct as_filter *cur_as_filter;
+ char str_buf[ASPATH_STR_DEFAULT_LEN];
+ uint32_t i;
+
+ new = aspath_dup(aspath);
+ cur_seg = new->segments;
+
+ while (cur_seg) {
+ cur_as_list = acl_list;
+ while (cur_as_list) {
+ cur_as_filter = cur_as_list->head;
+ while (cur_as_filter) {
+ for (i = 0; i < cur_seg->length; i++) {
+ snprintfrr(str_buf,
+ ASPATH_STR_DEFAULT_LEN,
+ ASN_FORMAT(new->asnotation),
+ &cur_seg->as[i]);
+ if (!regexec(cur_as_filter->reg,
+ str_buf, 0, NULL, 0))
+ cur_seg->as[i] = our_asn;
+ }
+ cur_as_filter = cur_as_filter->next;
+ }
+ cur_as_list = cur_as_list->next;
+ }
+ cur_seg = cur_seg->next;
+ }
+
+ aspath_str_update(new, false);
+ return new;
+}
+
+
/* Replace all instances of the target ASN with our own ASN */
struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
as_t target_asn, as_t our_asn)