Commit dcd49dce authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Don't attempt atomic route changes under Linux.

The netlink API doesn't natively support atomic route changes.  We used
to attempt to install the new route before removing the old route, but that
would fail in mysterious ways on non-multipath kernels, leading to "stuck"
routes.  Avoid the pain, just take the native approach.
parent 8d4d2c9e
......@@ -881,43 +881,27 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
ipv4 = v4mapped(gate);
if(operation == ROUTE_MODIFY) {
int added;
if(newmetric == metric && memcmp(newgate, gate, 16) == 0 &&
newifindex == ifindex)
return 0;
/* It is better to add the new route before removing the old
one, to avoid losing packets. However, if the old and new
priorities are equal, this only works if the kernel supports
ECMP. So we first try the "right" order, and fall back on
the "wrong" order if it fails with EEXIST. */
rc = kernel_route(ROUTE_ADD, dest, plen,
newgate, newifindex, newmetric,
NULL, 0, 0);
if(rc < 0) {
if(errno != EEXIST)
return rc;
added = 0;
} else {
added = 1;
}
/* It would be better to add the new route before removing the
old one, to avoid losing packets. However, this causes
problems with non-multipath kernels, which sometimes
silently fail the request, causing "stuck" routes. Let's
stick with the naive approach, and hope that the window is
small enough to be negligible. */
kernel_route(ROUTE_FLUSH, dest, plen,
gate, ifindex, metric,
NULL, 0, 0);
if(!added) {
rc = kernel_route(ROUTE_ADD, dest, plen,
newgate, newifindex, newmetric,
NULL, 0, 0);
if(rc < 0) {
if(errno == EEXIST)
rc = 1;
/* In principle, we should try to re-install the flushed
route on failure to preserve. However, this should
hopefully not matter much in practice. */
/* Should we try to re-install the flushed route on failure?
Error handling is hard. */
}
}
return rc;
}
......
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