I have a very specific questions about Linux Traffic control and u32 filters in particular. However, I don’t know where the right place is to ask such a question as it’s fairly niche.

The Linux Advanced Routing & Traffic Control site says it has a mailing list for questions, but the last post was from 2019. There is also the incredibly busy ‘linux-netdev’ mailing list, but, the traffic there looks like strictly source changes.

Any ideas?

The question I’m trying to find an answer to is: The u32 tc filter seems to support negative byte offsets which allows you to examine the Ethernet frame header (I don’t think I even found documentation on this, this is thanks to ChatGPT). However, when using u32 values to examine 8 bytes I can only use offsets in increments of 4 - like “at -8” or “at -12”, with any other increment giving me the error Illegal "match".

This seems like only a curiosity, but, I’ve been struggling to get my bit-matching to match the way I expect, and I’m wondering if this suggests that matching doesn’t function the way I think.

  • Ephera@lemmy.ml
    link
    fedilink
    arrow-up
    8
    ·
    11 months ago

    I don’t think posting to the linux-netdev mailing list is a terrible idea. For example, here’s someone who did post a question: https://marc.info/?l=linux-netdev&m=170628444014400&w=2

    But well, you might also be running into a bug or something that could potentially be exploited, or maybe just into a lack of documentation (which is also a bug). Either way, some devs might be interested in knowing about this.

  • Corngood@lemmy.ml
    link
    fedilink
    arrow-up
    7
    ·
    edit-2
    11 months ago

    I don’t have any previous knowledge of this at all, but from reading the docs, nothing you’re describing sounds wrong.

    A u32 selector will match 4 bytes (u32 meaning unsigned 32bit presumably, which is 4 bytes).

    It makes sense that you’d only be able to configure the matches on 4 byte intervals, because keeping them aligned may make the implementation simpler and more efficient. You can still match any set of bits this way.

    Perhaps you could describe what you’re trying to match exactly and the selectors you tried.

    Edit: also if you look at ‘raw payload expressions’ in nft: https://netfilter.org/projects/nftables/manpage.html

    That seems like it would do what you want, and you can actually access the ethernet header in a documented way. You have to switch to nft though.

    • NotAnArdvark@lemmy.caOP
      link
      fedilink
      arrow-up
      2
      ·
      11 months ago

      I really appreciate this, thank you. I think I had confused myself by playing with ‘u16’ and ‘u8’ and somehow coming to the conclusion that they were matching the right side of a 32-bit string. (Which may still be true, but, I’m just masking u32s now).

      This is what I ended up with, which is working the way I’d expect:

      tc filter add dev wlan0 protocol ip parent 1: prio 1 u32 \
      	match u32 0x30d6 0x0000ffff at -16 \
      	match u32 0xc92d1905 0xffffffff at -12 flowid 1:20
      

      This sends Ethernet frames destined for 30:d6:c9:2d:19:05 to flow 1:20, and it doesn’t seem to match a second device I tested. So, all good! Thank you again.