summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/bird.sgml6
-rw-r--r--filter/config.Y3
-rw-r--r--filter/filter.c7
3 files changed, 14 insertions, 2 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 6622c1a..3ccbd5e 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -544,7 +544,8 @@ incompatible with each other (that is to prevent you from shooting in the foot).
<p>The filter language supports common integer operators <cf>(+,-,*,/)</cf>, parentheses <cf/(a*(b+c))/, comparison
<cf/(a=b, a!=b, a&lt;b, a&gt;=b)/. Logical operations include unary not (<cf/!/), and (<cf/&amp;&amp;/) and or (<cf/&verbar;&verbar;/).
Special operators include <cf/&tilde;/ for "is element of a set" operation - it can be
-used on element and set of elements of the same type (returning true if element is contained in the given set), or on IP and prefix (returning true if IP is within the range defined by that prefix), or on
+used on element and set of elements of the same type (returning true if element is contained in the given set), or
+on two strings (returning true if first string matches a shell-like pattern stored in second string) or on IP and prefix (returning true if IP is within the range defined by that prefix), or on
prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on pair and clist (returning true if the community is element of the community list).
@@ -601,6 +602,9 @@ defined by using the <cf>defined( <m>attribute</m> )</cf> operator.
<tag><m/ip/ gw</tag>
Next hop packets routed using this route should be forwarded to.
+ <tag><m/string/ proto</tag>
+ The name of the protocol which the route has been imported from. Read-only.
+
<tag><m/enum/ source</tag>
what protocol has told me about this route. Possible values: <cf/RTS_DUMMY/, <cf/RTS_STATIC/, <cf/RTS_INHERIT/, <cf/RTS_DEVICE/, <cf/RTS_STATIC_DEVICE/, <cf/RTS_REDIRECT/, <cf/RTS_RIP/, <cf/RTS_OSPF/, <cf/RTS_OSPF_IA/, <cf/RTS_OSPF_EXT/, <cf/RTS_BGP/, <cf/RTS_PIPE/.
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;