08 Feb, 2023

3 commits


27 Sep, 2022

1 commit

  • This is the 5.15.70 stable release

    * tag 'v5.15.70': (2444 commits)
    Linux 5.15.70
    ALSA: hda/sigmatel: Fix unused variable warning for beep power change
    cgroup: Add missing cpus_read_lock() to cgroup_attach_task_all()
    ...

    Signed-off-by: Jason Liu

    Conflicts:
    arch/arm/boot/dts/imx6ul.dtsi
    arch/arm/mm/mmu.c
    arch/arm64/boot/dts/freescale/imx8mp-evk.dts
    drivers/gpu/drm/imx/dcss/dcss-kms.c
    drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
    drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
    drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
    drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
    drivers/soc/fsl/Kconfig
    drivers/soc/imx/gpcv2.c
    drivers/usb/dwc3/host.c
    net/dsa/slave.c
    sound/soc/fsl/imx-card.c

    Jason Liu
     

20 Sep, 2022

1 commit

  • [ Upstream commit 52267ce25f60f37ae40ccbca0b21328ebae5ae75 ]

    In case the source port cannot be decoded, print the warning only once. This
    still brings attention to the user and does not spam the logs at the same time.

    Signed-off-by: Kurt Kanzenbach
    Reviewed-by: Andrew Lunn
    Reviewed-by: Vladimir Oltean
    Link: https://lore.kernel.org/r/20220830163448.8921-1-kurt@linutronix.de
    Signed-off-by: Jakub Kicinski
    Signed-off-by: Sasha Levin

    Kurt Kanzenbach
     

31 Aug, 2022

1 commit


25 Aug, 2022

1 commit

  • commit 211987f3ac734000ea1548784b2a4539a974fbc8 upstream.

    ds->ops->port_stp_state_set() is, like most DSA methods, optional, and
    if absent, the port is supposed to remain in the forwarding state (as
    standalone). Such is the case with the mv88e6060 driver, which does not
    offload the bridge layer. DSA warns that the STP state can't be changed
    to FORWARDING as part of dsa_port_enable_rt(), when in fact it should not.

    The error message is also not up to modern standards, so take the
    opportunity to make it more descriptive.

    Fixes: fd3645413197 ("net: dsa: change scope of STP state setter")
    Reported-by: Sergei Antonov
    Signed-off-by: Vladimir Oltean
    Reviewed-by: Sergei Antonov
    Link: https://lore.kernel.org/r/20220816201445.1809483-1-vladimir.oltean@nxp.com
    Signed-off-by: Jakub Kicinski
    Signed-off-by: Greg Kroah-Hartman

    Vladimir Oltean
     

30 Jun, 2022

1 commit

  • This is the 5.15.41 stable release

    * tag 'v5.15.41': (1977 commits)
    Linux 5.15.41
    usb: gadget: uvc: allow for application to cleanly shutdown
    usb: gadget: uvc: rename function to be more consistent
    ...

    Signed-off-by: Jason Liu

    Conflicts:
    arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
    arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
    arch/arm64/configs/defconfig
    drivers/clk/imx/clk-imx8qxp-lpcg.c
    drivers/dma/imx-sdma.c
    drivers/gpu/drm/bridge/nwl-dsi.c
    drivers/mailbox/imx-mailbox.c
    drivers/net/phy/at803x.c
    drivers/tty/serial/fsl_lpuart.c
    security/keys/trusted-keys/trusted_core.c

    Jason Liu
     

09 May, 2022

1 commit

  • [ Upstream commit fc06b2867f4cea543505acfb194c2be4ebf0c7d3 ]

    The device_node pointer is returned by of_parse_phandle() with refcount
    incremented. We should use of_node_put() on it when done.
    of_node_put() will check for NULL value.

    Fixes: a20f997010c4 ("net: dsa: Don't instantiate phylink for CPU/DSA ports unless needed")
    Signed-off-by: Miaoqian Lin
    Signed-off-by: David S. Miller
    Signed-off-by: Sasha Levin

    Miaoqian Lin
     

04 May, 2022

