Commit 494d5bd5 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Index xroutes by (dest, nexthop) instead of just nexthop.

This avoids inconsistent routing if a neighbour is ingress filtering a
route.
parent 0a4d495f
...@@ -655,14 +655,15 @@ dump_tables(FILE *out) ...@@ -655,14 +655,15 @@ dump_tables(FILE *out)
route_feasible(&routes[i]) ? " (feasible)" : ""); route_feasible(&routes[i]) ? " (feasible)" : "");
} }
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
fprintf(out, "%s/%d gw %s cost %d metric %d age %d%s\n", fprintf(out, "%s/%d gw %s nexthop %s cost %d metric %d age %d%s\n",
format_address(xroutes[i].prefix), format_address(xroutes[i].prefix),
xroutes[i].plen, xroutes[i].plen,
format_address(xroutes[i].gateway->address), format_address(xroutes[i].gateway->address),
xroutes[i].cost, format_address(xroutes[i].nexthop->address),
xroutes[i].metric, xroutes[i].cost,
(int)(now.tv_sec - xroutes[i].time), xroutes[i].metric,
xroutes[i].installed ? " (installed)" : ""); (int)(now.tv_sec - xroutes[i].time),
xroutes[i].installed ? " (installed)" : "");
} }
fflush(out); fflush(out);
} }
......
...@@ -514,11 +514,14 @@ flushupdates(void) ...@@ -514,11 +514,14 @@ flushupdates(void)
int numpxroutes; int numpxroutes;
numpxroutes = 0; numpxroutes = 0;
for(j = 0; j < numxroutes; j++) { for(j = 0; j < numxroutes; j++) {
if(xroutes[j].gateway == buffered_updates[i]) if(xroutes[j].installed &&
xroutes[j].gateway == buffered_updates[i])
numpxroutes++; numpxroutes++;
} }
start_message(net, 20 + 20 * numpxroutes); start_message(net, 20 + 20 * numpxroutes);
for(j = 0; j < numxroutes; j++) { for(j = 0; j < numxroutes; j++) {
if(!xroutes[i].installed)
continue;
if(xroutes[j].gateway != buffered_updates[i]) if(xroutes[j].gateway != buffered_updates[i])
continue; continue;
/* See comment above */ /* See comment above */
......
...@@ -31,6 +31,7 @@ THE SOFTWARE. ...@@ -31,6 +31,7 @@ THE SOFTWARE.
#include "neighbour.h" #include "neighbour.h"
#include "destination.h" #include "destination.h"
#include "route.h" #include "route.h"
#include "xroute.h"
#include "message.h" #include "message.h"
struct neighbour neighs[MAXNEIGHBOURS]; struct neighbour neighs[MAXNEIGHBOURS];
...@@ -39,6 +40,7 @@ int numneighs = 0; ...@@ -39,6 +40,7 @@ int numneighs = 0;
void void
flush_neighbour(struct neighbour *neigh) flush_neighbour(struct neighbour *neigh)
{ {
flush_neighbour_xroutes(neigh);
flush_neighbour_routes(neigh); flush_neighbour_routes(neigh);
memset(neigh, 0, sizeof(*neigh)); memset(neigh, 0, sizeof(*neigh));
if(neigh == &neighs[numneighs - 1]) { if(neigh == &neighs[numneighs - 1]) {
......
...@@ -159,6 +159,7 @@ install_route(struct route *route) ...@@ -159,6 +159,7 @@ install_route(struct route *route)
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
if(xroutes[i].gateway == route->dest && if(xroutes[i].gateway == route->dest &&
xroutes[i].nexthop == route->nexthop &&
xroutes[i].time >= now.tv_sec - 240) { xroutes[i].time >= now.tv_sec - 240) {
update_xroute_metric(&xroutes[i], xroutes[i].cost); update_xroute_metric(&xroutes[i], xroutes[i].cost);
consider_xroute(&xroutes[i]); consider_xroute(&xroutes[i]);
...@@ -174,7 +175,7 @@ uninstall_route(struct route *route) ...@@ -174,7 +175,7 @@ uninstall_route(struct route *route)
return; return;
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
if(xroutes[i].installed && xroutes[i].gateway == route->dest) if(xroutes[i].installed && xroutes[i].nexthop == route->nexthop)
uninstall_xroute(&xroutes[i]); uninstall_xroute(&xroutes[i]);
} }
...@@ -329,11 +330,11 @@ update_route(const unsigned char *d, int seqno, int refmetric, ...@@ -329,11 +330,11 @@ update_route(const unsigned char *d, int seqno, int refmetric,
change_route_metric(route, metric); change_route_metric(route, metric);
if(seqno_compare(oldseqno, seqno) <= 0) { if(seqno_compare(oldseqno, seqno) <= 0) {
if(seqno_compare(oldseqno, seqno) < 0) if(seqno_compare(oldseqno, seqno) < 0)
retract_xroutes(dest, pxroutes, numpxroutes); retract_xroutes(dest, nexthop, pxroutes, numpxroutes);
for(i = 0; i < numpxroutes; i++) for(i = 0; i < numpxroutes; i++)
update_xroute(pxroutes[i].prefix, update_xroute(pxroutes[i].prefix,
pxroutes[i].plen, pxroutes[i].plen,
dest, dest, nexthop,
pxroutes[i].cost); pxroutes[i].cost);
} }
if(route->installed) if(route->installed)
...@@ -361,7 +362,7 @@ update_route(const unsigned char *d, int seqno, int refmetric, ...@@ -361,7 +362,7 @@ update_route(const unsigned char *d, int seqno, int refmetric,
for(i = 0; i < numpxroutes; i++) for(i = 0; i < numpxroutes; i++)
update_xroute(pxroutes[i].prefix, update_xroute(pxroutes[i].prefix,
pxroutes[i].plen, pxroutes[i].plen,
dest, dest, nexthop,
pxroutes[i].cost); pxroutes[i].cost);
consider_route(route); consider_route(route);
} }
......
...@@ -74,6 +74,7 @@ static struct xroute * ...@@ -74,6 +74,7 @@ static struct xroute *
find_best_xroute(unsigned char *prefix, unsigned short plen) find_best_xroute(unsigned char *prefix, unsigned short plen)
{ {
struct xroute *xroute = NULL; struct xroute *xroute = NULL;
struct route *route;
int i; int i;
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
...@@ -82,8 +83,10 @@ find_best_xroute(unsigned char *prefix, unsigned short plen) ...@@ -82,8 +83,10 @@ find_best_xroute(unsigned char *prefix, unsigned short plen)
if(xroutes[i].plen != plen || if(xroutes[i].plen != plen ||
memcmp(xroutes[i].prefix, prefix, 16) != 0) memcmp(xroutes[i].prefix, prefix, 16) != 0)
continue; continue;
if((!xroute || xroutes[i].metric < xroute->metric) && route = find_installed_route(xroutes[i].gateway);
find_installed_route(xroutes[i].gateway) != NULL) if(route->nexthop != xroutes[i].nexthop)
continue;
if(!xroute || xroutes[i].metric < xroute->metric)
xroute = &xroutes[i]; xroute = &xroutes[i];
} }
return xroute; return xroute;
...@@ -109,7 +112,7 @@ install_xroute(struct xroute *xroute) ...@@ -109,7 +112,7 @@ install_xroute(struct xroute *xroute)
} }
gwroute = find_installed_route(xroute->gateway); gwroute = find_installed_route(xroute->gateway);
if(!gwroute) { if(!gwroute || gwroute->nexthop != xroute->nexthop) {
fprintf(stderr, fprintf(stderr,
"Attempted to install a blackhole xroute " "Attempted to install a blackhole xroute "
"(this shouldn't happen).\n"); "(this shouldn't happen).\n");
...@@ -162,11 +165,14 @@ void ...@@ -162,11 +165,14 @@ void
consider_xroute(struct xroute *xroute) consider_xroute(struct xroute *xroute)
{ {
struct xroute *installed; struct xroute *installed;
struct route *route;
if(xroute->installed) if(xroute->installed)
return; return;
if(find_installed_route(xroute->gateway) == NULL) route = find_installed_route(xroute->gateway);
if(xroute->nexthop != route->nexthop)
return; return;
installed = find_installed_myxroute(xroute->prefix, xroute->plen); installed = find_installed_myxroute(xroute->prefix, xroute->plen);
...@@ -177,6 +183,17 @@ consider_xroute(struct xroute *xroute) ...@@ -177,6 +183,17 @@ consider_xroute(struct xroute *xroute)
} }
} }
void
consider_all_xroutes(struct route *route)
{
int i;
for(i = 0; i < numxroutes; i++) {
if(xroutes[i].nexthop == route->nexthop)
consider_route(route);
}
}
void void
flush_xroute(struct xroute *xroute) flush_xroute(struct xroute *xroute)
{ {
...@@ -210,13 +227,29 @@ flush_xroute(struct xroute *xroute) ...@@ -210,13 +227,29 @@ flush_xroute(struct xroute *xroute)
} }
void void
retract_xroutes(struct destination *gateway, flush_neighbour_xroutes(struct neighbour *neigh)
{
int i;
i = 0;
while(i < numxroutes) {
if(xroutes[i].nexthop == neigh) {
flush_xroute(xroutes + i);
continue;
}
i++;
}
}
void
retract_xroutes(struct destination *gateway, struct neighbour *nexthop,
const struct xroute *except, int numexcept) const struct xroute *except, int numexcept)
{ {
int i, j; int i, j;
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
if(xroutes[i].cost < INFINITY && xroutes[i].gateway == gateway) { if(xroutes[i].cost < INFINITY && xroutes[i].gateway == gateway &&
xroutes[i].nexthop == nexthop) {
for(j = 0; j < numexcept; j++) { for(j = 0; j < numexcept; j++) {
if(memcmp(xroutes[i].prefix, except[j].prefix, 16) == 0 && if(memcmp(xroutes[i].prefix, except[j].prefix, 16) == 0 &&
xroutes[i].plen == except[j].plen) xroutes[i].plen == except[j].plen)
...@@ -230,7 +263,7 @@ retract_xroutes(struct destination *gateway, ...@@ -230,7 +263,7 @@ retract_xroutes(struct destination *gateway,
struct xroute * struct xroute *
update_xroute(const unsigned char *prefix, unsigned short plen, update_xroute(const unsigned char *prefix, unsigned short plen,
struct destination *gateway, int cost) struct destination *gateway, struct neighbour *nexthop, int cost)
{ {
int i; int i;
struct xroute *xroute = NULL; struct xroute *xroute = NULL;
...@@ -248,7 +281,7 @@ update_xroute(const unsigned char *prefix, unsigned short plen, ...@@ -248,7 +281,7 @@ update_xroute(const unsigned char *prefix, unsigned short plen,
for(i = 0; i < numxroutes; i++) { for(i = 0; i < numxroutes; i++) {
xroute = &xroutes[i]; xroute = &xroutes[i];
if(xroute->gateway == gateway && if(xroute->gateway == gateway && xroute->nexthop == nexthop &&
memcmp(xroute->prefix, prefix, 16) == 0 && xroute->plen == plen) { memcmp(xroute->prefix, prefix, 16) == 0 && xroute->plen == plen) {
update_xroute_metric(xroute, cost); update_xroute_metric(xroute, cost);
xroute->time = now.tv_sec; xroute->time = now.tv_sec;
...@@ -267,6 +300,7 @@ update_xroute(const unsigned char *prefix, unsigned short plen, ...@@ -267,6 +300,7 @@ update_xroute(const unsigned char *prefix, unsigned short plen,
memcpy(&xroute->prefix, prefix, 16); memcpy(&xroute->prefix, prefix, 16);
xroute->plen = plen; xroute->plen = plen;
xroute->gateway = gateway; xroute->gateway = gateway;
xroute->nexthop = nexthop;
xroute->cost = cost; xroute->cost = cost;
xroute->metric = xroute->metric =
gwroute ? MIN(gwroute->metric + cost, INFINITY) : INFINITY; gwroute ? MIN(gwroute->metric + cost, INFINITY) : INFINITY;
......
...@@ -26,6 +26,7 @@ struct xroute { ...@@ -26,6 +26,7 @@ struct xroute {
unsigned char prefix[16]; unsigned char prefix[16];
unsigned short plen; unsigned short plen;
struct destination *gateway; struct destination *gateway;
struct neighbour *nexthop;
int cost; int cost;
int metric; int metric;
int time; int time;
...@@ -45,9 +46,11 @@ void install_xroute(struct xroute *xroute); ...@@ -45,9 +46,11 @@ void install_xroute(struct xroute *xroute);
void uninstall_xroute(struct xroute *xroute); void uninstall_xroute(struct xroute *xroute);
void consider_xroute(struct xroute *xroute); void consider_xroute(struct xroute *xroute);
void flush_xroute(struct xroute *xroute); void flush_xroute(struct xroute *xroute);
void retract_xroutes(struct destination *gateway, void flush_neighbour_xroutes(struct neighbour *neigh);
void retract_xroutes(struct destination *gateway, struct neighbour *nexthop,
const struct xroute *except, int numexcept); const struct xroute *except, int numexcept);
struct xroute * update_xroute(const unsigned char *prefix, unsigned short plen, struct xroute * update_xroute(const unsigned char *prefix, unsigned short plen,
struct destination *gateway, int cost); struct destination *gateway,
struct neighbour *nexthop, int cost);
void update_xroute_metric(struct xroute *xroute, int cost); void update_xroute_metric(struct xroute *xroute, int cost);
int check_myxroutes(void); int check_myxroutes(void);
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