On 2020-04-21 10:38, 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;
>               }
> 

Looks good to me. With this applied, I can no longer reproduce the
panic. Thanks for looking into this!

Julian

Reply via email to