Commit abe653ba authored by Matthieu Boutier's avatar Matthieu Boutier Committed by Juliusz Chroboczek

Add filter to choose the export routing table.

- 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.

Thanks to Jernej Kos <jernej@kos.mx> for its review.
parent 273bcc70
.TH BABELD 8 s.TH BABELD 8
.SH NAME .SH NAME
babeld \- ad-hoc network routing daemon babeld \- ad-hoc network routing daemon
.SH SYNOPSIS .SH SYNOPSIS
...@@ -410,8 +410,9 @@ A filtering rule is defined by a single line with the following format: ...@@ -410,8 +410,9 @@ A filtering rule is defined by a single line with the following format:
specifies the filter to which this entry will be added, and can be one of specifies the filter to which this entry will be added, and can be one of
.BR in , .BR in ,
.BR out , .BR out ,
.BR redistribute ,
or or
.BR redistribute . .BR install .
Each Each
.I selector .I selector
...@@ -498,6 +499,14 @@ For a redistribute filter, redistribute this route with metric ...@@ -498,6 +499,14 @@ For a redistribute filter, redistribute this route with metric
.BI src-prefix " prefix" .BI src-prefix " prefix"
For a redistribute filter, set the source prefix of this route to For a redistribute filter, set the source prefix of this route to
.IR prefix . .IR prefix .
.TP
.BI table " table"
In an
.B install
filter, specify the kernel routing table to use. For source-specific
routes, this only works reliably for IPv6, and only when
.B ipv6-subtrees
is true.
.PP .PP
If If
.I action .I action
......
...@@ -42,6 +42,7 @@ THE SOFTWARE. ...@@ -42,6 +42,7 @@ THE SOFTWARE.
struct filter *input_filters = NULL; struct filter *input_filters = NULL;
struct filter *output_filters = NULL; struct filter *output_filters = NULL;
struct filter *redistribute_filters = NULL; struct filter *redistribute_filters = NULL;
struct filter *install_filters = NULL;
struct interface_conf *default_interface_conf = NULL; struct interface_conf *default_interface_conf = NULL;
struct interface_conf *interface_confs = NULL; struct interface_conf *interface_confs = NULL;
...@@ -403,6 +404,13 @@ parse_filter(int c, gnc_t gnc, void *closure, struct filter **filter_return) ...@@ -403,6 +404,13 @@ parse_filter(int c, gnc_t gnc, void *closure, struct filter **filter_return)
goto error; goto error;
if(af == AF_INET && filter->action.src_plen == 96) if(af == AF_INET && filter->action.src_plen == 96)
memset(&filter->action.src_prefix, 0, 16); 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 { } else {
goto error; goto error;
} }
...@@ -846,6 +854,12 @@ parse_config(gnc_t gnc, void *closure) ...@@ -846,6 +854,12 @@ parse_config(gnc_t gnc, void *closure)
if(c < -1) if(c < -1)
return -1; return -1;
add_filter(filter, &redistribute_filters); add_filter(filter, &redistribute_filters);
} else if(strcmp(token, "install") == 0) {
struct filter *filter;
c = parse_filter(c, gnc, closure, &filter);
if(c < -1)
return -1;
add_filter(filter, &install_filters);
} else if(strcmp(token, "interface") == 0) { } else if(strcmp(token, "interface") == 0) {
struct interface_conf *if_conf; struct interface_conf *if_conf;
c = parse_ifconf(c, gnc, closure, &if_conf); c = parse_ifconf(c, gnc, closure, &if_conf);
...@@ -945,6 +959,7 @@ renumber_filters() ...@@ -945,6 +959,7 @@ renumber_filters()
renumber_filter(input_filters); renumber_filter(input_filters);
renumber_filter(output_filters); renumber_filter(output_filters);
renumber_filter(redistribute_filters); renumber_filter(redistribute_filters);
renumber_filter(install_filters);
} }
static int static int
...@@ -1078,6 +1093,20 @@ redistribute_filter(const unsigned char *prefix, unsigned short plen, ...@@ -1078,6 +1093,20 @@ redistribute_filter(const unsigned char *prefix, unsigned short plen,
return res; return res;
} }
int
install_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(install_filters, NULL, prefix, plen,
src_prefix, src_plen, NULL, ifindex, 0, result);
if(res < 0)
res = INFINITY;
return res;
}
int int
finalise_config() finalise_config()
{ {
......
...@@ -24,6 +24,7 @@ struct filter_result { ...@@ -24,6 +24,7 @@ struct filter_result {
unsigned int add_metric; /* allow = 0, deny = INF, metric = <0..INF> */ unsigned int add_metric; /* allow = 0, deny = INF, metric = <0..INF> */
unsigned char *src_prefix; unsigned char *src_prefix;
unsigned char src_plen; unsigned char src_plen;
unsigned int table;
}; };
struct filter { struct filter {
...@@ -61,4 +62,7 @@ int redistribute_filter(const unsigned char *prefix, unsigned short plen, ...@@ -61,4 +62,7 @@ int redistribute_filter(const unsigned char *prefix, unsigned short plen,
const unsigned char *src_prefix, unsigned short src_plen, const unsigned char *src_prefix, unsigned short src_plen,
unsigned int ifindex, int proto, unsigned int ifindex, int proto,
struct filter_result *result); struct filter_result *result);
int install_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); int finalise_config(void);
...@@ -51,6 +51,7 @@ THE SOFTWARE. ...@@ -51,6 +51,7 @@ THE SOFTWARE.
#include "kernel.h" #include "kernel.h"
#include "util.h" #include "util.h"
#include "interface.h" #include "interface.h"
#include "configuration.h"
#ifndef MAX_INTERFACES #ifndef MAX_INTERFACES
#define MAX_INTERFACES 20 #define MAX_INTERFACES 20
...@@ -893,6 +894,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -893,6 +894,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
const unsigned char *newgate, int newifindex, const unsigned char *newgate, int newifindex,
unsigned int newmetric) unsigned int newmetric)
{ {
struct filter_result filter_result = {0};
union { char raw[1024]; struct nlmsghdr nh; } buf; union { char raw[1024]; struct nlmsghdr nh; } buf;
struct rtmsg *rtm; struct rtmsg *rtm;
struct rtattr *rta; struct rtattr *rta;
...@@ -961,7 +963,10 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -961,7 +963,10 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
ipv4 = v4mapped(gate); ipv4 = v4mapped(gate);
if(src_plen == 0) { install_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; table = export_table;
} else if(kernel_disambiguate(ipv4)) { } else if(kernel_disambiguate(ipv4)) {
table = export_table; table = export_table;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment