[PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling between VEB and VEPA

Jakub Slepecki posted 8 patches 6 days, 15 hours ago
[PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling between VEB and VEPA
Posted by Jakub Slepecki 6 days, 15 hours ago
When changing into VEPA mode MAC rules are modified to forward all traffic
to the wire instead of allowing some packets to go into the loopback.
MAC,VLAN rules may and will also be used to forward loopback traffic
in VEB, so when we switch to VEPA, we want them to behave similarly to
MAC-only rules.

ice_vsi_update_bridge_mode() will now attempt a rollback of switch
filters in case an update fails.  If the rollback also fails, we will
now return the rollback error instead of the initial error.

Signed-off-by: Jakub Slepecki <jakub.slepecki@intel.com>

---
Testing hints:
  MAC,VLAN rules are created only if entire series is applied.
  The easiest way to test that rules were adjusted is to run traffic
  and observe what packets are sent to LAN.  VEPA is expected to behave
  same as before the series.  VEB is expected to (a) behave like VEPA
  if loopback traffic would cross VLANs, or (b) behave as before.
  Traffic from/to external hosts is expected to remain unchanged.

Dropping reviewed-by Michał due to changes.

Changes in v2:
  - Close open parenthesis in ice_vsi_update_bridge_mode() description.
  - Explain returns in ice_vsi_update_bridge_mode().
---
 drivers/net/ethernet/intel/ice/ice_main.c   | 48 +++++++++++++++++----
 drivers/net/ethernet/intel/ice/ice_switch.c |  8 ++--
 drivers/net/ethernet/intel/ice/ice_switch.h |  3 +-
 3 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 0b6175ade40d..921ed2b6c0aa 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -8104,8 +8104,16 @@ static int ice_vsi_update_bridge_mode(struct ice_vsi *vsi, u16 bmode)
  *
  * Sets the bridge mode (VEB/VEPA) of the switch to which the netdev (VSI) is
  * hooked up to. Iterates through the PF VSI list and sets the loopback mode (if
- * not already set for all VSIs connected to this switch. And also update the
+ * not already set for all VSIs connected to this switch). And also update the
  * unicast switch filter rules for the corresponding switch of the netdev.
+ *
+ * Return:
+ * * %0 if mode was set, propagated to VSIs, and changes to filters were all
+ *   successful,
+ * * %-EINVAL if requested netlink attributes or bridge mode were invalid,
+ * * otherwise an error from VSI update, filter rollback, or filter update is
+ *   forwarded. This may include %-EINVAL. See ice_vsi_update_bridge_mode() and
+ *   ice_update_sw_rule_bridge_mode().
  */
 static int
 ice_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
@@ -8115,8 +8123,8 @@ ice_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
 	struct ice_pf *pf = ice_netdev_to_pf(dev);
 	struct nlattr *attr, *br_spec;
 	struct ice_hw *hw = &pf->hw;
+	int rem, v, rb_err, err = 0;
 	struct ice_sw *pf_sw;
-	int rem, v, err = 0;
 
 	pf_sw = pf->first_sw;
 	/* find the attribute in the netlink message */
@@ -8126,6 +8134,7 @@ ice_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
 
 	nla_for_each_nested_type(attr, IFLA_BRIDGE_MODE, br_spec, rem) {
 		__u16 mode = nla_get_u16(attr);
+		u8 old_evb_veb = hw->evb_veb;
 
 		if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
 			return -EINVAL;
@@ -8147,17 +8156,38 @@ ice_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
 		/* Update the unicast switch filter rules for the corresponding
 		 * switch of the netdev
 		 */
-		err = ice_update_sw_rule_bridge_mode(hw);
+		err = ice_update_sw_rule_bridge_mode(hw, ICE_SW_LKUP_MAC);
+		if (err) {
+			/* evb_veb is expected to be already reverted in error
+			 * path because of the potential rollback.
+			 */
+			hw->evb_veb = old_evb_veb;
+			goto err_without_rollback;
+		}
+		err = ice_update_sw_rule_bridge_mode(hw, ICE_SW_LKUP_MAC_VLAN);
 		if (err) {
-			netdev_err(dev, "switch rule update failed, mode = %d err %d aq_err %s\n",
-				   mode, err,
+			/* ice_update_sw_rule_bridge_mode looks this up, so we
+			 * must revert it before attempting a rollback.
+			 */
+			hw->evb_veb = old_evb_veb;
+			goto err_rollback_mac;
+		}
+		pf_sw->bridge_mode = mode;
+		continue;
+
+err_rollback_mac:
+		rb_err = ice_update_sw_rule_bridge_mode(hw, ICE_SW_LKUP_MAC);
+		if (rb_err) {
+			netdev_err(dev, "switch rule update failed, mode = %d err %d; rollback failed, err %d aq_err %s\n",
+				   mode, err, rb_err,
 				   libie_aq_str(hw->adminq.sq_last_status));
-			/* revert hw->evb_veb */
-			hw->evb_veb = (pf_sw->bridge_mode == BRIDGE_MODE_VEB);
-			return err;
+			return rb_err;
 		}
 
-		pf_sw->bridge_mode = mode;
+err_without_rollback:
+		netdev_err(dev, "switch rule update failed, mode = %d err %d aq_err %s\n",
+			   mode, err, libie_aq_str(hw->adminq.sq_last_status));
+		return err;
 	}
 
 	return 0;
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index b3f5cda1571e..e0ff9a0882d5 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -3065,10 +3065,12 @@ ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
 /**
  * ice_update_sw_rule_bridge_mode
  * @hw: pointer to the HW struct
+ * @lkup: recipe/lookup type to update
  *
  * Updates unicast switch filter rules based on VEB/VEPA mode
  */
-int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
+int ice_update_sw_rule_bridge_mode(struct ice_hw *hw,
+				   enum ice_sw_lkup_type lkup)
 {
 	struct ice_switch_info *sw = hw->switch_info;
 	struct ice_fltr_mgmt_list_entry *fm_entry;
@@ -3076,8 +3078,8 @@ int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
 	struct mutex *rule_lock; /* Lock to protect filter rule list */
 	int status = 0;
 
-	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
-	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
+	rule_lock = &sw->recp_list[lkup].filt_rule_lock;
+	rule_head = &sw->recp_list[lkup].filt_rules;
 
 	mutex_lock(rule_lock);
 	list_for_each_entry(fm_entry, rule_head, list_entry) {
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h
index b694c131ad58..f1917e15b26c 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.h
+++ b/drivers/net/ethernet/intel/ice/ice_switch.h
@@ -361,7 +361,8 @@ int
 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 		 u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
 		 struct ice_rule_query_data *added_entry);
-int ice_update_sw_rule_bridge_mode(struct ice_hw *hw);
+int ice_update_sw_rule_bridge_mode(struct ice_hw *hw,
+				   enum ice_sw_lkup_type lkup);
 int ice_add_vlan(struct ice_hw *hw, struct list_head *m_list);
 int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list);
 int ice_add_mac(struct ice_hw *hw, struct list_head *m_lst);
-- 
2.43.0

RE: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling between VEB and VEPA
Posted by Loktionov, Aleksandr 6 days, 15 hours ago

> -----Original Message-----
> From: Slepecki, Jakub <jakub.slepecki@intel.com>
> Sent: Tuesday, November 25, 2025 9:35 AM
> To: intel-wired-lan@lists.osuosl.org
> Cc: linux-kernel@vger.kernel.org; netdev@vger.kernel.org; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; michal.swiatkowski@linux.intel.com; Slepecki,
> Jakub <jakub.slepecki@intel.com>; Loktionov, Aleksandr
> <aleksandr.loktionov@intel.com>
> Subject: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling
> between VEB and VEPA
> 
> When changing into VEPA mode MAC rules are modified to forward all traffic
> to the wire instead of allowing some packets to go into the loopback.
> MAC,VLAN rules may and will also be used to forward loopback traffic in VEB,
> so when we switch to VEPA, we want them to behave similarly to MAC-only
> rules.
> 
> ice_vsi_update_bridge_mode() will now attempt a rollback of switch filters
> in case an update fails.  If the rollback also fails, we will now return the
> rollback error instead of the initial error.
> 
> Signed-off-by: Jakub Slepecki <jakub.slepecki@intel.com>
> 
> ---
> Testing hints:
>   MAC,VLAN rules are created only if entire series is applied.
>   The easiest way to test that rules were adjusted is to run traffic
>   and observe what packets are sent to LAN.  VEPA is expected to behave
>   same as before the series.  VEB is expected to (a) behave like VEPA
>   if loopback traffic would cross VLANs, or (b) behave as before.
>   Traffic from/to external hosts is expected to remain unchanged.
> 
Better to provide exact bash commands.
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>


> Dropping reviewed-by Michał due to changes.
> 
> Changes in v2:
>   - Close open parenthesis in ice_vsi_update_bridge_mode() description.
>   - Explain returns in ice_vsi_update_bridge_mode().
> ---
>  drivers/net/ethernet/intel/ice/ice_main.c   | 48 +++++++++++++++++----
>  drivers/net/ethernet/intel/ice/ice_switch.c |  8 ++--
> drivers/net/ethernet/intel/ice/ice_switch.h |  3 +-
>  3 files changed, 46 insertions(+), 13 deletions(-)
> 

Re: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling between VEB and VEPA
Posted by Jakub Slepecki 3 days, 15 hours ago
On 2025-11-25 9:52, Loktionov, Aleksandr wrote:
> Better to provide exact bash commands.

All right, I'll review the commands in the 0/8 and see if I can expand
them for this context.  I'll refer it here.  I suppose I could add the
bridge(8) example for hwmode?  Something like:

     Testing hints:
         MAC,VLAN rules are created only if entire series is applied.
         The easiest way to test that rules were adjusted is to run traffic
         and observe what packets are sent to LAN.  VEPA is expected to behave
         same as before the series.  VEB is expected to (a) behave like VEPA
         if loopback traffic would cross VLANs, or (b) behave as before.
         Traffic from/to external hosts is expected to remain unchanged.

         Refer to 0/8 for full network configuration.  To change hwmode use:

         bridge link set dev $pf hwmode {veb,vepa}

> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

I'll drop it since you did not explicitly say it's fine to keep it.

Thanks!
RE: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling between VEB and VEPA
Posted by Loktionov, Aleksandr 3 days, 15 hours ago

> -----Original Message-----
> From: Slepecki, Jakub <jakub.slepecki@intel.com>
> Sent: Friday, November 28, 2025 9:29 AM
> To: Loktionov, Aleksandr <aleksandr.loktionov@intel.com>; intel-wired-
> lan@lists.osuosl.org
> Cc: linux-kernel@vger.kernel.org; netdev@vger.kernel.org; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; michal.swiatkowski@linux.intel.com
> Subject: Re: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when
> toggling between VEB and VEPA
> 
> On 2025-11-25 9:52, Loktionov, Aleksandr wrote:
> > Better to provide exact bash commands.
> 
> All right, I'll review the commands in the 0/8 and see if I can expand them
> for this context.  I'll refer it here.  I suppose I could add the
> bridge(8) example for hwmode?  Something like:
> 
>      Testing hints:
>          MAC,VLAN rules are created only if entire series is applied.
>          The easiest way to test that rules were adjusted is to run traffic
>          and observe what packets are sent to LAN.  VEPA is expected to
> behave
>          same as before the series.  VEB is expected to (a) behave like VEPA
>          if loopback traffic would cross VLANs, or (b) behave as before.
>          Traffic from/to external hosts is expected to remain unchanged.
> 
>          Refer to 0/8 for full network configuration.  To change hwmode use:
> 
>          bridge link set dev $pf hwmode {veb,vepa}
> 
> > Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> 
> I'll drop it since you did not explicitly say it's fine to keep it.
> 
> Thanks!

Thanks for clarifying and for adding the testing hints.

The example with `bridge link set dev $pf hwmode {veb,vepa}` looks good and makes the intent clear. Adding the note that MAC/VLAN rules require the full series is helpful.

One small suggestion: please include prerequisites in the 0/8 cover letter (e.g., `iproute2` version and that commands need root privileges), so testers don’t miss that.

Otherwise, the instructions are fine from my side. Please keep my:

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

Thanks!
Re: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling between VEB and VEPA
Posted by Jakub Slepecki 3 days, 11 hours ago
On 2025-11-28 9:36, Loktionov, Aleksandr wrote:
> One small suggestion: please include prerequisites in the 0/8 cover letter (e.g., `iproute2` version and that commands need root privileges), so testers don’t miss that.

Roger that; I plan to use following:

---
To reproduce the issue have a E810 ($pfa) connected to another adapter
($pfb), then:

     # echo 2 >/sys/class/net/$pfa/device/sriov_numvfs
     # ip l set $pfa vf 0 vlan 4
     # ip l set $pfa vf 1 vlan 7
     # ip l set $pfa_vf0 netns $pfa_vf0_netns up
     # ip l set $pfa_vf1 netns $pfa_vf1_netns up
     # ip netns exec $pfa_vf0_netns ip a add 10.0.0.1/24 dev $pfa_vf0
     # ip netns exec $pfa_vf1_netns ip a add 10.0.0.2/24 dev $pfa_vf1

And for the $pfb:

     # echo 2 >/sys/class/net/$pfb/device/sriov_numvfs
     # ip l set $pfb vf 0 trust on spoof off vlan 4
     # ip l set $pfb vf 1 trust on spoof off vlan 7
     # ip l add $br type bridge
     # ip l set $pfb_vf0 master $br up
     # ip l set $pfb_vf1 master $br up
     # ip l set $br up

We expect $pfa_vf0 to be able to reach $pfa_vf1 through the $br on
the link partner.  Instead, ARP is unable to resolve 10.0.0.2/24.
ARP request is fine because it's broadcasted and bounces off $br, but
ARP reply is stuck in the internal switch because the destination MAC
matches $pfa_vf0 and filter restricts it to loopback.

In testing I used: ip utility, iproute2-6.1.0, libbpf 1.3.0
---

> Otherwise, the instructions are fine from my side. Please keep my:
> 
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> 
> Thanks!

Thanks!

RE: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when toggling between VEB and VEPA
Posted by Loktionov, Aleksandr 16 hours ago

> -----Original Message-----
> From: Slepecki, Jakub <jakub.slepecki@intel.com>
> Sent: Friday, November 28, 2025 1:29 PM
> To: Loktionov, Aleksandr <aleksandr.loktionov@intel.com>; intel-wired-
> lan@lists.osuosl.org
> Cc: linux-kernel@vger.kernel.org; netdev@vger.kernel.org; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; michal.swiatkowski@linux.intel.com
> Subject: Re: [PATCH iwl-next v2 5/8] ice: update mac,vlan rules when
> toggling between VEB and VEPA
> 
> On 2025-11-28 9:36, Loktionov, Aleksandr wrote:
> > One small suggestion: please include prerequisites in the 0/8 cover
> letter (e.g., `iproute2` version and that commands need root
> privileges), so testers don’t miss that.
> 
> Roger that; I plan to use following:
> 
> ---
> To reproduce the issue have a E810 ($pfa) connected to another adapter
> ($pfb), then:
> 
>      # echo 2 >/sys/class/net/$pfa/device/sriov_numvfs
>      # ip l set $pfa vf 0 vlan 4
>      # ip l set $pfa vf 1 vlan 7
>      # ip l set $pfa_vf0 netns $pfa_vf0_netns up
>      # ip l set $pfa_vf1 netns $pfa_vf1_netns up
>      # ip netns exec $pfa_vf0_netns ip a add 10.0.0.1/24 dev $pfa_vf0
>      # ip netns exec $pfa_vf1_netns ip a add 10.0.0.2/24 dev $pfa_vf1
> 
> And for the $pfb:
> 
>      # echo 2 >/sys/class/net/$pfb/device/sriov_numvfs
>      # ip l set $pfb vf 0 trust on spoof off vlan 4
>      # ip l set $pfb vf 1 trust on spoof off vlan 7
>      # ip l add $br type bridge
>      # ip l set $pfb_vf0 master $br up
>      # ip l set $pfb_vf1 master $br up
>      # ip l set $br up
> 
> We expect $pfa_vf0 to be able to reach $pfa_vf1 through the $br on the
> link partner.  Instead, ARP is unable to resolve 10.0.0.2/24.
> ARP request is fine because it's broadcasted and bounces off $br, but
> ARP reply is stuck in the internal switch because the destination MAC
> matches $pfa_vf0 and filter restricts it to loopback.
> 
> In testing I used: ip utility, iproute2-6.1.0, libbpf 1.3.0
> ---
> 
> > Otherwise, the instructions are fine from my side. Please keep my:
> >
> > Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> >
> > Thanks!
> 
> Thanks!


Good day Jakub,
Thanks for sharing the reproduction steps and clarifying the environment details.\
Including prerequisites like iproute2 version and root privileges in the cover letter is a good idea—it helps testers avoid subtle issues.

Reviewed-by stays valid from my side.

Best regards,
Alex