summaryrefslogtreecommitdiff
path: root/bgpd/bgp_routemap.c
diff options
context:
space:
mode:
authorFrancois Dumontet <francois.dumontet@6wind.com>2024-04-23 11:16:24 +0200
committerMergify <37929162+mergify[bot]@users.noreply.github.com>2024-06-24 21:09:28 +0000
commitba67e107a577f0e432467b5a36fb8453aa589ef6 (patch)
treec39a44ad952c0c9ed9c59fb86951d640155f0ebe /bgpd/bgp_routemap.c
parent75757a246d53a8eec39e9cc75f618f3e98d5f836 (diff)
bgpd: fix "bgp as-pah access-list" with "set aspath exclude" set/unset issues
whith the following config router bgp 65001 no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as external neighbor 192.168.1.2 timers 3 10 ! address-family ipv4 unicast neighbor 192.168.1.2 route-map r2 in exit-address-family exit ! bgp as-path access-list FIRST seq 5 permit ^65 bgp as-path access-list SECOND seq 5 permit 2$ ! route-map r2 permit 6 match ip address prefix-list p2 set as-path exclude as-path-access-list SECOND exit ! route-map r2 permit 10 match ip address prefix-list p1 set as-path exclude 65003 exit ! route-map r2 permit 20 match ip address prefix-list p3 set as-path exclude all exit making some no bgp as-path access-list SECOND permit 2$ bgp as-path access-list SECOND permit 3$ clear bgp * no bgp as-path access-list SECOND permit 3$ bgp as-path access-list SECOND permit 2$ clear bgp * will induce some crashes thus we rework the links between aslists and aspath_exclude Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com> (cherry picked from commit 094dcc3cdac19d3da65b38effc45aa88d960909f)
Diffstat (limited to 'bgpd/bgp_routemap.c')
-rw-r--r--bgpd/bgp_routemap.c59
1 files changed, 23 insertions, 36 deletions
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index dbc3d6445d..e059357f09 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -2326,7 +2326,7 @@ static const struct route_map_rule_cmd route_set_aspath_prepend_cmd = {
static void *route_aspath_exclude_compile(const char *arg)
{
struct aspath_exclude *ase;
- struct aspath_exclude_list *ael;
+ struct as_list *aux_aslist;
const char *str = arg;
static const char asp_acl[] = "as-path-access-list";
@@ -2338,44 +2338,37 @@ static void *route_aspath_exclude_compile(const char *arg)
while (*str == ' ')
str++;
ase->exclude_aspath_acl_name = XSTRDUP(MTYPE_TMP, str);
- ase->exclude_aspath_acl = as_list_lookup(str);
+ aux_aslist = as_list_lookup(str);
+ if (!aux_aslist)
+ /* new orphan filter */
+ as_exclude_set_orphan(ase);
+ else
+ as_list_list_add_head(&aux_aslist->exclude_rule, ase);
+
+ ase->exclude_aspath_acl = aux_aslist;
} else
ase->aspath = aspath_str2aspath(str, bgp_get_asnotation(NULL));
- if (ase->exclude_aspath_acl) {
- ael = XCALLOC(MTYPE_ROUTE_MAP_COMPILED,
- sizeof(struct aspath_exclude_list));
- ael->bp_as_excl = ase;
- ael->next = ase->exclude_aspath_acl->exclude_list;
- ase->exclude_aspath_acl->exclude_list = ael;
- }
-
return ase;
}
static void route_aspath_exclude_free(void *rule)
{
struct aspath_exclude *ase = rule;
- struct aspath_exclude_list *cur_ael = NULL;
- struct aspath_exclude_list *prev_ael = NULL;
+ struct as_list *acl;
+
+ /* manage references to that rule*/
+ if (ase->exclude_aspath_acl) {
+ acl = ase->exclude_aspath_acl;
+ as_list_list_del(&acl->exclude_rule, ase);
+ } else {
+ /* no ref to acl, this aspath exclude is orphan */
+ as_exclude_remove_orphan(ase);
+ }
aspath_free(ase->aspath);
if (ase->exclude_aspath_acl_name)
XFREE(MTYPE_TMP, ase->exclude_aspath_acl_name);
- if (ase->exclude_aspath_acl)
- cur_ael = ase->exclude_aspath_acl->exclude_list;
- while (cur_ael) {
- if (cur_ael->bp_as_excl == ase) {
- if (prev_ael)
- prev_ael->next = cur_ael->next;
- else
- ase->exclude_aspath_acl->exclude_list = NULL;
- XFREE(MTYPE_ROUTE_MAP_COMPILED, cur_ael);
- break;
- }
- prev_ael = cur_ael;
- cur_ael = cur_ael->next;
- }
XFREE(MTYPE_ROUTE_MAP_COMPILED, ase);
}
@@ -2410,16 +2403,10 @@ route_set_aspath_exclude(void *rule, const struct prefix *dummy, void *object)
else if (ase->exclude_all)
path->attr->aspath = aspath_filter_exclude_all(new_path);
- else if (ase->exclude_aspath_acl_name) {
- if (!ase->exclude_aspath_acl)
- ase->exclude_aspath_acl =
- as_list_lookup(ase->exclude_aspath_acl_name);
- if (ase->exclude_aspath_acl)
- path->attr->aspath =
- aspath_filter_exclude_acl(new_path,
- ase->exclude_aspath_acl);
- }
-
+ else if (ase->exclude_aspath_acl)
+ path->attr->aspath =
+ aspath_filter_exclude_acl(new_path,
+ ase->exclude_aspath_acl);
return RMAP_OKAY;
}