diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-07-04 08:11:49 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-07-04 08:11:49 +0000 |
commit | 60182bff1635bc9fff8c90aee5f5b4df2889d4f2 (patch) | |
tree | 9deee6aeb308be73f2b8907ec55c0212f72c1bba /sys/net | |
parent | 506102808d35ed6e7d36139f0f73b21fe0a6c77a (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.c | 6 | ||||
-rw-r--r-- | sys/net/rtable.c | 15 |
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); } |