Commit 9d84a093 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Implement -A.

parent 752dc5cb
...@@ -171,6 +171,11 @@ main(int argc, char **argv) ...@@ -171,6 +171,11 @@ main(int argc, char **argv)
if(kernel_metric < 0 || kernel_metric > 0xFFFF) if(kernel_metric < 0 || kernel_metric > 0xFFFF)
goto usage; goto usage;
break; break;
case 'A':
allow_duplicates = atoi(optarg);
if(allow_duplicates < 0 || allow_duplicates > 0xFFFF)
goto usage;
break;
case 'P': case 'P':
parasitic = 1; parasitic = 1;
break; break;
...@@ -231,7 +236,6 @@ main(int argc, char **argv) ...@@ -231,7 +236,6 @@ main(int argc, char **argv)
} }
} }
if(!config_file) { if(!config_file) {
if(access("/etc/babeld.conf", F_OK) >= 0) if(access("/etc/babeld.conf", F_OK) >= 0)
config_file = "/etc/babeld.conf"; config_file = "/etc/babeld.conf";
...@@ -258,6 +262,12 @@ main(int argc, char **argv) ...@@ -258,6 +262,12 @@ main(int argc, char **argv)
wired_hello_interval = 20000; wired_hello_interval = 20000;
wired_hello_interval = MAX(wired_hello_interval, 5); wired_hello_interval = MAX(wired_hello_interval, 5);
if(parasitic && allow_duplicates >= 0) {
/* Too difficult to get right. */
fprintf(stderr, "Sorry, -P and -A are incompatible.\n");
exit(1);
}
if(do_daemonise) { if(do_daemonise) {
if(logfile == NULL) if(logfile == NULL)
logfile = "/var/log/babeld.log"; logfile = "/var/log/babeld.log";
...@@ -776,7 +786,7 @@ main(int argc, char **argv) ...@@ -776,7 +786,7 @@ main(int argc, char **argv)
" " " "
"[-h hello] [-H wired_hello] [-i idle_hello]\n" "[-h hello] [-H wired_hello] [-i idle_hello]\n"
" " " "
"[-k metric] [-s] [-P] [-l] [-w] [-d level] [-g port]\n" "[-k metric] [-A metric] [-s] [-P] [-l] [-w] [-d level] [-g port]\n"
" " " "
"[-t table] [-T table] [-c file] [-C statement]\n" "[-t table] [-T table] [-c file] [-C statement]\n"
" " " "
......
...@@ -878,16 +878,15 @@ flushupdates(struct network *net) ...@@ -878,16 +878,15 @@ flushupdates(struct network *net)
} }
xroute = find_xroute(b[i].prefix, b[i].plen); xroute = find_xroute(b[i].prefix, b[i].plen);
if(xroute) { route = find_installed_route(b[i].prefix, b[i].plen);
if(xroute && (!route || xroute->metric <= kernel_metric)) {
really_send_update(net, myid, really_send_update(net, myid,
xroute->prefix, xroute->plen, xroute->prefix, xroute->plen,
myseqno, xroute->metric); myseqno, xroute->metric);
last_prefix = xroute->prefix; last_prefix = xroute->prefix;
last_plen = xroute->plen; last_plen = xroute->plen;
continue; } else if(route) {
}
route = find_installed_route(b[i].prefix, b[i].plen);
if(route) {
seqno = route->seqno; seqno = route->seqno;
metric = route->metric; metric = route->metric;
if(metric < INFINITY) if(metric < INFINITY)
...@@ -903,13 +902,12 @@ flushupdates(struct network *net) ...@@ -903,13 +902,12 @@ flushupdates(struct network *net)
update_source(route->src, seqno, metric); update_source(route->src, seqno, metric);
last_prefix = route->src->prefix; last_prefix = route->src->prefix;
last_plen = route->src->plen; last_plen = route->src->plen;
continue; } else {
/* There's no route for this prefix. This can happen shortly
after an xroute has been retracted, so send a retraction. */
really_send_update(net, myid, b[i].prefix, b[i].plen,
myseqno, INFINITY);
} }
/* If we reach this point, there's no route for this prefix.
This can happen after an xroute has been retracted, so send
a retraction. */
really_send_update(net, myid, b[i].prefix, b[i].plen,
myseqno, INFINITY);
} }
schedule_flush_now(net); schedule_flush_now(net);
done: done:
...@@ -1348,7 +1346,9 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, ...@@ -1348,7 +1346,9 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
struct neighbour *successor = NULL; struct neighbour *successor = NULL;
xroute = find_xroute(prefix, plen); xroute = find_xroute(prefix, plen);
if(xroute) { route = find_installed_route(prefix, plen);
if(xroute && (!route || xroute->metric <= kernel_metric)) {
if(hop_count > 0 && memcmp(id, myid, 8) == 0) { if(hop_count > 0 && memcmp(id, myid, 8) == 0) {
if(seqno_compare(seqno, myseqno) > 0) { if(seqno_compare(seqno, myseqno) > 0) {
if(seqno_minus(seqno, myseqno) > 100) { if(seqno_minus(seqno, myseqno) > 100) {
...@@ -1362,7 +1362,6 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix, ...@@ -1362,7 +1362,6 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
return; return;
} }
route = find_installed_route(prefix, plen);
if(route && if(route &&
(memcmp(id, route->src->id, 8) != 0 || (memcmp(id, route->src->id, 8) != 0 ||
seqno_compare(seqno, route->seqno) <= 0)) { seqno_compare(seqno, route->seqno) <= 0)) {
......
...@@ -42,6 +42,7 @@ THE SOFTWARE. ...@@ -42,6 +42,7 @@ THE SOFTWARE.
struct route *routes = NULL; struct route *routes = NULL;
int numroutes = 0, maxroutes = 0; int numroutes = 0, maxroutes = 0;
int kernel_metric = 0; int kernel_metric = 0;
int allow_duplicates = -1;
struct route * struct route *
find_route(const unsigned char *prefix, unsigned char plen, find_route(const unsigned char *prefix, unsigned char plen,
...@@ -512,6 +513,7 @@ void ...@@ -512,6 +513,7 @@ void
consider_route(struct route *route) consider_route(struct route *route)
{ {
struct route *installed; struct route *installed;
struct xroute *xroute;
if(route->installed) if(route->installed)
return; return;
...@@ -519,8 +521,9 @@ consider_route(struct route *route) ...@@ -519,8 +521,9 @@ consider_route(struct route *route)
if(!route_feasible(route)) if(!route_feasible(route))
return; return;
if(find_xroute(route->src->prefix, route->src->plen)) xroute = find_xroute(route->src->prefix, route->src->plen);
return; if(xroute && (allow_duplicates < 0 || xroute->metric >= allow_duplicates))
return;
installed = find_installed_route(route->src->prefix, route->src->plen); installed = find_installed_route(route->src->prefix, route->src->plen);
......
...@@ -34,7 +34,7 @@ struct route { ...@@ -34,7 +34,7 @@ struct route {
extern struct route *routes; extern struct route *routes;
extern int numroutes, maxroutes; extern int numroutes, maxroutes;
extern int kernel_metric; extern int kernel_metric, allow_duplicates;
struct route *find_route(const unsigned char *prefix, unsigned char plen, struct route *find_route(const unsigned char *prefix, unsigned char plen,
struct neighbour *neigh, const unsigned char *nexthop); struct neighbour *neigh, const unsigned char *nexthop);
......
...@@ -208,8 +208,11 @@ check_xroutes(int send_updates) ...@@ -208,8 +208,11 @@ check_xroutes(int send_updates)
if(rc) { if(rc) {
struct route *route; struct route *route;
route = find_installed_route(routes[i].prefix, routes[i].plen); route = find_installed_route(routes[i].prefix, routes[i].plen);
if(route) if(route) {
uninstall_route(route); if(allow_duplicates < 0 ||
routes[i].metric < allow_duplicates)
uninstall_route(route);
}
change = 1; change = 1;
if(send_updates) if(send_updates)
send_update(NULL, 0, routes[i].prefix, routes[i].plen); send_update(NULL, 0, routes[i].prefix, routes[i].plen);
......
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