* Rule with double check ignore with 802.1Q packet
@ 2025-10-10 17:45 Antoine C.
2025-10-10 18:16 ` Brian Davidson
0 siblings, 1 reply; 3+ messages in thread
From: Antoine C. @ 2025-10-10 17:45 UTC (permalink / raw)
To: netfilter
Hello,
I found a weird behavior with NF tables. I am trying to filter specific packets and I cannot understand what is going on in the following case. It looks like a bug, but I do not know NFT very well so I prefer to ask first.
I am using 2 virtual interfaces veth0 and veth1 on Linux:
Linux sopvubu22-214d 6.8.0-64-generic #67~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Jun 24 15:19:46 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
Interfaces were created with:
ip link add veth0 type veth peer name veth1
NFT were configured with the following script:
---
#!/usr/sbin/nft -f
flush ruleset
# INPUT Filtering
table netdev tb_in {
chain ch_in {
type filter hook ingress device veth1 priority 100;
nftrace set 1
ether saddr AA:BB:CC:DD:00:38 log prefix "--test 1-- "
ip saddr 192.168.140.56 log prefix "--test 2-- "
ether saddr AA:BB:CC:DD:00:38 ip saddr 192.168.140.56 log prefix "--tests 1&2 -- "
ip saddr 192.168.140.56 ether saddr AA:BB:CC:DD:00:38 log prefix "--tests 2&1 -- "
}
}
---
Then I send this specific packet:
echo AA BB CC DD 00 50 AA BB CC DD 00 38 81 00 28 48 08 00 45 00 00 1C 00 01 00 00 40 11 E0 F6 C0 A8 8C 38 C0 A8 8C 50 1D 89 1D 83 00 08 2A F8 | xxd -r -p | socat - INTERFACE:veth0
And I get the following log:
trace id 5235f40e netdev tb_in ch_in packet: iif "veth1" ether saddr aa:bb:cc:dd:00:38 ether daddr aa:bb:cc:dd:00:50 vlan pcp 1 vlan dei 0 vlan id 2120 ip saddr 192.168.140.56 ip daddr 192.168.140.80 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 1 ip protocol udp ip length 28 udp sport 7561 udp dport 7555 udp length 8
trace id 5235f40e netdev tb_in ch_in rule meta nftrace set 1 (verdict continue)
trace id 5235f40e netdev tb_in ch_in rule ether saddr aa:bb:cc:dd:00:38 log prefix "--test 1-- " (verdict continue)
trace id 5235f40e netdev tb_in ch_in rule ip saddr 192.168.140.56 log prefix "--test 2-- " (verdict continue)
trace id 5235f40e netdev tb_in ch_in rule ip saddr 192.168.140.56 ether saddr aa:bb:cc:dd:00:38 log prefix "--tests 2&1 -- " (verdict continue)
trace id 5235f40e netdev tb_in ch_in policy accept
What is very strange is that the "test 1 & 2" is failing, despite being exactly identical, apart the order, to other tests. I get the same log with 'dmesg'.
The packet sent can be decomposed in (ether + vlan + ip + udp) headers but no data. And if I remove the vlan part (81 00 28 48), it works.
Is it a bug or do I miss something ? Maybe it has been corrected in a newer kernel version?
Thanks for your help,
Antoine
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: Rule with double check ignore with 802.1Q packet
2025-10-10 17:45 Rule with double check ignore with 802.1Q packet Antoine C.
@ 2025-10-10 18:16 ` Brian Davidson
2025-10-11 13:57 ` Re : " Antoine C.
0 siblings, 1 reply; 3+ messages in thread
From: Brian Davidson @ 2025-10-10 18:16 UTC (permalink / raw)
To: Antoine C.; +Cc: netfilter
On Fri, Oct 10, 2025 at 1:45 PM Antoine C. <acalando@free.fr> wrote:
>
> Hello,
>
> I found a weird behavior with NF tables. I am trying to filter specific packets and I cannot understand what is going on in the following case. It looks like a bug, but I do not know NFT very well so I prefer to ask first.
>
> I am using 2 virtual interfaces veth0 and veth1 on Linux:
> Linux sopvubu22-214d 6.8.0-64-generic #67~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Jun 24 15:19:46 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
>
> Interfaces were created with:
> ip link add veth0 type veth peer name veth1
>
>
> NFT were configured with the following script:
> ---
> #!/usr/sbin/nft -f
>
> flush ruleset
>
> # INPUT Filtering
> table netdev tb_in {
> chain ch_in {
> type filter hook ingress device veth1 priority 100;
> nftrace set 1
> ether saddr AA:BB:CC:DD:00:38 log prefix "--test 1-- "
> ip saddr 192.168.140.56 log prefix "--test 2-- "
> ether saddr AA:BB:CC:DD:00:38 ip saddr 192.168.140.56 log prefix "--tests 1&2 -- "
> ip saddr 192.168.140.56 ether saddr AA:BB:CC:DD:00:38 log prefix "--tests 2&1 -- "
> }
> }
> ---
> Then I send this specific packet:
> echo AA BB CC DD 00 50 AA BB CC DD 00 38 81 00 28 48 08 00 45 00 00 1C 00 01 00 00 40 11 E0 F6 C0 A8 8C 38 C0 A8 8C 50 1D 89 1D 83 00 08 2A F8 | xxd -r -p | socat - INTERFACE:veth0
>
> And I get the following log:
> trace id 5235f40e netdev tb_in ch_in packet: iif "veth1" ether saddr aa:bb:cc:dd:00:38 ether daddr aa:bb:cc:dd:00:50 vlan pcp 1 vlan dei 0 vlan id 2120 ip saddr 192.168.140.56 ip daddr 192.168.140.80 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 1 ip protocol udp ip length 28 udp sport 7561 udp dport 7555 udp length 8
> trace id 5235f40e netdev tb_in ch_in rule meta nftrace set 1 (verdict continue)
> trace id 5235f40e netdev tb_in ch_in rule ether saddr aa:bb:cc:dd:00:38 log prefix "--test 1-- " (verdict continue)
> trace id 5235f40e netdev tb_in ch_in rule ip saddr 192.168.140.56 log prefix "--test 2-- " (verdict continue)
> trace id 5235f40e netdev tb_in ch_in rule ip saddr 192.168.140.56 ether saddr aa:bb:cc:dd:00:38 log prefix "--tests 2&1 -- " (verdict continue)
> trace id 5235f40e netdev tb_in ch_in policy accept
>
> What is very strange is that the "test 1 & 2" is failing, despite being exactly identical, apart the order, to other tests. I get the same log with 'dmesg'.
>
> The packet sent can be decomposed in (ether + vlan + ip + udp) headers but no data. And if I remove the vlan part (81 00 28 48), it works.
>
> Is it a bug or do I miss something ? Maybe it has been corrected in a newer kernel version?
>
> Thanks for your help,
> Antoine
Despite having the same expressions, the rules get interpreted
differently by nftables. The second rule checks the meta protocol
also. This is on kernel 6.6.104 and nftables 1.1.1.
# nft list table netdev t
table netdev t {
chain c {
ether saddr aa:bb:cc:dd:00:38 ip saddr 192.168.140.56 \
log prefix "--tests 1&2 --"
ip saddr 192.168.140.56 ether saddr aa:bb:cc:dd:00:38 \
log prefix "--tests 2&1 --"
}
}
# nft list table netdev t | nft -c -d netlink -f /dev/stdin
netdev (null) (null) use 0
netdev t c
[ meta load iiftype => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
[ payload load 8b @ link header + 6 => reg 1 ]
[ cmp eq reg 1 0xddccbbaa 0x00083800 ]
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp eq reg 1 0x388ca8c0 ]
[ log prefix --tests 1&2 -- ]
netdev t c
[ meta load protocol => reg 1 ]
[ cmp eq reg 1 0x00000008 ]
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp eq reg 1 0x388ca8c0 ]
[ meta load iiftype => reg 1 ]
[ cmp eq reg 1 0x00000001 ]
[ payload load 6b @ link header + 6 => reg 1 ]
[ cmp eq reg 1 0xddccbbaa 0x00003800 ]
[ log prefix --tests 2&1 -- ]
^ permalink raw reply [flat|nested] 3+ messages in thread* Re : Re: Rule with double check ignore with 802.1Q packet
2025-10-10 18:16 ` Brian Davidson
@ 2025-10-11 13:57 ` Antoine C.
0 siblings, 0 replies; 3+ messages in thread
From: Antoine C. @ 2025-10-11 13:57 UTC (permalink / raw)
To: Brian Davidson; +Cc: netfilter
----- Brian Davidson <davidson.brian@gmail.com> a écrit :
> On Fri, Oct 10, 2025 at 1:45 PM Antoine C. <acalando@free.fr> wrote:
> >
> > Hello,
> >
> > I found a weird behavior with NF tables. I am trying to filter specific packets and I cannot understand what is going on in the following case. It looks like a bug, but I do not know NFT very well so I prefer to ask first.
> >
> > I am using 2 virtual interfaces veth0 and veth1 on Linux:
> > Linux sopvubu22-214d 6.8.0-64-generic #67~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Jun 24 15:19:46 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
> >
> > Interfaces were created with:
> > ip link add veth0 type veth peer name veth1
> >
> >
> > NFT were configured with the following script:
> > ---
> > #!/usr/sbin/nft -f
> >
> > flush ruleset
> >
> > # INPUT Filtering
> > table netdev tb_in {
> > chain ch_in {
> > type filter hook ingress device veth1 priority 100;
> > nftrace set 1
> > ether saddr AA:BB:CC:DD:00:38 log prefix "--test 1-- "
> > ip saddr 192.168.140.56 log prefix "--test 2-- "
> > ether saddr AA:BB:CC:DD:00:38 ip saddr 192.168.140.56 log prefix "--tests 1&2 -- "
> > ip saddr 192.168.140.56 ether saddr AA:BB:CC:DD:00:38 log prefix "--tests 2&1 -- "
> > }
> > }
> > ---
> > Then I send this specific packet:
> > echo AA BB CC DD 00 50 AA BB CC DD 00 38 81 00 28 48 08 00 45 00 00 1C 00 01 00 00 40 11 E0 F6 C0 A8 8C 38 C0 A8 8C 50 1D 89 1D 83 00 08 2A F8 | xxd -r -p | socat - INTERFACE:veth0
> >
> > And I get the following log:
> > trace id 5235f40e netdev tb_in ch_in packet: iif "veth1" ether saddr aa:bb:cc:dd:00:38 ether daddr aa:bb:cc:dd:00:50 vlan pcp 1 vlan dei 0 vlan id 2120 ip saddr 192.168.140.56 ip daddr 192.168.140.80 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 1 ip protocol udp ip length 28 udp sport 7561 udp dport 7555 udp length 8
> > trace id 5235f40e netdev tb_in ch_in rule meta nftrace set 1 (verdict continue)
> > trace id 5235f40e netdev tb_in ch_in rule ether saddr aa:bb:cc:dd:00:38 log prefix "--test 1-- " (verdict continue)
> > trace id 5235f40e netdev tb_in ch_in rule ip saddr 192.168.140.56 log prefix "--test 2-- " (verdict continue)
> > trace id 5235f40e netdev tb_in ch_in rule ip saddr 192.168.140.56 ether saddr aa:bb:cc:dd:00:38 log prefix "--tests 2&1 -- " (verdict continue)
> > trace id 5235f40e netdev tb_in ch_in policy accept
> >
> > What is very strange is that the "test 1 & 2" is failing, despite being exactly identical, apart the order, to other tests. I get the same log with 'dmesg'.
> >
> > The packet sent can be decomposed in (ether + vlan + ip + udp) headers but no data. And if I remove the vlan part (81 00 28 48), it works.
> >
> > Is it a bug or do I miss something ? Maybe it has been corrected in a newer kernel version?
> >
> > Thanks for your help,
> > Antoine
>
> Despite having the same expressions, the rules get interpreted
> differently by nftables. The second rule checks the meta protocol
> also. This is on kernel 6.6.104 and nftables 1.1.1.
>
> # nft list table netdev t
> table netdev t {
> chain c {
> ether saddr aa:bb:cc:dd:00:38 ip saddr 192.168.140.56 \
> log prefix "--tests 1&2 --"
> ip saddr 192.168.140.56 ether saddr aa:bb:cc:dd:00:38 \
> log prefix "--tests 2&1 --"
> }
> }
> # nft list table netdev t | nft -c -d netlink -f /dev/stdin
> netdev (null) (null) use 0
> netdev t c
> [ meta load iiftype => reg 1 ]
> [ cmp eq reg 1 0x00000001 ]
> [ payload load 8b @ link header + 6 => reg 1 ]
> [ cmp eq reg 1 0xddccbbaa 0x00083800 ]
> [ payload load 4b @ network header + 12 => reg 1 ]
> [ cmp eq reg 1 0x388ca8c0 ]
> [ log prefix --tests 1&2 -- ]
> netdev t c
> [ meta load protocol => reg 1 ]
> [ cmp eq reg 1 0x00000008 ]
> [ payload load 4b @ network header + 12 => reg 1 ]
> [ cmp eq reg 1 0x388ca8c0 ]
> [ meta load iiftype => reg 1 ]
> [ cmp eq reg 1 0x00000001 ]
> [ payload load 6b @ link header + 6 => reg 1 ]
> [ cmp eq reg 1 0xddccbbaa 0x00003800 ]
> [ log prefix --tests 2&1 -- ]
Thanks Brian, I did not think of using '-d netlink'
However, my analysis is a bit different: both rules check
the protocol, but in the `1&2` case, it is loaded at the
same time than the MAC src, eight byte at a time, as an
erroneous optimization, because in that case the protocol
is after the 802.1Q header. So it is a bug.
One workaround is to do as in the '2&1' case, by inverting
the order, however this is a bit weird as usually, the
parser is complaining with
"Error: conflicting protocols specified: xxx vs yyy"
if the layers are specified in the wrong order.
Can anybody think of a better workaround?
Antoine
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-10-11 13:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-10 17:45 Rule with double check ignore with 802.1Q packet Antoine C.
2025-10-10 18:16 ` Brian Davidson
2025-10-11 13:57 ` Re : " Antoine C.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).