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.
#include "route.h"
#include "source.h"
#include "neighbour.h"
#include "rule.h"
struct zone {
const unsigned char *dst_prefix;
......@@ -211,45 +212,53 @@ is_installed(struct zone *zone)
static int
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,
route->nexthop,
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
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,
route->nexthop,
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
chg_route(const struct zone *zone, const struct babel_route *old,
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,
old->nexthop, old->neigh->ifp->ifindex,
metric_to_kernel(route_metric(old)),
new->nexthop, new->neigh->ifp->ifindex,
metric_to_kernel(route_metric(new)));
metric_to_kernel(route_metric(new)), table);
}
static int
chg_route_metric(const struct zone *zone, const struct babel_route *route,
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,
route->nexthop, route->neigh->ifp->ifindex,
old_metric,
route->nexthop, route->neigh->ifp->ifindex,
new_metric);
new_metric, table);
}
int
......
......@@ -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_channel(const char *ifname, int ifindex);
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 *gate, int ifindex, unsigned int metric,
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_callback(struct kernel_filter *filter);
int if_eui64(char *ifname, int ifindex, unsigned char *eui);
......
......@@ -883,13 +883,13 @@ kernel_has_ipv6_subtrees(void)
}
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 *gate, int ifindex, unsigned int metric,
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;
struct rtmsg *rtm;
struct rtattr *rta;
......@@ -938,14 +938,14 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
silently fail the request, causing "stuck" routes. Let's
stick with the naive approach, and hope that the window is
small enough to be negligible. */
kernel_route(ROUTE_FLUSH, dest, plen,
kernel_route(ROUTE_FLUSH, table, dest, plen,
src, src_plen,
gate, ifindex, metric,
NULL, 0, 0);
rc = kernel_route(ROUTE_ADD, dest, plen,
NULL, 0, 0, 0);
rc = kernel_route(ROUTE_ADD, newtable, dest, plen,
src, src_plen,
newgate, newifindex, newmetric,
NULL, 0, 0);
NULL, 0, 0, 0);
if(rc < 0) {
if(errno == EEXIST)
rc = 1;
......@@ -957,20 +957,7 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
ipv4 = v4mapped(gate);
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;
}
use_src = (src_plen != 0 && kernel_disambiguate(ipv4));
kdebugf("kernel_route: %s %s from %s "
"table %d metric %d dev %d nexthop %s\n",
......
......@@ -404,11 +404,12 @@ kernel_has_ipv6_subtrees(void)
}
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 *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric)
unsigned int newmetric, int newtable)
{
struct {
struct rt_msghdr m_rtm;
......@@ -451,14 +452,14 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(operation == ROUTE_MODIFY) {
/* 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,
gate, ifindex, metric,
NULL, 0, 0);
return kernel_route(ROUTE_ADD, dest, plen,
NULL, 0, 0, 0);
return kernel_route(ROUTE_ADD, table, dest, plen,
src, src_plen,
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)
}
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;
int i, found;
if(src_plen == 0 ||
(kernel_disambiguate(src_plen >= 96 && v4mapped(src)))) {
fprintf(stderr, "Find_table called for route handled by kernel "
"(this shouldn't happen).");
return -1;
install_filter(dest, plen, src, src_plen, &filter_result);
if(filter_result.table) {
return filter_result.table;
} else if(src_plen == 0) {
return export_table;
} else if(kernel_disambiguate(v4mapped(dest))) {
return export_table;
}
i = find_table_slot(src, src_plen, &found);
......
......@@ -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
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);
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