qed*: Support other classification modes.
Currently, driver supports flow classification to PF receive queues based on TCP/UDP 4 tuples [src_ip, dst_ip, src_port, dst_port] only. This patch enables to configure different flow profiles [For example - only UDP dest port or src_ip based] on the adapter so that classification can be done according to just those fields as well. Although, at a time just one type of flow configuration is supported due to limited number of flow profiles available on the device. For example - ethtool -N enp7s0f0 flow-type udp4 dst-port 45762 action 2 ethtool -N enp7s0f0 flow-type tcp4 src-ip 192.16.4.10 action 1 ethtool -N enp7s0f0 flow-type udp6 dst-port 45762 action 3 Signed-off-by: Manish Chopra <manish.chopra@cavium.com> Signed-off-by: Shahed Shaikh <shahed.shaikh@cavium.com> Signed-off-by: Ariel Elior <ariel.elior@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
89ffd14ee9
commit
3893fc62b1
@@ -1973,6 +1973,8 @@ qed_arfs_mode_to_hsi(enum qed_filter_config_mode mode)
|
|||||||
return GFT_PROFILE_TYPE_4_TUPLE;
|
return GFT_PROFILE_TYPE_4_TUPLE;
|
||||||
if (mode == QED_FILTER_CONFIG_MODE_IP_DEST)
|
if (mode == QED_FILTER_CONFIG_MODE_IP_DEST)
|
||||||
return GFT_PROFILE_TYPE_IP_DST_ADDR;
|
return GFT_PROFILE_TYPE_IP_DST_ADDR;
|
||||||
|
if (mode == QED_FILTER_CONFIG_MODE_IP_SRC)
|
||||||
|
return GFT_PROFILE_TYPE_IP_SRC_ADDR;
|
||||||
return GFT_PROFILE_TYPE_L4_DST_PORT;
|
return GFT_PROFILE_TYPE_L4_DST_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1623,9 +1623,17 @@ static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev,
|
|||||||
t->src_port = fs->h_u.tcp_ip4_spec.psrc;
|
t->src_port = fs->h_u.tcp_ip4_spec.psrc;
|
||||||
t->dst_port = fs->h_u.tcp_ip4_spec.pdst;
|
t->dst_port = fs->h_u.tcp_ip4_spec.pdst;
|
||||||
|
|
||||||
/* We must have a valid 4-tuple */
|
/* We must either have a valid 4-tuple or only dst port
|
||||||
|
* or only src ip as an input
|
||||||
|
*/
|
||||||
if (t->src_port && t->dst_port && t->src_ipv4 && t->dst_ipv4) {
|
if (t->src_port && t->dst_port && t->src_ipv4 && t->dst_ipv4) {
|
||||||
t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
|
t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
|
||||||
|
} else if (!t->src_port && t->dst_port &&
|
||||||
|
!t->src_ipv4 && !t->dst_ipv4) {
|
||||||
|
t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
|
||||||
|
} else if (!t->src_port && !t->dst_port &&
|
||||||
|
!t->dst_ipv4 && t->src_ipv4) {
|
||||||
|
t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
|
||||||
} else {
|
} else {
|
||||||
DP_INFO(edev, "Invalid N-tuple\n");
|
DP_INFO(edev, "Invalid N-tuple\n");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@@ -1697,11 +1705,21 @@ static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev,
|
|||||||
t->src_port = fs->h_u.tcp_ip6_spec.psrc;
|
t->src_port = fs->h_u.tcp_ip6_spec.psrc;
|
||||||
t->dst_port = fs->h_u.tcp_ip6_spec.pdst;
|
t->dst_port = fs->h_u.tcp_ip6_spec.pdst;
|
||||||
|
|
||||||
/* We must make sure we have a valid 4-tuple */
|
/* We must make sure we have a valid 4-tuple or only dest port
|
||||||
|
* or only src ip as an input
|
||||||
|
*/
|
||||||
if (t->src_port && t->dst_port &&
|
if (t->src_port && t->dst_port &&
|
||||||
memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) &&
|
memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) &&
|
||||||
memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) {
|
memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) {
|
||||||
t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
|
t->mode = QED_FILTER_CONFIG_MODE_5_TUPLE;
|
||||||
|
} else if (!t->src_port && t->dst_port &&
|
||||||
|
!memcmp(&t->src_ipv6, p, sizeof(struct in6_addr)) &&
|
||||||
|
!memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr))) {
|
||||||
|
t->mode = QED_FILTER_CONFIG_MODE_L4_PORT;
|
||||||
|
} else if (!t->src_port && !t->dst_port &&
|
||||||
|
!memcmp(&t->dst_ipv6, p, sizeof(struct in6_addr)) &&
|
||||||
|
memcmp(&t->src_ipv6, p, sizeof(struct in6_addr))) {
|
||||||
|
t->mode = QED_FILTER_CONFIG_MODE_IP_SRC;
|
||||||
} else {
|
} else {
|
||||||
DP_INFO(edev, "Invalid N-tuple\n");
|
DP_INFO(edev, "Invalid N-tuple\n");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@@ -1779,6 +1797,15 @@ static int qede_flow_spec_validate(struct qede_dev *edev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if the filtering-mode could support the filter */
|
||||||
|
if (edev->arfs->filter_count &&
|
||||||
|
edev->arfs->mode != t->mode) {
|
||||||
|
DP_INFO(edev,
|
||||||
|
"flow_spec would require filtering mode %08x, but %08x is configured\n",
|
||||||
|
t->mode, edev->arfs->filter_count);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (fs->ring_cookie >= QEDE_RSS_COUNT(edev)) {
|
if (fs->ring_cookie >= QEDE_RSS_COUNT(edev)) {
|
||||||
DP_INFO(edev, "Queue out-of-bounds\n");
|
DP_INFO(edev, "Queue out-of-bounds\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@@ -66,6 +66,7 @@ enum qed_filter_config_mode {
|
|||||||
QED_FILTER_CONFIG_MODE_5_TUPLE,
|
QED_FILTER_CONFIG_MODE_5_TUPLE,
|
||||||
QED_FILTER_CONFIG_MODE_L4_PORT,
|
QED_FILTER_CONFIG_MODE_L4_PORT,
|
||||||
QED_FILTER_CONFIG_MODE_IP_DEST,
|
QED_FILTER_CONFIG_MODE_IP_DEST,
|
||||||
|
QED_FILTER_CONFIG_MODE_IP_SRC,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_ntuple_filter_params {
|
struct qed_ntuple_filter_params {
|
||||||
|
Reference in New Issue
Block a user