[Babel-users] [PATCH 2/2] Add filter to choose the export routing table.

Matthieu Boutier boutier at pps.univ-paris-diderot.fr
Thu Sep 3 07:45:01 UTC 2015


- We keep the "export-table" option for compatibility reasons.

- It overrides the selection of source-specific tables.  Not sure if it
  is the right thing to do.
---
 babeld.man       |  6 ++++++
 configuration.c  | 29 +++++++++++++++++++++++++++++
 configuration.h  |  4 ++++
 kernel_netlink.c |  7 ++++++-
 4 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/babeld.man b/babeld.man
index 1991811..1712d71 100644
--- a/babeld.man
+++ b/babeld.man
@@ -498,6 +498,12 @@ For a redistribute filter, redistribute this route with metric
 .BI src-prefix " prefix"
 For a redistribute filter, set the source prefix of this route to
 .IR prefix .
+.TP
+.BI table " table"
+For an export filter, specify the kernel routing table to use when inserting
+that route.  This may conflict with the disambiguation algorithm.  You should
+not use it with IPv4 source-specific routes, nor IPv6 sources-specific routes if
+you don't have IPv6 subtrees.
 .PP
 If
 .I action
diff --git a/configuration.c b/configuration.c
index 4b85df0..a6c7cc0 100644
--- a/configuration.c
+++ b/configuration.c
@@ -42,6 +42,7 @@ THE SOFTWARE.
 struct filter *input_filters = NULL;
 struct filter *output_filters = NULL;
 struct filter *redistribute_filters = NULL;
+struct filter *export_filters = NULL;
 struct interface_conf *default_interface_conf = NULL;
 struct interface_conf *interface_confs = NULL;
 
@@ -403,6 +404,13 @@ parse_filter(int c, gnc_t gnc, void *closure, struct filter **filter_return)
                 goto error;
             if(af == AF_INET && filter->action.src_plen == 96)
                 memset(&filter->action.src_prefix, 0, 16);
+        } else if(strcmp(token, "table") == 0) {
+            int table;
+            c = getint(c, &table, gnc, closure);
+            if(c < -1) goto error;
+            if(table <= 0 || table > INFINITY)
+                goto error;
+            filter->action.table = table;
         } else {
             goto error;
         }
@@ -846,6 +854,12 @@ parse_config(gnc_t gnc, void *closure)
             if(c < -1)
                 return -1;
             add_filter(filter, &redistribute_filters);
+        } else if(strcmp(token, "export") == 0) {
+            struct filter *filter;
+            c = parse_filter(c, gnc, closure, &filter);
+            if(c < -1)
+                return -1;
+            add_filter(filter, &export_filters);
         } else if(strcmp(token, "interface") == 0) {
             struct interface_conf *if_conf;
             c = parse_ifconf(c, gnc, closure, &if_conf);
@@ -945,6 +959,7 @@ renumber_filters()
     renumber_filter(input_filters);
     renumber_filter(output_filters);
     renumber_filter(redistribute_filters);
+    renumber_filter(export_filters);
 }
 
 static int
@@ -1079,6 +1094,20 @@ redistribute_filter(const unsigned char *prefix, unsigned short plen,
 }
 
 int
+export_filter(const unsigned char *prefix, unsigned short plen,
+              const unsigned char *src_prefix, unsigned short src_plen,
+              unsigned int ifindex,
+              struct filter_result *result)
+{
+    int res;
+    res = do_filter(export_filters, NULL, prefix, plen,
+                    src_prefix, src_plen, NULL, ifindex, 0, result);
+    if(res < 0)
+        res = INFINITY;
+    return res;
+}
+
+int
 finalise_config()
 {
     struct filter *filter = calloc(1, sizeof(struct filter));
diff --git a/configuration.h b/configuration.h
index 67e6cde..5e5f4cd 100644
--- a/configuration.h
+++ b/configuration.h
@@ -24,6 +24,7 @@ struct filter_result {
     unsigned int add_metric; /* allow = 0, deny = INF, metric = <0..INF> */
     unsigned char *src_prefix;
     unsigned char src_plen;
+    unsigned char table; /* linux specific: export in the FIB table number */
 };
 
 struct filter {
@@ -61,4 +62,7 @@ int redistribute_filter(const unsigned char *prefix, unsigned short plen,
                     const unsigned char *src_prefix, unsigned short src_plen,
                     unsigned int ifindex, int proto,
                     struct filter_result *result);
+int export_filter(const unsigned char *prefix, unsigned short plen,
+                  const unsigned char *src_prefix, unsigned short src_plen,
+                  unsigned int ifindex, struct filter_result *result);
 int finalise_config(void);
diff --git a/kernel_netlink.c b/kernel_netlink.c
index 1b87e74..b3101e1 100644
--- a/kernel_netlink.c
+++ b/kernel_netlink.c
@@ -51,6 +51,7 @@ THE SOFTWARE.
 #include "kernel.h"
 #include "util.h"
 #include "interface.h"
+#include "configuration.h"
 
 #ifndef MAX_INTERFACES
 #define MAX_INTERFACES 20
@@ -893,6 +894,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
              const unsigned char *newgate, int newifindex,
              unsigned int newmetric)
 {
+    struct filter_result filter_result = {0};
     union { char raw[1024]; struct nlmsghdr nh; } buf;
     struct rtmsg *rtm;
     struct rtattr *rta;
@@ -961,7 +963,10 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
 
     ipv4 = v4mapped(gate);
 
-    if(src_plen == 0) {
+    export_filter(dest, plen, src, src_plen, ifindex, &filter_result);
+    if(filter_result.table) {
+        table = filter_result.table;
+    } else if(src_plen == 0) {
         table = export_table;
     } else if(kernel_disambiguate(ipv4)) {
         table = export_table;
-- 
2.1.4




More information about the Babel-users mailing list