diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2021-04-20 06:11:57 +0200 | 
|---|---|---|
| committer | Martin Winter <mwinter@opensourcerouting.org> | 2021-07-06 01:44:34 +0200 | 
| commit | 2b6b16fc21d35693914231509c8710eff6a58c4a (patch) | |
| tree | 545863ce2606dff91c0a0dad58b7906ebd55be29 /lib/plist.c | |
| parent | f06c6e3ef91027205e653a4aa72a2bb8969466e9 (diff) | |
lib, pimd: add address match mode to prefix lists
... the PIM code is kinda misusing prefix lists to match addresses.
Considering the weird semantics of access-lists, I can't fault it.
However, prefix lists aren't great at matching addresses by default,
since they try to match the prefix length too.  So, here's an "address
match mode" for prefix lists to get that to work more reasonably.
Fixes: #8492
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/plist.c')
| -rw-r--r-- | lib/plist.c | 20 | 
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/plist.c b/lib/plist.c index 0ee02f8a0b..1ee855a594 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -750,7 +750,7 @@ static const char *prefix_list_type_str(struct prefix_list_entry *pentry)  }  static int prefix_list_entry_match(struct prefix_list_entry *pentry, -				   const struct prefix *p) +				   const struct prefix *p, bool address_mode)  {  	int ret; @@ -761,6 +761,9 @@ static int prefix_list_entry_match(struct prefix_list_entry *pentry,  	if (!ret)  		return 0; +	if (address_mode) +		return 1; +  	/* In case of le nor ge is specified, exact match is performed. */  	if (!pentry->le && !pentry->ge) {  		if (pentry->prefix.prefixlen != p->prefixlen) @@ -777,14 +780,15 @@ static int prefix_list_entry_match(struct prefix_list_entry *pentry,  	return 1;  } -enum prefix_list_type prefix_list_apply_which_prefix( +enum prefix_list_type prefix_list_apply_ext(  	struct prefix_list *plist, -	const struct prefix **which, -	const void *object) +	const struct prefix_list_entry **which, +	union prefixconstptr object, +	bool address_mode)  {  	struct prefix_list_entry *pentry, *pbest = NULL; -	const struct prefix *p = (const struct prefix *)object; +	const struct prefix *p = object.p;  	const uint8_t *byte = p->u.val;  	size_t depth;  	size_t validbits = p->prefixlen; @@ -809,7 +813,7 @@ enum prefix_list_type prefix_list_apply_which_prefix(  		     pentry = pentry->next_best) {  			if (pbest && pbest->seq < pentry->seq)  				continue; -			if (prefix_list_entry_match(pentry, p)) +			if (prefix_list_entry_match(pentry, p, address_mode))  				pbest = pentry;  		} @@ -830,7 +834,7 @@ enum prefix_list_type prefix_list_apply_which_prefix(  		     pentry = pentry->next_best) {  			if (pbest && pbest->seq < pentry->seq)  				continue; -			if (prefix_list_entry_match(pentry, p)) +			if (prefix_list_entry_match(pentry, p, address_mode))  				pbest = pentry;  		}  		break; @@ -838,7 +842,7 @@ enum prefix_list_type prefix_list_apply_which_prefix(  	if (which) {  		if (pbest) -			*which = &pbest->prefix; +			*which = pbest;  		else  			*which = NULL;  	}  | 
