Implements 'bgppath ~ int set' filter op.

This commit is contained in:
Ondrej Zajicek 2013-07-09 23:27:10 +02:00
parent c01a94663c
commit cc31b75a8f
5 changed files with 32 additions and 3 deletions

View file

@ -1090,7 +1090,7 @@ incompatible with each other (that is to prevent you from shooting in the foot).
Special operators include <cf/&tilde;/ for "is element of a set" operation - it can be
used on element and set of elements of the same type (returning true if element is contained in the given set), or
on two strings (returning true if first string matches a shell-like pattern stored in second string) or on IP and prefix (returning true if IP is within the range defined by that prefix), or on
prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on number and bgppath (returning true if the number is in the path) or on pair/quad and clist (returning true if the pair/quad is element of the clist) or on clist and pair/quad set (returning true if there is an element of the clist that is also a member of the pair/quad set).
prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on number and bgppath (returning true if the number is in the path) or on bgppath and int (number) set (returning true if any ASN from the path is in the set) or on pair/quad and clist (returning true if the pair/quad is element of the clist) or on clist and pair/quad set (returning true if there is an element of the clist that is also a member of the pair/quad set).
<p>There is one operator related to ROA infrastructure -
<cf/roa_check()/. It examines a ROA table and does RFC 6483 route

View file

@ -418,6 +418,9 @@ val_in_range(struct f_val v1, struct f_val v2)
if ((v1.type == T_ECLIST) && (v2.type == T_SET))
return eclist_match_set(v1.val.ad, v2.val.t);
if ((v1.type == T_PATH) && (v2.type == T_SET))
return as_path_match_set(v1.val.ad, v2.val.t);
if (v2.type == T_SET)
switch (v1.type) {
case T_ENUM:

View file

@ -95,10 +95,10 @@ eclist el2;
p2 = prepend( p2, 3 );
p2 = prepend( p2, 4 );
print "Testing paths: ", p2;
print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2;
print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20];
print "4 = ", p2.len;
p2 = prepend( p2, 5 );
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2;
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, 10..20],;
print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /;
print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =];
print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4);

View file

@ -264,6 +264,29 @@ as_path_is_member(struct adata *path, u32 as)
return 0;
}
int
as_path_match_set(struct adata *path, struct f_tree *set)
{
u8 *p = path->data;
u8 *q = p+path->length;
int i, n;
while (p<q)
{
n = p[1];
p += 2;
for (i=0; i<n; i++)
{
struct f_val v = {T_INT, .val.i = get_as(p)};
if (find_tree(set, v))
return 1;
p += BS;
}
}
return 0;
}
struct pm_pos
{

View file

@ -25,6 +25,8 @@
* to 16bit slot (like in 16bit AS_PATH). See RFC 4893 for details
*/
struct f_tree;
struct adata *as_path_prepend(struct linpool *pool, struct adata *olda, u32 as);
int as_path_convert_to_old(struct adata *path, byte *dst, int *new_used);
int as_path_convert_to_new(struct adata *path, byte *dst, int req_as);
@ -34,6 +36,7 @@ int as_path_getlen_int(struct adata *path, int bs);
int as_path_get_first(struct adata *path, u32 *orig_as);
int as_path_get_last(struct adata *path, u32 *last_as);
int as_path_is_member(struct adata *path, u32 as);
int as_path_match_set(struct adata *path, struct f_tree *set);
#define PM_ASN 0
#define PM_QUESTION 1