diff options
Diffstat (limited to 'filter')
-rw-r--r-- | filter/config.Y | 15 | ||||
-rw-r--r-- | filter/filter.c | 25 | ||||
-rw-r--r-- | filter/filter.h | 6 |
3 files changed, 24 insertions, 22 deletions
diff --git a/filter/config.Y b/filter/config.Y index b0562974..953dfbcd 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -106,7 +106,7 @@ type: | PREFIX { $$ = T_PREFIX; } | PAIR { $$ = T_PAIR; } | STRING { $$ = T_STRING; } - | BGP_PATH { $$ = T_PATH; } + | BGP_PATH { $$ = T_PATH_MASK; } | type SET { switch ($1) { default: @@ -313,8 +313,8 @@ bgp_one: ; bgp_path: - bgp_one { $$ = cfg_alloc(sizeof(struct f_path)); $$->next = NULL; $$->val = $1; } - | bgp_one bgp_path { $$ = cfg_alloc(sizeof(struct f_path)); $$->next = $2; $$->val = $1; } + bgp_one { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = NULL; $$->val = $1; } + | bgp_one bgp_path { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->val = $1; } ; constant: @@ -327,7 +327,7 @@ constant: | prefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; } | '[' set_items ']' { DBG( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_SET; $$->a2.p = build_tree($2); DBG( "ook\n" ); } | ENUM { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; } - | '/' bgp_path '/' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PATH; $$->a2.p = $2; } + | '/' bgp_path '/' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PATH_MASK; $$->a2.p = $2; } ; /* @@ -384,7 +384,7 @@ term: case SYM_VARIABLE | T_PAIR: case SYM_VARIABLE | T_PREFIX: case SYM_VARIABLE | T_IP: - case SYM_VARIABLE | T_PATH: + case SYM_VARIABLE | T_PATH_MASK: $$->code = 'C'; $$->a1.p = $1->aux2; break; @@ -413,8 +413,9 @@ term: | term '.' RESET { } /* Paths */ - | term '.' APPEND '(' term ')' { } -/* | term '.' LEN { } Hmm, this would colide with ip.len. What to do with that? */ + | rtadot PATH '~' term { } + | rtadot PATH '.' APPEND '(' term ')' { } + | rtadot PATH '.' LEN { $$->code = P('P','l'); } /* function_call is inlined here */ | SYM '(' var_list ')' { diff --git a/filter/filter.c b/filter/filter.c index 9788edb6..2da2a28e 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -133,7 +133,7 @@ val_print(struct f_val v) case T_PAIR: PRINTF( "(%d,%d)", v.val.i >> 16, v.val.i & 0xffff ); break; case T_SET: tree_print( v.val.t ); PRINTF( "\n" ); break; case T_ENUM: PRINTF( "(enum %x)%d", v.type, v.val.i ); break; - case T_PATH: debug( "(path " ); { struct f_path *p = v.val.s; while (p) { debug("%d ", p->val); p=p->next; } debug(")" ); } break; + case T_PATH_MASK: debug( "(path " ); { struct f_path_mask *p = v.val.s; while (p) { debug("%d ", p->val); p=p->next; } debug(")" ); } break; default: PRINTF( "[unknown type %x]", v.type ); #undef PRINTF } @@ -249,7 +249,7 @@ interpret(struct f_inst *what) case T_IP: case T_PREFIX: case T_PAIR: - case T_PATH: + case T_PATH_MASK: if (sym->class != (SYM_VARIABLE | v2.type)) runtime( "Variable of bad type" ); * (struct f_val *) sym->aux2 = v2; @@ -643,13 +643,14 @@ path_format(u8 *p, int len) #define PM_END -1 #define PM_ASTERIX -2 -#define MASK_PLUS do { if (*++mask == PM_END) return next == q; \ - asterix = (*mask == PM_ASTERIX); \ +#define MASK_PLUS do { mask = mask->next; if (mask->val == PM_END) return next == q; \ + asterix = (mask->val == PM_ASTERIX); \ printf( "Asterix now %d\n", asterix ); \ - if (asterix) { if (*++mask == PM_END) { printf( "Quick exit\n" ); return 1; } } \ + if (asterix) { mask = mask->next; if (mask->val == PM_END) { printf( "Quick exit\n" ); return 1; } } \ } while(0) + int -path_match(u8 *p, int len, s32 *mask) +path_match(u8 *p, int len, struct f_path_mask *mask) { int i; int asterix = 0; @@ -666,11 +667,11 @@ path_match(u8 *p, int len, s32 *mask) retry: p = p_save; for (i=0; i<len; i++) { - if (asterix && (get_u16(p) == *mask)) { + if (asterix && (get_u16(p) == mask->val)) { MASK_PLUS; goto retry; } - if (!asterix && (get_u16(p) == *mask)) { + if (!asterix && (get_u16(p) == mask->val)) { p = next; MASK_PLUS; goto okay; @@ -687,10 +688,10 @@ path_match(u8 *p, int len, s32 *mask) len = *p++; for (i=0; i<len; i++) { next = p+2; - if (asterix && (get_u16(p) == *mask)) + if (asterix && (get_u16(p) == mask->val)) MASK_PLUS; else if (!asterix) { - if (get_u16(p) != *mask) + if (get_u16(p) != mask->val) return 0; MASK_PLUS; } @@ -767,7 +768,7 @@ self_test(void) DBG( "%s\n", path_format(path1, sizeof(path1)) ); DBG( "%s\n", path_format(path2, sizeof(path2)) ); DBG( "5, 6 = %d, %d\n", path_getlen(path1, sizeof(path1)), path_getlen(path2, sizeof(path2)) ); - DBG( "%d\n", path_match(path1, sizeof(path1), match)); - DBG( "%d\n", path_match(path2, sizeof(path2), match)); +// DBG( "%d\n", path_match(path1, sizeof(path1), match)); +// DBG( "%d\n", path_match(path2, sizeof(path2), match)); // die( "okay" ); } diff --git a/filter/filter.h b/filter/filter.h index ecfd88d7..ab337398 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -50,8 +50,8 @@ struct f_val { } val; }; -struct f_path { - struct f_path *next; +struct f_path_mask { + struct f_path_mask *next; int val; }; @@ -115,7 +115,7 @@ void val_print(struct f_val v); #define T_IP 0x20 #define T_PREFIX 0x21 #define T_STRING 0x22 -#define T_PATH 0x23 /* BGP path */ +#define T_PATH_MASK 0x23 /* mask for BGP path */ #define T_RETURN 0x40 #define T_SET 0x80 |