17 Nov, 2019

2 commits

  • Lots of overlapping changes and parallel additions, stuff
    like that.

    Signed-off-by: David S. Miller

    David S. Miller
     
  • This sequence of operations:
    ip link set dev br0 type bridge vlan_filtering 1
    bridge vlan del dev swp2 vid 1
    ip link set dev br0 type bridge vlan_filtering 1
    ip link set dev br0 type bridge vlan_filtering 0

    apparently fails with the message:

    [ 31.305716] sja1105 spi0.1: Reset switch and programmed static config. Reason: VLAN filtering
    [ 31.322161] sja1105 spi0.1: Couldn't determine PVID attributes (pvid 0)
    [ 31.328939] sja1105 spi0.1: Failed to setup VLAN tagging for port 1: -2
    [ 31.335599] ------------[ cut here ]------------
    [ 31.340215] WARNING: CPU: 1 PID: 194 at net/switchdev/switchdev.c:157 switchdev_port_attr_set_now+0x9c/0xa4
    [ 31.349981] br0: Commit of attribute (id=6) failed.
    [ 31.354890] Modules linked in:
    [ 31.357942] CPU: 1 PID: 194 Comm: ip Not tainted 5.4.0-rc6-01792-gf4f632e07665-dirty #2062
    [ 31.366167] Hardware name: Freescale LS1021A
    [ 31.370437] [] (unwind_backtrace) from [] (show_stack+0x10/0x14)
    [ 31.378153] [] (show_stack) from [] (dump_stack+0xe0/0x10c)
    [ 31.385437] [] (dump_stack) from [] (__warn+0xf4/0x10c)
    [ 31.392373] [] (__warn) from [] (warn_slowpath_fmt+0x74/0xb8)
    [ 31.399827] [] (warn_slowpath_fmt) from [] (switchdev_port_attr_set_now+0x9c/0xa4)
    [ 31.409097] [] (switchdev_port_attr_set_now) from [] (__br_vlan_filter_toggle+0x6c/0x118)
    [ 31.418971] [] (__br_vlan_filter_toggle) from [] (br_changelink+0xf8/0x518)
    [ 31.427637] [] (br_changelink) from [] (__rtnl_newlink+0x3f4/0x76c)
    [ 31.435613] [] (__rtnl_newlink) from [] (rtnl_newlink+0x44/0x60)
    [ 31.443329] [] (rtnl_newlink) from [] (rtnetlink_rcv_msg+0x2cc/0x51c)
    [ 31.451477] [] (rtnetlink_rcv_msg) from [] (netlink_rcv_skb+0xb8/0x110)
    [ 31.459796] [] (netlink_rcv_skb) from [] (netlink_unicast+0x17c/0x1f8)
    [ 31.468026] [] (netlink_unicast) from [] (netlink_sendmsg+0x2bc/0x3b4)
    [ 31.476261] [] (netlink_sendmsg) from [] (___sys_sendmsg+0x230/0x250)
    [ 31.484408] [] (___sys_sendmsg) from [] (__sys_sendmsg+0x50/0x8c)
    [ 31.492209] [] (__sys_sendmsg) from [] (ret_fast_syscall+0x0/0x28)
    [ 31.500090] Exception stack(0xedf47fa8 to 0xedf47ff0)
    [ 31.505122] 7fa0: 00000002 b6f2e060 00000003 beabd6a4 00000000 00000000
    [ 31.513265] 7fc0: 00000002 b6f2e060 5d6e3213 00000128 00000000 00000001 00000006 000619c4
    [ 31.521405] 7fe0: 00086078 beabd658 0005edbc b6e7ce68

    The reason is the implementation of br_get_pvid:

    static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
    {
    if (!vg)
    return 0;

    smp_rmb();
    return vg->pvid;
    }

    Since VID 0 is an invalid pvid from the bridge's point of view, let's
    add this check in dsa_8021q_restore_pvid to avoid restoring a pvid that
    doesn't really exist.

    Fixes: 5f33183b7fdf ("net: dsa: tag_8021q: Restore bridge VLANs when enabling vlan_filtering")
    Signed-off-by: Vladimir Oltean
    Reviewed-by: Andrew Lunn
    Signed-off-by: David S. Miller

    Vladimir Oltean
     

