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);
}