Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ARP panic in HEAD



On Sun, Oct 11, 2026 at 01:03:56PM -0400, Greg Troxel wrote:
> Manuel Bouyer <bouyer%antioche.eu.org@localhost> writes:
> 
> > I just got a panic in a current kernel (updated today)
> > [ 7710.0533258] panic: kernel diagnostic assertion "op == ARPOP_REPLY || op == ARPOP_REQUEST" failed: file "/dsk/l1/misc/bouyer/HEAD/clean/src/sys/netinet/if_arp.c", line 801 
> > [ 7710.0996509] cpu0: Begin traceback...
> > [ 7710.1108929] vpanic() at netbsd:vpanic+0x18d
> > [ 7710.1236555] kern_assert() at netbsd:kern_assert+0x61
> > [ 7710.1340323] in_arpinput() at netbsd:in_arpinput+0x4b9
> > [ 7710.1553295] arpintr() at netbsd:arpintr+0x12e
> > [ 7710.1646365] softint_dispatch() at netbsd:softint_dispatch+0x124
> > [ 7710.1891263] DDB lost frame for netbsd:Xsoftintr+0x4c, trying 0xffffde00695cd0f0
> > [ 7710.2147638] Xsoftintr() at netbsd:Xsoftintr+0x4c
> > [ 7710.2272680] --- interrupt ---
> 
> No but a quick ksrccode_skim() reveals:
> 
>  in_arpinput(), which appears to process an mbuf with contents taht
>  arrrived over the wire, has
> 
>    KASSERT(op == ARPOP_REPLY || op == ARPOP_REQUEST);
> 
>  and this is "obviously wrong" as asserts are only for internal
>  consistency checks (things you think you should be able to prove by
>  static analysis, ish).  If the incoming packet has a bad opcode, that
>  should just be cause to discard the packet and probably increment some
>  stat counter.  However.... arpintr has that same check with a
>  discard/statinc, and only calls in_arpinput if it's one of those two.
>  So it's fine.  This is confusing because in_arpinput doesn't document
>  the precondition.   I'd wonder if it were called  from elsewhere, but
>  your stack trace shows it from arpintr.
> 
> 
> This was changed in July by riastradh@.  I read the code in arpintr and
> in_arpinput and I can't see anything wrong.
> 
> I wonder
> 
>   - if your system is MP, and if you have any non-default MPSAFE stuff

It is MP but is otherwise quite standard. The only change I did to GENERIC
was disable all drm stuff and add
options         DOM0OPS
pseudo-device  xenevt
pseudo-device  xvif
pseudo-device  xbdback
options NMBCLUSTERS=262144


>   - are there hosts on your LAN trying to do trailers (cue vax
>     flashbacks)?

No idea; but AFAIK nothing changed recently on (v)lan.

>   - what did you update from?

It's a test system so I have 3 partitions: one for netbsd-10, one
for netbsd-11 and one for HEAD (which was previously netbsd-9). 
The /boot.cfg loader let me choose which one I want.
The hardware has not changed for several years


>   - how many times has it happened

I got a first one after maybe an hour of uptime. A second one just after
reboot, it didn't reach the login: prompt. A third one occured overnight.
After that I installed a new kernel with the attached diff,
it didn't panic yet. One possibility is that it's another instance of
over-optimisation from the compiler. Unfortunably I didn't keep the crashing
kernel around (but I can revert the patch and rebuild).


> 
>   - did you get a crash dump, and what is in the arp packet in the mbuf?
>     What's ar_op?  ar_pro?  Is it otherwise sane?

Unfortunably no crash dump

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: if_arp.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/if_arp.c,v
retrieving revision 1.321
diff -u -p -u -r1.321 if_arp.c
--- if_arp.c	23 Jul 2026 21:49:19 -0000	1.321
+++ if_arp.c	12 Oct 2026 19:33:09 -0000
@@ -787,6 +787,7 @@ in_arpinput(struct mbuf *m)
 	struct sockaddr sa;
 	struct in_addr isaddr, itaddr, myaddr;
 	int op, rt_cmd, new_state = 0;
+	uint16_t oop;
 	void *tha;
 	net_stat_ref_t arps;
 	struct psref psref, psref_ia;
@@ -794,11 +795,14 @@ in_arpinput(struct mbuf *m)
 	char ipbuf[INET_ADDRSTRLEN];
 	bool find_source, do_dad;
 
+	ah = mtod(m, struct arphdr *);
+	oop = ntohs(ah->ar_op);
 	if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
 		goto out;
 	ah = mtod(m, struct arphdr *);
 	op = ntohs(ah->ar_op);
-	KASSERT(op == ARPOP_REPLY || op == ARPOP_REQUEST);
+	KASSERTMSG(op == ARPOP_REPLY || op == ARPOP_REQUEST,
+	    "op not REQUEST or REPLY: %d %d", op, oop);
 
 	if (ah->ar_pln != sizeof(struct in_addr))
 		goto out;


Home | Main Index | Thread Index | Old Index