31 commits

  • Drivers might have error messages to propagate to user space, most
    common being that they support a single mirror port.

    Propagate the netlink extack so that they can inform user space in a
    verbal way of their limitations.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: Jakub Kicinski
    (cherry picked from commit 0148bb50b8fd51baf357de8b237c0c6011506540)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • Similar to the port-based default priority, IEEE 802.1Q-2018 allows the
    Application Priority Table to define QoS classes (0 to 7) per IP DSCP
    value (0 to 63).

    In the absence of an app table entry for a packet with DSCP value X,
    QoS classification for that packet falls back to other methods (VLAN PCP
    or port-based default). The presence of an app table for DSCP value X
    with priority Y makes the hardware classify the packet to QoS class Y.

    As opposed to the default-prio where DSA exposes only a "set" in
    dsa_switch_ops (because the port-based default is the fallback, it
    always exists, either implicitly or explicitly), for DSCP priorities we
    expose an "add" and a "del". The addition of a DSCP entry means trusting
    that DSCP priority, the deletion means ignoring it.

    Drivers that already trust (at least some) DSCP values can describe
    their configuration in dsa_switch_ops :: port_get_dscp_prio(), which is
    called for each DSCP value from 0 to 63.

    Again, there can be more than one dcbnl app table entry for the same
    DSCP value, DSA chooses the one with the largest configured priority.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 47d75f7822064d024ec9207c0fc1777f983783b7)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • The port-based default QoS class is assigned to packets that lack a
    VLAN PCP (or the port is configured to not trust the VLAN PCP),
    an IP DSCP (or the port is configured to not trust IP DSCP), and packets
    on which no tc-skbedit action has matched.

    Similar to other drivers, this can be exposed to user space using the
    DCB Application Priority Table. IEEE 802.1Q-2018 specifies in Table
    D-8 - Sel field values that when the Selector is 1, the Protocol ID
    value of 0 denotes the "Default application priority. For use when
    application priority is not otherwise specified."

    The way in which the dcbnl integration in DSA has been designed has to
    do with its requirements. Andrew Lunn explains that SOHO switches are
    expected to come with some sort of pre-configured QoS profile, and that
    it is desirable for this to come pre-loaded into the DSA slave interfaces'
    DCB application priority table.

    In the dcbnl design, this is possible because calls to dcb_ieee_setapp()
    can be initiated by anyone including being self-initiated by this device
    driver.

    However, what makes this challenging to implement in DSA is that the DSA
    core manages the net_devices (effectively hiding them from drivers),
    while drivers manage the hardware. The DSA core has no knowledge of what
    individual drivers' QoS policies are. DSA could export to drivers a
    wrapper over dcb_ieee_setapp() and these could call that function to
    pre-populate the app priority table, however drivers don't have a good
    moment in time to do this. The dsa_switch_ops :: setup() method gets
    called before the net_devices are created (dsa_slave_create), and so is
    dsa_switch_ops :: port_setup(). What remains is dsa_switch_ops ::
    port_enable(), but this gets called upon each ndo_open. If we add app
    table entries on every open, we'd need to remove them on close, to avoid
    duplicate entry errors. But if we delete app priority entries on close,
    what we delete may not be the initial, driver pre-populated entries, but
    rather user-added entries.

    So it is clear that letting drivers choose the timing of the
    dcb_ieee_setapp() call is inappropriate. The alternative which was
    chosen is to introduce hardware-specific ops in dsa_switch_ops, and
    effectively hide dcbnl details from drivers as well. For pre-populating
    the application table, dsa_slave_dcbnl_init() will call
    ds->ops->port_get_default_prio() which is supposed to read from
    hardware. If the operation succeeds, DSA creates a default-prio app
    table entry. The method is called as soon as the slave_dev is
    registered, but before we release the rtnl_mutex. This is done such that
    user space sees the app table entries as soon as it sees the interface
    being registered.

    The fact that we populate slave_dev->dcbnl_ops with a non-NULL pointer
    changes behavior in dcb_doit() from net/dcb/dcbnl.c, which used to
    return -EOPNOTSUPP for any dcbnl operation where netdev->dcbnl_ops is
    NULL. Because there are still dcbnl-unaware DSA drivers even if they
    have dcbnl_ops populated, the way to restore the behavior is to make all
    dcbnl_ops return -EOPNOTSUPP on absence of the hardware-specific
    dsa_switch_ops method.

    The dcbnl framework absurdly allows there to be more than one app table
    entry for the same selector and protocol (in other words, more than one
    port-based default priority). In the iproute2 dcb program, there is a
    "replace" syntactical sugar command which performs an "add" and a "del"
    to hide this away. But we choose the largest configured priority when we
    call ds->ops->port_set_default_prio(), using __fls(). When there is no
    default-prio app table entry left, the port-default priority is restored
    to 0.

    Link: https://patchwork.kernel.org/project/netdevbpf/patch/20210113154139.1803705-2-olteanv@gmail.com/
    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit d538eca85c2aa6ecb5036e6ff47efc93d9f294da)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • Certain DSA switches can eliminate flooding to the CPU when none of the
    ports have the IFF_ALLMULTI or IFF_PROMISC flags set. This is done by
    synthesizing a call to dsa_port_bridge_flags() for the CPU port, a call
    which normally comes from the bridge driver via switchdev.

    The bridge port flags and IFF_PROMISC|IFF_ALLMULTI have slightly
    different semantics, and due to inattention/lack of proper testing, the
    IFF_PROMISC flag allows unknown unicast to be flooded to the CPU, but
    not unknown multicast.

    This must be fixed by setting both BR_FLOOD (unicast) and BR_MCAST_FLOOD
    in the synthesized dsa_port_bridge_flags() call, since IFF_PROMISC means
    that packets should not be filtered regardless of their MAC DA.

    Fixes: 7569459a52c9 ("net: dsa: manage flooding on the CPU ports")
    Signed-off-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Signed-off-by: David S. Miller
    (cherry picked from commit 7c762e70c50b462fabe44a597e2a6c3e56c236c0)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • If a port joins a bridge that it can't offload, it will fallback to
    standalone mode and software bridging. In this case, we never want to
    offload any FDB entries to hardware either.

    Previously, for host addresses, we would eventually end up in
    dsa_port_bridge_host_fdb_add, which would unconditionally dereference
    dp->bridge and cause a segfault.

    Fixes: c26933639b54 ("net: dsa: request drivers to perform FDB isolation")
    Signed-off-by: Tobias Waldekranz
    Reviewed-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Link: https://lore.kernel.org/r/20220315233033.1468071-1-tobias@waldekranz.com
    Signed-off-by: Jakub Kicinski
    (cherry picked from commit a860352e9dd02552e04a0503d0982cf9a4d3a0f4)
    Signed-off-by: Vladimir Oltean

    Tobias Waldekranz
     
  • In this situation (VLAN filtering disabled on br0):

    br0.10
    /
    br0
    / \
    swp0 swp1

    When a frame is transmitted from the VLAN upper, the bridge will send
    it down to one of the switch ports with forward offloading
    enabled. This will cause tag_dsa to generate a FORWARD tag. Before
    this change, that tag would have it's VID set to 10, even though VID
    10 is not loaded in the VTU.

    Before the blamed commit, the frame would trigger a VTU miss and be
    forwarded according to the PVT configuration. Now that all fabric
    ports are in 802.1Q secure mode, the frame is dropped instead.

    Therefore, restrict the condition under which we rewrite an 802.1Q tag
    to a DSA tag. On standalone port's, reuse is always safe since we will
    always generate FROM_CPU tags in that case. For bridged ports though,
    we must ensure that VLAN filtering is enabled, which in turn
    guarantees that the VID in question is loaded into the VTU.

    Fixes: d352b20f4174 ("net: dsa: mv88e6xxx: Improve multichip isolation of standalone ports")
    Signed-off-by: Tobias Waldekranz
    Tested-by: Andrew Lunn
    Reviewed-by: Vladimir Oltean
    Link: https://lore.kernel.org/r/20220307110548.812455-1-tobias@waldekranz.com
    Signed-off-by: Paolo Abeni
    (cherry picked from commit 6c43a920a5cd26511059751f594c3ac05f9a6125)
    Signed-off-by: Vladimir Oltean

    Tobias Waldekranz
     
  • A cross-chip notifier with "targeted_match=true" is one that matches
    only the local port of the switch that emitted it. In other words,
    passing through the cross-chip notifier layer serves no purpose.

    Eliminate this concept by calling directly ds->ops->port_change_mtu
    instead of emitting a targeted cross-chip notifier. This leaves the
    DSA_NOTIFIER_MTU event being emitted only for MTU updates on the CPU
    port, which need to be reflected also across all DSA links.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit be6ff9665d642d4cd0800b508ded289eaa5b02a2)
    Signed-off-by: Vladimir Oltean

    Conflicts in net/dsa/dsa_priv.h and net/dsa/port.c with commit
    8e6598a7b0fa ("net: dsa: Pass VLAN MSTI migration notifications to
    driver") which we did not backport.

    Vladimir Oltean
     
  • We can get a hold of the "ds" pointer directly from "dp", no need for
    the dsa_slave_priv.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 4715029fa7e9072443af229dcc324e933c83436c)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • We could retrieve the cpu_dp pointer directly from the "dp" we already
    have, no need to resort to dsa_to_port(ds, port).

    This change also removes the need for an "int port", so that is also
    deleted.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit cf1c39d3b3a583c83fc7e077e1b3689b37187bd2)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • Use the more conventional iterator over user ports instead of explicitly
    ignoring them, and use the more conventional name "other_dp" instead of
    "dp_iter", for readability.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit b2033a05a7197f5ddef617be8f510c9957a82553)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • To determine whether a given port should react to the port targeted by
    the notifier, dsa_port_host_vlan_match() and dsa_port_host_address_match()
    look at the positioning of the switch port currently executing the
    notifier relative to the switch port for which the notifier was emitted.

    To maintain stylistic compatibility with the other match functions from
    switch.c, the host address and host VLAN match functions take the
    notifier information about targeted port, switch and tree indices as
    argument. However, these functions only use that information to retrieve
    the struct dsa_port *targeted_dp, which is an invariant for the outer
    loop that calls them. So it makes more sense to calculate the targeted
    dp only once, and pass it to them as argument.

    But furthermore, the targeted dp is actually known at the time the call
    to dsa_port_notify() is made. It is just that we decide to only save the
    indices of the port, switch and tree in the notifier structure, just to
    retrace our steps and find the dp again using dsa_switch_find() and
    dsa_to_port().

    But both the above functions are relatively expensive, since they need
    to iterate through lists. It appears more straightforward to make all
    notifiers just pass the targeted dp inside their info structure, and
    have the code that needs the indices to look at info->dp->index instead
    of info->port, or info->dp->ds->index instead of info->sw_index, or
    info->dp->ds->dst->index instead of info->tree_index.

    For the sake of consistency, all cross-chip notifiers are converted to
    pass the "dp" directly.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 726816a129cbb1d645ed319a6f181f152f0dbda8)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • In dsa_port_switchdev_unsync_attrs() there is a comment that resetting
    the VLAN filtering isn't done where it is expected. And since commit
    108dc8741c20 ("net: dsa: Avoid cross-chip syncing of VLAN filtering"),
    there is no reason to handle this in switch.c either.

    Therefore, move the logic to port.c, and adapt it slightly to the data
    structures and naming conventions from there.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 8e9e678e4758b69b6231d3ad4d26d3381fdb5f3f)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • This reverts commit 11fd667dac315ea3f2469961f6d2869271a46cae.

    dsa_slave_change_mtu() updates the MTU of the DSA master and of the
    associated CPU port, but only if it detects a change to the master MTU.

    The blamed commit in the Fixes: tag below addressed a regression where
    dsa_slave_change_mtu() would return early and not do anything due to
    ds->ops->port_change_mtu() not being implemented.

    However, that commit also had the effect that the master MTU got set up
    to the correct value by dsa_master_setup(), but the associated CPU port's
    MTU did not get updated. This causes breakage for drivers that rely on
    the ->port_change_mtu() DSA call to account for the tagging overhead on
    the CPU port, and don't set up the initial MTU during the setup phase.

    Things actually worked before because they were in a fragile equilibrium
    where dsa_slave_change_mtu() was called before dsa_master_setup() was.
    So dsa_slave_change_mtu() could actually detect a change and update the
    CPU port MTU too.

    Restore the code to the way things used to work by reverting the reorder
    of dsa_tree_setup_master() and dsa_tree_setup_ports(). That change did
    not have a concrete motivation going for it anyway, it just looked
    better.

    Fixes: 066dfc429040 ("Revert "net: dsa: stop updating master MTU from master.c"")
    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 762c2998c9625f642f0d23da7d3f7e4f90665fdf)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • This reverts commit a1ff94c2973c43bc1e2677ac63ebb15b1d1ff846.

    Switch drivers that don't implement ->port_change_mtu() will cause the
    DSA master to remain with an MTU of 1500, since we've deleted the other
    code path. In turn, this causes a regression for those systems, where
    MTU-sized traffic can no longer be terminated.

    Revert the change taking into account the fact that rtnl_lock() is now
    taken top-level from the callers of dsa_master_setup() and
    dsa_master_teardown(). Also add a comment in order for it to be
    absolutely clear why it is still needed.

    Fixes: a1ff94c2973c ("net: dsa: stop updating master MTU from master.c")
    Reported-by: Luiz Angelo Daros de Luca
    Signed-off-by: Vladimir Oltean
    Tested-by: Luiz Angelo Daros de Luca
    Signed-off-by: David S. Miller
    (cherry picked from commit 066dfc4290406b1b0b014ae3267d4266a344efd1)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • DSA ports are stacked devices, so they use dev_mc_add() to sync their
    address list to their lower interface (DSA master). But they are also
    hardware devices, so they program those addresses to hardware using the
    __dev_mc_add() sync and unsync callbacks.

    Unfortunately both cannot work at the same time, and it seems that the
    multicast addresses which are already present on the DSA master, like
    33:33:00:00:00:01 (added by addrconf.c as in6addr_linklocal_allnodes)
    are synced to the master via dev_mc_sync(), but not to hardware by
    __dev_mc_sync().

    This happens because both the dev_mc_sync() -> __hw_addr_sync_one()
    code path, as well as __dev_mc_sync() -> __hw_addr_sync_dev(), operate
    on the same variable: ha->sync_cnt, in a way that causes the "sync"
    method (dsa_slave_sync_mc) to no longer be called.

    To fix the issue we need to work with the API in the way in which it was
    intended to be used, and therefore, call dev_uc_add() and friends for
    each individual hardware address, from the sync and unsync callbacks.

    Fixes: 5e8a1e03aa4d ("net: dsa: install secondary unicast and multicast addresses as host FDB/MDB")
    Link: https://lore.kernel.org/netdev/20220321163213.lrn5sk7m6grighbl@skbuf/
    Signed-off-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Link: https://lore.kernel.org/r/20220322003701.2056895-1-vladimir.oltean@nxp.com
    Signed-off-by: Jakub Kicinski
    (cherry picked from commit 5077e2c8cf4d6b22a95a6c54a917f764e8887978)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • DSA probing is atypical because a tree of devices must probe all at
    once, so out of N switches which call dsa_tree_setup_routing_table()
    during probe, for (N - 1) of them, "complete" will return false and they
    will exit probing early. The Nth switch will set up the whole tree on
    their behalf.

    The implication is that for (N - 1) switches, the driver binds to the
    device successfully, without doing anything. When the driver is bound,
    the ->shutdown() method may run. But if the Nth switch has failed to
    initialize the tree, there is nothing to do for the (N - 1) driver
    instances, since the slave devices have not been created, etc. Moreover,
    dsa_switch_shutdown() expects that the calling @ds has been in fact
    initialized, so it jumps at dereferencing the various data structures,
    which is incorrect.

    Avoid the ensuing NULL pointer dereferences by simply checking whether
    the Nth switch has previously set "ds->setup = true" for the switch
    which is currently shutting down. The entire setup is serialized under
    dsa2_mutex which we already hold.

    Fixes: 0650bf52b31f ("net: dsa: be compatible with masters which unregister on shutdown")
    Signed-off-by: Vladimir Oltean
    Link: https://lore.kernel.org/r/20220318195443.275026-1-vladimir.oltean@nxp.com
    Signed-off-by: Jakub Kicinski
    (cherry picked from commit 8fd36358ce82382519b50b05f437493e1e00c4a9)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • The Felix driver declares FDB isolation but puts all standalone ports in
    VID 0. This is mostly problem-free as discussed with Alvin here:
    https://patchwork.kernel.org/project/netdevbpf/cover/20220302191417.1288145-1-vladimir.oltean@nxp.com/#24763870

    however there is one catch. DSA still thinks that FDB entries are
    installed on the CPU port as many times as there are user ports, and
    this is problematic when multiple user ports share the same MAC address.

    Consider the default case where all user ports inherit their MAC address
    from the DSA master, and then the user runs:

    ip link set swp0 address 00:01:02:03:04:05

    The above will make dsa_slave_set_mac_address() call
    dsa_port_standalone_host_fdb_add() for 00:01:02:03:04:05 in port 0's
    standalone database, and dsa_port_standalone_host_fdb_del() for the old
    address of swp0, again in swp0's standalone database.

    Both the ->port_fdb_add() and ->port_fdb_del() will be propagated down
    to the felix driver, which will end up deleting the old MAC address from
    the CPU port. But this is still in use by other user ports, so we end up
    breaking unicast termination for them.

    There isn't a problem in the fact that DSA keeps track of host
    standalone addresses in the individual database of each user port: some
    drivers like sja1105 need this. There also isn't a problem in the fact
    that some drivers choose the same VID/FID for all standalone ports.
    It is just that the deletion of these host addresses must be delayed
    until they are known to not be in use any longer, and only the driver
    has this knowledge. Since DSA keeps these addresses in &cpu_dp->fdbs and
    &cpu_db->mdbs, it is just a matter of walking over those lists and see
    whether the same MAC address is present on the CPU port in the port db
    of another user port.

    I have considered reusing the generic dsa_port_walk_fdbs() and
    dsa_port_walk_mdbs() schemes for this, but locking makes it difficult.
    In the ->port_fdb_add() method and co, &dp->addr_lists_lock is held, but
    dsa_port_walk_fdbs() also acquires that lock. Also, even assuming that
    we introduce an unlocked variant of the address iterator, we'd still
    need some relatively complex data structures, and a void *ctx in the
    dsa_fdb_walk_cb_t which we don't currently pass, such that drivers are
    able to figure out, after iterating, whether the same MAC address is or
    isn't present in the port db of another port.

    All the above, plus the fact that I expect other drivers to follow the
    same model as felix where all standalone ports use the same FID, made me
    conclude that a generic method provided by DSA is necessary:
    dsa_fdb_present_in_other_db() and the mdb equivalent. Felix calls this
    from the ->port_fdb_del() handler for the CPU port, when the database
    was classified to either a port db, or a LAG db.

    For symmetry, we also call this from ->port_fdb_add(), because if the
    address was installed once, then installing it a second time serves no
    purpose: it's already in hardware in VID 0 and it affects all standalone
    ports.

    This change moves dsa_db_equal() from switch.c to dsa.c, since it now
    has one more caller.

    Fixes: 54c319846086 ("net: mscc: ocelot: enforce FDB isolation when VLAN-unaware")
    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 7e580490ac9819dd55a36be2a9b3380d1391f91b)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • Since the slave unicast address is synced to hardware and to the DSA
    master during dsa_slave_open(), this means that a call to
    dsa_slave_set_mac_address() while the slave interface is down will
    result to a call to dsa_port_standalone_host_fdb_del() and to
    dev_uc_del() for the MAC address while there was no previous
    dsa_port_standalone_host_fdb_add() or dev_uc_add().

    This is a partial revert of the blamed commit below, which was too
    aggressive.

    Fixes: 35aae5ab9121 ("net: dsa: remove workarounds for changing master promisc/allmulti only while up")
    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit e2d0576f0c009acdba63e1d763276743ff3788cc)
    Signed-off-by: Vladimir Oltean

    Conflicts in net/dsa/slave.c with commit e35b8d7dbb09 ("net: use
    eth_hw_addr_set() instead of ether_addr_copy()") which we did not
    backport.

    Vladimir Oltean
     
  • &cpu_db->fdbs and &cpu_db->mdbs may be uninitialized lists during some
    call paths of felix_set_tag_protocol().

    There was an attempt to avoid calling dsa_port_walk_fdbs() during setup
    by using a "bool change" in the felix driver, but this doesn't work when
    the tagging protocol is defined in the device tree, and a change is
    triggered by DSA at pseudo-runtime:

    dsa_tree_setup_switches
    -> dsa_switch_setup
    -> dsa_switch_setup_tag_protocol
    -> ds->ops->change_tag_protocol
    dsa_tree_setup_ports
    -> dsa_port_setup
    -> &dp->fdbs and &db->mdbs only get initialized here

    So it seems like the only way to fix this is to move the initialization
    of these lists earlier.

    dsa_port_touch() is called from dsa_switch_touch_ports() which is called
    from dsa_switch_parse_of(), and this runs completely before
    dsa_tree_setup(). Similarly, dsa_switch_release_ports() runs after
    dsa_tree_teardown().

    Fixes: f9cef64fa23f ("net: dsa: felix: migrate host FDB and MDB entries when changing tag proto")
    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit fe95784fb14e4d56072b7be7325ef859efa38135)
    Signed-off-by: Vladimir Oltean

    Conflicts in net/dsa/dsa2.c with commit 65c563a67755 ("net: dsa: do not
    open-code dsa_switch_for_each_port") which we did not backport.

    Vladimir Oltean
     
  • There has been recent work towards matching each switchdev object
    addition with a corresponding deletion.

    Therefore, having elements in the fdbs, mdbs, vlans lists at the time of
    a shared (DSA, CPU) port's teardown is indicative of a bug somewhere
    else, and not something that is to be expected.

    We shouldn't try to silently paper over that. Instead, print a warning
    and a stack trace.

    This change is a prerequisite for moving the initialization/teardown of
    these lists. Make it clear that clearing the lists isn't needed.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 0832cd9f1f023226527e95002d537123061ddac4)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • After the blamed commit, dsa_tree_setup_master() may exit without
    calling rtnl_unlock(), fix that.

    Fixes: c146f9bc195a ("net: dsa: hold rtnl_mutex when calling dsa_master_{setup,teardown}")
    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit afb3cc1a397d77771f342691b7e6b032a234d7f2)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • The blamed commit said one thing but did another. It explains that we
    should restore the "return err" to the original "goto out_unwind_tagger",
    but instead it replaced it with "goto out_unlock".

    When DSA_NOTIFIER_TAG_PROTO fails after the first switch of a
    multi-switch tree, the switches would end up not using the same tagging
    protocol.

    Fixes: 0b0e2ff10356 ("net: dsa: restore error path of dsa_tree_change_tag_proto")
    Signed-off-by: Vladimir Oltean
    Link: https://lore.kernel.org/r/20220303154249.1854436-1-vladimir.oltean@nxp.com
    Signed-off-by: Jakub Kicinski
    (cherry picked from commit e1bec7fa1cee311a6d3fb9161037c7675904134d)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • The "ocelot" and "ocelot-8021q" tagging protocols make use of different
    hardware resources, and host FDB entries have different destination
    ports in the switch analyzer module, practically speaking.

    So when the user requests a tagging protocol change, the driver must
    migrate all host FDB and MDB entries from the NPI port (in fact CPU port
    module) towards the same physical port, but this time used as a regular
    port.

    It is pointless for the felix driver to keep a copy of the host
    addresses, when we can create and export DSA helpers for walking through
    the addresses that it already needs to keep on the CPU port, for
    refcounting purposes.

    felix_classify_db() is moved up to avoid a forward declaration.

    We pass "bool change" because dp->fdbs and dp->mdbs are uninitialized
    lists when felix_setup() first calls felix_set_tag_protocol(), so we
    need to avoid calling dsa_port_walk_fdbs() during probe time.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit f9cef64fa23f6c1ff177be5082113c5a94e34e5d)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • DSA can treat IFF_PROMISC and IFF_ALLMULTI on standalone user ports as
    signifying whether packets with an unknown MAC DA will be received or
    not. Since known MAC DAs are handled by FDB/MDB entries, this means that
    promiscuity is analogous to including/excluding the CPU port from the
    flood domain of those packets.

    There are two ways to signal CPU flooding to drivers.

    The first (chosen here) is to synthesize a call to
    ds->ops->port_bridge_flags() for the CPU port, with a mask of
    BR_FLOOD | BR_MCAST_FLOOD. This has the effect of turning on egress
    flooding on the CPU port regardless of source.

    The alternative would be to create a new ds->ops->port_host_flood()
    which is called per user port. Some switches (sja1105) have a flood
    domain that is managed per {ingress port, egress port} pair, so it would
    make more sense for this kind of switch to not flood the CPU from port A
    if just port B requires it. Nonetheless, the sja1105 has other quirks
    that prevent it from making use of unicast filtering, and without a
    concrete user making use of this feature, I chose not to implement it.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 7569459a52c95bc6e82c0b4075c4380df55cd343)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • To be able to safely turn off CPU flooding for standalone ports, we need
    to ensure that the dev_addr of each DSA slave interface is installed as
    a standalone host FDB entry for compatible switches.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 499aa9e1b3329263bd26856699899120e56b2d7d)
    Signed-off-by: Vladimir Oltean

    Conflicts in net/dsa/slave.c with commit e35b8d7dbb09 ("net: use
    eth_hw_addr_set() instead of ether_addr_copy()") which we did not
    backport.

    Vladimir Oltean
     
  • In preparation of disabling flooding towards the CPU in standalone ports
    mode, identify the addresses requested by upper interfaces and use the
    new API for DSA FDB isolation to request the hardware driver to offload
    these as FDB or MDB objects. The objects belong to the user port's
    database, and are installed pointing towards the CPU port.

    Because dev_uc_add()/dev_mc_add() is VLAN-unaware, we offload to the
    port standalone database addresses with VID 0 (also VLAN-unaware).
    So this excludes switches with global VLAN filtering from supporting
    unicast filtering, because there, it is possible for a port of a switch
    to join a VLAN-aware bridge, and this changes the VLAN awareness of
    standalone ports, requiring VLAN-aware standalone host FDB entries.
    For the same reason, hellcreek, which requires VLAN awareness in
    standalone mode, is also exempted from unicast filtering.

    We create "standalone" variants of dsa_port_host_fdb_add() and
    dsa_port_host_mdb_add() (and the _del coresponding functions).

    We also create a separate work item type for handling deferred
    standalone host FDB/MDB entries compared to the switchdev one.
    This is done for the purpose of clarity - the procedure for offloading a
    bridge FDB entry is different than offloading a standalone one, and
    the switchdev event work handles only FDBs anyway, not MDBs.
    Deferral is needed for standalone entries because ndo_set_rx_mode runs
    in atomic context. We could probably optimize things a little by first
    queuing up all entries that need to be offloaded, and scheduling the
    work item just once, but the data structures that we can pass through
    __dev_uc_sync() and __dev_mc_sync() are limiting (there is nothing like
    a void *priv), so we'd have to keep the list of queued events somewhere
    in struct dsa_switch, and possibly a lock for it. Too complicated for
    now.

    Adding the address to the master is handled by dev_uc_sync(), adding it
    to the hardware is handled by __dev_uc_sync(). So this is the reason why
    dsa_port_standalone_host_fdb_add() does not call dev_uc_add(). Not that
    it had the rtnl_mutex anyway - ndo_set_rx_mode has it, but is atomic.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 5e8a1e03aa4dc5744032d4c925adcc35d41e523d)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • We are preparing to add API in port.c that adds FDB and MDB entries that
    correspond to the port's standalone database. Rename the existing
    methods to make it clear that the FDB and MDB entries offloaded come
    from the bridge database.

    Since the function names lengthen in dsa_slave_switchdev_event_work(),
    we place "addr" and "vid" in temporary variables, to shorten those.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 68d6d71eafd1c14c77f0468cfe374a53d34d819c)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • Lennert Buytenhek explains in commit df02c6ff2e39 ("dsa: fix master
    interface allmulti/promisc handling"), dated Nov 2008, that changing the
    promiscuity of interfaces that are down (here the master) is broken.

    This fact regarding promisc/allmulti has changed since commit
    b6c40d68ff64 ("net: only invoke dev->change_rx_flags when device is UP")
    by Vlad Yasevich, dated Nov 2013.

    Therefore, DSA now has unnecessary complexity to handle master state
    transitions from down to up. In fact, syncing the unicast and multicast
    addresses can happen completely asynchronously to the administrative
    state changes.

    This change reduces that complexity by effectively fully reverting
    commit df02c6ff2e39 ("dsa: fix master interface allmulti/promisc
    handling").

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 35aae5ab91219f295b298ea922308d33c06470b3)
    Signed-off-by: Vladimir Oltean

    Conflicts in net/dsa/slave.c with commit e35b8d7dbb09 ("net: use
    eth_hw_addr_set() instead of ether_addr_copy()") which we did not
    backport.

    Vladimir Oltean
     
  • When the DSA_NOTIFIER_TAG_PROTO returns an error, the user space process
    which initiated the protocol change exits the kernel processing while
    still holding the rtnl_mutex. So any other process attempting to lock
    the rtnl_mutex would deadlock after such event.

    The error handling of DSA_NOTIFIER_TAG_PROTO was inadvertently changed
    by the blamed commit, introducing this regression. We must still call
    rtnl_unlock(), and we must still call DSA_NOTIFIER_TAG_PROTO for the old
    protocol. The latter is due to the limiting design of notifier chains
    for cross-chip operations, which don't have a built-in error recovery
    mechanism - we should look into using notifier_call_chain_robust for that.

    Fixes: dc452a471dba ("net: dsa: introduce tagger-owned storage for private and shared data")
    Signed-off-by: Vladimir Oltean
    Link: https://lore.kernel.org/r/20220228141715.146485-1-vladimir.oltean@nxp.com
    Signed-off-by: Jakub Kicinski
    (cherry picked from commit 0b0e2ff10356e7e2ffd66ecdd6eee69a2f03449b)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • As FDB isolation cannot be enforced between VLAN-aware bridges in lack
    of hardware assistance like extra FID bits, it seems plausible that many
    DSA switches cannot do it. Therefore, they need to reject configurations
    with multiple VLAN-aware bridges from the two code paths that can
    transition towards that state:

    - joining a VLAN-aware bridge
    - toggling VLAN awareness on an existing bridge

    The .port_vlan_filtering method already propagates the netlink extack to
    the driver, let's propagate it from .port_bridge_join too, to make sure
    that the driver can use the same function for both.

    Signed-off-by: Vladimir Oltean
    Signed-off-by: David S. Miller
    (cherry picked from commit 06b9cce42634a50f2840777a66553b02320db5ef)
    Signed-off-by: Vladimir Oltean

    Vladimir Oltean
     
  • If a bridged port is not offloaded to the hardware - either because the
    underlying driver does not implement the port_bridge_{join,leave} ops,
    or because the operation failed - then its dp->bridge pointer will be
    NULL when dsa_port_bridge_leave() is called. Avoid dereferncing NULL.

    This fixes the following splat when removing a port from a bridge:

    Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000
    Internal error: Oops: 96000004 [#1] PREEMPT_RT SMP
    CPU: 3 PID: 1119 Comm: brctl Tainted: G O 5.17.0-rc4-rt4 #1
    Call trace:
    dsa_port_bridge_leave+0x8c/0x1e4
    dsa_slave_changeupper+0x40/0x170
    dsa_slave_netdevice_event+0x494/0x4d4
    notifier_call_chain+0x80/0xe0
    raw_notifier_call_chain+0x1c/0x24
    call_netdevice_notifiers_info+0x5c/0xac
    __netdev_upper_dev_unlink+0xa4/0x200
    netdev_upper_dev_unlink+0x38/0x60
    del_nbp+0x1b0/0x300
    br_del_if+0x38/0x114
    add_del_if+0x60/0xa0
    br_ioctl_stub+0x128/0x2dc
    br_ioctl_call+0x68/0xb0
    dev_ifsioc+0x390/0x554
    dev_ioctl+0x128/0x400
    sock_do_ioctl+0xb4/0xf4
    sock_ioctl+0x12c/0x4e0
    __arm64_sys_ioctl+0xa8/0xf0
    invoke_syscall+0x4c/0x110
    el0_svc_common.constprop.0+0x48/0xf0
    do_el0_svc+0x28/0x84
    el0_svc+0x1c/0x50
    el0t_64_sync_handler+0xa8/0xb0
    el0t_64_sync+0x17c/0x180
    Code: f9402f00 f0002261 f9401302 913cc021 (a9401404)
    ---[ end trace 0000000000000000 ]---

    Fixes: d3eed0e57d5d ("net: dsa: keep the bridge_dev and bridge_num as part of the same structure")
    Signed-off-by: Alvin Šipraga
    Reviewed-by: Vladimir Oltean
    Reviewed-by: Florian Fainelli
    Link: https://lore.kernel.org/r/20220221203539.310690-1-alvin@pqrs.dk
    Signed-off-by: Jakub Kicinski
    (cherry picked from commit 342b6419193c6f697fd47d9c72fcff9cafc70687)
    Signed-off-by: Vladimir Oltean

    Alvin Šipraga