[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