[PATCH iwl-next v2 2/8] ice: allow creating mac,vlan filters along mac filters

Jakub Slepecki
2025-11-25T08:35:04Z

Among other uses, MAC filters are currently used to forward loopback
traffic between VSIs. However, they only match destination MAC addresses
making them prone to mistakes when handling traffic within multiple
VLANs and especially across the boundaries.

This patch allows the driver to create MAC,VLAN filters in the same
flow as MAC-only filters completely interchangeably. This is intended
to be used to forward the loopback traffic only within the boundaries
of particular VLANs.

Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Jakub Slepecki <jakub.slepecki@intel.com>

---
No changes in v2.
---
drivers/net/ethernet/intel/ice/ice_switch.c | 48 ++++++++++++++++-----
1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index 84848f0123e7..0275e2910c6b 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -3606,6 +3606,29 @@ bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
return false;
}

+/**
+ * ice_fltr_mac_address - Find MAC in filter
+ * @dst: output MAC address
+ * @info: information struct for the filter in question
+ *
+ * Return: 0 for success, %-ENXIO if no address was found in the filter
+ * information.
+ */
+static
+int ice_fltr_mac_address(u8 *dst, struct ice_fltr_info *info)
+{
+ switch (info->lkup_type) {
+ case ICE_SW_LKUP_MAC:
+ ether_addr_copy(dst, info->l_data.mac.mac_addr);
+ return 0;
+ case ICE_SW_LKUP_MAC_VLAN:
+ ether_addr_copy(dst, info->l_data.mac_vlan.mac_addr);
+ return 0;
+ default:
+ return -ENXIO;
+ }
+}
+
/**
* ice_add_mac - Add a MAC address based filter rule
* @hw: pointer to the hardware structure
@@ -3614,16 +3637,19 @@ bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
int ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
{
struct ice_fltr_list_entry *m_list_itr;
- int status = 0;
+ int err;

if (!m_list || !hw)
return -EINVAL;

list_for_each_entry(m_list_itr, m_list, list_entry) {
- u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
+ u8 addr[ETH_ALEN];
u16 vsi_handle;
u16 hw_vsi_id;

+ err = ice_fltr_mac_address(addr, &m_list_itr->fltr_info);
+ if (err || is_zero_ether_addr(addr))
+ return -EINVAL;
m_list_itr->fltr_info.flag = ICE_FLTR_TX;
vsi_handle = m_list_itr->fltr_info.vsi_handle;
if (!ice_is_vsi_valid(hw, vsi_handle))
@@ -3634,17 +3660,19 @@ int ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
return -EINVAL;
m_list_itr->fltr_info.src = hw_vsi_id;
- if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
- is_zero_ether_addr(add))
+ if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC &&
+ m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC_VLAN)
return -EINVAL;

- m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
- m_list_itr);
+ m_list_itr->status =
+ ice_add_rule_internal(hw,
+ m_list_itr->fltr_info.lkup_type,
+ m_list_itr);
if (m_list_itr->status)
return m_list_itr->status;
}

- return status;
+ return 0;
}

/**
@@ -4055,7 +4083,7 @@ int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
u16 vsi_handle;

- if (l_type != ICE_SW_LKUP_MAC)
+ if (l_type != ICE_SW_LKUP_MAC && l_type != ICE_SW_LKUP_MAC_VLAN)
return -EINVAL;

vsi_handle = list_itr->fltr_info.vsi_handle;
@@ -4066,7 +4094,7 @@ int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
ice_get_hw_vsi_num(hw, vsi_handle);

list_itr->status = ice_remove_rule_internal(hw,
- ICE_SW_LKUP_MAC,
+ l_type,
list_itr);
if (list_itr->status)
return list_itr->status;
@@ -4507,6 +4535,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,

switch (lkup) {
case ICE_SW_LKUP_MAC:
+ case ICE_SW_LKUP_MAC_VLAN:
ice_remove_mac(hw, &remove_list_head);
break;
case ICE_SW_LKUP_VLAN:
@@ -4516,7 +4545,6 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
case ICE_SW_LKUP_PROMISC_VLAN:
ice_remove_promisc(hw, lkup, &remove_list_head);
break;
- case ICE_SW_LKUP_MAC_VLAN:
case ICE_SW_LKUP_ETHERTYPE:
case ICE_SW_LKUP_ETHERTYPE_MAC:
case ICE_SW_LKUP_DFLT:
--
2.43.0