I am attempting to use ebtables to match a specific VLAN ID (non zero) along with a specific VLAN PCP value.

I tried the following:

ebtables -A FORWARD -p 0x8100 --vlan-id 5 --vlan-prio 3 -j DROP

Ebtables does not complain (as the check has been commented out in ebtables), but the rule reported back using "ebtables -L" only contained the match for VLAN ID.

I did see in the ebtables man page that when vlan-prio is used, the vlan-id must either be zero or not specified.

Why this is the case? I have so far not been able to find any references to support that the ID must be zero when the priority bits are used.

Is there anyway to make this possible, aside from creating a separate chain to match the vlan-id and vlan-prio separately?


The explanation isn't really making sense, but here it is in the kernel at linux/net/bridge/netfilter/ebt_vlan.c:

      if (!!info->id) { /* if id!=0 => check vid range */
          if (info->id > VLAN_N_VID) {
              pr_debug("id %d is out of range (1-4096)\n",
              return -EINVAL;
          /* Note: This is valid VLAN-tagged frame point.
           * Any value of user_priority are acceptable,
           * but should be ignored according to 802.1Q Std.
           * So we just drop the prio flag.
          info->bitmask &= ~EBT_VLAN_PRIO;
      /* Else, id=0 (null VLAN ID)  => user_priority range (any?) */

So as far as I understand, kernel's side of ebtables enforces ignoring the prio (PCP) flag/option when receiving the rule with a non-null VLAN ID (VID), so I don't see how you can succeed without using an user chain with two rules as workaround.

It's quite difficult to be able to consult without account any 802.1Q official document, but I couldn't find in the version from 2005 I could get to see an explanation for this comment. I understand it's written that VID=0 means there's only the PCP, but not that a PCP implies VID=0 nor that there is any interaction between both parameters (I mean there's nothing written about).

Note: nftables doesn't have this limitation:

nft add table bridge filter
nft add chain bridge filter forward '{ type filter hook forward priority -200; policy accept; }'
nft add rule bridge filter forward ether type vlan vlan id 5 vlan pcp 3 counter drop

Will give back what was provided (debug bytecode included, here shown in little-endian, hence 0x81 instead of 0x8100 etc.):

# nft --debug=netlink list chain bridge filter forward -a
bridge filter forward 2 
  [ payload load 2b @ link header + 12 => reg 1 ]
  [ cmp eq reg 1 0x00000081 ]
  [ payload load 2b @ link header + 14 => reg 1 ]
  [ bitwise reg 1 = (reg=1 & 0x0000ff0f ) ^ 0x00000000 ]
  [ cmp eq reg 1 0x00000500 ]
  [ payload load 1b @ link header + 14 => reg 1 ]
  [ bitwise reg 1 = (reg=1 & 0x000000e0 ) ^ 0x00000000 ]
  [ cmp eq reg 1 0x00000060 ]
  [ counter pkts 0 bytes 0 ]
  [ immediate reg 0 drop ]

table bridge filter {
    chain forward { # handle 1
        type filter hook forward priority -200; policy accept;
        vlan id 5 vlan pcp 3 counter packets 0 bytes 0 drop # handle 2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.