mlx5_esw_host_functions_enabled() only treated host functions as
disabled for an ECPF manager.
To support a non PF acting as an e-switch manager, add a check for a non
PF e-switch manager that treats host functions as disabled. This will
avoid allocating a host-PF vport in mlx5_esw_vports_init().
With host functions disabled for non PF, its e-switch is the expected
manager + uplink only.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-14-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
mlx5_esw_hold() and mlx5_eswitch_unblock_ipsec() bail out on
!mlx5_esw_allowed(), and their comments explained that as "a VF has no
eswitch" / "core dev is not a PF". New FW will let a VF act as a nested
e-switch manager - such a VF has an eswitch and passes
mlx5_esw_allowed() - so that equivalence no longer holds. Reword the
comments to describe the actual condition, the device is not an e-switch
manager, with no functional change.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-13-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The shared-FDB support check still requires the esw_shared_ingress_acl
capability. That capability backed the merged uplink ingress ACL, where
the slave uplink's ingress-ACL root was pointed at the master's
(esw_set_uplink_slave_ingress_root()). That handling was removed in
commit 82e86a6c71 ("net/mlx5: E-switch, remove special uplink ingress
ACL handling") once both uplinks were tagged with the same reserved
metadata (MLX5_ESW_METADATA_RSVD_UPLINK) - a single FDB rule then
matches traffic from either uplink, with no shared ingress ACL involved.
The capability check was left behind and has been dead since: the driver
programs no shared ingress ACL, yet the check still keeps otherwise
shared-FDB-capable devices out of shared FDB. Drop it.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-12-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The mapping debugfs file dumps the LAG virtual-to-physical port mapping.
In MPESW mode the LAG does not own that mapping - port selection is
driven by user steering rules, not by the LAG - so the dumped values are
meaningless.
Treat MPESW as if LAG is inactive and don't print anything to the user.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-11-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
mlx5_eswitch_manager_vport() hardcoded the e-switch manager vport as
either the ECPF or the host PF. Read esw_manager_vport_number from the
e-switch capability when esw_manager_vport_number_valid is set, so the
manager vport can be a VF - a prerequisite for VFs acting as e-switch
managers. Keep the previous mapping as fallback when the capability does
not report a number.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-10-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The per-peer reverse index lived in a fixed esw->offloads.peer_flows[]
array of list heads indexed by the peer's LAG sequence number, capping a
shared FDB at MLX5_MAX_PORTS members.
Replace the array with an xarray keyed by the peer vhca_id. Each entry
is a heap-allocated list head that chains the flows duplicated to that
peer via their peer node. This lifts the MLX5_MAX_PORTS cap: the number
of peers is bounded only by the number of distinct vhca_ids.
The lifetime of the duplicated peer flows list_head follows the devcom
pairing of the two eswitches:
- pair (mlx5_esw_offloads_pair): kzalloc_obj + INIT_LIST_HEAD +
xa_store the dup_peer_flows under the peer's vhca_id.
- add (mlx5e_tc_add_fdb_peer_flow): xa_load the dup_peer_flows and
list_add the duplicated flow's peer node.
- del (mlx5e_tc_del_fdb_peer_flow): list_del that node.
- flush (mlx5e_tc_clean_fdb_peer_flows): xa_for_each dup_peer_flows,
drop every duplicated flow on it; called from unpair.
- unpair (mlx5_esw_offloads_unpair): xa_erase + kfree the
dup_peer_flows.
So a dup_peer_flows is created when the local eswitch pairs with a peer
over devcom and freed when they unpair.
No functional change.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-9-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
A TC eswitch flow offloaded to a shared FDB is duplicated onto every
peer eswitch. Besides the forward list of duplicates on the origin flow
(mlx5e_tc_flow.peer_flows), the eswitch keeps a reverse index,
esw->offloads.peer_flows[], an array of per-peer list heads keyed by the
peer's LAG sequence number, used to tear down a peer's duplicates when
it is removed.
That reverse index was anchored on the origin: since one origin can have
a duplicate on every peer, the origin carried per-peer storage sized to
the max port count - a peer[MLX5_MAX_PORTS] array of list nodes plus a
peer_used bitmap - and each duplicate stored its peer_index.
Anchor it on the duplicate instead, which belongs to a single peer. Give
each flow one list node, mlx5e_tc_flow.peer, and place the duplicate -
not the origin - on its peer's list through it; add a peer_orig back-ref
so del can reach the origin from the duplicate. One node then replaces
the origin's per-peer array, and del unlinks the duplicate directly, so
peer[], peer_used and peer_index are dropped.
The per-peer list heads remain the fixed esw->offloads.peer_flows[]
array keyed by the LAG sequence number - that array is replaced in the
next patch. No functional change.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-8-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
mlx5_lag_drop_rule_setup() walks the per-port tracker state, but does so
through a per-port scratch array, mlx5_lag_drop_rule_setup() collects
the disabled ports to create a per-port drop rule.
Walk the tracker state inline removing its MLX5_MAX_PORTS dependency.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-6-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
mlx5_lag_print_mapping(), mlx5_infer_tx_affinity_mapping() and
lag_active_port_bits() each used a MLX5_MAX_PORTS-sized stack buffer to
hold per-port working state. Allocate these buffers with
kcalloc(ldev->ports, ...) instead so they track the actual port count
and no longer depend on MLX5_MAX_PORTS.
lag_active_port_bits() can now fail on allocation, so it returns int and
propagates -ENOMEM; a non-negative return is the active-port bitmask as
before. Its two callers, mlx5_cmd_create_lag() and _mlx5_modify_lag(),
check for a negative return and bail out, then narrow the value back
into the u8 they hand to the device.
This removes these buffers' dependency on MLX5_MAX_PORTS.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-5-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
v2p_map was a fixed array sized MLX5_MAX_PORTS *
MLX5_LAG_MAX_HASH_BUCKETS embedded in struct mlx5_lag. Turn it into a
pointer allocated in mlx5_lag_dev_alloc() once ldev->ports is known,
sized by the actual port count, and free it in mlx5_ldev_free(). The
ldev->ports / ldev->buckets initialization is moved up so the allocation
can use it.
The matching scratch buffer in mlx5_modify_lag() is converted from a
MLX5_MAX_PORTS-sized stack array to a kcalloc() of the same extent, with
the trailing teardown reworked through a goto so the buffer is freed on
every path. The memcpy() that previously relied on sizeof() of the stack
array now uses the explicit ldev->ports * MLX5_LAG_MAX_HASH_BUCKETS
span.
No functional change; this removes v2p_map's dependency on
MLX5_MAX_PORTS.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-4-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
If the initial PAIR event fails, the eswitch offloads devcom component
stays registered until eswitch teardown even though no peer was ever
paired. devcom is optional, so this is not a functional bug - but a
registered component that reflects no actual pairing is incorrect state
to keep around.
Release it when the initial pairing fails.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-3-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
mlx5e_set_netdev_dev_addr() falls back to a random MAC only when the
queried address is all-zeros AND the device is not a vport group
manager. A vport group manager that comes up with a zero MAC is
therefore left with an invalid all-zero address.
The vport_group_manager exception is unnecessary: a zero MAC is always
invalid, regardless of device type. Drop the condition and assign a
random MAC whenever the queried address is zero, so every netdev comes
up with a valid address.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260923103830.1183-2-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
In bcm_sysport_stop(), the error messages printed when tdma_enable_set()
and rdma_enable_set() time out were inverted: the failure of
tdma_enable_set() logged 'timeout disabling RDMA' and the failure of
rdma_enable_set() logged 'timeout disabling TDMA'.
Swap the error messages so they correctly describe the failing engine.
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260922232440.598918-9-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
In bcm_sysport_suspend_to_wol(), the loop enabling programmed RXCHK
filters in RXCHK_CONTROL used an auxiliary counter 'i' instead of the
actual set filter index 'index'.
When non-contiguous filters were configured (for example, if filter 0
was deleted and filter 1 remained), the code would enable bit
(RXCHK_BRCM_TAG_MATCH_SHIFT + 0) corresponding to filter 0 rather than
filter 1, causing Wake-on-LAN filter matching to fail.
Fix this by using the filter 'index' to set the appropriate match bit
in RXCHK_CONTROL.
Cc: stable+noautosel@kernel.org # never worked
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260922232440.598918-5-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
If allocation of priv->rx_cbs fails during bcm_sysport_init_rx_ring(),
error unwinding in bcm_sysport_open() calls bcm_sysport_fini_rx_ring().
Without checking if priv->rx_cbs is non-NULL, bcm_sysport_fini_rx_ring()
dereferences priv->rx_cbs, resulting in a NULL pointer dereference.
Add a check for !priv->rx_cbs at the beginning of
bcm_sysport_fini_rx_ring(), matching bcm_sysport_fini_tx_ring().
Cc: stable+noautosel@kernel.org # unlikely driver error path
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260922232440.598918-4-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Florian Fainelli says:
====================
net: broadcom: Couple of minor changes
The first change makes sure there is proper reference counting handling
in case of error/removal for the bcmsysport driver.
The second change removes duplicates definitions in the ASP2 driver.
====================
Link: https://patch.msgid.link/20260922222525.3992167-1-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
In bcm_sysport_probe(), priv->phy_dn is only initialized if the device
tree node has a fixed-link configuration (of_phy_is_fixed_link). When
connecting to a discrete MDIO-attached PHY referenced via 'phy-handle',
priv->phy_dn remains NULL. This causes of_phy_connect() during
bcm_sysport_open() to fail with -ENODEV since of_phy_find_device(NULL)
returns NULL.
Fix this by parsing 'phy-handle' via of_parse_phandle() and falling back
to of_phy_is_fixed_link(). Ensure proper of_node_get() and of_node_put()
refcounting lifecycle on both error unwinding and module remove paths.
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260922222525.3992167-2-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Eric Dumazet says:
====================
vxlan: convert configuration to RCU and enable lockless dumps
This patch series converts struct vxlan_config to RCU protection, eliminates
redundant destination fields, and enables lockless RTNL-free link dumping
in vxlan_fill_info().
====================
Link: https://patch.msgid.link/20260922181102.3989489-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Now that vxlan->cfg is RCU-protected, we can update vxlan_fill_info()
to run under RCU read lock instead of relying on RTNL.
This completes the transition to RTNL-less link info dumping for VXLAN.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-9-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Now that vxlan->cfg is an RCU-protected pointer, storing default
destination attributes (remote_ip, remote_vni, remote_ifindex) in
vxlan->default_dst is redundant and creates potential data races for
lockless readers.
Furthermore, several fields of struct vxlan_rdst (remote_port,
offloaded, list, rcu, dst_cache) in default_dst were completely unused.
The remaining one, remote_dev, only tracked the lower device, a role
now taken by vxlan->lowerdev, so drop it from struct vxlan_rdst.
Replace vxlan->default_dst with a 'struct net_device *lowerdev' pointer
in struct vxlan_dev to track adjacent upper/lower netdev topology under
RTNL, and switch all remaining users over to reading configuration
attributes from vxlan->cfg.
Also update mlx5e_tc_tun_get_remote_ifindex() to read remote_ifindex
from vxlan->cfg under rcu_read_lock().
In vxlan_changelink(), pass lowerdev to vxlan_config_apply() to preserve
needed_headroom and needed_tailroom. The mtu is still only reconsidered
when the lower device changes, so that an unrelated changelink can not
shrink it.
cfg->remote_ifindex is now committed unconditionally, where
default_dst.remote_ifindex was left untouched when IFLA_VXLAN_LINK was
cleared, so a changelink dropping the lower device no longer leaves a
stale ifindex behind. For the same reason vxlan_changelink() no longer
needs to compute the ifindex that will actually be committed.
Setting IFLA_VXLAN_LINK to 0 now also tears down the upper/lower
adjacency, which netdev_adjacent_change_commit() used to skip for a NULL
new device, resets needed_tailroom, and is rejected if per-VNI multicast
groups are configured.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-8-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Move 'struct vxlan_config' from an embedded structure inside
'struct vxlan_dev' to a dynamically allocated RCU-protected pointer
'vxlan->cfg'.
Updating configuration via vxlan_changelink() or vxlan_dev_configure()
allocates a new struct vxlan_config and publishes it with
rcu_assign_pointer(), freeing the previous config with kfree_rcu().
Readers are converted to use rcu_dereference() or rtnl_dereference().
In vxlan_xmit(), acquire rcu_read_lock() to protect config access.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-7-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
VXLAN_F_MDB is an internal runtime state flag indicating whether any
MDB entries are configured on the device, rather than a netlink
configuration attribute.
In preparation for converting vxlan->cfg to an RCU-protected pointer,
move VXLAN_F_MDB from struct vxlan_config to a dedicated 'flags' field
in struct vxlan_dev as VXLAN_DEV_F_MDB, using atomic bitops (set_bit(),
clear_bit(), test_bit()) to avoid KCSAN data races between the TX path
and RTNL operations.
This avoids having to dynamically reallocate and publish a new
vxlan_config structure via RCU whenever the first MDB entry is added
or the last one is removed, and prevents potential memory allocation
failures during MDB teardown under memory pressure.
mlxsw validates cfg->flags against a deny-by-default mask, so
VXLAN_F_MDB used to make mlxsw_sp_nve_vxlan_can_offload() reject a
device with MDB entries as carrying an unsupported flag. Add an
explicit VXLAN_DEV_F_MDB test there to keep that rejection, with a
message naming the actual reason.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
In preparation for converting vxlan->cfg to an RCU-protected pointer,
refactor internal helper functions in the RX, TX, MDB, and VNIFILTER
paths to accept a pointer to struct vxlan_config (or pass flags/
saddr_family where appropriate) rather than directly accessing
vxlan->cfg.
No functional changes.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
vxlan_vnifilter_dump() walks all vxlan devices of a netns, and for each
one walks vg->vni_list. Both cursors are plain ordinals stored in
cb->args[0] and cb->args[1], and RTNL is released between dump skbs.
A concurrent __vxlan_vni_add_list(), which inserts sorted by VNI,
__vxlan_vni_del_list(), or an in-place group update in
vxlan_vni_update() (which splits or merges coalesced VNI ranges) shifts
the second cursor, duplicating or skipping entries. Unregistering a
vxlan device shifts the first one, and the partially dumped device is
then skipped altogether by the "if (idx < s_idx)" test, silently losing
the rest of its VNIs.
Add a per-netns generation counter, bumped whenever the set of vxlan
devices in the netns or any vni_list changes, and feed it to
nl_dump_check_consistent() so that user space gets NLM_F_DUMP_INTR and
can retry, as vxlan_mdb_dump() already does.
The counter is keyed on dev_net(vxlan->dev) rather than vxlan->net,
because the dump enumerates devices with for_each_netdev_rcu() in the
netns the netdevice lives in, which differs from the packet i/o netns
when the device was created with a separate link netns.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
RTM_GETTUNNEL dumps currently run under RTNL lock, but
vxlan_vnifilter_dump() also acquires rcu_read_lock().
1) Currently vxlan_vnifilter_dump_dev() traverses vg->vni_list using
list_for_each_entry_safe(). Even though RTNL is held today, writers
modify vg->vni_list with list_add_rcu() and list_del_rcu().
Switch to list_for_each_entry_rcu() for proper RCU traversal and
as preparation for future lockless dump support.
2) During a paginated dump, RTNL is released between dump skbs.
If vxlan_vnifilter_dump_dev() returns early because VXLAN_F_VNIFILTER
is not set or vg has no VNIs, cb->args[1] was not cleared. This leaked
a non-zero VNI offset to subsequent devices, silently skipping their
first N VNIs.
Furthermore, if devices are added or removed between dump calls,
ordinal device indexes can shift. Track the current device ifindex
in cb->args[2] and reset cb->args[1] if the device changes.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
vxlan_changelink() only refreshed the default fdb entries when the
remote IP changed, but vxlan_config_apply() also updates
default_dst.remote_ifindex when the lower device changes. A changelink
that only swaps the lower device therefore left the all zeros mac rdst
pointing at the old ifindex:
ip link add vxlan0 type vxlan id 10 group 239.1.1.1 dev eth0
ip link set dev vxlan0 type vxlan group 239.1.1.1 dev eth1
vxlan_xmit_one() uses rdst->remote_ifindex as the route oif, so traffic
kept leaving eth0.
VNI filter entries have the same problem, and are worse: their fdb
entries are keyed on the device remote_ifindex even when the vni
carries its own group, but vxlan_vnilist_update_group() only visited
the vnis without one. vxlan_vni_delete_group() later looks an entry up
with the current remote_ifindex, and vxlan_fdb_find_rdst() requires an
exact match, so the lookup failed and the entry survived the delete.
Re-adding the same vni then appended a second rdst, duplicating
transmitted BUM traffic.
Likewise, in vxlan_vni_update_group(), oldrip was only set when newrip
was NULL, so changing an existing VNI's group appended the new rdst
without deleting the old one. Set oldrip to the previous effective
remote IP whenever updating an existing VNI (!create).
Pass the old and new ifindex down to vxlan_update_default_fdb_entry()
so the append targets the new lower device and the delete still matches
the entry created for the old one, and refresh every vni rather than
only those inheriting the device group. If updating the vni list fails
partway through, unwind the already updated fdb entries (still deleting
the new rdst even if re-adding the old one fails) so default_dst and
the fdb entries do not diverge.
Also run vxlan_multicast_leave() and vxlan_multicast_join() when
VXLAN_F_VNIFILTER is set so per-VNI multicast memberships are migrated
even when the device default remote_ip is not multicast, and make
vxlan_multicast_leave_vnigrp() skip the default group and ignore
-EADDRNOTAVAIL when multiple VNIs share a multicast group.
The new ifindex is the one vxlan_config_apply() will commit, which is
the current one when lowerdev is NULL, so that default_dst and the fdb
entries can not diverge.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260922181102.3989489-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
hinic3_init_hwdev() stores the result of hinic3_adev_idx_alloc() in
hwdev->dev_id without checking for an error. If ID allocation fails but
the remaining initialization succeeds, hinic3_add_one_adev() uses the
negative error code as the auxiliary device ID instead of a reserved ID.
Return the allocation error before initializing the hardware. Add an
unwind label that clears pci_adapter->hwdev and frees the allocation
without attempting to release an ID that was never allocated.
Cc: stable+noautosel@kernel.org # untested fix to unlikely driver error path
Reported-by: Changyul Lee <lcy8047@gmail.com>
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Link: https://patch.msgid.link/179001656835.91284.3719235813225229273.idr-bug-81@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
After conntrack NAT rewrites a packet, OVS refreshes the cached flow
key in ovs_nat_update_key(), which has a per-protocol branch for the
L4 ports (UDP/TCP/SCTP, conntrack.c). Address-only NAT cannot tell a
working SCTP branch from a missing one: the ports survive unchanged
either way, so a post-recirc match on the original port stays green
even with the branch deleted. The suite's NAT coverage drives TCP
over nc, and the merged SCTP test has no conntrack in the path, so
the SCTP branch goes unexercised.
Add test_sctp_nat_connect_v4: untracked client traffic to
192.168.0.20:4443 hits ct(commit,nat(dst=172.31.110.20:5555)),recirc,
and the post-recirc flows match the translated tuple,
ipv4(dst=172.31.110.20),sctp(dst=5555). Reply traffic is matched on
the restored original tuple, sctp(src=4443). With the SCTP branch
broken the translated port never reaches the key, no post-recirc
flow matches, and the association fails. The probe flow uses the
same ct+nat action as the real flows, so a kernel without
CONFIG_NF_NAT rejects it at flow-add time and the test skips instead
of failing. The config fragment sets CONFIG_NETFILTER_ADVANCED=y so
CONFIG_NF_CT_PROTO_SCTP is visible, CONFIG_NF_CT_PROTO_SCTP=y, and
CONFIG_NF_NAT=m so the reference build actually has those pieces.
After the association succeeds the test pushes a known payload
across and waits for the listener to log it.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
Reviewed-by: Narcisa Vasile <narcisav.kernel@gmail.com>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260918144647.2024095-3-houminxi@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The merged SCTP test covers only IPv4. The SCTP branch of the IPv6
extractor (the proto=132 walk after parse_ipv6hdr) and the v6 side of
the SCTP netlink validation (match_validate() requires the sctp() key
whenever ipv6(proto=132) is matched) have no selftest coverage.
Add test_sctp_connect_v6 mirroring the v4 test: bare icmpv6() flows
forward NS/NA, and ipv6(proto=132),sctp(dst=4443)/sctp(src=4443)
flows gate the association in the same three phases (flows installed,
removed, reinstalled). A keyless ipv6(proto=132) install must be
refused with EINVAL, pinning the reject side of the match_validate()
rule; without it a regression dropping the requirement would pass
unnoticed. The refusal is asserted to be EINVAL specifically, not a
parse error of the flow string. After the association succeeds the
test also pushes a known payload across and waits for the listener
to log it, proving the datapath carries the association's traffic
end to end, not only its handshake. Skips when the sctp module is
missing, socat lacks SCTP or IPv6 support, or IPv6 is unavailable;
an association or payload failure with the flows installed fails
the test.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
Reviewed-by: Narcisa Vasile <narcisav.kernel@gmail.com>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260918144647.2024095-2-houminxi@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Remove stale @vport parameter descriptions from
idpf_rx_desc_rel_all() and idpf_vport_queue_grp_rel_all().
Signed-off-by: Ayush Yaduvanshi <ayush37735@gmail.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Link: https://patch.msgid.link/20260925000244.72480-1-ayush37735@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Remove stale @count and @cgu parameter descriptions from
ice_dpll_init_fwnode_pins() and ice_dpll_init_pins_e825().
Signed-off-by: Ayush Yaduvanshi <ayush37735@gmail.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Link: https://patch.msgid.link/20260924232138.69492-1-ayush37735@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Jakub Kicinski says:
====================
dpll: fix LLM nit picks from the spec scan
Fix issues found by an LLM scan of the Netlink spec for DPLL.
====================
Link: https://patch.msgid.link/20260924231211.568213-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The lock-status doc tells userspace that DPLL_LOCK_STATUS_UNLOCKED
can be forced by setting DPLL_A_MODE to DPLL_MODE_DETACHED.
But no such value has been defined so far. enum dpll_mode has only
MANUAL and AUTOMATIC. Let's make sure the doc reflects current
reality.
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
Link: https://patch.msgid.link/20260924231211.568213-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Pads need to be propagated to subsets if they are used.
Otherwise Python YNL can fail with:
YnlException: Space 'frequency-range' has no attribute with value '4'
This affects only platforms which care about alignment
so not much real impact.
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
Link: https://patch.msgid.link/20260924231211.568213-3-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
DPLL_A_PIN_FREQUENCY is a u64 on the wire and dpll_pin_freq_set() keeps it
as one, but dpll_pin_is_freq_supported() takes a u32 while the ranges it
compares against are u64. The supported-frequency check therefore only
looks at the low 32 bits, and the full value is what reaches the driver.
Nothing is hitting this today. Reaching it at all needs a pin-set above
U32_MAX, which no sane caller sends, and the outcome is mild: a pin
advertising 10 kHz accepts 0x1_0000_2710, ice narrows it straight back to
10 kHz in ice_dpll_pin_freq_set(), so the hardware still ends up on an
advertised frequency and only the "frequency is not supported by the
device" rejection goes missing. The other direction - a legitimate request
above U32_MAX wrapping out of the pin's range - needs a driver advertising
such a range, and none does; zl3073x_pin_check_freq() refuses one outright.
So this is types rather than a live bug. Widen the check to match the
attribute, the ranges and the driver callback instead of adding a U32_MAX
rejection, so that the second case stays right if such a driver appears.
dpll_pin_esync_set() already keeps u64 throughout its equivalent loop.
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
Link: https://patch.msgid.link/20260924231211.568213-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The MXL86211C also supports 2.5G via 2500BASEX, switch the config init
to indicate support for that mode. Datasheet checks indicate that the
2.5G speed indication is the same between GPY211 & MXL86211C.
The same should be true for MXL86252 & MXL86282, those are not modified
for a lack of testing hardware.
With this change 2.5G negotiates correctly with a Mikrotik
CRS310-8G+2S+IN.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Rouven Czerwinski <rouven.czerwinski@linaro.org>
Link: https://patch.msgid.link/20260924-mainline-rouven-mxl2g5-v2-1-fc8367a4c3ad@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Convert the deprecated send and receive completion tasklets in
net/rds/ib to BH work items queued on system_bh_wq.
In rds_ib_conn_path_shutdown(), replace tasklet_kill() with
disable_work_sync(), and call enable_work() after destroying the CQs so
the work items can be used again when the connection reconnects.
Signed-off-by: Sunny Tiwari <sunnytiwari@google.com>
Reviewed-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20cbfc32678019daadd3c67fd75262b8264aa180.1790178801.git.sunnytiwari@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Kim Wooseok via says:
====================
net: macb: Rework hardware timestamp configuration
This started with two problems I found while using PTP hardware
timestamping on a Raspberry Pi 5. A rejected RX filter could still
change the TX one-step setting, and the PTPv1 Sync and Delay_Req filters
returned success without enabling RX timestamps.
This series reworks gem_set_hwtst() to validate the whole request before
programming the hardware. It calculates the settings locally, then
updates the registers and saved configuration under bp->lock. With the
register writes now in the setter, the two helpers are no longer needed.
The remaining patches use the existing ALL fallback for the specific
PTPv1 filters and clear SRTSM when switching away from a PTPv2 filter.
Each change is kept in its own patch.
For v1, I compared the old and new behavior on the Pi 5. When I
requested a TX mode change together with an invalid RX filter, the
patched driver rejected the request without changing the saved settings
or NCR. I also checked transitions between PTPv2 RX and the other
receive filters. SRTSM followed the selected RX filter without changing
unrelated NCR bits.
For the PTPv1 filters, I checked the effect by sending Sync and Delay_Req
packets over Ethernet. Before the change, the packets arrived without
hardware timestamps. With the patches, the driver returned ALL and I
could read the hardware timestamps from the received packets. PTPv2
multicast reception continued to provide hardware timestamps, and
selecting NONE disabled timestamping. I ran these tests with the changes
backported to the Pi's existing Linux 6.18.46 RT kernel.
====================
Link: https://patch.msgid.link/20260923-macb-hwtstamp-rework-v2-0-75c909b2676d@khu.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
A PTPv2 receive filter sets NCR.SRTSM, but switching to NONE, ALL or a
PTPv1 filter leaves it set. As a result, selecting the same filter can
produce a different register setting depending on whether PTPv2 was
used before.
Update SRTSM whenever the RX filter changes, setting it only for PTPv2.
Switching away from PTPv2 then clears the old setting, so the bit follows
the currently selected filter.
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Tested-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Kim Wooseok <5mghybrid@khu.ac.kr>
Link: https://patch.msgid.link/20260923-macb-hwtstamp-rework-v2-3-75c909b2676d@khu.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Selecting a PTPv1 Sync or Delay_Req filter in gem_set_hwtst() returns
success, but leaves rx_bd_control at its initial value of
TSTAMP_DISABLED. The requested filter therefore appears to have been
applied, even though received packets have no hardware timestamps.
The PTPv1 event case already enables timestamping for all frames, so
use that path for Sync and Delay_Req as well. This enables timestamping
for both requests and returns HWTSTAMP_FILTER_ALL to tell the caller
which filter was actually applied.
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Tested-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Kim Wooseok <5mghybrid@khu.ac.kr>
Link: https://patch.msgid.link/20260923-macb-hwtstamp-rework-v2-2-75c909b2676d@khu.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
gem_set_hwtst() can reject a request after changing the TX one-step
setting, because it programs the TX mode before checking the RX
filter. The call returns -ERANGE, but the hardware may no longer match
the cached configuration.
Validate both settings first and keep the adjusted RX filter local
until validation succeeds. Then apply the register settings and update
the configuration. A rejected request now leaves the hardware, the
caller's settings and the cached configuration unchanged.
Protect the NCR read-modify-write with bp->lock, keeping the descriptor
writes and cache update in the same section. With the register writes
now in the setter, remove gem_ptp_set_one_step_sync() and
gem_ptp_set_ts_mode().
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Tested-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Kim Wooseok <5mghybrid@khu.ac.kr>
Link: https://patch.msgid.link/20260923-macb-hwtstamp-rework-v2-1-75c909b2676d@khu.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Sergey Shtylyov says:
====================
ch9200: stop ignoring the register write errors
The successful register writes, done via the USB control requests, seem
vital for the normal functioning of the device, however the driver tends
to completely ignore the register write errors, even though it could well
propagate the errors from its bind() method. Additionally, it masks any
USB errors returned by usb_control_msg(), pretending that the call was
successful. Let's stop doing all that and see how it goes... :-)
====================
Link: https://patch.msgid.link/20260923201440.36966-1-s.shtylyov@auroraos.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Compared with control_read(), control_write() looks really strange:
it ignores any errors returned by usb_control_msg(), always returning
0 instead, despite overriding a positive result of usb_control_msg()
(indicating short transfer) to -EINVAL before doing that. Drop that
dubious *return* and propagate USB errors to the callers...
Signed-off-by: Sergey Shtylyov <s.shtylyov@auroraos.dev>
Link: https://patch.msgid.link/20260923201440.36966-3-s.shtylyov@auroraos.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The successful register writes, done via the USB control requests in
control_write(), seem vital for the normal functioning of the device,
however the driver's bind() method ignores error codes returned from
control_write(). Do bail out of ch9200_bind() on failed writes...
Signed-off-by: Sergey Shtylyov <s.shtylyov@auroraos.dev>
Link: https://patch.msgid.link/20260923201440.36966-2-s.shtylyov@auroraos.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The Lynx PCS setup for 10g-qxgmii and usxgmii programs the
USXGMII replicator advertisement, but does not explicitly enable and
restart in-band autonegotiation or program the replicator link timers.
This leaves the PCS dependent on firmware or bootloader state. Systems
which do not get the USXGMII replicator preconfigured before Linux may
therefore fail to negotiate the link correctly.
After programming the USXGMII device ability, configure the replicator
BMCR with reset, autonegotiation enable and autonegotiation restart. Also
program the replicator link timer registers using the value returned by
phylink_get_link_timer_ns().
Co-developed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Patryk Biel <pbiel7@gmail.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260923-b4-fix-pcs-lynx-an-v4-1-3f7927606d12@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>