Filter: Implement last_nonaggregated operator on bgp_path
This commit is contained in:
parent
c2106b674c
commit
9c9cc35c02
5 changed files with 45 additions and 3 deletions
|
@ -1119,9 +1119,12 @@ foot).
|
||||||
|
|
||||||
<cf><m/P/.last</cf> returns the last ASN (the source ASN) in path <m/P/.
|
<cf><m/P/.last</cf> returns the last ASN (the source ASN) in path <m/P/.
|
||||||
|
|
||||||
|
<cf><m/P/.last_nonaggregated</cf> returns the last ASN in the non-aggregated part of the path <m/P/.
|
||||||
|
|
||||||
Both <cf/first/ and <cf/last/ return zero if there is no appropriate
|
Both <cf/first/ and <cf/last/ return zero if there is no appropriate
|
||||||
ASN, for example if the path contains an AS set element as the first (or
|
ASN, for example if the path contains an AS set element as the first (or
|
||||||
the last) part.
|
the last) part. If the path ends with an AS set, <cf/last_nonaggregated/
|
||||||
|
may be used to get last ASN before any AS set.
|
||||||
|
|
||||||
<cf><m/P/.len</cf> returns the length of path <m/P/.
|
<cf><m/P/.len</cf> returns the length of path <m/P/.
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
||||||
LEN,
|
LEN,
|
||||||
DEFINED,
|
DEFINED,
|
||||||
ADD, DELETE, CONTAINS, RESET,
|
ADD, DELETE, CONTAINS, RESET,
|
||||||
PREPEND, FIRST, LAST, MATCH,
|
PREPEND, FIRST, LAST, LAST_NONAGGREGATED, MATCH,
|
||||||
ROA_CHECK,
|
ROA_CHECK,
|
||||||
EMPTY,
|
EMPTY,
|
||||||
FILTER, WHERE, EVAL)
|
FILTER, WHERE, EVAL)
|
||||||
|
@ -752,6 +752,7 @@ term:
|
||||||
| term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = P('i','M'); $$->a1.p = $1; $$->a2.p = $5; }
|
| term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = P('i','M'); $$->a1.p = $1; $$->a2.p = $5; }
|
||||||
| term '.' FIRST { $$ = f_new_inst(); $$->code = P('a','f'); $$->a1.p = $1; }
|
| term '.' FIRST { $$ = f_new_inst(); $$->code = P('a','f'); $$->a1.p = $1; }
|
||||||
| term '.' LAST { $$ = f_new_inst(); $$->code = P('a','l'); $$->a1.p = $1; }
|
| term '.' LAST { $$ = f_new_inst(); $$->code = P('a','l'); $$->a1.p = $1; }
|
||||||
|
| term '.' LAST_NONAGGREGATED { $$ = f_new_inst(); $$->code = P('a','L'); $$->a1.p = $1; }
|
||||||
|
|
||||||
/* Communities */
|
/* Communities */
|
||||||
/* This causes one shift/reduce conflict
|
/* This causes one shift/reduce conflict
|
||||||
|
|
|
@ -1091,6 +1091,14 @@ interpret(struct f_inst *what)
|
||||||
res.type = T_INT;
|
res.type = T_INT;
|
||||||
res.val.i = as;
|
res.val.i = as;
|
||||||
break;
|
break;
|
||||||
|
case P('a','L'): /* Get last ASN from non-aggregated part of AS PATH */
|
||||||
|
ONEARG;
|
||||||
|
if (v1.type != T_PATH)
|
||||||
|
runtime( "AS path expected" );
|
||||||
|
|
||||||
|
res.type = T_INT;
|
||||||
|
res.val.i = as_path_get_last_nonaggregated(v1.val.ad);
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
ONEARG;
|
ONEARG;
|
||||||
res = v1;
|
res = v1;
|
||||||
|
|
|
@ -220,7 +220,7 @@ as_path_get_last(struct adata *path, u32 *orig_as)
|
||||||
p += BS * len;
|
p += BS * len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: bug("as_path_get_first: Invalid path segment");
|
default: bug("Invalid path segment");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +229,35 @@ as_path_get_last(struct adata *path, u32 *orig_as)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32
|
||||||
|
as_path_get_last_nonaggregated(struct adata *path)
|
||||||
|
{
|
||||||
|
u8 *p = path->data;
|
||||||
|
u8 *q = p+path->length;
|
||||||
|
u32 res = 0;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
while (p<q)
|
||||||
|
{
|
||||||
|
switch (*p++)
|
||||||
|
{
|
||||||
|
case AS_PATH_SET:
|
||||||
|
return res;
|
||||||
|
|
||||||
|
case AS_PATH_SEQUENCE:
|
||||||
|
if (len = *p++)
|
||||||
|
res = get_as(p + BS * (len - 1));
|
||||||
|
p += BS * len;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: bug("Invalid path segment");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
as_path_get_first(struct adata *path, u32 *last_as)
|
as_path_get_first(struct adata *path, u32 *last_as)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ int as_path_getlen(struct adata *path);
|
||||||
int as_path_getlen_int(struct adata *path, int bs);
|
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_first(struct adata *path, u32 *orig_as);
|
||||||
int as_path_get_last(struct adata *path, u32 *last_as);
|
int as_path_get_last(struct adata *path, u32 *last_as);
|
||||||
|
u32 as_path_get_last_nonaggregated(struct adata *path);
|
||||||
int as_path_contains(struct adata *path, u32 as, int min);
|
int as_path_contains(struct adata *path, u32 as, int min);
|
||||||
int as_path_match_set(struct adata *path, struct f_tree *set);
|
int as_path_match_set(struct adata *path, struct f_tree *set);
|
||||||
struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_tree *set, u32 key, int pos);
|
struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_tree *set, u32 key, int pos);
|
||||||
|
|
Loading…
Reference in a new issue