diff options
| author | Francois Dumontet <francois.dumontet@6wind.com> | 2024-04-23 11:16:24 +0200 | 
|---|---|---|
| committer | Mergify <37929162+mergify[bot]@users.noreply.github.com> | 2024-06-24 21:09:28 +0000 | 
| commit | ba67e107a577f0e432467b5a36fb8453aa589ef6 (patch) | |
| tree | c39a44ad952c0c9ed9c59fb86951d640155f0ebe /bgpd/bgp_routemap.c | |
| parent | 75757a246d53a8eec39e9cc75f618f3e98d5f836 (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.c | 59 | 
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;  }  | 
