Commit a03c9ce2 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Make route switch atomic.

parent c7440a51
...@@ -157,6 +157,34 @@ uninstall_route(struct route *route) ...@@ -157,6 +157,34 @@ uninstall_route(struct route *route)
route->installed = 0; route->installed = 0;
} }
/* This is equivalent to uninstall_route followed with install_route,
but without the race condition. The destination of both routes
must be the same. */
void
change_route(struct route *old, struct route *new)
{
int rc;
if(!old) {
install_route(new);
return;
}
if(!old->installed)
return;
rc = kernel_route(ROUTE_MODIFY, old->src->prefix, old->src->plen,
old->nexthop->address, old->nexthop->network->ifindex,
metric_to_kernel(old->metric),
new->nexthop->address, new->nexthop->network->ifindex,
metric_to_kernel(new->metric));
if(rc >= 0) {
old->installed = 0;
new->installed = 1;
}
}
void void
change_route_metric(struct route *route, int newmetric) change_route_metric(struct route *route, int newmetric)
{ {
...@@ -403,9 +431,7 @@ consider_route(struct route *route) ...@@ -403,9 +431,7 @@ consider_route(struct route *route)
return; return;
install: install:
if(installed) change_route(installed, route);
uninstall_route(installed);
install_route(route);
if(installed && route->installed) if(installed && route->installed)
send_triggered_update(route, installed->src, installed->metric); send_triggered_update(route, installed->src, installed->metric);
else else
......
...@@ -46,6 +46,7 @@ void flush_neighbour_routes(struct neighbour *neigh); ...@@ -46,6 +46,7 @@ void flush_neighbour_routes(struct neighbour *neigh);
unsigned int metric_to_kernel(int metric); unsigned int metric_to_kernel(int metric);
void install_route(struct route *route); void install_route(struct route *route);
void uninstall_route(struct route *route); void uninstall_route(struct route *route);
void change_route(struct route *old, struct route *new);
void change_route_metric(struct route *route, int newmetric); void change_route_metric(struct route *route, int newmetric);
int route_feasible(struct route *route); int route_feasible(struct route *route);
int update_feasible(const unsigned char *a, int update_feasible(const unsigned char *a,
......
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