net/sfc: fix filter exceptions logic
Now exception logic handles these cases: When FW variant does not support filters with transport ports, but IP protocol filters are supported, TCP/UDP protocol filters may be used. When FW variant does not support filters with IPv4/6 addresses or IP protocol, but filters with EtherType are supported, IPv4 and IPv6 EtherTypes may be used Fixes: 096dba799b4a ("net/sfc: avoid creation of ineffective flow rules") Cc: stable@dpdk.org Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
This commit is contained in:
parent
3126df2237
commit
b0df5b32ae
@ -75,6 +75,7 @@ int
|
|||||||
sfc_filter_attach(struct sfc_adapter *sa)
|
sfc_filter_attach(struct sfc_adapter *sa)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
sfc_log_init(sa, "entry");
|
sfc_log_init(sa, "entry");
|
||||||
|
|
||||||
@ -88,6 +89,19 @@ sfc_filter_attach(struct sfc_adapter *sa)
|
|||||||
|
|
||||||
efx_filter_fini(sa->nic);
|
efx_filter_fini(sa->nic);
|
||||||
|
|
||||||
|
sa->filter.supports_ip_proto_or_addr_filter = B_FALSE;
|
||||||
|
sa->filter.supports_rem_or_local_port_filter = B_FALSE;
|
||||||
|
for (i = 0; i < sa->filter.supported_match_num; ++i) {
|
||||||
|
if (sa->filter.supported_match[i] &
|
||||||
|
(EFX_FILTER_MATCH_IP_PROTO | EFX_FILTER_MATCH_LOC_HOST |
|
||||||
|
EFX_FILTER_MATCH_REM_HOST))
|
||||||
|
sa->filter.supports_ip_proto_or_addr_filter = B_TRUE;
|
||||||
|
|
||||||
|
if (sa->filter.supported_match[i] &
|
||||||
|
(EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))
|
||||||
|
sa->filter.supports_rem_or_local_port_filter = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
sfc_log_init(sa, "done");
|
sfc_log_init(sa, "done");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -25,6 +25,16 @@ struct sfc_filter {
|
|||||||
uint32_t *supported_match;
|
uint32_t *supported_match;
|
||||||
/** List of flow rules */
|
/** List of flow rules */
|
||||||
struct sfc_flow_list flow_list;
|
struct sfc_flow_list flow_list;
|
||||||
|
/**
|
||||||
|
* Supports any of ip_proto, remote host or local host
|
||||||
|
* filters. This flag is used for filter match exceptions
|
||||||
|
*/
|
||||||
|
boolean_t supports_ip_proto_or_addr_filter;
|
||||||
|
/**
|
||||||
|
* Supports any of remote port or local port filters.
|
||||||
|
* This flag is used for filter match exceptions
|
||||||
|
*/
|
||||||
|
boolean_t supports_rem_or_local_port_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sfc_adapter;
|
struct sfc_adapter;
|
||||||
|
@ -2095,11 +2095,14 @@ sfc_flow_is_match_with_vids(efx_filter_match_flags_t match_flags,
|
|||||||
* Check whether the spec maps to a hardware filter which is known to be
|
* Check whether the spec maps to a hardware filter which is known to be
|
||||||
* ineffective despite being valid.
|
* ineffective despite being valid.
|
||||||
*
|
*
|
||||||
|
* @param filter[in]
|
||||||
|
* SFC filter with list of supported filters.
|
||||||
* @param spec[in]
|
* @param spec[in]
|
||||||
* SFC flow specification.
|
* SFC flow specification.
|
||||||
*/
|
*/
|
||||||
static boolean_t
|
static boolean_t
|
||||||
sfc_flow_is_match_flags_exception(struct sfc_flow_spec *spec)
|
sfc_flow_is_match_flags_exception(struct sfc_filter *filter,
|
||||||
|
struct sfc_flow_spec *spec)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint16_t ether_type;
|
uint16_t ether_type;
|
||||||
@ -2115,8 +2118,9 @@ sfc_flow_is_match_flags_exception(struct sfc_flow_spec *spec)
|
|||||||
EFX_FILTER_MATCH_ETHER_TYPE |
|
EFX_FILTER_MATCH_ETHER_TYPE |
|
||||||
EFX_FILTER_MATCH_LOC_MAC)) {
|
EFX_FILTER_MATCH_LOC_MAC)) {
|
||||||
ether_type = spec->filters[i].efs_ether_type;
|
ether_type = spec->filters[i].efs_ether_type;
|
||||||
if (ether_type == EFX_ETHER_TYPE_IPV4 ||
|
if (filter->supports_ip_proto_or_addr_filter &&
|
||||||
ether_type == EFX_ETHER_TYPE_IPV6)
|
(ether_type == EFX_ETHER_TYPE_IPV4 ||
|
||||||
|
ether_type == EFX_ETHER_TYPE_IPV6))
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
} else if (sfc_flow_is_match_with_vids(match_flags,
|
} else if (sfc_flow_is_match_with_vids(match_flags,
|
||||||
EFX_FILTER_MATCH_ETHER_TYPE |
|
EFX_FILTER_MATCH_ETHER_TYPE |
|
||||||
@ -2126,8 +2130,9 @@ sfc_flow_is_match_flags_exception(struct sfc_flow_spec *spec)
|
|||||||
EFX_FILTER_MATCH_IP_PROTO |
|
EFX_FILTER_MATCH_IP_PROTO |
|
||||||
EFX_FILTER_MATCH_LOC_MAC)) {
|
EFX_FILTER_MATCH_LOC_MAC)) {
|
||||||
ip_proto = spec->filters[i].efs_ip_proto;
|
ip_proto = spec->filters[i].efs_ip_proto;
|
||||||
if (ip_proto == EFX_IPPROTO_TCP ||
|
if (filter->supports_rem_or_local_port_filter &&
|
||||||
ip_proto == EFX_IPPROTO_UDP)
|
(ip_proto == EFX_IPPROTO_TCP ||
|
||||||
|
ip_proto == EFX_IPPROTO_UDP))
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2154,7 +2159,7 @@ sfc_flow_validate_match_flags(struct sfc_adapter *sa,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sfc_flow_is_match_flags_exception(&flow->spec)) {
|
if (sfc_flow_is_match_flags_exception(&sa->filter, &flow->spec)) {
|
||||||
rte_flow_error_set(error, ENOTSUP,
|
rte_flow_error_set(error, ENOTSUP,
|
||||||
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
|
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
|
||||||
"The flow rule pattern is unsupported");
|
"The flow rule pattern is unsupported");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user