On Tue, Apr 21, 2020 at 10:38:54AM +0200, Martin Pieuchot wrote:
> 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;
>               }
> 

Makes sense. OK claudio@

-- 
:wq Claudio

Reply via email to