Commit a6ccffaa authored by Haiyue Wang's avatar Haiyue Wang Committed by Tony Nguyen

iavf: Support Ethernet Type Flow Director filters

Support the addition and deletion of Ethernet filters.

Supported fields are: proto
Supported flow-types are: ether

Example usage:
ethtool -N ens787f0v0 flow-type ether proto 0x8863 action 6
ethtool -N ens787f0v0 flow-type ether proto 0x8864 action 7
Signed-off-by: default avatarHaiyue Wang <haiyue.wang@intel.com>
Tested-by: default avatarChen Bo <BoX.C.Chen@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent e90cbc25
...@@ -861,6 +861,8 @@ static int iavf_fltr_to_ethtool_flow(enum iavf_fdir_flow_type flow) ...@@ -861,6 +861,8 @@ static int iavf_fltr_to_ethtool_flow(enum iavf_fdir_flow_type flow)
return ESP_V6_FLOW; return ESP_V6_FLOW;
case IAVF_FDIR_FLOW_IPV6_OTHER: case IAVF_FDIR_FLOW_IPV6_OTHER:
return IPV6_USER_FLOW; return IPV6_USER_FLOW;
case IAVF_FDIR_FLOW_NON_IP_L2:
return ETHER_FLOW;
default: default:
/* 0 is undefined ethtool flow */ /* 0 is undefined ethtool flow */
return 0; return 0;
...@@ -900,6 +902,8 @@ static enum iavf_fdir_flow_type iavf_ethtool_flow_to_fltr(int eth) ...@@ -900,6 +902,8 @@ static enum iavf_fdir_flow_type iavf_ethtool_flow_to_fltr(int eth)
return IAVF_FDIR_FLOW_IPV6_ESP; return IAVF_FDIR_FLOW_IPV6_ESP;
case IPV6_USER_FLOW: case IPV6_USER_FLOW:
return IAVF_FDIR_FLOW_IPV6_OTHER; return IAVF_FDIR_FLOW_IPV6_OTHER;
case ETHER_FLOW:
return IAVF_FDIR_FLOW_NON_IP_L2;
default: default:
return IAVF_FDIR_FLOW_NONE; return IAVF_FDIR_FLOW_NONE;
} }
...@@ -1025,6 +1029,10 @@ iavf_get_ethtool_fdir_entry(struct iavf_adapter *adapter, ...@@ -1025,6 +1029,10 @@ iavf_get_ethtool_fdir_entry(struct iavf_adapter *adapter,
fsp->m_u.usr_ip6_spec.tclass = rule->ip_mask.tclass; fsp->m_u.usr_ip6_spec.tclass = rule->ip_mask.tclass;
fsp->m_u.usr_ip6_spec.l4_proto = rule->ip_mask.proto; fsp->m_u.usr_ip6_spec.l4_proto = rule->ip_mask.proto;
break; break;
case ETHER_FLOW:
fsp->h_u.ether_spec.h_proto = rule->eth_data.etype;
fsp->m_u.ether_spec.h_proto = rule->eth_mask.etype;
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
break; break;
...@@ -1197,6 +1205,10 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe ...@@ -1197,6 +1205,10 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe
fltr->ip_mask.tclass = fsp->m_u.usr_ip6_spec.tclass; fltr->ip_mask.tclass = fsp->m_u.usr_ip6_spec.tclass;
fltr->ip_mask.proto = fsp->m_u.usr_ip6_spec.l4_proto; fltr->ip_mask.proto = fsp->m_u.usr_ip6_spec.l4_proto;
break; break;
case ETHER_FLOW:
fltr->eth_data.etype = fsp->h_u.ether_spec.h_proto;
fltr->eth_mask.etype = fsp->m_u.ether_spec.h_proto;
break;
default: default:
/* not doing un-parsed flow types */ /* not doing un-parsed flow types */
return -EINVAL; return -EINVAL;
......
...@@ -277,9 +277,19 @@ iavf_fill_fdir_eth_hdr(struct iavf_fdir_fltr *fltr, ...@@ -277,9 +277,19 @@ iavf_fill_fdir_eth_hdr(struct iavf_fdir_fltr *fltr,
struct virtchnl_proto_hdrs *proto_hdrs) struct virtchnl_proto_hdrs *proto_hdrs)
{ {
struct virtchnl_proto_hdr *hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; struct virtchnl_proto_hdr *hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
struct ethhdr *ehdr = (struct ethhdr *)hdr->buffer;
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, ETH); VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, ETH);
if (fltr->eth_mask.etype == htons(U16_MAX)) {
if (fltr->eth_data.etype == htons(ETH_P_IP) ||
fltr->eth_data.etype == htons(ETH_P_IPV6))
return -EOPNOTSUPP;
ehdr->h_proto = fltr->eth_data.etype;
VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, ETH, ETHERTYPE);
}
return 0; return 0;
} }
...@@ -351,6 +361,8 @@ int iavf_fill_fdir_add_msg(struct iavf_adapter *adapter, struct iavf_fdir_fltr * ...@@ -351,6 +361,8 @@ int iavf_fill_fdir_add_msg(struct iavf_adapter *adapter, struct iavf_fdir_fltr *
err = iavf_fill_fdir_ip6_hdr(fltr, proto_hdrs) | err = iavf_fill_fdir_ip6_hdr(fltr, proto_hdrs) |
iavf_fill_fdir_l4_hdr(fltr, proto_hdrs); iavf_fill_fdir_l4_hdr(fltr, proto_hdrs);
break; break;
case IAVF_FDIR_FLOW_NON_IP_L2:
break;
default: default:
err = -EINVAL; err = -EINVAL;
break; break;
...@@ -392,6 +404,8 @@ static const char *iavf_fdir_flow_proto_name(enum iavf_fdir_flow_type flow_type) ...@@ -392,6 +404,8 @@ static const char *iavf_fdir_flow_proto_name(enum iavf_fdir_flow_type flow_type)
case IAVF_FDIR_FLOW_IPV4_OTHER: case IAVF_FDIR_FLOW_IPV4_OTHER:
case IAVF_FDIR_FLOW_IPV6_OTHER: case IAVF_FDIR_FLOW_IPV6_OTHER:
return "Other"; return "Other";
case IAVF_FDIR_FLOW_NON_IP_L2:
return "Ethernet";
default: default:
return NULL; return NULL;
} }
...@@ -468,6 +482,11 @@ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *f ...@@ -468,6 +482,11 @@ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *f
fltr->ip_data.proto, fltr->ip_data.proto,
ntohl(fltr->ip_data.l4_header)); ntohl(fltr->ip_data.l4_header));
break; break;
case IAVF_FDIR_FLOW_NON_IP_L2:
dev_info(&adapter->pdev->dev, "Rule ID: %u eth_type: 0x%x\n",
fltr->loc,
ntohs(fltr->eth_data.etype));
break;
default: default:
break; break;
} }
...@@ -489,7 +508,9 @@ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr * ...@@ -489,7 +508,9 @@ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *
if (tmp->flow_type != fltr->flow_type) if (tmp->flow_type != fltr->flow_type)
continue; continue;
if (!memcmp(&tmp->ip_data, &fltr->ip_data, if (!memcmp(&tmp->eth_data, &fltr->eth_data,
sizeof(fltr->eth_data)) &&
!memcmp(&tmp->ip_data, &fltr->ip_data,
sizeof(fltr->ip_data))) { sizeof(fltr->ip_data))) {
ret = true; ret = true;
break; break;
......
...@@ -30,6 +30,7 @@ enum iavf_fdir_flow_type { ...@@ -30,6 +30,7 @@ enum iavf_fdir_flow_type {
IAVF_FDIR_FLOW_IPV6_AH, IAVF_FDIR_FLOW_IPV6_AH,
IAVF_FDIR_FLOW_IPV6_ESP, IAVF_FDIR_FLOW_IPV6_ESP,
IAVF_FDIR_FLOW_IPV6_OTHER, IAVF_FDIR_FLOW_IPV6_OTHER,
IAVF_FDIR_FLOW_NON_IP_L2,
/* MAX - this must be last and add anything new just above it */ /* MAX - this must be last and add anything new just above it */
IAVF_FDIR_FLOW_PTYPE_MAX, IAVF_FDIR_FLOW_PTYPE_MAX,
}; };
...@@ -44,6 +45,10 @@ struct iavf_ipv6_addrs { ...@@ -44,6 +45,10 @@ struct iavf_ipv6_addrs {
struct in6_addr dst_ip; struct in6_addr dst_ip;
}; };
struct iavf_fdir_eth {
__be16 etype;
};
struct iavf_fdir_ip { struct iavf_fdir_ip {
union { union {
struct iavf_ipv4_addrs v4_addrs; struct iavf_ipv4_addrs v4_addrs;
...@@ -66,6 +71,9 @@ struct iavf_fdir_fltr { ...@@ -66,6 +71,9 @@ struct iavf_fdir_fltr {
enum iavf_fdir_flow_type flow_type; enum iavf_fdir_flow_type flow_type;
struct iavf_fdir_eth eth_data;
struct iavf_fdir_eth eth_mask;
struct iavf_fdir_ip ip_data; struct iavf_fdir_ip ip_data;
struct iavf_fdir_ip ip_mask; struct iavf_fdir_ip ip_mask;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment