[PATCH] Allow to match on the kernel route protocol in filters
Jérémie Dimino
jeremie at dimino.org
Tue Mar 13 16:23:09 CET 2012
This patch add the two following attributes:
- krt_source: an enum which export the value of u.krt.src
- krt_proto: an integer which export the value of u.krt.proto
---
doc/bird.sgml | 9 +++++++++
filter/config.Y | 10 +++++++++-
filter/filter.c | 8 ++++++++
filter/filter.h | 1 +
sysdep/unix/config.Y | 2 ++
sysdep/unix/main.c | 2 +-
6 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/doc/bird.sgml b/doc/bird.sgml
index b8dabf4..d74483d 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -991,6 +991,9 @@ undefined value is regarded as empty clist for most purposes.
<tag><m/enum/ dest</tag>
Type of destination the packets should be sent to (<cf/RTD_ROUTER/ for forwarding to a neighboring router, <cf/RTD_DEVICE/ for routing to a directly-connected network, <cf/RTD_BLACKHOLE/ for packets to be silently discarded, <cf/RTD_UNREACHABLE/, <cf/RTD_PROHIBIT/ for packets that should be returned with ICMP host unreachable / ICMP administratively prohibited messages). Read-only.
+ <tag><m/enum/ krt_source</tag>
+ the source of kernel routes. Possible values: <cf/KRT_SRC_BIRD/, <cf/KRT_SRC_REDIRECT/, <cf/KRT_SRC_ALIEN/, <cf/KRT_SRC_KERNEL/.
+
<tag><m/int/ igp_metric</tag>
The optional attribute that can be used to specify a distance
to the network for routes that do not have a native protocol
@@ -1603,6 +1606,12 @@ We support these attributes:
<tag>int <cf/krt_realm/</tag> (Linux) The realm of the route. Can be
used for traffic classification.
+
+ <tag>enum krt_source <cf/krt_source/</tag> The source of the route.
+
+ <tag>int <cf/krt_proto/</tag> The OS-dependent source of the route.
+ It is more precice than <cf/krt_source/ but is not available on all systems.
+ Currently its value is only meaningful under Linux.
</descrip>
<sect1>Example
diff --git a/filter/config.Y b/filter/config.Y
index 0166d27..65a2ee2 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -255,6 +255,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
IF, THEN, ELSE, CASE,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, PREFERENCE,
+ KRT_PROTO, KRT_SOURCE,
LEN,
DEFINED,
ADD, DELETE, CONTAINS, RESET,
@@ -265,7 +266,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%nonassoc THEN
%nonassoc ELSE
-%type <x> term block cmds cmds_int cmd function_body constant constructor print_one print_list var_list var_listn dynamic_attr static_attr function_call symbol bgp_path_expr
+%type <x> term block cmds cmds_int cmd function_body constant constructor print_one print_list var_list var_listn dynamic_attr static_attr krt_attr function_call symbol bgp_path_expr
%type <f> filter filter_body where_filter
%type <i> type break_command pair_expr ec_kind
%type <i32> pair_atom ec_expr
@@ -705,6 +706,11 @@ static_attr:
| DEST { $$ = f_new_inst(); $$->aux = T_ENUM_RTD; $$->a2.i = OFFSETOF(struct rta, dest); }
;
+krt_attr:
+ KRT_SOURCE { $$ = f_new_inst(); $$->aux = T_ENUM_KRT_SOURCE; $$->a2.i = OFFSETOF(struct rte, u.krt.src); }
+ | KRT_PROTO { $$ = f_new_inst(); $$->aux = T_INT; $$->a2.i = OFFSETOF(struct rte, u.krt.proto); }
+ ;
+
term:
'(' term ')' { $$ = $2; }
| term '+' term { $$ = f_new_inst(); $$->code = '+'; $$->a1.p = $1; $$->a2.p = $3; }
@@ -733,6 +739,8 @@ term:
| rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); }
+ | rtadot krt_attr { $$ = $2; $$->code = 'k'; }
+
| term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; }
| term '.' LEN { $$ = f_new_inst(); $$->code = 'L'; $$->a1.p = $1; }
| term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = P('i','M'); $$->a1.p = $1; $$->a2.p = $5; }
diff --git a/filter/filter.c b/filter/filter.c
index d6d338b..8cea76b 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -833,6 +833,14 @@ interpret(struct f_inst *what)
}
}
break;
+ case 'k': /* u.krt access */
+ {
+ res.type = what->aux;
+ if ((*f_rte)->attrs->source == RTS_INHERIT)
+ res.val.i = * ((char *) (*f_rte) + what->a2.i);
+ else
+ res.val.i = -1;
+ }
case P('a','S'):
ONEARG;
if (what->aux != v1.type)
diff --git a/filter/filter.h b/filter/filter.h
index 2cf4652..51f5b7e 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -141,6 +141,7 @@ int tree_compare(const void *p1, const void *p2);
#define T_ENUM_SCOPE 0x32
#define T_ENUM_RTC 0x33
#define T_ENUM_RTD 0x34
+#define T_ENUM_KRT_SOURCE 0x35
/* new enums go here */
#define T_ENUM_EMPTY 0x3f /* Special hack for atomic_aggr */
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index 844f53d..e6d60b0 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -16,6 +16,8 @@ CF_DECLS
CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, BASE, NAME)
+CF_ENUM(T_ENUM_KRT_SOURCE, KRT_SRC_, BIRD, REDIRECT, ALIEN, KERNEL)
+
%type <i> log_mask log_mask_list log_cat
%type <g> log_file
%type <t> cfg_name
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index d617684..b022be9 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -188,7 +188,7 @@ sysdep_preconfig(struct config *c)
init_list(&c->logfiles);
#ifdef PATH_IPROUTE_DIR
- // read_iproute_table(PATH_IPROUTE_DIR "/rt_protos", "ipp_", 256);
+ read_iproute_table(PATH_IPROUTE_DIR "/rt_protos", "ipp_", 256);
read_iproute_table(PATH_IPROUTE_DIR "/rt_realms", "ipr_", 256);
read_iproute_table(PATH_IPROUTE_DIR "/rt_scopes", "ips_", 256);
read_iproute_table(PATH_IPROUTE_DIR "/rt_tables", "ipt_", 256);
--
1.7.9.1
--MP_/H2IZm=0dknKvFOfee5JxakH--
More information about the Bird-users
mailing list