summaryrefslogtreecommitdiff
path: root/sys/net/rtable.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-06-22 06:32:33 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-06-22 06:32:33 +0000
commit67965e113b32181663309143032281ad16a0943b (patch)
treea82c5a48b42f663f3bb7f5852084b70f90c59ad2 /sys/net/rtable.c
parent6b7119be11c201a22244f663a13af2c7995825ba (diff)
rework art_walk so it will behave in an mpsafe world.
art_walk now explicitly takes the same lock used to serialise change made via rtable_insert and _delete, so it can safely adjust the refcnts on tables while it recurses into them. they need to still exist when returning out of the recursion. it uses srps to access nodes and drops the lock before calling the callback function. this is because some callbacks sleep (eg, copyout in the sysctl code that dumps an rtable to userland), which you shouldnt hold a lock accross. other callbacks attempt to modify the rtable (eg, marking routes as down when then interface theyre on goes down), which tries to take the lock again, which probably wont work in the future. ok jmatthew@ mpi@
Diffstat (limited to 'sys/net/rtable.c')
-rw-r--r--sys/net/rtable.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/net/rtable.c b/sys/net/rtable.c
index 24fce7d9ea4..77bd9517012 100644
--- a/sys/net/rtable.c
+++ b/sys/net/rtable.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtable.c,v 1.47 2016/06/14 04:42:02 jmatthew Exp $ */
+/* $OpenBSD: rtable.c,v 1.48 2016/06/22 06:32:32 dlg Exp $ */
/*
* Copyright (c) 2014-2015 Martin Pieuchot
@@ -853,16 +853,16 @@ struct rtable_walk_cookie {
int
rtable_walk_helper(struct art_node *an, void *xrwc)
{
+ struct srp_ref sr;
struct rtable_walk_cookie *rwc = xrwc;
- struct rtentry *rt, *nrt;
+ struct rtentry *rt;
int error = 0;
- KERNEL_ASSERT_LOCKED();
-
- SRPL_FOREACH_SAFE_LOCKED(rt, &an->an_rtlist, rt_next, nrt) {
+ SRPL_FOREACH(rt, &sr, &an->an_rtlist, rt_next) {
if ((error = (*rwc->rwc_func)(rt, rwc->rwc_arg, rwc->rwc_rid)))
break;
}
+ SRPL_LEAVE(&sr);
return (error);
}