this reorders the code so a functioning art_node is inserted into
the table instead of an empty node.

if we move art to use srps, an insert will make the node available
for lookups immediately. having a functional node in that situation
is useful.

this includes previous diffz so it can apply and work.

ok?

Index: rtable.c
===================================================================
RCS file: /cvs/src/sys/net/rtable.c,v
retrieving revision 1.42
diff -u -p -r1.42 rtable.c
--- rtable.c    18 May 2016 03:46:03 -0000      1.42
+++ rtable.c    1 Jun 2016 05:17:51 -0000
@@ -666,6 +666,7 @@ rtable_insert(unsigned int rtableid, str
        struct art_node                 *an, *prev;
        uint8_t                         *addr;
        int                              plen;
+       unsigned int                     rt_flags;
 
        KERNEL_ASSERT_LOCKED();
 
@@ -704,18 +705,23 @@ rtable_insert(unsigned int rtableid, str
        if (an == NULL)
                return (ENOBUFS);
 
-       SRPL_INIT(&an->an_rtlist);
+       /* prepare for immediate operation if insert succeeds */
+       rt_flags = rt->rt_flags;
+       rt->rt_flags &= ~RTF_MPATH;
+       rt->rt_dest = dst;
+       rt->rt_plen = plen;
+       SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next);
 
        prev = art_insert(ar, an, addr, plen);
-       if (prev == NULL) {
+       if (prev != an) {
+               SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry,
+                   rt_next);
+               rt->rt_flags = rt_flags;
                art_put(an);
-               return (ESRCH);
-       }
 
-       if (prev == an) {
-               rt->rt_flags &= ~RTF_MPATH;
-       } else {
-               art_put(an);
+               if (prev == NULL)
+                       return ESRCH;
+
 #ifndef SMALL_KERNEL
                an = prev;
 
@@ -740,21 +746,16 @@ rtable_insert(unsigned int rtableid, str
                                }
                        }
                }
+
+               SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next);
+
+               /* Put newly inserted entry at the right place. */
+               rtable_mpath_reprio(rtableid, dst, mask, rt->rt_priority, rt);
 #else
                return (EEXIST);
 #endif /* SMALL_KERNEL */
        }
 
-       rt->rt_dest = dst;
-       rt->rt_plen = plen;
-       rtref(rt);
-       SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next);
-
-#ifndef SMALL_KERNEL
-       /* Put newly inserted entry at the right place. */
-       rtable_mpath_reprio(rtableid, dst, mask, rt->rt_priority, rt);
-#endif /* SMALL_KERNEL */
-
        return (0);
 }
 
@@ -813,7 +814,6 @@ rtable_delete(unsigned int rtableid, str
 
        KASSERT(rt->rt_refcnt >= 2);
        SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry, rt_next);
-       rtfree(rt);
 
        art_put(an);
        return (0);
@@ -899,6 +899,7 @@ rtable_mpath_reprio(unsigned int rtablei
 
        KERNEL_ASSERT_LOCKED();
 
+       rtref(rt); /* keep rt alive in between remove and add */
        SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry, rt_next);
        rt->rt_priority = prio;
 
@@ -931,6 +932,7 @@ rtable_mpath_reprio(unsigned int rtablei
        } else {
                SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next);
        }
+       rtfree(rt);
 
        return (0);
 }
Index: art.c
===================================================================
RCS file: /cvs/src/sys/net/art.c,v
retrieving revision 1.14
diff -u -p -r1.14 art.c
--- art.c       13 Apr 2016 08:04:14 -0000      1.14
+++ art.c       1 Jun 2016 05:17:51 -0000
@@ -803,6 +803,7 @@ art_get(struct sockaddr *dst, uint8_t pl
 
        an->an_dst = dst;
        an->an_plen = plen;
+       SRPL_INIT(&an->an_rtlist);
 
        return (an);
 }

Reply via email to