Commit 3b4b972e authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Fix handling of retractions with no next-hop again.

RFC 8966 Section 3.2.6 says that the route table is indexed by
triples of the form (prefix, plen, neigh).  Our indexing used to
be incorrect, we'd sometimes include the next hop address, which
made it impossible to interpret retractions with no next hop.
parent b29cb705
...@@ -728,9 +728,13 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -728,9 +728,13 @@ parse_packet(const unsigned char *from, struct interface *ifp,
format_prefix(prefix, plen), format_prefix(prefix, plen),
format_address(from), ifp->name); format_address(from), ifp->name);
if(message[2] == 1) { if(message[2] == 1) {
if(!have_v4_nh) if(have_v4_nh) {
goto fail; nh = v4_nh;
nh = v4_nh; } else {
if(metric < INFINITY)
goto fail;
nh = NULL;
}
} else if(have_v6_nh) { } else if(have_v6_nh) {
nh = v6_nh; nh = v6_nh;
} else { } else {
......
...@@ -130,7 +130,7 @@ find_route_slot(const unsigned char *prefix, unsigned char plen, ...@@ -130,7 +130,7 @@ find_route_slot(const unsigned char *prefix, unsigned char plen,
struct babel_route * struct babel_route *
find_route(const unsigned char *prefix, unsigned char plen, find_route(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen, const unsigned char *src_prefix, unsigned char src_plen,
struct neighbour *neigh, const unsigned char *nexthop) struct neighbour *neigh)
{ {
struct babel_route *route; struct babel_route *route;
int i = find_route_slot(prefix, plen, src_prefix, src_plen, NULL); int i = find_route_slot(prefix, plen, src_prefix, src_plen, NULL);
...@@ -141,7 +141,7 @@ find_route(const unsigned char *prefix, unsigned char plen, ...@@ -141,7 +141,7 @@ find_route(const unsigned char *prefix, unsigned char plen,
route = routes[i]; route = routes[i];
while(route) { while(route) {
if(route->neigh == neigh && memcmp(route->nexthop, nexthop, 16) == 0) if(route->neigh == neigh)
return route; return route;
route = route->next; route = route->next;
} }
...@@ -885,7 +885,8 @@ update_route(const unsigned char *id, ...@@ -885,7 +885,8 @@ update_route(const unsigned char *id,
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",
format_prefix(prefix, plen), format_prefix(prefix, plen),
format_prefix(src_prefix, src_plen), format_address(nexthop)); format_prefix(src_prefix, src_plen),
nexthop ? format_address(nexthop) : "(unknown)");
return NULL; return NULL;
} }
...@@ -898,7 +899,7 @@ update_route(const unsigned char *id, ...@@ -898,7 +899,7 @@ update_route(const unsigned char *id,
if(add_metric >= INFINITY) if(add_metric >= INFINITY)
return NULL; return NULL;
route = find_route(prefix, plen, src_prefix, src_plen, neigh, nexthop); route = find_route(prefix, plen, src_prefix, src_plen, neigh);
if(refmetric >= INFINITY && !route) { if(refmetric >= INFINITY && !route) {
/* Somebody's retracting a route that we've never seen. */ /* Somebody's retracting a route that we've never seen. */
...@@ -996,6 +997,12 @@ update_route(const unsigned char *id, ...@@ -996,6 +997,12 @@ update_route(const unsigned char *id,
if(refmetric >= INFINITY) if(refmetric >= INFINITY)
/* Somebody's retracting a route we never saw. */ /* Somebody's retracting a route we never saw. */
return NULL; return NULL;
if(nexthop == NULL) {
fprintf(stderr,
"No nexthop in update_route, this shouldn't happen.\n");
return NULL;
}
if(!feasible) { if(!feasible) {
send_unfeasible_request(neigh, 0, seqno, metric, src); send_unfeasible_request(neigh, 0, seqno, metric, src);
} }
......
...@@ -69,7 +69,7 @@ route_metric_noninterfering(const struct babel_route *route) ...@@ -69,7 +69,7 @@ route_metric_noninterfering(const struct babel_route *route)
struct babel_route *find_route(const unsigned char *prefix, unsigned char plen, struct babel_route *find_route(const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen, const unsigned char *src_prefix, unsigned char src_plen,
struct neighbour *neigh, const unsigned char *nexthop); struct neighbour *neigh);
struct babel_route *find_installed_route(const unsigned char *prefix, struct babel_route *find_installed_route(const unsigned char *prefix,
unsigned char plen, const unsigned char *src_prefix, unsigned char plen, const unsigned char *src_prefix,
unsigned char src_plen); unsigned char src_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