• Vladimir Oltean's avatar
    net: bridge: add a helper for retrieving port VLANs from the data path · ee80dd2e
    Vladimir Oltean authored
    Introduce a brother of br_vlan_get_info() which is protected by the RCU
    mechanism, as opposed to br_vlan_get_info() which relies on taking the
    write-side rtnl_mutex.
    
    This is needed for drivers which need to find out whether a bridge port
    has a VLAN configured or not. For example, certain DSA switches might
    not offer complete source port identification to the CPU on RX, just the
    VLAN in which the packet was received. Based on this VLAN, we cannot set
    an accurate skb->dev ingress port, but at least we can configure one
    that behaves the same as the correct one would (this is possible because
    DSA sets skb->offload_fwd_mark = 1).
    
    When we look at the bridge RX handler (br_handle_frame), we see that
    what matters regarding skb->dev is the VLAN ID and the port STP state.
    So we need to select an skb->dev that has the same bridge VLAN as the
    packet we're receiving, and is in the LEARNING or FORWARDING STP state.
    The latter is easy, but for the former, we should somehow keep a shadow
    list of the bridge VLANs on each port, and a lookup table between VLAN
    ID and the 'designated port for imprecise RX'. That is rather
    complicated to keep in sync properly (the designated port per VLAN needs
    to be updated on the addition and removal of a VLAN, as well as on the
    join/leave events of the bridge on that port).
    
    So, to avoid all that complexity, let's just iterate through our finite
    number of ports and ask the bridge, for each packet: "do you have this
    VLAN configured on this port?".
    
    Cc: Roopa Prabhu <roopa@nvidia.com>
    Cc: Nikolay Aleksandrov <nikolay@nvidia.com>
    Cc: Ido Schimmel <idosch@nvidia.com>
    Cc: Jiri Pirko <jiri@nvidia.com>
    Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    ee80dd2e
br_vlan.c 54.3 KB