summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2013-09-26 22:08:21 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2013-09-26 22:08:21 +0200
commita5fc59587fe864e4fcfb44eb3be57231b4ca339b (patch)
tree8c9459d5a432e85e8a3febb0c42fa6674fede9df /filter
parent4df2019ebfc0f77feb16b6a33dea6d5ac595f55e (diff)
Rewrites static attribute filter code and adds ifname/ifindex attributes.
Thanks to Sergey Popovich for the original ifname/ifindex patch.
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y21
-rw-r--r--filter/filter.c57
-rw-r--r--filter/filter.h13
3 files changed, 52 insertions, 39 deletions
diff --git a/filter/config.Y b/filter/config.Y
index 66234050..04acfbab 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -261,7 +261,8 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST,
IF, THEN, ELSE, CASE,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
- FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, PREFERENCE,
+ FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, IFNAME, IFINDEX,
+ PREFERENCE,
LEN,
DEFINED,
ADD, DELETE, CONTAINS, RESET,
@@ -680,14 +681,16 @@ symbol:
}
static_attr:
- FROM { $$ = f_new_inst(); $$->aux = T_IP; $$->a2.i = OFFSETOF(struct rta, from); $$->a1.i = 1; }
- | 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); }
- | DEST { $$ = f_new_inst(); $$->aux = T_ENUM_RTD; $$->a2.i = OFFSETOF(struct rta, dest); $$->a1.i = 1; }
+ FROM { $$ = f_new_inst(); $$->aux = T_IP; $$->a2.i = SA_FROM; $$->a1.i = 1; }
+ | GW { $$ = f_new_inst(); $$->aux = T_IP; $$->a2.i = SA_GW; $$->a1.i = 1; }
+ | NET { $$ = f_new_inst(); $$->aux = T_PREFIX; $$->a2.i = SA_NET; }
+ | PROTO { $$ = f_new_inst(); $$->aux = T_STRING; $$->a2.i = SA_PROTO; }
+ | SOURCE { $$ = f_new_inst(); $$->aux = T_ENUM_RTS; $$->a2.i = SA_SOURCE; }
+ | SCOPE { $$ = f_new_inst(); $$->aux = T_ENUM_SCOPE; $$->a2.i = SA_SCOPE; $$->a1.i = 1; }
+ | CAST { $$ = f_new_inst(); $$->aux = T_ENUM_RTC; $$->a2.i = SA_CAST; }
+ | DEST { $$ = f_new_inst(); $$->aux = T_ENUM_RTD; $$->a2.i = SA_DEST; $$->a1.i = 1; }
+ | IFNAME { $$ = f_new_inst(); $$->aux = T_STRING; $$->a2.i = SA_IFNAME; }
+ | IFINDEX { $$ = f_new_inst(); $$->aux = T_INT; $$->a2.i = SA_IFINDEX; }
;
term:
diff --git a/filter/filter.c b/filter/filter.c
index 1f090528..0fc10f1f 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -824,24 +824,23 @@ interpret(struct f_inst *what)
ACCESS_RTE;
struct rta *rta = (*f_rte)->attrs;
res.type = what->aux;
- switch(res.type) {
- case T_IP:
- res.val.px.ip = * (ip_addr *) ((char *) rta + what->a2.i);
- break;
- 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;
- res.val.px.len = (*f_rte)->net->n.pxlen;
- break;
- }
+
+ switch (what->a2.i)
+ {
+ case SA_FROM: res.val.px.ip = rta->from; break;
+ case SA_GW: res.val.px.ip = rta->gw; break;
+ case SA_NET: res.val.px.ip = (*f_rte)->net->n.prefix;
+ res.val.px.len = (*f_rte)->net->n.pxlen; break;
+ case SA_PROTO: res.val.s = rta->proto->name; break;
+ case SA_SOURCE: res.val.i = rta->source; break;
+ case SA_SCOPE: res.val.i = rta->scope; break;
+ case SA_CAST: res.val.i = rta->cast; break;
+ case SA_DEST: res.val.i = rta->dest; break;
+ case SA_IFNAME: res.val.s = rta->iface ? rta->iface->name : ""; break;
+ case SA_IFINDEX: res.val.i = rta->iface ? rta->iface->index : 0; break;
+
default:
- bug( "Invalid type for rta access (%x)", res.type );
+ bug("Invalid static attribute access (%x)", res.type);
}
}
break;
@@ -850,19 +849,20 @@ interpret(struct f_inst *what)
ONEARG;
if (what->aux != v1.type)
runtime( "Attempt to set static attribute to incompatible type" );
+
f_rta_cow();
{
struct rta *rta = (*f_rte)->attrs;
- ip_addr ip;
-
- switch (what->aux) {
- case T_IP:
- ip = v1.val.px.ip;
+ switch (what->a2.i)
+ {
+ case SA_FROM:
+ rta->from = v1.val.px.ip;
+ break;
- /* "gw" attribute? */
- if (what->a2.i == OFFSETOF(struct rta, gw))
+ case SA_GW:
{
+ ip_addr ip = v1.val.px.ip;
neighbor *n = neigh_find(rta->proto, &ip, 0);
if (!n || (n->scope == SCOPE_HOST))
runtime( "Invalid gw address" );
@@ -873,16 +873,13 @@ interpret(struct f_inst *what)
rta->nexthops = NULL;
rta->hostentry = NULL;
}
- else /* or "from" attribute? */
- rta->from = ip;
-
break;
- case T_ENUM_SCOPE:
+ case SA_SCOPE:
rta->scope = v1.val.i;
break;
- case T_ENUM_RTD:
+ case SA_DEST:
i = v1.val.i;
if ((i != RTD_BLACKHOLE) && (i != RTD_UNREACHABLE) && (i != RTD_PROHIBIT))
runtime( "Destination can be changed only to blackhole, unreachable or prohibit" );
@@ -895,7 +892,7 @@ interpret(struct f_inst *what)
break;
default:
- bug( "Unknown type in set of static attribute" );
+ bug("Invalid static attribute access (%x)", res.type);
}
}
break;
diff --git a/filter/filter.h b/filter/filter.h
index 1d5150e7..dcac8253 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -172,6 +172,19 @@ void val_print(struct f_val v);
#define T_SET 0x80
#define T_PREFIX_SET 0x81
+
+#define SA_FROM 1
+#define SA_GW 2
+#define SA_NET 3
+#define SA_PROTO 4
+#define SA_SOURCE 5
+#define SA_SCOPE 6
+#define SA_CAST 7
+#define SA_DEST 8
+#define SA_IFNAME 9
+#define SA_IFINDEX 10
+
+
struct f_tree {
struct f_tree *left, *right;
struct f_val from, to;