Skip to content

Commit b4a38d4

Browse files
vcgomesJeff Kirsher
authored andcommitted
igb: Add MAC address support for ethtool nftuple filters
This adds the capability of configuring the queue steering of arriving packets based on their source and destination MAC addresses. Source address steering (i.e. driving traffic to a specific queue), for the i210, does not work, but filtering does (i.e. accepting traffic based on the source address). So, trying to add a filter specifying only a source address will be an error. In practical terms this adds support for the following use cases, characterized by these examples: $ ethtool -N eth0 flow-type ether dst aa:aa:aa:aa:aa:aa action 0 (this will direct packets with destination address "aa:aa:aa:aa:aa:aa" to the RX queue 0) $ ethtool -N eth0 flow-type ether src 44:44:44:44:44:44 \ proto 0x22f0 action 3 (this will direct packets with source address "44:44:44:44:44:44" and ethertype 0x22f0 to the RX queue 3) Signed-off-by: Vinicius Costa Gomes <[email protected]> Tested-by: Aaron Brown <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent bae51fe commit b4a38d4

File tree

1 file changed

+39
-4
lines changed

1 file changed

+39
-4
lines changed

drivers/net/ethernet/intel/igb/igb_ethtool.c

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,23 @@ static int igb_get_ethtool_nfc_entry(struct igb_adapter *adapter,
24952495
fsp->h_ext.vlan_tci = rule->filter.vlan_tci;
24962496
fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK);
24972497
}
2498+
if (rule->filter.match_flags & IGB_FILTER_FLAG_DST_MAC_ADDR) {
2499+
ether_addr_copy(fsp->h_u.ether_spec.h_dest,
2500+
rule->filter.dst_addr);
2501+
/* As we only support matching by the full
2502+
* mask, return the mask to userspace
2503+
*/
2504+
eth_broadcast_addr(fsp->m_u.ether_spec.h_dest);
2505+
}
2506+
if (rule->filter.match_flags & IGB_FILTER_FLAG_SRC_MAC_ADDR) {
2507+
ether_addr_copy(fsp->h_u.ether_spec.h_source,
2508+
rule->filter.src_addr);
2509+
/* As we only support matching by the full
2510+
* mask, return the mask to userspace
2511+
*/
2512+
eth_broadcast_addr(fsp->m_u.ether_spec.h_source);
2513+
}
2514+
24982515
return 0;
24992516
}
25002517
return -EINVAL;
@@ -2768,8 +2785,16 @@ static int igb_rxnfc_write_vlan_prio_filter(struct igb_adapter *adapter,
27682785

27692786
int igb_add_filter(struct igb_adapter *adapter, struct igb_nfc_filter *input)
27702787
{
2788+
struct e1000_hw *hw = &adapter->hw;
27712789
int err = -EINVAL;
27722790

2791+
if (hw->mac.type == e1000_i210 &&
2792+
!(input->filter.match_flags & ~IGB_FILTER_FLAG_SRC_MAC_ADDR)) {
2793+
dev_err(&adapter->pdev->dev,
2794+
"i210 doesn't support flow classification rules specifying only source addresses.\n");
2795+
return -EOPNOTSUPP;
2796+
}
2797+
27732798
if (input->filter.match_flags & IGB_FILTER_FLAG_ETHER_TYPE) {
27742799
err = igb_rxnfc_write_etype_filter(adapter, input);
27752800
if (err)
@@ -2933,10 +2958,6 @@ static int igb_add_ethtool_nfc_entry(struct igb_adapter *adapter,
29332958
if ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW)
29342959
return -EINVAL;
29352960

2936-
if (fsp->m_u.ether_spec.h_proto != ETHER_TYPE_FULL_MASK &&
2937-
fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK))
2938-
return -EINVAL;
2939-
29402961
input = kzalloc(sizeof(*input), GFP_KERNEL);
29412962
if (!input)
29422963
return -ENOMEM;
@@ -2946,6 +2967,20 @@ static int igb_add_ethtool_nfc_entry(struct igb_adapter *adapter,
29462967
input->filter.match_flags = IGB_FILTER_FLAG_ETHER_TYPE;
29472968
}
29482969

2970+
/* Only support matching addresses by the full mask */
2971+
if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) {
2972+
input->filter.match_flags |= IGB_FILTER_FLAG_SRC_MAC_ADDR;
2973+
ether_addr_copy(input->filter.src_addr,
2974+
fsp->h_u.ether_spec.h_source);
2975+
}
2976+
2977+
/* Only support matching addresses by the full mask */
2978+
if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) {
2979+
input->filter.match_flags |= IGB_FILTER_FLAG_DST_MAC_ADDR;
2980+
ether_addr_copy(input->filter.dst_addr,
2981+
fsp->h_u.ether_spec.h_dest);
2982+
}
2983+
29492984
if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) {
29502985
if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) {
29512986
err = -EINVAL;

0 commit comments

Comments
 (0)