ocelot_updat...lassify_rule(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

okay so real talk, we're in the Kernel API Manual and today's main character is ocelot_updat...lassify_rule(9). yes the truncated name is sending me too but that's literally how it's printed, so we're keeping it. it's the ocelot_update_vlan_reclassify_rule page and it is lowkey a whole journey πŸ¦‹


πŸŽ€ NAME πŸŽ€

ocelot_update_vlan_reclassify_rule β€” make the switch aware only to the bridge VLAN TPID. that's it, that's the whole vibe ✨

πŸ’– SYNOPSIS πŸ’–

int ocelot_update_vlan_reclassify_rule (struct ocelot *ocelot , int port );

🫢 ARGUMENTS 🫢

  • ocelot β€” the switch's private data structure, iykyk πŸ’…
  • port β€” index of the ingress port

🌸 DESCRIPTION 🌸

okay so buckle up. IEEE 802.1Q-2018 clauses "5.5 C-VLAN component conformance" and "5.6 S-VLAN component conformance" suggest that a C-VLAN component should only recognize and filter on C-Tags, and an S-VLAN component should only recognize and process based on C-Tags. periodt, that's what the standard is giving.

In Linux, as per commit 1a0b20b25732 ("Merge branch 'bridge-next'"), C-VLAN components are largely represented by a bridge with vlan_protocol 802.1Q, and S-VLAN components by a bridge with vlan_protocol 802.1ad. cute, we have a mapping πŸŽ€

Currently the driver only offloads vlan_protocol 802.1Q β€” but the hardware design is non-conformant πŸ’€, because the switch assigns each frame to a VLAN based on an entirely different question. it's all spelled out in the figure "Basic VLAN Classification Flow" from its manual, reproduced right here bestie:

Set TAG_TYPE, PCP, DEI, VID to port-default values in VLAN_CFG register
if VLAN_AWARE_ENA[port] and frame has outer tag then:
  if VLAN_INNER_TAG_ENA[port] and frame has inner tag then:
    TAG_TYPE = (Frame.InnerTPID <> 0x8100)
    Set PCP, DEI, VID to values from inner VLAN header
  else:
    TAG_TYPE = (Frame.OuterTPID <> 0x8100)
    Set PCP, DEI, VID to values from outer VLAN header
if VID == 0 then:
  VID = VLAN_CFG.VLAN_VID

Summarized (because that block ate), the switch will recognize both 802.1Q and 802.1ad TPIDs as VLAN "with equal rights", and just set the TAG_TYPE bit to 0 (if 802.1Q) or to 1 (if 802.1ad). It will classify based on whichever of the tags is "outer", no matter what TPID that may have (or "inner", if VLAN_INNER_TAG_ENA[port]). truly no thoughts head empty classification 😭

In the VLAN Table, the TAG_TYPE information is not accessible β€” just the classified VID is β€” so it's as if each VLAN Table entry is for 2 VLANs: C-VLAN X, and S-VLAN X. one entry, two identities, main character energy πŸ‘‘

Whereas the Linux bridge behavior is to only filter on frames with a TPID equal to the vlan_protocol, and treat everything else as VLAN-untagged. different strokes honestly.

Consider an ingress packet tagged with 802.1ad VID=3 and 802.1Q VID=5, received on a bridge vlan_filtering=1 vlan_protocol=802.1Q port. This frame should be treated as 802.1Q-untagged, and classified to the PVID of that bridge port. Not to VID=3, and not to VID=5. like, do not pass go, do not collect VID=3 πŸ™ˆ

so how do we fix it? The VCAP IS1 TCAM has everything we need to overwrite the choices made in the basic VLAN classification pipeline: it can match on TAG_TYPE in the key, and it can modify the classified VID in the action. slay. Thus, for each port under a vlan_filtering bridge, we can insert a rule in VCAP IS1 lookup 0 to match on 802.1ad tagged frames and modify their classified VID to the 802.1Q PVID of the port. This effectively makes it appear to the outside world as if those packets were processed as VLAN-untagged. gaslight, gatekeep, girlboss πŸ’…

The rule needs to be updated each time the bridge PVID changes, and needs to be deleted if the bridge PVID is deleted, or if the port becomes VLAN-unaware.

🚨 bestie please actually keep it in sync β€” this rule is a live thing. update it when the bridge PVID changes, and delete it when the bridge PVID goes away or the port goes VLAN-unaware. don't just leave it lying around ngl.

πŸ”₯ SEE ALSO πŸ”₯


and that's the whole page 🫢 brought to you by ./drivers/net/ethernet/mscc, October 2026 edition of the Kernel API Manual. go be iconic with your VLANs βœ¨πŸ’œ

πŸ“¦ where this page comes from