diff options
author | wollman <wollman@FreeBSD.org> | 1995-10-16 19:09:40 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1995-10-16 19:09:40 +0000 |
commit | e34bd6ff015f6bd2cfcce2d517f878cdb61a6ff0 (patch) | |
tree | bf99b793dfb9af98d113f016744adf44e6ed5bb6 /sys/net/route.c | |
parent | 770f16a538c07c7169c28674120d08bf6084a54d (diff) | |
download | FreeBSD-src-e34bd6ff015f6bd2cfcce2d517f878cdb61a6ff0.zip FreeBSD-src-e34bd6ff015f6bd2cfcce2d517f878cdb61a6ff0.tar.gz |
When adding a route fails because there is already a route with the same
(mask,value) in the tree, don't immediately return EEXIST. Instead, check
to see if the pre-existing route was generated by protcol-cloning. If so,
then it is OK to simply blow away the old route and re-attempt the insertion.
If not, then fall back to the same error code as before.
Diffstat (limited to 'sys/net/route.c')
-rw-r--r-- | sys/net/route.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index 4f5fdf7..e5bae41 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)route.c 8.2 (Berkeley) 11/15/93 - * $Id: route.c,v 1.24 1995/07/10 15:22:37 wollman Exp $ + * $Id: route.c,v 1.25 1995/07/29 11:41:02 bde Exp $ */ #include <sys/param.h> @@ -465,6 +465,28 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask, rnh, rt->rt_nodes); if (rn == 0) { + struct rtentry *rt2; + /* + * Uh-oh, we already have one of these in the tree. + * We do a special hack: if the route that's already + * there was generated by the protocol-cloning + * mechanism, then we just blow it away and retry + * the insertion of the new one. + */ + rt2 = rtalloc1(dst, 0, RTF_PRCLONING); + if (rt2 && rt2->rt_parent) { + rtrequest(RTM_DELETE, + (struct sockaddr *)rt_key(rt2), + rt2->rt_gateway, + rt_mask(rt2), rt2->rt_flags, 0); + RTFREE(rt2); + rn = rnh->rnh_addaddr((caddr_t)ndst, + (caddr_t)netmask, + rnh, rt->rt_nodes); + } + } + + if (rn == 0) { if (rt->rt_gwroute) rtfree(rt->rt_gwroute); if (rt->rt_ifa) { |