diff options
-rw-r--r-- | filter/config.Y | 2 | ||||
-rw-r--r-- | filter/filter.c | 28 | ||||
-rw-r--r-- | filter/test.conf | 2 | ||||
-rw-r--r-- | nest/a-path.c | 18 | ||||
-rw-r--r-- | nest/attrs.h | 7 |
5 files changed, 36 insertions, 21 deletions
diff --git a/filter/config.Y b/filter/config.Y index 0c2247dc..6ce89e7a 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -407,7 +407,7 @@ term: | rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); } | 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; } /* Communities */ diff --git a/filter/filter.c b/filter/filter.c index 768ff938..6763f0ce 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -404,13 +404,22 @@ interpret(struct f_inst *what) } 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 ... */ ONEARG; if (v1.type != T_PREFIX) runtime( "Can not convert non-prefix this way" ); res.type = what->aux; 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; 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)) return 0; break; - case 'p': ONEARG; break; + case 'p': case 'L': ONEARG; break; case '?': TWOARGS; break; case '0': case 'E': 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? */ -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; \ asterix = (mask->val == PM_ANY); \ if (asterix) { mask = mask->next; if (!mask) { return 1; } } \ diff --git a/filter/test.conf b/filter/test.conf index a31c7f2d..a39e6a3d 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -41,9 +41,11 @@ bgppath p2; p2 = prepend( p2, 4 ); print "Testing paths: ", p2; print "Should be true: ", p2 ~ p; + print "4 = ", p2.len; p2 = prepend( p2, 5 ); print "Should be false: ", p2 ~ p; print "Should be true: ", p2 ~ / * 4 3 2 1 /, p2, / * 4 3 2 1 /; + print "5 = ", p2.len; } function startup() diff --git a/nest/a-path.c b/nest/a-path.c index ca39e296..d808bc9a 100644 --- a/nest/a-path.c +++ b/nest/a-path.c @@ -81,3 +81,21 @@ as_path_format(struct adata *path, byte *buf, unsigned int size) } *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; +} diff --git a/nest/attrs.h b/nest/attrs.h index fc960fb5..67ec52d8 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -11,12 +11,13 @@ /* 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_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 */ void int_set_format(struct adata *set, byte *buf, unsigned int size); |