Commit febf623a authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Implement proper redistribution of routes.

Xroutes are now generated dynamically as needed.
parent 70a28d7c
...@@ -24,6 +24,7 @@ THE SOFTWARE. ...@@ -24,6 +24,7 @@ THE SOFTWARE.
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#include "babel.h" #include "babel.h"
#include "kernel.h" #include "kernel.h"
...@@ -32,72 +33,118 @@ THE SOFTWARE. ...@@ -32,72 +33,118 @@ THE SOFTWARE.
#include "route.h" #include "route.h"
#include "xroute.h" #include "xroute.h"
#include "util.h" #include "util.h"
#include "filter.h"
struct xroute xroutes[MAXXROUTES]; struct xroute xroutes[MAXXROUTES];
int numxroutes = 0; int numxroutes = 0;
struct xroute * struct xroute *
find_exported_xroute(const unsigned char *prefix, unsigned char plen) find_xroute(const unsigned char *prefix, unsigned char plen)
{ {
int i; int i;
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
if(xroutes[i].exported) {
if(xroutes[i].plen == plen && if(xroutes[i].plen == plen &&
memcmp(xroutes[i].prefix, prefix, 16) == 0) memcmp(xroutes[i].prefix, prefix, 16) == 0)
return &xroutes[i]; return &xroutes[i];
} }
}
return NULL; return NULL;
} }
int void
check_xroutes() flush_xroute(struct xroute *xroute)
{ {
int i, j, n, change; int n;
struct kernel_route routes[120];
debugf("\nChecking kernel routes.\n"); n = xroute - xroutes;
assert(n >= 0 && n < numxroutes);
n = -1; if(n != numxroutes - 1)
for(i = 0; i < numxroutes; i++) memcpy(xroutes + n, xroutes + numxroutes - 1, sizeof(struct xroute));
if(xroutes[i].exported < 2) numxroutes--;
n = MAX(n, xroutes[i].plen); VALGRIND_MAKE_MEM_UNDEFINED(xroutes + numxroutes, sizeof(struct xroute));
}
if(n < 0) int
add_xroute(unsigned char prefix[16], unsigned char plen,
unsigned short metric, unsigned int ifindex, int proto)
{
struct xroute *xroute = find_xroute(prefix, plen);
if(xroute) {
if(xroute->metric <= metric)
return 0;
if(xroute->forced)
return 0; return 0;
xroute->metric = metric;
return 1;
}
if(numxroutes >= MAXXROUTES)
return -1;
memcpy(xroutes[numxroutes].prefix, prefix, 16);
xroutes[numxroutes].plen = plen;
xroutes[numxroutes].forced = 0;
xroutes[numxroutes].metric = metric;
xroutes[numxroutes].ifindex = ifindex;
xroutes[numxroutes].proto = proto;
numxroutes++;
return 1;
}
n = kernel_routes(n, routes, 120); int
check_xroutes()
{
int i, j, n, metric, export, change = 0, rc;
struct kernel_route routes[240];
debugf("\nChecking kernel routes.\n");
n = kernel_routes(routes, 240);
if(n < 0) if(n < 0)
return -1; return -1;
change = 0; i = 0;
for(i = 0; i < numxroutes; i++) { while(i < numxroutes) {
int export; if(xroutes[i].forced) {
if(xroutes[i].exported == 2) i++;
continue; continue;
}
export = 0; export = 0;
metric = redistribute_filter(xroutes[i].prefix, xroutes[i].plen,
xroutes[i].ifindex, xroutes[i].proto);
if((metric < INFINITY && metric == xroutes[i].metric) ||
metric == METRIC_INHERIT) {
for(j = 0; j < n; j++) { for(j = 0; j < n; j++) {
if(xroutes[i].plen == routes[j].plen && if(xroutes[i].plen == routes[j].plen &&
memcmp(xroutes[i].prefix, routes[j].prefix, 16) == 0) { memcmp(xroutes[i].prefix, routes[j].prefix, 16) == 0 &&
xroutes[i].ifindex == routes[j].ifindex &&
xroutes[i].proto == routes[j].proto) {
if(metric < INFINITY ||
(metric == METRIC_INHERIT &&
xroutes[i].metric == routes[j].metric)) {
export = 1; export = 1;
break; break;
} }
} }
if(xroutes[i].exported != export) { }
xroutes[i].exported = export; }
if(export) { if(!export) {
struct route *route; flush_xroute(&xroutes[i]);
route = find_installed_route(xroutes[i].prefix, change = 1;
xroutes[i].plen);
if(route)
uninstall_route(route);
} else { } else {
struct route *route; i++;
route = find_best_route(xroutes[i].prefix, xroutes[i].plen); }
if(route)
install_route(route);
} }
send_update(NULL, 1, xroutes[i].prefix, xroutes[i].plen);
for(i = 0; i < n; i++) {
metric = redistribute_filter(routes[i].prefix, routes[i].plen,
routes[i].ifindex, routes[i].proto);
if(metric == METRIC_INHERIT)
metric = routes[i].metric;
if(metric < INFINITY) {
rc = add_xroute(routes[i].prefix, routes[i].plen,
metric, routes[i].ifindex, routes[i].proto);
if(rc)
change = 1; change = 1;
} }
} }
......
...@@ -25,13 +25,14 @@ int check_xroutes(void); ...@@ -25,13 +25,14 @@ int check_xroutes(void);
struct xroute { struct xroute {
unsigned char prefix[16]; unsigned char prefix[16];
unsigned char plen; unsigned char plen;
char exported; char forced;
unsigned short metric; unsigned short metric;
unsigned int ifindex;
int proto;
}; };
extern struct xroute xroutes[MAXXROUTES]; extern struct xroute xroutes[MAXXROUTES];
extern int numxroutes; extern int numxroutes;
struct xroute *find_exported_xroute(const unsigned char *prefix, struct xroute *find_xroute(const unsigned char *prefix, unsigned char plen);
unsigned char plen);
int check_xroutes(void); int check_xroutes(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