Use the _SAFE_ version of SRPL_FOREACH() in rtable_walk_helper() to
authormpi <mpi@openbsd.org>
Mon, 4 Jul 2016 08:11:48 +0000 (08:11 +0000)
committermpi <mpi@openbsd.org>
Mon, 4 Jul 2016 08:11:48 +0000 (08:11 +0000)
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@

sys/net/art.c
sys/net/rtable.c

index e809c39..bbbf759 100644 (file)
@@ -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);
index 77bd951..9a3298c 100644 (file)
@@ -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);
 }