Commit 21bdbeaf authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Switch to 8-byte router ids.

parent 31f695ae
......@@ -54,7 +54,7 @@ THE SOFTWARE.
struct timeval now;
unsigned char myid[16];
unsigned char myid[8];
int debug = 0;
time_t reboot_time;
......@@ -103,7 +103,7 @@ int
main(int argc, char **argv)
{
struct sockaddr_in6 sin6;
int i, rc, fd, rfd, have_id = 0;
int rc, fd, rfd;
time_t expiry_time, source_expiry_time, kernel_dump_time;
char *config_file = NULL;
void *vrc;
......@@ -335,90 +335,66 @@ main(int argc, char **argv)
gettime(&now);
{
unsigned char dummy[16];
rc = parse_address(*arg, dummy, NULL);
if(rc >= 0) {
fprintf(stderr, "Warning: obsolete router-id given.\n");
SHIFTE();
}
}
rfd = open("/dev/urandom", O_RDONLY);
if(rfd < 0) {
perror("open(random)");
} else {
rc = read(rfd, &seed, sizeof(unsigned int));
if(rc < sizeof(unsigned int)) {
perror("read(random)");
}
}
seed ^= (now.tv_sec ^ now.tv_usec);
srandom(seed);
rc = parse_address(*arg, myid, NULL);
if(rc >= 0) {
have_id = 1;
/* Cannot use SHIFTE -- need to goto fail */
SHIFT();
if(*arg == NULL) {
fprintf(stderr, "No interfaces given.\n");
while(*arg) {
debugf("Adding network %s.\n", *arg);
vrc = add_network(*arg);
if(vrc == NULL)
goto fail;
SHIFT();
}
} else {
struct kernel_route routes[240];
rc = kernel_addresses(NULL, 0, routes, 240);
if(rc < 0) {
perror("kernel_addresses");
}
if(rc > 0) {
/* Search for a global IPv6 address */
for(i = 0; i < rc; i++) {
if(martian_prefix(routes[i].prefix, routes[i].plen))
FOR_ALL_NETS(net) {
/* net->ifindex is not necessarily valid at this point */
int ifindex = if_nametoindex(net->ifname);
if(ifindex > 0) {
unsigned char eui[8];
rc = if_eui64(net->ifname, ifindex, eui);
if(rc < 0)
continue;
if(routes[i].plen == 128 &&
(routes[i].prefix[0] & 0xE0) == 0x20) {
memcpy(myid, routes[i].prefix, 16);
have_id = 1;
break;
}
}
/* Try a global Ipv4 address */
if(!have_id) {
for(i = 0; i < rc; i++) {
if(martian_prefix(routes[i].prefix, routes[i].plen))
continue;
if(routes[i].plen == 128 &&
v4mapped(routes[i].prefix) &&
routes[i].prefix[12] != 10 &&
(routes[i].prefix[12] != 172 ||
(routes[i].prefix[13] & 0xF0) != 16) &&
(routes[i].prefix[12] != 192 ||
routes[i].prefix[13] != 168)) {
memcpy(myid, routes[i].prefix, 16);
have_id = 1;
break;
}
}
}
memcpy(myid, eui, 8);
goto have_id;
}
}
if(!have_id) {
if(rfd < 0) {
fprintf(stderr, "Couldn't find suitable router-id.\n");
goto fail;
}
fprintf(stderr,
"Warning: couldn't find suitable router-id, "
"using random value.\n");
rc = read(rfd, myid, 16);
if(rc < 16) {
"Warning: couldn't find router id -- using random value.\n");
if(rfd >= 0) {
rc = read(rfd, myid, 8);
if(rc < 8) {
perror("read(random)");
goto fail;
} else {
have_id = 1;
}
}
if(rfd < 0) {
memcpy(&seed, myid + 12, 4);
} else {
rc = read(rfd, &seed, sizeof(unsigned int));
if(rc < sizeof(unsigned int)) {
perror("read(random)");
memcpy(&seed, myid + 12, 4);
goto fail;
}
/* Clear group and global bits */
myid[0] &= ~3;
have_id:
if(rfd >= 0)
close(rfd);
rfd = -1;
}
seed ^= (now.tv_sec ^ now.tv_usec);
srandom(seed);
reboot_time = now.tv_sec;
myseqno = (random() & 0xFFFF);
......@@ -445,8 +421,8 @@ main(int argc, char **argv)
buf[rc] = '\0';
rc = sscanf(buf, "%99s %d %ld\n", buf2, &s, &t);
if(rc == 3 && s >= 0 && s <= 0xFFFF) {
unsigned char sid[16];
rc = parse_address(buf2, sid, NULL);
unsigned char sid[8];
rc = parse_eui64(buf2, sid);
if(rc < 0) {
fprintf(stderr, "Couldn't parse babel-state.\n");
} else {
......@@ -454,7 +430,7 @@ main(int argc, char **argv)
debugf("Got %s %d %ld from babel-state.\n",
format_address(sid), s, t);
gettimeofday(&realnow, NULL);
if(memcmp(sid, myid, 16) == 0)
if(memcmp(sid, myid, 8) == 0)
myseqno = seqno_plus(s, 1);
else
fprintf(stderr, "ID mismatch in babel-state.\n");
......@@ -480,14 +456,6 @@ main(int argc, char **argv)
goto fail;
}
while(*arg) {
debugf("Adding network %s.\n", *arg);
vrc = add_network(*arg);
if(vrc == NULL)
goto fail;
SHIFT();
}
#ifndef NO_LOCAL_INTERFACE
if(local_server_port >= 0) {
local_server_socket = tcp_server_socket(local_server_port, 1);
......@@ -788,7 +756,7 @@ main(int argc, char **argv)
char buf[100];
gettimeofday(&realnow, NULL);
rc = snprintf(buf, 100, "%s %d %ld\n",
format_address(myid), (int)myseqno,
format_eui64(myid), (int)myseqno,
(long)realnow.tv_sec);
if(rc < 0 || rc >= 100) {
fprintf(stderr, "write(babel-state): overflow.\n");
......@@ -954,11 +922,10 @@ dump_tables(FILE *out)
fprintf(out, "\n");
fprintf(out, "My id %s seqno %d\n", format_address(myid), myseqno);
fprintf(out, "My id %s seqno %d\n", format_eui64(myid), myseqno);
FOR_ALL_NEIGHBOURS(neigh) {
fprintf(out, "Neighbour %s ", format_address(neigh->id));
fprintf(out, "at %s dev %s reach %04x rxcost %d txcost %d%s.\n",
fprintf(out, "Neighbour %s dev %s reach %04x rxcost %d txcost %d%s.\n",
format_address(neigh->address),
neigh->network->ifname,
neigh->reach,
......@@ -972,18 +939,14 @@ dump_tables(FILE *out)
xroutes[i].metric);
}
for(i = 0; i < numroutes; i++) {
int id =
routes[i].src->plen != 128 ||
memcmp(routes[i].src->prefix, routes[i].src->id, 16) != 0;
const unsigned char *nexthop =
memcmp(routes[i].nexthop, routes[i].neigh->address, 16) == 0 ?
NULL : routes[i].nexthop;
fprintf(out, "%s metric %d refmetric %d %s%s seqno %d age %d "
fprintf(out, "%s metric %d refmetric %d id %s seqno %d age %d "
"via %s neigh %s%s%s%s\n",
format_prefix(routes[i].src->prefix, routes[i].src->plen),
routes[i].metric, routes[i].refmetric,
id ? "id " : "",
id ? format_address(routes[i].src->id) : "",
format_eui64(routes[i].src->id),
(int)routes[i].seqno,
(int)(now.tv_sec - routes[i].time),
routes[i].neigh->network->ifname,
......
......@@ -65,7 +65,7 @@ extern int link_detect;
extern int all_wireless;
extern int local_socket;
extern unsigned char myid[16];
extern unsigned char myid[8];
extern const unsigned char zeroes[16], ones[16];
......
......@@ -237,7 +237,7 @@ parse_filter(gnc_t gnc, void *closure)
filter->neigh = neigh;
} else if(strcmp(token, "id") == 0) {
unsigned char *id;
c = getip(c, &id, NULL, gnc, closure);
c = getid(c, &id, gnc, closure);
if(c < -1)
goto error;
filter->id = id;
......@@ -424,7 +424,7 @@ filter_match(struct filter *f, const unsigned char *id,
}
}
if(f->id) {
if(!id || memcmp(f->id, id, 16) != 0)
if(!id || memcmp(f->id, id, 8) != 0)
return 0;
}
if(f->prefix) {
......
......@@ -97,7 +97,7 @@ local_notify_self()
return;
rc = snprintf(buf, 512, "add self alamakota id %s\n",
format_address(myid));
format_eui64(myid));
if(rc < 0 || rc >= 512)
goto fail;
......@@ -133,13 +133,12 @@ local_notify_neighbour(struct neighbour *neigh, int kind)
return;
rc = snprintf(buf, 512,
"%s neighbour %lx id %s address %s "
"%s neighbour %lx address %s "
"if %s reach %04x rxcost %d txcost %d cost %d\n",
local_kind(kind),
/* Neighbours never move aroundin memory , so we can use the
/* Neighbours never move around in memory , so we can use the
address as a unique identifier. */
(unsigned long int)neigh,
format_address(neigh->id),
format_address(neigh->address),
neigh->network->ifname,
neigh->reach,
......@@ -199,18 +198,17 @@ local_notify_route(struct route *route, int kind)
rc = snprintf(buf, 512,
"%s route %s-%s-%lx prefix %s installed %s "
"id %s metric %d refmetric %d via %s if %s neigh %s\n",
"id %s metric %d refmetric %d via %s if %s\n",
local_kind(kind),
format_prefix(route->src->prefix, route->src->plen),
format_address(route->src->id),
format_eui64(route->src->id),
(unsigned long)route->neigh,
format_prefix(route->src->prefix, route->src->plen),
route->installed ? "yes" : "no",
format_address(route->src->id),
format_eui64(route->src->id),
route->metric, route->refmetric,
format_address(route->neigh->address),
route->neigh->network->ifname,
format_address(route->neigh->id));
route->neigh->network->ifname);
if(rc < 0 || rc >= 512)
goto fail;
......
......@@ -80,7 +80,7 @@ find_request(const unsigned char *prefix, unsigned char plen,
int
record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash,
unsigned short seqno, const unsigned char *id,
struct network *network, int delay)
{
struct resend *resend;
......@@ -103,11 +103,14 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
resend->delay = delay;
resend->time = now;
resend->max = kind == RESEND_REQUEST ? 128 : UPDATE_MAX;
if(resend->router_hash == router_hash &&
if(id && memcmp(resend->id, id, 8) == 0 &&
seqno_compare(resend->seqno, seqno) > 0) {
return 0;
}
resend->router_hash = router_hash;
if(id)
memcpy(resend->id, id, 8);
else
memset(resend->id, 0, 8);
resend->seqno = seqno;
if(resend->network != network)
resend->network = NULL;
......@@ -121,7 +124,10 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
memcpy(resend->prefix, prefix, 16);
resend->plen = plen;
resend->seqno = seqno;
resend->router_hash = router_hash;
if(id)
memcpy(resend->id, id, 8);
else
memset(resend->id, 0, 8);
resend->network = network;
resend->time = now;
resend->next = to_resend;
......@@ -149,7 +155,7 @@ resend_expired(struct resend *resend)
int
unsatisfied_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash)
unsigned short seqno, const unsigned char *id)
{
struct resend *request;
......@@ -157,7 +163,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen,
if(request == NULL || resend_expired(request))
return 0;
if(request->router_hash != router_hash ||
if(memcmp(request->id, id, 8) != 0 ||
seqno_compare(request->seqno, seqno) <= 0)
return 1;
......@@ -168,7 +174,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen,
int
request_redundant(struct network *net,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash)
unsigned short seqno, const unsigned char *id)
{
struct resend *request;
......@@ -176,7 +182,7 @@ request_redundant(struct network *net,
if(request == NULL || resend_expired(request))
return 0;
if(request->router_hash == router_hash &&
if(memcmp(request->id, id, 8) == 0 &&
seqno_compare(request->seqno, seqno) > 0)
return 0;
......@@ -197,7 +203,7 @@ request_redundant(struct network *net,
int
satisfy_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash,
unsigned short seqno, const unsigned char *id,
struct network *network)
{
struct resend *request, *previous;
......@@ -209,7 +215,7 @@ satisfy_request(const unsigned char *prefix, unsigned char plen,
if(network != NULL && request->network != network)
return 0;
if(request->router_hash != router_hash ||
if(memcmp(request->id, id, 8) != 0 ||
seqno_compare(request->seqno, seqno) <= 0) {
/* We cannot remove the request, as we may be walking the list right
now. Mark it as expired, so that expire_resend will remove it. */
......@@ -282,9 +288,9 @@ do_resend()
if(timeval_compare(&now, &timeout) >= 0) {
switch(resend->kind) {
case RESEND_REQUEST:
send_request(resend->network,
resend->prefix, resend->plen, 127,
resend->seqno, resend->router_hash);
send_multihop_request(resend->network,
resend->prefix, resend->plen,
resend->seqno, resend->id, 127);
break;
case RESEND_UPDATE:
send_update(resend->network, 1,
......
......@@ -34,7 +34,7 @@ struct resend {
unsigned char prefix[16];
unsigned char plen;
unsigned short seqno;
unsigned short router_hash;
unsigned char id[8];
struct network *network;
struct resend *next;
};
......@@ -45,15 +45,15 @@ struct resend *find_request(const unsigned char *prefix, unsigned char plen,
struct resend **previous_return);
void flush_resends(struct neighbour *neigh);
int record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash,
unsigned short seqno, const unsigned char *id,
struct network *net, int delay);
int unsatisfied_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash);
unsigned short seqno, const unsigned char *id);
int request_redundant(struct network *net,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash);
unsigned short seqno, const unsigned char *id);
int satisfy_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short router_hash,
unsigned short seqno, const unsigned char *id,
struct network *net);
void expire_resend(void);
......
......@@ -347,7 +347,8 @@ update_route(const unsigned char *a, const unsigned char *p, unsigned char plen,
return NULL;
}
add_metric = input_filter(a, p, plen, neigh->id, neigh->network->ifindex);
add_metric = input_filter(a, p, plen,
neigh->address, neigh->network->ifindex);
if(add_metric >= INFINITY)
return NULL;
......@@ -460,7 +461,7 @@ send_unfeasible_request(struct neighbour *neigh, int force,
send_request_resend(neigh, prefix, plen,
src->metric >= INFINITY ?
src->seqno : seqno_plus(src->seqno, 1),
hash_id(src->id));
src->id);
}
}
......@@ -539,7 +540,7 @@ send_triggered_update(struct route *route, struct source *oldsrc,
/* Make sure that requests are satisfied speedily */
if(urgent < 1) {
if(unsatisfied_request(route->src->prefix, route->src->plen,
route->seqno, hash_id(route->src->id)))
route->seqno, route->src->id))
urgent = 1;
}
......@@ -558,10 +559,9 @@ send_triggered_update(struct route *route, struct source *oldsrc,
route->src->metric >= INFINITY ?
route->src->seqno :
seqno_plus(route->src->seqno, 1),
hash_id(route->src->id));
route->src->id);
} else if(newmetric >= oldmetric + 288) {
send_request(NULL, route->src->prefix, route->src->plen,
0, 0, 0);
send_request(NULL, route->src->prefix, route->src->plen);
}
}
}
......@@ -604,7 +604,7 @@ route_lost(struct source *src, unsigned oldmetric)
send_request_resend(NULL, src->prefix, src->plen,
src->metric >= INFINITY ?
src->seqno : seqno_plus(src->seqno, 1),
hash_id(src->id));
src->id);
}
}
......@@ -630,8 +630,7 @@ expire_routes(void)
if(route->installed && route->refmetric < INFINITY) {
if(route->time < now.tv_sec - MAX(10, route_timeout_delay * 7 / 8))
send_unicast_request(route->neigh,
route->src->prefix, route->src->plen,
0, 0, 0);
route->src->prefix, route->src->plen);
}
i++;
}
......
......@@ -41,9 +41,9 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
for(src = srcs; src; src = src->next) {
/* This should really be a hash table. For now, check the
last byte first. */
if(src->id[15] != id[15])
if(src->id[7] != id[7])
continue;
if(memcmp(src->id, id, 16) != 0)
if(memcmp(src->id, id, 8) != 0)
continue;
if(source_match(src, p, plen))
return src;
......@@ -58,7 +58,7 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
return NULL;
}
memcpy(src->id, id, 16);
memcpy(src->id, id, 8);
memcpy(src->prefix, p, 16);
src->plen = plen;
src->seqno = seqno;
......
......@@ -24,7 +24,7 @@ THE SOFTWARE.
struct source {
struct source *next;
unsigned char id[16];
unsigned char id[8];
unsigned char prefix[16];
unsigned char plen;
unsigned short seqno;
......
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