Commit 72a62643 authored by Matthieu Boutier's avatar Matthieu Boutier Committed by Juliusz Chroboczek

Move the table selection into rule.c.

parent fd2a93fb
...@@ -34,6 +34,7 @@ THE SOFTWARE. ...@@ -34,6 +34,7 @@ THE SOFTWARE.
#include "route.h" #include "route.h"
#include "source.h" #include "source.h"
#include "neighbour.h" #include "neighbour.h"
#include "rule.h"
struct zone { struct zone {
const unsigned char *dst_prefix; const unsigned char *dst_prefix;
...@@ -211,45 +212,53 @@ is_installed(struct zone *zone) ...@@ -211,45 +212,53 @@ is_installed(struct zone *zone)
static int static int
add_route(const struct zone *zone, const struct babel_route *route) add_route(const struct zone *zone, const struct babel_route *route)
{ {
return kernel_route(ROUTE_ADD, zone->dst_prefix, zone->dst_plen, int table = find_table(zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen);
return kernel_route(ROUTE_ADD, table, zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen, zone->src_prefix, zone->src_plen,
route->nexthop, route->nexthop,
route->neigh->ifp->ifindex, route->neigh->ifp->ifindex,
metric_to_kernel(route_metric(route)), NULL, 0, 0); metric_to_kernel(route_metric(route)), NULL, 0, 0, 0);
} }
static int static int
del_route(const struct zone *zone, const struct babel_route *route) del_route(const struct zone *zone, const struct babel_route *route)
{ {
return kernel_route(ROUTE_FLUSH, zone->dst_prefix, zone->dst_plen, int table = find_table(zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen);
return kernel_route(ROUTE_FLUSH, table, zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen, zone->src_prefix, zone->src_plen,
route->nexthop, route->nexthop,
route->neigh->ifp->ifindex, route->neigh->ifp->ifindex,
metric_to_kernel(route_metric(route)), NULL, 0, 0); metric_to_kernel(route_metric(route)), NULL, 0, 0, 0);
} }
static int static int
chg_route(const struct zone *zone, const struct babel_route *old, chg_route(const struct zone *zone, const struct babel_route *old,
const struct babel_route *new) const struct babel_route *new)
{ {
return kernel_route(ROUTE_MODIFY, zone->dst_prefix, zone->dst_plen, int table = find_table(zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen);
return kernel_route(ROUTE_MODIFY, table, zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen, zone->src_prefix, zone->src_plen,
old->nexthop, old->neigh->ifp->ifindex, old->nexthop, old->neigh->ifp->ifindex,
metric_to_kernel(route_metric(old)), metric_to_kernel(route_metric(old)),
new->nexthop, new->neigh->ifp->ifindex, new->nexthop, new->neigh->ifp->ifindex,
metric_to_kernel(route_metric(new))); metric_to_kernel(route_metric(new)), table);
} }
static int static int
chg_route_metric(const struct zone *zone, const struct babel_route *route, chg_route_metric(const struct zone *zone, const struct babel_route *route,
int old_metric, int new_metric) int old_metric, int new_metric)
{ {
return kernel_route(ROUTE_MODIFY, zone->dst_prefix, zone->dst_plen, int table = find_table(zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen);
return kernel_route(ROUTE_MODIFY, table, zone->dst_prefix, zone->dst_plen,
zone->src_prefix, zone->src_plen, zone->src_prefix, zone->src_plen,
route->nexthop, route->neigh->ifp->ifindex, route->nexthop, route->neigh->ifp->ifindex,
old_metric, old_metric,
route->nexthop, route->neigh->ifp->ifindex, route->nexthop, route->neigh->ifp->ifindex,
new_metric); new_metric, table);
} }
int int
......
...@@ -91,11 +91,12 @@ int kernel_interface_mtu(const char *ifname, int ifindex); ...@@ -91,11 +91,12 @@ int kernel_interface_mtu(const char *ifname, int ifindex);
int kernel_interface_wireless(const char *ifname, int ifindex); int kernel_interface_wireless(const char *ifname, int ifindex);
int kernel_interface_channel(const char *ifname, int ifindex); int kernel_interface_channel(const char *ifname, int ifindex);
int kernel_disambiguate(int v4); int kernel_disambiguate(int v4);
int kernel_route(int operation, const unsigned char *dest, unsigned short plen, int kernel_route(int operation, int table,
const unsigned char *dest, unsigned short plen,
const unsigned char *src, unsigned short src_plen, const unsigned char *src, unsigned short src_plen,
const unsigned char *gate, int ifindex, unsigned int metric, const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex, const unsigned char *newgate, int newifindex,
unsigned int newmetric); unsigned int newmetric, int newtable);
int kernel_dump(int operation, struct kernel_filter *filter); int kernel_dump(int operation, struct kernel_filter *filter);
int kernel_callback(struct kernel_filter *filter); int kernel_callback(struct kernel_filter *filter);
int if_eui64(char *ifname, int ifindex, unsigned char *eui); int if_eui64(char *ifname, int ifindex, unsigned char *eui);
......
...@@ -883,13 +883,13 @@ kernel_has_ipv6_subtrees(void) ...@@ -883,13 +883,13 @@ kernel_has_ipv6_subtrees(void)
} }
int int
kernel_route(int operation, const unsigned char *dest, unsigned short plen, kernel_route(int operation, int table,
const unsigned char *dest, unsigned short plen,
const unsigned char *src, unsigned short src_plen, const unsigned char *src, unsigned short src_plen,
const unsigned char *gate, int ifindex, unsigned int metric, const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex, const unsigned char *newgate, int newifindex,
unsigned int newmetric) unsigned int newmetric, int newtable)
{ {
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;
...@@ -938,14 +938,14 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -938,14 +938,14 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
silently fail the request, causing "stuck" routes. Let's silently fail the request, causing "stuck" routes. Let's
stick with the naive approach, and hope that the window is stick with the naive approach, and hope that the window is
small enough to be negligible. */ small enough to be negligible. */
kernel_route(ROUTE_FLUSH, dest, plen, kernel_route(ROUTE_FLUSH, table, dest, plen,
src, src_plen, src, src_plen,
gate, ifindex, metric, gate, ifindex, metric,
NULL, 0, 0); NULL, 0, 0, 0);
rc = kernel_route(ROUTE_ADD, dest, plen, rc = kernel_route(ROUTE_ADD, newtable, dest, plen,
src, src_plen, src, src_plen,
newgate, newifindex, newmetric, newgate, newifindex, newmetric,
NULL, 0, 0); NULL, 0, 0, 0);
if(rc < 0) { if(rc < 0) {
if(errno == EEXIST) if(errno == EEXIST)
rc = 1; rc = 1;
...@@ -957,20 +957,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -957,20 +957,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
ipv4 = v4mapped(gate); ipv4 = v4mapped(gate);
use_src = (src_plen != 0 && kernel_disambiguate(ipv4));
install_filter(dest, plen, src, src_plen, &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;
use_src = 1;
} else {
table = find_table(src, src_plen);
if(table < 0)
return -1;
}
kdebugf("kernel_route: %s %s from %s " kdebugf("kernel_route: %s %s from %s "
"table %d metric %d dev %d nexthop %s\n", "table %d metric %d dev %d nexthop %s\n",
......
...@@ -404,11 +404,12 @@ kernel_has_ipv6_subtrees(void) ...@@ -404,11 +404,12 @@ kernel_has_ipv6_subtrees(void)
} }
int int
kernel_route(int operation, const unsigned char *dest, unsigned short plen, kernel_route(int operation, int table,
const unsigned char *dest, unsigned short plen,
const unsigned char *src, unsigned short src_plen, const unsigned char *src, unsigned short src_plen,
const unsigned char *gate, int ifindex, unsigned int metric, const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex, const unsigned char *newgate, int newifindex,
unsigned int newmetric) unsigned int newmetric, int newtable)
{ {
struct { struct {
struct rt_msghdr m_rtm; struct rt_msghdr m_rtm;
...@@ -451,14 +452,14 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -451,14 +452,14 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(operation == ROUTE_MODIFY) { if(operation == ROUTE_MODIFY) {
/* Avoid atomic route changes that is buggy on OS X. */ /* Avoid atomic route changes that is buggy on OS X. */
kernel_route(ROUTE_FLUSH, dest, plen, kernel_route(ROUTE_FLUSH, table, dest, plen,
src, src_plen, src, src_plen,
gate, ifindex, metric, gate, ifindex, metric,
NULL, 0, 0); NULL, 0, 0, 0);
return kernel_route(ROUTE_ADD, dest, plen, return kernel_route(ROUTE_ADD, table, dest, plen,
src, src_plen, src, src_plen,
newgate, newifindex, newmetric, newgate, newifindex, newmetric,
NULL, 0, 0); NULL, 0, 0, 0);
} }
......
...@@ -174,16 +174,20 @@ find_table_slot(const unsigned char *src, unsigned short src_plen, int *found) ...@@ -174,16 +174,20 @@ find_table_slot(const unsigned char *src, unsigned short src_plen, int *found)
} }
int int
find_table(const unsigned char *src, unsigned short src_plen) find_table(const unsigned char *dest, unsigned short plen,
const unsigned char *src, unsigned short src_plen)
{ {
struct filter_result filter_result = {0};
struct rule *kr = NULL; struct rule *kr = NULL;
int i, found; int i, found;
if(src_plen == 0 || install_filter(dest, plen, src, src_plen, &filter_result);
(kernel_disambiguate(src_plen >= 96 && v4mapped(src)))) { if(filter_result.table) {
fprintf(stderr, "Find_table called for route handled by kernel " return filter_result.table;
"(this shouldn't happen)."); } else if(src_plen == 0) {
return -1; return export_table;
} else if(kernel_disambiguate(v4mapped(dest))) {
return export_table;
} }
i = find_table_slot(src, src_plen, &found); i = find_table_slot(src, src_plen, &found);
......
...@@ -27,6 +27,7 @@ extern int src_table_prio; /* first prio range */ ...@@ -27,6 +27,7 @@ extern int src_table_prio; /* first prio range */
/* Return the number of the table using src_plen, allocate the table in the /* Return the number of the table using src_plen, allocate the table in the
kernel if necessary. */ kernel if necessary. */
int find_table(const unsigned char *src, unsigned short src_plen); int find_table(const unsigned char *dest, unsigned short plen,
const unsigned char *src, unsigned short src_plen);
void release_tables(void); void release_tables(void);
int check_rules(void); int check_rules(void);
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