13 Nov, 2019

1 commit

  • It is possible for a switch driver to use NET_DSA_TAG_8021Q as a valid
    DSA tagging protocol since it registers itself as such, unfortunately
    since there are not xmit or rcv functions provided, the lack of a xmit()
    function will lead to a NPD in dsa_slave_xmit() to start with.

    net/dsa/tag_8021q.c is only comprised of a set of helper functions at
    the moment, but is not a fully autonomous or functional tagging "driver"
    (though it could become later on). We do not have any users of
    NET_DSA_TAG_8021Q so now is a good time to make sure there are not
    issues being encountered by making this file strictly a place holder for
    helper functions.

    Reviewed-by: Vladimir Oltean
    Signed-off-by: Florian Fainelli
    Signed-off-by: David S. Miller

    Florian Fainelli
     

01 Nov, 2019

1 commit

  • Now that there's no restriction from the DSA core side regarding
    the switch IDs and port numbers, only tag_8021q which is currently
    reserving 3 bits for the switch ID and 4 bits for the port number, has
    limitation for these values. Update their descriptions to reflect that.

    Signed-off-by: Vivien Didelot
    Signed-off-by: David S. Miller

    Vivien Didelot
     

23 Oct, 2019

1 commit

  • Do not let the drivers access the ds->ports static array directly
    while there is a dsa_to_port helper for this purpose.

    At the same time, un-const this helper since the SJA1105 driver
    assigns the priv member of the returned dsa_port structure.

    Signed-off-by: Vivien Didelot
    Reviewed-by: Florian Fainelli
    Reviewed-by: Andrew Lunn
    Signed-off-by: Jakub Kicinski

    Vivien Didelot
     

03 Sep, 2019

1 commit


01 Sep, 2019

1 commit

  • The bridge core assumes that enabling/disabling vlan_filtering will
    translate into the simple toggling of a flag for switchdev drivers.

    That is clearly not the case for sja1105, which alters the VLAN table
    and the pvids in order to obtain port separation in standalone mode.

    There are 2 parts to the issue.

    First, tag_8021q changes the pvid to a unique per-port rx_vid for frame
    identification. But we need to disable tag_8021q when vlan_filtering
    kicks in, and at that point, the VLAN configured as pvid will have to be
    removed from the filtering table of the ports. With an invalid pvid, the
    ports will drop all traffic. Since the bridge will not call any vlan
    operation through switchdev after enabling vlan_filtering, we need to
    ensure we're in a functional state ourselves. Hence read the pvid that
    the bridge is aware of, and program that into our ports.

    Secondly, tag_8021q uses the 1024-3071 range privately in
    vlan_filtering=0 mode. Had the user installed one of these VLANs during
    a previous vlan_filtering=1 session, then upon the next tag_8021q
    cleanup for vlan_filtering to kick in again, VLANs in that range will
    get deleted unconditionally, hence breaking user expectation. So when
    deleting the VLANs, check if the bridge had knowledge about them, and if
    it did, re-apply the settings. Wrap this logic inside a
    dsa_8021q_vid_apply helper function to reduce code duplication.

    Signed-off-by: Vladimir Oltean
    Reviewed-by: Vivien Didelot
    Signed-off-by: David S. Miller

    Vladimir Oltean
     

28 Aug, 2019

