From e29fa06ece1bf9f9a47f224db797df940556136e Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 14 Nov 2008 14:50:37 +0100 Subject: New read-only route attribute 'proto' added. It returns a string representing a name of the protocol that originated the route. Strings can be compared using = or matched using ~. Routes can be filtered, for example: show route where proto ~ "bgp1*" --- filter/config.Y | 3 ++- filter/filter.c | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'filter') diff --git a/filter/config.Y b/filter/config.Y index fdfb2e7..d131a25 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -21,7 +21,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, INT, BOOL, IP, PREFIX, PAIR, SET, STRING, BGPMASK, BGPPATH, CLIST, IF, THEN, ELSE, CASE, TRUE, FALSE, - FROM, GW, NET, MASK, SOURCE, SCOPE, CAST, DEST, PREFERENCE, + FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, PREFERENCE, LEN, DEFINED, ADD, DELETE, CONTAINS, RESET, @@ -331,6 +331,7 @@ static_attr: | GW { $$ = f_new_inst(); $$->aux = T_IP; $$->a2.i = OFFSETOF(struct rta, gw); $$->a1.i = 1; } | NET { $$ = f_new_inst(); $$->aux = T_PREFIX; $$->a2.i = 0x12345678; /* This is actually ok - T_PREFIX is special-cased. */ } + | PROTO { $$ = f_new_inst(); $$->aux = T_STRING; $$->a2.i = 0x12345678; /* T_STRING is also special-cased. */ } | SOURCE { $$ = f_new_inst(); $$->aux = T_ENUM_RTS; $$->a2.i = OFFSETOF(struct rta, source); } | SCOPE { $$ = f_new_inst(); $$->aux = T_ENUM_SCOPE; $$->a2.i = OFFSETOF(struct rta, scope); $$->a1.i = 1; } | CAST { $$ = f_new_inst(); $$->aux = T_ENUM_RTC; $$->a2.i = OFFSETOF(struct rta, cast); } diff --git a/filter/filter.c b/filter/filter.c index 6f85c06..bdc6f08 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -137,6 +137,8 @@ val_compare(struct f_val v1, struct f_val v2) return 0; case T_PATH_MASK: return pm_path_compare(v1.val.path_mask, v2.val.path_mask); + case T_STRING: + return strcmp(v1.val.s, v2.val.s); default: debug( "Compare of unkown entities: %x\n", v1.type ); return CMP_ERROR; @@ -153,6 +155,8 @@ val_simple_in_range(struct f_val v1, struct f_val v2) return as_path_match(v1.val.ad, v2.val.path_mask); if ((v1.type == T_PAIR) && (v2.type == T_CLIST)) return int_set_contains(v2.val.ad, v1.val.i); + if ((v1.type == T_STRING) && (v2.type == T_STRING)) + return patmatch(v2.val.s, v1.val.s); if ((v1.type == T_IP) && (v2.type == T_PREFIX)) return !(ipa_compare(ipa_and(v2.val.px.ip, ipa_mkmask(v2.val.px.len)), ipa_and(v1.val.px.ip, ipa_mkmask(v2.val.px.len)))); @@ -497,6 +501,9 @@ interpret(struct f_inst *what) case T_ENUM: res.val.i = * ((char *) rta + what->a2.i); break; + case T_STRING: /* Warning: this is a special case for proto attribute */ + res.val.s = rta->proto->name; + break; case T_PREFIX: /* Warning: this works only for prefix of network */ { res.val.px.ip = (*f_rte)->net->n.prefix; -- cgit v1.2.3