summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2008-11-14 14:50:37 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2008-11-14 14:50:37 +0100
commite29fa06ece1bf9f9a47f224db797df940556136e (patch)
tree10775979f654be43a67c072e225879d3f42973d9 /filter
parentaebe06b40ce730a88cc8a3121be1944b3ddf5765 (diff)
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*"
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y3
-rw-r--r--filter/filter.c7
2 files changed, 9 insertions, 1 deletions
diff --git a/filter/config.Y b/filter/config.Y
index fdfb2e74..d131a25f 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 6f85c064..bdc6f088 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;