summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2016-07-04 08:11:49 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2016-07-04 08:11:49 +0000
commit60182bff1635bc9fff8c90aee5f5b4df2889d4f2 (patch)
tree9deee6aeb308be73f2b8907ec55c0212f72c1bba /sys/net
parent506102808d35ed6e7d36139f0f73b21fe0a6c77a (diff)
Use the _SAFE_ version of SRPL_FOREACH() in rtable_walk_helper() to
prevent an off-by-one when removing entries from the mpath list. Fix a regression introduced by the refactoring needed to serialize rtable_walk() with create/delete. ok jca@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/art.c6
-rw-r--r--sys/net/rtable.c15
2 files changed, 12 insertions, 9 deletions
diff --git a/sys/net/art.c b/sys/net/art.c
index e809c395c01..bbbf759c40f 100644
--- a/sys/net/art.c
+++ b/sys/net/art.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: art.c,v 1.20 2016/06/22 06:32:32 dlg Exp $ */
+/* $OpenBSD: art.c,v 1.21 2016/07/04 08:11:48 mpi Exp $ */
/*
* Copyright (c) 2015 Martin Pieuchot
@@ -706,11 +706,11 @@ art_walk_apply(struct art_root *ar,
{
int error = 0;
+ KERNEL_ASSERT_LOCKED();
+
if ((an != NULL) && (an != next)) {
/* this assumes an->an_dst is not used by f */
- KERNEL_UNLOCK();
error = (*f)(an, arg);
- KERNEL_LOCK();
}
return (error);
diff --git a/sys/net/rtable.c b/sys/net/rtable.c
index 77bd9517012..9a3298c7c00 100644
--- a/sys/net/rtable.c
+++ b/sys/net/rtable.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtable.c,v 1.48 2016/06/22 06:32:32 dlg Exp $ */
+/* $OpenBSD: rtable.c,v 1.49 2016/07/04 08:11:48 mpi Exp $ */
/*
* Copyright (c) 2014-2015 Martin Pieuchot
@@ -853,16 +853,19 @@ 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;
+ struct rtentry *rt, *nrt;
int error = 0;
- SRPL_FOREACH(rt, &sr, &an->an_rtlist, rt_next) {
- if ((error = (*rwc->rwc_func)(rt, rwc->rwc_arg, rwc->rwc_rid)))
+ KERNEL_ASSERT_LOCKED();
+
+ SRPL_FOREACH_SAFE_LOCKED(rt, &an->an_rtlist, rt_next, nrt) {
+ KERNEL_UNLOCK();
+ error = (*rwc->rwc_func)(rt, rwc->rwc_arg, rwc->rwc_rid);
+ KERNEL_LOCK();
+ if (error)
break;
}
- SRPL_LEAVE(&sr);
return (error);
}