Message ID | 20231201075043.7822-3-kurt@linutronix.de (mailing list archive) |
---|---|
State | Awaiting Upstream |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | igc: ethtool: Check VLAN TCI mask | expand |
On Fri, Dec 01, 2023 at 08:50:43AM +0100, Kurt Kanzenbach wrote: > Currently the driver accepts VLAN TCI steering rules regardless of the > configured mask. And things might fail silently or with confusing error > messages to the user. > > There are two ways to handle the VLAN TCI mask: > > 1. Match on the PCP field using a VLAN prio filter > 2. Match on complete TCI field using a flex filter > > Therefore, add checks and code for that. > > For instance the following rule is invalid and will be converted into a > VLAN prio rule which is not correct: > |root@host:~# ethtool -N enp3s0 flow-type ether vlan 0x0001 m 0xf000 \ > | action 1 > |Added rule with ID 61 > |root@host:~# ethtool --show-ntuple enp3s0 > |4 RX rings available > |Total 1 rules > | > |Filter: 61 > | Flow Type: Raw Ethernet > | Src MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF > | Dest MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF > | Ethertype: 0x0 mask: 0xFFFF > | VLAN EtherType: 0x0 mask: 0xffff > | VLAN: 0x1 mask: 0x1fff > | User-defined: 0x0 mask: 0xffffffffffffffff > | Action: Direct to queue 1 > > After: > |root@host:~# ethtool -N enp3s0 flow-type ether vlan 0x0001 m 0xf000 \ > | action 1 > |rmgr: Cannot insert RX class rule: Operation not supported > > Fixes: 7991487ecb2d ("igc: Allow for Flex Filters to be installed") > Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> > Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com> Reviewed-by: Simon Horman <horms@kernel.org>
On 12/1/2023 09:50, Kurt Kanzenbach wrote: > Currently the driver accepts VLAN TCI steering rules regardless of the > configured mask. And things might fail silently or with confusing error > messages to the user. > > There are two ways to handle the VLAN TCI mask: > > 1. Match on the PCP field using a VLAN prio filter > 2. Match on complete TCI field using a flex filter > > Therefore, add checks and code for that. > > For instance the following rule is invalid and will be converted into a > VLAN prio rule which is not correct: > |root@host:~# ethtool -N enp3s0 flow-type ether vlan 0x0001 m 0xf000 \ > | action 1 > |Added rule with ID 61 > |root@host:~# ethtool --show-ntuple enp3s0 > |4 RX rings available > |Total 1 rules > | > |Filter: 61 > | Flow Type: Raw Ethernet > | Src MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF > | Dest MAC addr: 00:00:00:00:00:00 mask: FF:FF:FF:FF:FF:FF > | Ethertype: 0x0 mask: 0xFFFF > | VLAN EtherType: 0x0 mask: 0xffff > | VLAN: 0x1 mask: 0x1fff > | User-defined: 0x0 mask: 0xffffffffffffffff > | Action: Direct to queue 1 > > After: > |root@host:~# ethtool -N enp3s0 flow-type ether vlan 0x0001 m 0xf000 \ > | action 1 > |rmgr: Cannot insert RX class rule: Operation not supported > > Fixes: 7991487ecb2d ("igc: Allow for Flex Filters to be installed") > Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> > Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com> > --- > drivers/net/ethernet/intel/igc/igc.h | 1 + > drivers/net/ethernet/intel/igc/igc_ethtool.c | 28 +++++++++++++++++--- > 2 files changed, 26 insertions(+), 3 deletions(-) Tested-by: Naama Meir <naamax.meir@linux.intel.com>
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index f48f82d5e274..85cc16396506 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -568,6 +568,7 @@ struct igc_nfc_filter { u16 etype; __be16 vlan_etype; u16 vlan_tci; + u16 vlan_tci_mask; u8 src_addr[ETH_ALEN]; u8 dst_addr[ETH_ALEN]; u8 user_data[8]; diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 69b2fd006293..b56b4f338bd3 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -958,6 +958,7 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev, } #define ETHER_TYPE_FULL_MASK ((__force __be16)~0) +#define VLAN_TCI_FULL_MASK ((__force __be16)~0) static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter, struct ethtool_rxnfc *cmd) { @@ -989,7 +990,7 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter, if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) { fsp->flow_type |= FLOW_EXT; fsp->h_ext.vlan_tci = htons(rule->filter.vlan_tci); - fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK); + fsp->m_ext.vlan_tci = htons(rule->filter.vlan_tci_mask); } if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) { @@ -1224,6 +1225,7 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule, if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) { rule->filter.vlan_tci = ntohs(fsp->h_ext.vlan_tci); + rule->filter.vlan_tci_mask = ntohs(fsp->m_ext.vlan_tci); rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI; } @@ -1261,11 +1263,19 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule, memcpy(rule->filter.user_mask, fsp->m_ext.data, sizeof(fsp->m_ext.data)); } - /* When multiple filter options or user data or vlan etype is set, use a - * flex filter. + /* The i225/i226 has various different filters. Flex filters provide a + * way to match up to the first 128 bytes of a packet. Use them for: + * a) For specific user data + * b) For VLAN EtherType + * c) For full TCI match + * d) Or in case multiple filter criteria are set + * + * Otherwise, use the simple MAC, VLAN PRIO or EtherType filters. */ if ((rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) || (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) || + ((rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) && + rule->filter.vlan_tci_mask == ntohs(VLAN_TCI_FULL_MASK)) || (rule->filter.match_flags & (rule->filter.match_flags - 1))) rule->flex = true; else @@ -1335,6 +1345,18 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter, return -EINVAL; } + /* There are two ways to match the VLAN TCI: + * 1. Match on PCP field and use vlan prio filter for it + * 2. Match on complete TCI field and use flex filter for it + */ + if ((fsp->flow_type & FLOW_EXT) && + fsp->m_ext.vlan_tci && + fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK) && + fsp->m_ext.vlan_tci != VLAN_TCI_FULL_MASK) { + netdev_dbg(netdev, "VLAN mask not supported\n"); + return -EOPNOTSUPP; + } + if (fsp->location >= IGC_MAX_RXNFC_RULES) { netdev_dbg(netdev, "Invalid location\n"); return -EINVAL;