Path_getlen moved to nest and length was made callable from filters.
This commit is contained in:
parent
ecd25633bd
commit
684c6f5a0e
5 changed files with 36 additions and 21 deletions
|
@ -407,7 +407,7 @@ term:
|
||||||
| rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); }
|
| rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); }
|
||||||
|
|
||||||
| term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; }
|
| term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; }
|
||||||
| term '.' LEN { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_INT; }
|
| term '.' LEN { $$ = f_new_inst(); $$->code = 'L'; $$->a1.p = $1; }
|
||||||
| 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; }
|
||||||
|
|
||||||
/* Communities */
|
/* Communities */
|
||||||
|
|
|
@ -404,13 +404,22 @@ interpret(struct f_inst *what)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'L': /* Get length of */
|
||||||
|
ONEARG;
|
||||||
|
res.type = T_INT;
|
||||||
|
switch(v1.type) {
|
||||||
|
case T_PREFIX: res.val.i = v1.val.px.len; break;
|
||||||
|
case T_PATH: res.val.i = as_path_getlen(v1.val.ad); break;
|
||||||
|
default: bug( "Length of what?" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
case P('c','p'): /* Convert prefix to ... */
|
case P('c','p'): /* Convert prefix to ... */
|
||||||
ONEARG;
|
ONEARG;
|
||||||
if (v1.type != T_PREFIX)
|
if (v1.type != T_PREFIX)
|
||||||
runtime( "Can not convert non-prefix this way" );
|
runtime( "Can not convert non-prefix this way" );
|
||||||
res.type = what->aux;
|
res.type = what->aux;
|
||||||
switch(res.type) {
|
switch(res.type) {
|
||||||
case T_INT: res.val.i = v1.val.px.len; break;
|
/* case T_INT: res.val.i = v1.val.px.len; break; Not needed any more */
|
||||||
case T_IP: res.val.px.ip = v1.val.px.ip; break;
|
case T_IP: res.val.px.ip = v1.val.px.ip; break;
|
||||||
default: bug( "Unknown prefix to conversion" );
|
default: bug( "Unknown prefix to conversion" );
|
||||||
}
|
}
|
||||||
|
@ -536,7 +545,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
|
||||||
if (val_compare(* (struct f_val *) f1->a1.p, * (struct f_val *) f2->a2.p))
|
if (val_compare(* (struct f_val *) f1->a1.p, * (struct f_val *) f2->a2.p))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 'p': ONEARG; break;
|
case 'p': case 'L': ONEARG; break;
|
||||||
case '?': TWOARGS; break;
|
case '?': TWOARGS; break;
|
||||||
case '0': case 'E': break;
|
case '0': case 'E': break;
|
||||||
case P('p',','): ONEARG; A2_SAME; break;
|
case P('p',','): ONEARG; A2_SAME; break;
|
||||||
|
@ -612,21 +621,6 @@ filter_same(struct filter *new, struct filter *old)
|
||||||
* Or maybe both versions are usefull?
|
* Or maybe both versions are usefull?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
|
||||||
path_getlen(u8 *p, int len)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
u8 *q = p+len;
|
|
||||||
while (p<q) {
|
|
||||||
switch (*p++) {
|
|
||||||
case 1: len = *p++; res++; p += 2*len; break;
|
|
||||||
case 2: len = *p++; res+=len; p += 2*len; break;
|
|
||||||
default: bug("This should not be in path");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MASK_PLUS do { mask = mask->next; if (!mask) return next == q; \
|
#define MASK_PLUS do { mask = mask->next; if (!mask) return next == q; \
|
||||||
asterix = (mask->val == PM_ANY); \
|
asterix = (mask->val == PM_ANY); \
|
||||||
if (asterix) { mask = mask->next; if (!mask) { return 1; } } \
|
if (asterix) { mask = mask->next; if (!mask) { return 1; } } \
|
||||||
|
|
|
@ -41,9 +41,11 @@ bgppath p2;
|
||||||
p2 = prepend( p2, 4 );
|
p2 = prepend( p2, 4 );
|
||||||
print "Testing paths: ", p2;
|
print "Testing paths: ", p2;
|
||||||
print "Should be true: ", p2 ~ p;
|
print "Should be true: ", p2 ~ p;
|
||||||
|
print "4 = ", p2.len;
|
||||||
p2 = prepend( p2, 5 );
|
p2 = prepend( p2, 5 );
|
||||||
print "Should be false: ", p2 ~ p;
|
print "Should be false: ", p2 ~ p;
|
||||||
print "Should be true: ", p2 ~ / * 4 3 2 1 /, p2, / * 4 3 2 1 /;
|
print "Should be true: ", p2 ~ / * 4 3 2 1 /, p2, / * 4 3 2 1 /;
|
||||||
|
print "5 = ", p2.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
function startup()
|
function startup()
|
||||||
|
|
|
@ -81,3 +81,21 @@ as_path_format(struct adata *path, byte *buf, unsigned int size)
|
||||||
}
|
}
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
as_path_getlen(struct adata *path)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
u8 *p = path->data;
|
||||||
|
u8 *q = p+path->length;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
while (p<q) {
|
||||||
|
switch (*p++) {
|
||||||
|
case 1: len = *p++; res++; p += 2*len; break;
|
||||||
|
case 2: len = *p++; res+=len; p += 2*len; break;
|
||||||
|
default: bug("This should not be in path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
|
|
||||||
/* a-path.c */
|
/* a-path.c */
|
||||||
|
|
||||||
struct adata *as_path_prepend(struct linpool *pool, struct adata *olda, int as);
|
|
||||||
void as_path_format(struct adata *path, byte *buf, unsigned int size);
|
|
||||||
|
|
||||||
#define AS_PATH_SET 1 /* Types of path segments */
|
#define AS_PATH_SET 1 /* Types of path segments */
|
||||||
#define AS_PATH_SEQUENCE 2
|
#define AS_PATH_SEQUENCE 2
|
||||||
|
|
||||||
|
struct adata *as_path_prepend(struct linpool *pool, struct adata *olda, int as);
|
||||||
|
void as_path_format(struct adata *path, byte *buf, unsigned int size);
|
||||||
|
int as_path_getlen(struct adata *path);
|
||||||
|
|
||||||
/* a-set.c */
|
/* a-set.c */
|
||||||
|
|
||||||
void int_set_format(struct adata *set, byte *buf, unsigned int size);
|
void int_set_format(struct adata *set, byte *buf, unsigned int size);
|
||||||
|
|
Loading…
Reference in a new issue