1 commit

  • After witnessing the discussion in https://lkml.org/lkml/2019/8/14/151
    w.r.t. ioctl extensibility, it became clear that such an issue might
    prevent that the 3 RSV bits inside the DSA 802.1Q tag might also suffer
    the same fate and be useless for further extension.

    So clearly specify that the reserved bits should currently be
    transmitted as zero and ignored on receive. The DSA tagger already does
    this (and has always did), and is the only known user so far (no
    Wireshark dissection plugin, etc). So there should be no incompatibility
    to speak of.

    Fixes: 0471dd429cea ("net: dsa: tag_8021q: Create a stable binary format")
    Signed-off-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Signed-off-by: David S. Miller

    Vladimir Oltean
     

09 Jun, 2019

1 commit

  • This removes the existing implementation from tag_sja1105, which was
    partially incorrect (it was not changing the MAC header offset, thereby
    leaving it to point 4 bytes earlier than it should have).

    This overwrites the VLAN tag by moving the Ethernet source and
    destination MACs 4 bytes to the right. Then skb->data (assumed to be
    pointing immediately after the EtherType) is temporarily pushed to the
    beginning of the new Ethernet header, the new Ethernet header offset and
    length are recorded, then skb->data is moved back to where it was.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller

    Vladimir Oltean
     

31 May, 2019

2 commits

  • Tools like tcpdump need to be able to decode the significance of fake
    VLAN headers that DSA uses to separate switch ports.

    But currently these have no global significance - they are simply an
    ordered list of DSA_MAX_SWITCHES x DSA_MAX_PORTS numbers ending at 4095.

    The reason why this is submitted as a fix is that the existing mapping
    of VIDs should not enter into a stable kernel, so we can pretend that
    only the new format exists. This way tcpdump won't need to try to make
    something out of the VLAN tags on 5.2 kernels.

    Fixes: f9bbe4477c30 ("net: dsa: Optional VLAN-based port separation for switches without tagging")
    Signed-off-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Signed-off-by: David S. Miller

    Vladimir Oltean
     
  • The 802.1Q tagging performs an unbalanced setup in terms of RX VIDs on
    the CPU port. For the ingress path of a 802.1Q switch to work, the RX
    VID of a port needs to be seen as tagged egress on the CPU port.

    While configuring the other front-panel ports to be part of this VID,
    for bridge scenarios, the untagged flag is applied even on the CPU port
    in dsa_switch_vlan_add. This happens because DSA applies the same flags
    on the CPU port as on the (bridge-controlled) slave ports, and the
    effect in this case is that the CPU port tagged settings get deleted.

    Instead of fixing DSA by introducing a way to control VLAN flags on the
    CPU port (and hence stop inheriting from the slave ports) - a hard,
    perhaps intractable problem - avoid this situation by moving the setup
    part of the RX VID on the CPU port after all the other front-panel ports
    have been added to the VID.

    Fixes: f9bbe4477c30 ("net: dsa: Optional VLAN-based port separation for switches without tagging")
    Signed-off-by: Ioana Ciornei
    Signed-off-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Signed-off-by: David S. Miller

    Ioana Ciornei
     

06 May, 2019

