Thread (7 messages) 7 messages, 2 authors, 18d ago

Re: [PATCH iwl-net v2 2/2] ice: preserve uplink DFLT Rx rule on switchdev release

From: Petr Oros <hidden>
Date: 2026-06-29 13:23:24

On 6/23/26 18:25, Simon Horman wrote:
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
ice: preserve uplink DFLT Rx rule on switchdev release

This commit preserves the default Rx rule on the uplink VSI when releasing
the switchdev environment if the interface is in promiscuous mode. This
prevents the catch-all rule from being removed while the netdev flags still
request promiscuity.
quoted
diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c
index 2e4f0969035f7..48273ef9f69dc 100644
--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
+++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
[ ... ]
quoted
@@ -278,8 +280,16 @@ static void ice_eswitch_release_env(struct ice_pf *pf)
  	vlan_ops->ena_rx_filtering(uplink_vsi);
[Severity: High]
Could this lockless read of netdev->flags cause a regression due to a TOCTOU
race?
Both reads key on the same live netdev->flags & IFF_PROMISC (the pruning
read just above included); it is a single word, so no torn read, and a
flip in the two-statement window is transient and reconciled by the next
ice_vsi_sync_fltr() after switchdev stops. I kept the read live on purpose
so the preserved rule and the pruning decision key on the same source.
The ena_rx_filtering() call eventually reaches ice_cfg_vlan_pruning(),
which reads uplink_vsi->netdev->flags & IFF_PROMISC locklessly to decide
whether to enable VLAN pruning.
quoted
  	ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
  			 ICE_FLTR_TX);
-	ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
-			 ICE_FLTR_RX);
+
+	/* Keep the Rx DFLT rule if the uplink is promiscuous; it must outlive
+	 * the session. Test the live netdev->flags, the same value
+	 * ena_rx_filtering() -> ice_cfg_vlan_pruning() above keys its decision
+	 * on, so the preserved DFLT rule and the pruning state stay consistent.
+	 */
+	if (!(uplink_vsi->netdev->flags & IFF_PROMISC))
... and then the exact same flags are read locklessly again right here.

Because setup/teardown paths are protected by devl_lock rather than
rtnl_lock, could a concurrent dev_change_flags() holding rtnl_lock toggle
IFF_PROMISC between the two checks?

If IFF_PROMISC changes from 0 to 1 in this window, the code would incorrectly
enable VLAN pruning (seeing 0) and then incorrectly retain the DFLT_RX rule
(seeing 1), leaving the hardware with VLAN pruning enabled during promiscuous
mode.

[Severity: High]
Does preserving the Rx DFLT rule here cause a regression by permanently
breaking multicast promiscuity configuration if IFF_PROMISC was set?
Correct, the DFLT rule is unicast only. v3 will fix this in patch 1:
ice_set_promisc(ICE_MCAST_PROMISC_BITS) will run whenever the netdev is
promiscuous, including when ice_is_dflt_vsi_in_use() is already true.
During the switchdev session, ice_remove_vsi_fltr() removes the
ICE_SW_LKUP_PROMISC rules. By manually preserving the DFLT rule here, any
future synchronization via ice_vsi_sync_fltr() will evaluate
!ice_is_dflt_vsi_in_use(vsi->port_info) as false:

ice_main.c:ice_vsi_sync_fltr() {
     ...
     if (!ice_is_dflt_vsi_in_use(vsi->port_info)) {
         err = ice_set_dflt_vsi(vsi);
         ...
         err = ice_set_promisc(vsi, ICE_MCAST_PROMISC_BITS);
     }
     ...
}

Because it is skipped, ICE_MCAST_PROMISC_BITS is never configured, leaving
the VSI in unicast promiscuous mode but silently dropping multicast traffic
destined for other MAC addresses.
quoted
+		ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx,
+				 false, ICE_FLTR_RX);
+
  	ice_fltr_add_mac_and_broadcast(uplink_vsi,
  				       uplink_vsi->port_info->mac.perm_addr,
  				       ICE_FWD_TO_VSI);
[Severity: High]
This is a pre-existing issue, but does this teardown function fail to
synchronize hardware state for previously joined multicast groups and
secondary unicast addresses?
Pre-existing (rx_mode is gated during switchdev). This patch only gates
the DFLT Rx removal in ice_eswitch_release_env(); the multicast-promisc
half is covered by the v3 patch 1 change above, and replaying the full
deferred uc/mc list is a wider item left out here.

Petr
When entering switchdev mode, __dev_uc_unsync() and __dev_mc_unsync() clear
the synchronization state of OS-level MAC addresses, and
ice_remove_vsi_fltr() removes the actual hardware filters. While switchdev
runs, calls to ndo_set_rx_mode return early and do not update hardware.

When returning to legacy mode, this function restores only the primary MAC
and broadcast addresses, but doesn't seem to invoke netif_set_rx_mode() or
equivalent to resynchronize the deferred Rx filters from the netdev to the
hardware. Could this cause the hardware to silently drop packets for
previously joined groups until the interface is bounced?
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help