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