Commit d3734a10 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Fix retractions with no router-id.

Thanks to Fabian Blaese.
parent f9698a56
...@@ -718,7 +718,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -718,7 +718,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
} }
have_router_id = 1; have_router_id = 1;
} }
if(!have_router_id && message[2] != 0) { if(metric < INFINITY && !have_router_id && message[2] != 0) {
fprintf(stderr, "Received prefix with no router id.\n"); fprintf(stderr, "Received prefix with no router id.\n");
goto fail; goto fail;
} }
...@@ -773,7 +773,8 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -773,7 +773,8 @@ parse_packet(const unsigned char *from, struct interface *ifp,
goto done; goto done;
} }
update_route(router_id, prefix, plen, src_prefix, src_plen, seqno, update_route(have_router_id ? router_id : NULL,
prefix, plen, src_prefix, src_plen, seqno,
metric, interval, neigh, nh, metric, interval, neigh, nh,
channels, channels_len); channels, channels_len);
} else if(type == MESSAGE_REQUEST) { } else if(type == MESSAGE_REQUEST) {
......
...@@ -877,8 +877,15 @@ update_route(const unsigned char *id, ...@@ -877,8 +877,15 @@ update_route(const unsigned char *id,
int add_metric; int add_metric;
int hold_time = MAX((4 * interval) / 100 + interval / 50, 15); int hold_time = MAX((4 * interval) / 100 + interval / 50, 15);
int is_v4; int is_v4;
if(memcmp(id, myid, 8) == 0)
if(!id) {
if(refmetric < INFINITY) {
fprintf(stderr, "Update with no id and finite metric.");
return NULL;
}
} else if(memcmp(id, myid, 8) == 0) {
return NULL; return NULL;
}
if(martian_prefix(prefix, plen) || martian_prefix(src_prefix, src_plen)) { if(martian_prefix(prefix, plen) || martian_prefix(src_prefix, src_plen)) {
fprintf(stderr, "Rejecting martian route to %s from %s through %s.\n", fprintf(stderr, "Rejecting martian route to %s from %s through %s.\n",
...@@ -898,6 +905,19 @@ update_route(const unsigned char *id, ...@@ -898,6 +905,19 @@ update_route(const unsigned char *id,
route = find_route(prefix, plen, src_prefix, src_plen, neigh, nexthop); route = find_route(prefix, plen, src_prefix, src_plen, neigh, nexthop);
if(refmetric >= INFINITY && !route) {
/* Somebody's retracting a route that we've never seen. */
return NULL;
} else if(!id) {
/* Pretend the retraction came from the currently installed source. */
id = route->src->id;
}
if(!id) {
fprintf(stderr, "No id in update_route -- this shouldn't happen.\n");
return NULL;
}
if(route && memcmp(route->src->id, id, 8) == 0) if(route && memcmp(route->src->id, id, 8) == 0)
/* Avoid scanning the source table. */ /* Avoid scanning the source table. */
src = route->src; src = route->src;
...@@ -919,7 +939,7 @@ update_route(const unsigned char *id, ...@@ -919,7 +939,7 @@ update_route(const unsigned char *id,
oldsrc = route->src; oldsrc = route->src;
oldmetric = route_metric(route); oldmetric = route_metric(route);
/* If a successor switches sources, we must accept his update even /* If a successor switches sources, we must accept their update even
if it makes a route unfeasible in order to break any routing loops if it makes a route unfeasible in order to break any routing loops
in a timely manner. If the source remains the same, we ignore in a timely manner. If the source remains the same, we ignore
the update. */ the update. */
......
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