1 commit

  • This patch provides generic DSA code for using VLAN (802.1Q) tags for
    the same purpose as a dedicated switch tag for injection/extraction.
    It is based on the discussions and interest that has been so far
    expressed in https://www.spinics.net/lists/netdev/msg556125.html.

    Unlike all other DSA-supported tagging protocols, CONFIG_NET_DSA_TAG_8021Q
    does not offer a complete solution for drivers (nor can it). Instead, it
    provides generic code that driver can opt into calling:
    - dsa_8021q_xmit: Inserts a VLAN header with the specified contents.
    Can be called from another tagging protocol's xmit function.
    Currently the LAN9303 driver is inserting headers that are simply
    802.1Q with custom fields, so this is an opportunity for code reuse.
    - dsa_8021q_rcv: Retrieves the TPID and TCI from a VLAN-tagged skb.
    Removing the VLAN header is left as a decision for the caller to make.
    - dsa_port_setup_8021q_tagging: For each user port, installs an Rx VID
    and a Tx VID, for proper untagged traffic identification on ingress
    and steering on egress. Also sets up the VLAN trunk on the upstream
    (CPU or DSA) port. Drivers are intentionally left to call this
    function explicitly, depending on the context and hardware support.
    The expected switch behavior and VLAN semantics should not be violated
    under any conditions. That is, after calling
    dsa_port_setup_8021q_tagging, the hardware should still pass all
    ingress traffic, be it tagged or untagged.

    For uniformity with the other tagging protocols, a module for the
    dsa_8021q_netdev_ops structure is registered, but the typical usage is
    to set up another tagging protocol which selects CONFIG_NET_DSA_TAG_8021Q,
    and calls the API from tag_8021q.h. Null function definitions are also
    provided so that a "depends on" is not forced in the Kconfig.

    This tagging protocol only works when switch ports are standalone, or
    when they are added to a VLAN-unaware bridge. It will probably remain
    this way for the reasons below.

    When added to a bridge that has vlan_filtering 1, the bridge core will
    install its own VLANs and reset the pvids through switchdev. For the
    bridge core, switchdev is a write-only pipe. All VLAN-related state is
    kept in the bridge core and nothing is read from DSA/switchdev or from
    the driver. So the bridge core will break this port separation because
    it will install the vlan_default_pvid into all switchdev ports.

    Even if we could teach the bridge driver about switchdev preference of a
    certain vlan_default_pvid (task difficult in itself since the current
    setting is per-bridge but we would need it per-port), there would still
    exist many other challenges.

    Firstly, in the DSA rcv callback, a driver would have to perform an
    iterative reverse lookup to find the correct switch port. That is
    because the port is a bridge slave, so its Rx VID (port PVID) is subject
    to user configuration. How would we ensure that the user doesn't reset
    the pvid to a different value (which would make an O(1) translation
    impossible), or to a non-unique value within this DSA switch tree (which
    would make any translation impossible)?

    Finally, not all switch ports are equal in DSA, and that makes it
    difficult for the bridge to be completely aware of this anyway.
    The CPU port needs to transmit tagged packets (VLAN trunk) in order for
    the DSA rcv code to be able to decode source information.
    But the bridge code has absolutely no idea which switch port is the CPU
    port, if nothing else then just because there is no netdevice registered
    by DSA for the CPU port.
    Also DSA does not currently allow the user to specify that they want the
    CPU port to do VLAN trunking anyway. VLANs are added to the CPU port
    using the same flags as they were added on the user port.

    So the VLANs installed by dsa_port_setup_8021q_tagging per driver
    request should remain private from the bridge's and user's perspective,
    and should not alter the VLAN semantics observed by the user.

    In the current implementation a VLAN range ending at 4095 (VLAN_N_VID)
    is reserved for this purpose. Each port receives a unique Rx VLAN and a
    unique Tx VLAN. Separate VLANs are needed for Rx and Tx because they
    serve different purposes: on Rx the switch must process traffic as
    untagged and process it with a port-based VLAN, but with care not to
    hinder bridging. On the other hand, the Tx VLAN is where the
    reachability restrictions are imposed, since by tagging frames in the
    xmit callback we are telling the switch onto which port to steer the
    frame.

    Some general guidance on how this support might be employed for
    real-life hardware (some comments made by Florian Fainelli):

    - If the hardware supports VLAN tag stacking, it should somehow back
    up its private VLAN settings when the bridge tries to override them.
    Then the driver could re-apply them as outer tags. Dedicating an outer
    tag per bridge device would allow identical inner tag VID numbers to
    co-exist, yet preserve broadcast domain isolation.

    - If the switch cannot handle VLAN tag stacking, it should disable this
    port separation when added as slave to a vlan_filtering bridge, in
    that case having reduced functionality.

    - Drivers for old switches that don't support the entire VLAN_N_VID
    range will need to rework the current range selection mechanism.

    Signed-off-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Reviewed-by: Vivien Didelot
    Signed-off-by: David S. Miller

    Vladimir Oltean