On Fri, Oct 25, 2024 at 04:48:25PM +0200, Alexander Bluhm wrote:
> On Fri, Oct 25, 2024 at 11:52:13AM +0300, Vitaliy Makkoveev wrote:
> > On Fri, Oct 25, 2024 at 10:18:42AM +0200, Holger Glaess wrote:
> > > hi
> > > 
> > > see below , is from the first reboot aber sysupgrade from 7.5 to 7.6
> > > 
> > > 
> > > Holger
> > > 
> > > 
> > > ===> Adding the _dhcp6leased user
> > > panic: rw_enter: inpnotify locking against myself
> > > Stopped at?????????? db_enter+0x14:?? popq?????? %rbp
> > > ===> Adding the _dhcp6leased user
> > > ?????? TID?????? PID?????? UID???????? PRFLAGS???????? PFLAGS?? CPU?? 
> > > COMMAND
> > > ??239340???? 5005?????????? 0?????? 0x100803???????? 0x2000?????? 0K grep
> > > *432877?? 32323?????????? 0???????? 0x14000?????????? 0x200?????? 1?? 
> > > softnet0
> > > db_enter() at db_enter+0x14
> > > panic(ffffffff8233bb4f) at panic+0xdd
> > > rw_enter_diag(ffffffff828bb170,1) at rw_enter_diag+0x4e
> > > rw_enter(ffffffff828bb170,1) at rw_enter+0x103
> > > udp_input(ffff800030da6ab8,ffff800030da6ac4,11,2) at udp_input+0x60f
> > > ip_deliver(ffff800030da6ab8,ffff800030da6ac4,11,2,1) at ip_deliver+0xf8
> > > ip_ours(ffff800030da6ab8,ffff800030da6ac4,ffff800030da6a0c,0) at
> > > ip_ours+0x6f
> > > ip_input_running
> > > rc.sysmergeif(ffff800030da6ab8,ffff800030da6ac4,31,0,ffff8000008ab800) at
> > > ip_inpu
> > > t_if+0x1f0
> > > ipv4_input(ffff8000008ab800,fffffd807d870300) at i===> Adding the
> > > _dhcp6leased grouppv4_input+0x38
> > > ether_input(ffff8000008ab800,fffffd807d870300) at ether_input+0x3df
> > > vxlan_input(ffff800001315680,fffffd807d870300,fffffd8074bcb050,0,fffffd8074bcb0
> > > 64,1c) at vxlan_input+0x301
> > > udp_sbappend(fffffd82779de000,fffffd807d870300,fffffd8074bcb050,0,14,fffffd8074
> > > bcb064,cae52dbc4504571,14) at udp_sbappend+0x7f
> > > udp_input(ffff800030da6fa8,ffff800030da6fb4,11,2) at udp_input+0x9c2
> > > ip_deliver(ffff800030da6fa8,ffff800030da6fb4,11,2,1) at ip_deliver+0xf8
> > > end trace frame: 0xffff800030da6eb0, count: 0
> > > https://www.openbsd.org/ddb.html describes the minimum info required in 
> > > bug
> > > reports.?? Insufficient info makes it difficult to find and fix bugs.
> > > 
> > 
> > This diff should help.
> 
> The inpt_notify lock is there to lock the inp_notify field.
> mvs@, we should not release it while traversing over inpcblist.
> 

Yeah, missed that. In other hand, we could use iterators like
pipex_iterator() and avoid locks while doing udp_sbappend(). This makes
`inpt_notify' rwlock unnecessary as the temporary list. So hypothetical
udp_input() code will be like below.

                inp = tinp = NULL;
                while ((inp = in_pcb_iterator((&table->inpt_queue, inp,
                    &iter))) {
                        if (inp->inp_socket->so_rcv.sb_state & SS_CANTRCVMORE)
                                continue;
                        if (rtable_l2(inp->inp_rtableid) !=
                            rtable_l2(m->m_pkthdr.ph_rtableid))
                                continue;
                        /* do other checks */

                        if (tinp) {
                                struct mbuf *n;

                                n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
                                if (n != NULL) {
                                        udp_sbappend(tinp, n, ip, ip6,
                                            iphlen, uh, &srcsa.sa, 0);
                                in_pcbunref(tinp);
                        }

                        in_pcbref(inp);
                        tinp = inp;

                        if ((inp->inp_socket->so_options & (SO_REUSEPORT |
                            SO_REUSEADDR)) == 0) {
                                in_pcbunref(inp);
                                break;
                        }
                }

                if (tinp == NULL) {
                        /*
                         * No matching pcb found; discard datagram.
                         * (No need to send an ICMP Port Unreachable
                         * for a broadcast or multicast datgram.)
                         */
                        udpstat_inc(udps_noportbcast);
                        goto bad;
                }

                udp_sbappend(tinp, n, ip, ip6, iphlen, uh, &srcsa.sa, 0);
                in_pcbunref(tinp);

                return IPPROTO_DONE;
        }

> The problem is in the UDP multicast or broadcast code.  Holger, do
> you use vxlan on multicast sockets or with broadcase packets?  If
> yes, what is the use case?  Could the kernel just forbid that vxlan
> runs with multicast or broadcast?
> 
> bluhm
> 
> > Index: sys/netinet/udp_usrreq.c
> > ===================================================================
> > RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
> > diff -u -p -r1.324 udp_usrreq.c
> > --- sys/netinet/udp_usrreq.c        6 Aug 2024 20:15:53 -0000       1.324
> > +++ sys/netinet/udp_usrreq.c        25 Oct 2024 08:49:12 -0000
> > @@ -503,8 +503,12 @@ udp_input(struct mbuf **mp, int *offp, i
> >                     else
> >                             n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
> >                     if (n != NULL) {
> > +                           if (inp->inp_upcall != NULL)
> > +                                   rw_exit_write(&table->inpt_notify);
> >                             udp_sbappend(inp, n, ip, ip6, iphlen, uh,
> >                                 &srcsa.sa, 0);
> > +                           if (inp->inp_upcall != NULL)
> > +                                   rw_enter_write(&table->inpt_notify);
> >                     }
> >                     in_pcbunref(inp);
> >             }

Reply via email to