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

Reply via email to