netdev egress 'log' + tcpdump : capturing 'Bogus IPv4 version (3, must be 4)' packets
Martin Weber <[email protected]> Fri, 19 Sep 2025 06:37:40 +0000
| Newsgroups | gmane.comp.security.firewalls.netfilter.general |
|---|---|
| Message-ID | <PAVPR03MB9137E7B52B4174E4F9F5AC399A11A@PAVPR03MB9137.eurprd03.prod.outlook.com> |
Hiho!
I’m trying to use a netdev ingress and egress filter to ensure I’m only getting the L2 traffic I want.
The netdev ingress and egress portions of the ruleset look like this (snipped from `nft list ruleset`)
```
table netdev l2filters {
chain ctrl_allowed_in {
meta protocol { ip, arp, 0x8035, 0x88cc, 0x88f7 } meta mark set 0x00000003 log group 42 counter packets 1383 bytes 215821 accept comment "IPv4, ARP, RARP, LLDP, PTP"
}
chain ctrl_in {
type filter hook ingress device "eth0" priority filter; policy drop;
counter packets 4066 bytes 342541 jump ctrl_allowed_in
}
chain ctrl_out {
type filter hook egress device "eth0" priority filter; policy drop;
meta protocol { ip, arp, 0x8035, 0x88cc, 0x88f7 } meta mark set 0x00000005 log group 42 counter packets 644 bytes 134224 accept comment "IPv4, ARP, RARP, LLDP, PTP"
}
```
(previous iterations used the same chain (now ctrl_allowed_in) and both ingress and egress would `jump` to it, but I suspected the shared chain to be the culprit of what I see. I have now confirmed it’s not …)
So with the above setup, I would expect to be able to use: `tcpdump -I nflog:42 -w /tmp/traffic.pcap` and get both ingress and egress packets “verbatim”.
Now, if I look at the pcap file, I’ll see something like this (output from `tshark -r traffic.pcap`):
```
204 2.886077 172.31.175.11 → 172.31.175.61 TCP 184 62014 → 22 [ACK] Seq=5201 Ack=5201 Win=654 Len=0 TSval=2141425389 TSecr=3529538637
205 2.886077 172.31.175.11 → 172.31.175.61 ICMP 216 Echo (ping) request id=0x03e8, seq=1/256, ttl=63
206 2.886078 → IPv4 180 Bogus IPv4 version (3, must be 4)
207 2.886078 172.31.175.11 → 172.31.175.63 UDP 248 58051 → 19540 Len=88
208 2.886078 172.31.175.7 → 172.31.175.63 UDP 248 54943 → 19540 Len=88
209 4.166141 172.31.175.11 → 172.31.175.61 ICMP 216 Echo (ping) request id=0x03e8, seq=2/512, ttl=63
210 4.166144 → IPv4 180 Bogus IPv4 version (3, must be 4)
211 4.166145 → IPv4 440 Bogus IPv4 version (15, must be 4)
212 4.166146 172.31.175.11 → 172.31.175.61 ICMP 216 Echo (ping) request id=0x03e8, seq=3/768, ttl=63
```
(172.31.175.61 being my box in question, 172.31.175.11 the box from which I connect)
All my output (egress) logged packets are essentially broken .. do they only contain a portion of the packet?
I’ve also noticed that on the egress, `meta protocol` doesn’t seem to work as I though it would – at least I can see that one of the ethertypes I allow (GOOSE and SV on another device, i.e., 0x88b8 and 0x88ba) similarly to the above chain (`meta protocol <ethertypes-set>`) do not get passed. So I assume my egress filter doesn’t see the whole packet (yet?)
This is on linux 6.12, with nftables 1.1.5
I assume netdev egress filtering works as intended in general, so I assume this is a problem on my end. If the above description triggers any war memories, I’d be happy to get told those to learn and fix my setup.
Thanks in advance & Regards,
-Martin