On 20/04/20(Mon) 14:27, Julian Brost wrote:
> On 2020-04-20 12:14, Martin Pieuchot wrote:
> >> login: panic: kernel diagnostic assertion "!ISSET(rt->rt_flags,
> >> RTF_LOCAL)" failed: file "/usr/src/sys/netinet6/nd6.c", line 727
> >
> > That means some part of the ND code is incorrectly setting an `expire'
> > value to an entry that is local, and therefor should never expire.
> >
> > Could you try to reproduce the issue with the diff below? It should
> > also panic but points us to the place where the bug is.
> >
> > [...]
> With the diff applied, this is the panic message:
>
> starting network
> vio0: DAD detected duplicate IPv6 address fe80:1::1: NS in/out=0/1, NA in=1
> vio0: DAD complete for fe80:1::1 - duplicate found
> vio0: manual intervention required
> reordering libraries:ndp info overwritten for fe80:1::1 by
> 76:fa:d3:57:ec:56 on vio0
> panic: kernel diagnostic assertion "!ISSET(ln->ln_rt->rt_flags,
> RTF_LOCAL)" failed: file "/usr/src/sys/netinet6/nd6.c", line 309
> Stopped at db_enter+0x10: popq %rbp
>
> TID PID UID PRFLAGS PFLAGS CPU COMMAND
> *457148 43436 0 0x14000 0x200 0 softnet
> db_enter() at db_enter+0x10
> panic() at panic+0x128
> __assert(ffffffff81c8d6ea,ffffffff81c94c17,135,ffffffff81c9fb69) at
> __assert+0x
> 2b
>
> nd6_llinfo_settimer(fffffd803ec6ff00,15180) at nd6_llinfo_settimer+0xdf
> nd6_cache_lladdr(ffff8000000972a8,ffff800014a496a0,fffffd803714f874,8,86,0)
> at n
> d6_cache_lladdr+0x2be
>
> nd6_rtr_cache(fffffd8036ee3000,28,38,86) at nd6_rtr_cache+0x31e
> icmp6_input(ffff800014a499d8,ffff800014a499e4,3a,18) at icmp6_input+0x33d
> ip_deliver(ffff800014a499d8,ffff800014a499e4,3a,18) at ip_deliver+0x1b3
> ip6_input_if(ffff800014a499d8,ffff800014a499e4,29,0,ffff8000000972a8) at
Thanks, diff below fixes nd6_rtr_cache(). It was already skipping
static entries the same should be done for local entries.
I left the panic in there in case there's another place where the bug
can be triggered.
Index: netinet6/nd6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.229
diff -u -p -r1.229 nd6.c
--- netinet6/nd6.c 29 Nov 2019 16:41:01 -0000 1.229
+++ netinet6/nd6.c 21 Apr 2020 08:36:01 -0000
@@ -306,6 +306,7 @@ nd6_llinfo_settimer(struct llinfo_nd6 *l
time_t expire = time_uptime + secs;
NET_ASSERT_LOCKED();
+ KASSERT(!ISSET(ln->ln_rt->rt_flags, RTF_LOCAL));
ln->ln_rt->rt_expire = expire;
if (!timeout_pending(&nd6_timer_to) || expire < nd6_timer_next) {
@@ -1111,17 +1112,11 @@ nd6_cache_lladdr(struct ifnet *ifp, stru
rt = nd6_lookup(from, 0, ifp, ifp->if_rdomain);
if (rt == NULL) {
-#if 0
- /* nothing must be done if there's no lladdr */
- if (!lladdr || !lladdrlen)
- return NULL;
-#endif
-
rt = nd6_lookup(from, 1, ifp, ifp->if_rdomain);
is_newentry = 1;
} else {
- /* do nothing if static ndp is set */
- if (rt->rt_flags & RTF_STATIC) {
+ /* do not overwrite local or static entry */
+ if (ISSET(rt->rt_flags, RTF_STATIC|RTF_LOCAL)) {
rtfree(rt);
return;
}