Commit d8401b34 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Integrate check_addresses into check_xroutes.

Also removes stale local routes.
parent 7f82d0e1
......@@ -457,23 +457,19 @@ main(int argc, char **argv)
changed = 0;
}
if (kernel_link_changed) {
if (kernel_link_changed || kernel_addr_changed) {
check_networks();
kernel_link_changed = 0;
}
if (kernel_addr_changed) {
check_addresses();
kernel_addr_changed = 0;
}
if(kernel_routes_changed || now.tv_sec >= kernel_dump_time) {
if(kernel_routes_changed || kernel_addr_changed ||
now.tv_sec >= kernel_dump_time) {
rc = check_xroutes();
if(rc > 0)
send_self_update(NULL, 1);
else if(rc < 0)
fprintf(stderr, "Warning: couldn't check exported routes.\n");
kernel_routes_changed = 0;
kernel_routes_changed = kernel_addr_changed = 0;
if(kernel_socket >= 0)
kernel_dump_time = now.tv_sec + 200 + random() % 200;
else
......@@ -489,7 +485,6 @@ main(int argc, char **argv)
}
if(now.tv_sec >= expiry_time) {
check_addresses();
check_networks();
expire_routes();
expire_requests();
......
......@@ -22,6 +22,8 @@ THE SOFTWARE.
#define METRIC_INHERIT (INFINITY + 1)
#define PROTO_LOCAL -2
struct filter {
int af;
char *ifname;
......
......@@ -102,40 +102,86 @@ add_xroute(int kind, unsigned char prefix[16], unsigned char plen,
int
check_xroutes()
{
int i, j, n, metric, export, change = 0, rc;
int i, j, metric, export, change = 0, rc;
struct kernel_route routes[240];
struct in6_addr addresses[240];
int numroutes, numaddr;
debugf("\nChecking kernel routes.\n");
n = kernel_routes(routes, 240);
if(n < 0)
return -1;
numaddr = 0;
for(i = 0; i < numnets; i++) {
if(!nets[i].up)
continue;
rc = kernel_addresses(nets[i].ifindex,
addresses + numaddr, 240 - numaddr);
if(rc < 0) {
fprintf(stderr, "Couldn't get addresses for network %s\n",
nets[i].ifname);
continue;
}
numaddr += rc;
if(numaddr >= 240) {
fprintf(stderr, "Too many local routes.\n");
break;
}
}
rc = kernel_routes(routes, 240);
if(rc < 0) {
fprintf(stderr, "Couldn't get kernel routes.\n");
numroutes = 0;
} else {
numroutes = rc;
}
/* Check for any routes that need to be flushed */
i = 0;
while(i < numxroutes) {
if(xroutes[i].kind != XROUTE_REDISTRIBUTED) {
i++;
continue;
}
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++) {
if(xroutes[i].plen == routes[j].plen &&
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;
break;
if(xroutes[i].kind == XROUTE_FORCED) {
export = 1;
} else if(xroutes[i].kind == XROUTE_LOCAL) {
metric = redistribute_filter(xroutes[i].prefix, xroutes[i].plen,
xroutes[i].ifindex, PROTO_LOCAL);
if(metric == METRIC_INHERIT)
metric = 0;
if(metric < INFINITY && metric == xroutes[i].metric) {
for(j = 0; j < numaddr; j++) {
if(xroutes[i].plen == 128 &&
memcmp(xroutes[i].prefix,
addresses[j].s6_addr, 128) == 0) {
if(metric < INFINITY) {
export = 1;
break;
}
}
}
}
} else if(xroutes[i].kind == XROUTE_REDISTRIBUTED) {
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 < numroutes; j++) {
if(xroutes[i].plen == routes[j].plen &&
memcmp(xroutes[i].prefix, routes[j].prefix, 16) == 0 &&
xroutes[i].ifindex == routes[j].ifindex &&
xroutes[i].proto == routes[j].proto) {
if(metric < INFINITY) {
export = 1;
break;
} else if(metric == METRIC_INHERIT &&
xroutes[i].metric == routes[j].metric) {
export = 1;
break;
}
}
}
}
}
if(!export) {
flush_xroute(&xroutes[i]);
change = 1;
......@@ -144,7 +190,21 @@ check_xroutes()
}
}
for(i = 0; i < n; i++) {
/* Add any new routes */
for(i = 0; i < numaddr; i++) {
metric = redistribute_filter(addresses[i].s6_addr, 128, 0, PROTO_LOCAL);
if(metric == METRIC_INHERIT)
metric = 0;
if(metric < INFINITY) {
rc = add_xroute(XROUTE_LOCAL,
addresses[i].s6_addr, 128, 0, 0, PROTO_LOCAL);
if(rc)
change = 1;
}
}
for(i = 0; i < numroutes; i++) {
if(martian_prefix(routes[i].prefix, routes[i].plen))
continue;
metric = redistribute_filter(routes[i].prefix, routes[i].plen,
......@@ -161,27 +221,3 @@ check_xroutes()
}
return change;
}
int
check_addresses()
{
int maxaddr = MAXXROUTES;
struct in6_addr addresses[MAXXROUTES];
int found = 0;
int i;
int rc;
for (i = 0; i < numnets; i++) {
rc = kernel_addresses(nets[i].ifindex, addresses + found, maxaddr);
if (rc < 0)
break;
for (i = 0; i < rc && numxroutes < MAXXROUTES; i++) {
rc = add_xroute(XROUTE_LOCAL,
addresses[i].s6_addr, 128, 0, nets[i].ifindex,
RTPROTO_BABEL_LOCAL);
if (rc < 0)
break;
}
}
return 0;
}
......@@ -21,7 +21,6 @@ THE SOFTWARE.
*/
int check_xroutes(void);
int check_addresses(void);
/* These should come in decreasing order of priority. */
......
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