summaryrefslogtreecommitdiffstats
path: root/sys/netinet/if_ether.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2003-10-30 23:02:51 +0000
committersam <sam@FreeBSD.org>2003-10-30 23:02:51 +0000
commit9183d53dd706fc6cf2da442eac0d791630796da2 (patch)
tree86b489ad92452a54684a5299e07cbdce8229465b /sys/netinet/if_ether.c
parent778c2eee4276d3b48a83b3d80320a61f39ea8d83 (diff)
downloadFreeBSD-src-9183d53dd706fc6cf2da442eac0d791630796da2.zip
FreeBSD-src-9183d53dd706fc6cf2da442eac0d791630796da2.tar.gz
Overhaul routing table entry cleanup by introducing a new rtexpunge
routine that takes a locked routing table reference and removes all references to the entry in the various data structures. This eliminates instances of recursive locking and also closes races where the lock on the entry had to be dropped prior to calling rtrequest(RTM_DELETE). This also cleans up confusion where the caller held a reference to an entry that might have been reclaimed (and in some cases used that reference). Supported by: FreeBSD Foundation
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r--sys/netinet/if_ether.c11
1 files changed, 3 insertions, 8 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 4cc1d4e..d5916ba 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -949,14 +949,9 @@ arplookup(addr, create, proxy)
* arplookup() is creating the route, then purge
* it from the routing table as it is probably bogus.
*/
- RT_UNLOCK(rt);
- if (rt->rt_refcnt == 1 && ISDYNCLONE(rt)) {
- rtrequest(RTM_DELETE,
- (struct sockaddr *)rt_key(rt),
- rt->rt_gateway, rt_mask(rt),
- rt->rt_flags, 0);
- }
- RTFREE(rt);
+ if (rt->rt_refcnt == 1 && ISDYNCLONE(rt))
+ rtexpunge(rt);
+ RTFREE_LOCKED(rt);
return (0);
#undef ISDYNCLONE
} else {
OpenPOWER on IntegriCloud