diff options
author | Manish Chopra <manish.chopra@cavium.com> | 2018-05-24 18:54:50 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-05-25 22:10:42 +0200 |
commit | 89ffd14ee95dca812874fcd25ad3538ff3592a49 (patch) | |
tree | 87b1b3040658c4e2742a7c99c2c3488317165cdf | |
parent | qede: Refactor ethtool rx classification flow. (diff) | |
download | linux-89ffd14ee95dca812874fcd25ad3538ff3592a49.tar.xz linux-89ffd14ee95dca812874fcd25ad3538ff3592a49.zip |
qede: Validate unsupported configurations
Validate and prevent some of the configurations for
unsupported [by firmware] inputs [for example - mac ext,
vlans, masks/prefix, tos/tclass] via ethtool -N/-U.
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>
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_filter.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index bd5b4e4c1d47..43ed420900c1 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -1560,10 +1560,63 @@ static void qede_flow_build_ipv6_hdr(struct qede_arfs_tuple *t, ports[1] = t->dst_port; } +/* Validate fields which are set and not accepted by the driver */ +static int qede_flow_spec_validate_unused(struct qede_dev *edev, + struct ethtool_rx_flow_spec *fs) +{ + if (fs->flow_type & FLOW_MAC_EXT) { + DP_INFO(edev, "Don't support MAC extensions\n"); + return -EOPNOTSUPP; + } + + if ((fs->flow_type & FLOW_EXT) && + (fs->h_ext.vlan_etype || fs->h_ext.vlan_tci)) { + DP_INFO(edev, "Don't support vlan-based classification\n"); + return -EOPNOTSUPP; + } + + if ((fs->flow_type & FLOW_EXT) && + (fs->h_ext.data[0] || fs->h_ext.data[1])) { + DP_INFO(edev, "Don't support user defined data\n"); + return -EOPNOTSUPP; + } + + return 0; +} + static int qede_flow_spec_to_tuple_ipv4_common(struct qede_dev *edev, struct qede_arfs_tuple *t, struct ethtool_rx_flow_spec *fs) { + if ((fs->h_u.tcp_ip4_spec.ip4src & + fs->m_u.tcp_ip4_spec.ip4src) != fs->h_u.tcp_ip4_spec.ip4src) { + DP_INFO(edev, "Don't support IP-masks\n"); + return -EOPNOTSUPP; + } + + if ((fs->h_u.tcp_ip4_spec.ip4dst & + fs->m_u.tcp_ip4_spec.ip4dst) != fs->h_u.tcp_ip4_spec.ip4dst) { + DP_INFO(edev, "Don't support IP-masks\n"); + return -EOPNOTSUPP; + } + + if ((fs->h_u.tcp_ip4_spec.psrc & + fs->m_u.tcp_ip4_spec.psrc) != fs->h_u.tcp_ip4_spec.psrc) { + DP_INFO(edev, "Don't support port-masks\n"); + return -EOPNOTSUPP; + } + + if ((fs->h_u.tcp_ip4_spec.pdst & + fs->m_u.tcp_ip4_spec.pdst) != fs->h_u.tcp_ip4_spec.pdst) { + DP_INFO(edev, "Don't support port-masks\n"); + return -EOPNOTSUPP; + } + + if (fs->h_u.tcp_ip4_spec.tos) { + DP_INFO(edev, "Don't support tos\n"); + return -EOPNOTSUPP; + } + t->eth_proto = htons(ETH_P_IP); t->src_ipv4 = fs->h_u.tcp_ip4_spec.ip4src; t->dst_ipv4 = fs->h_u.tcp_ip4_spec.ip4dst; @@ -1619,6 +1672,23 @@ static int qede_flow_spec_to_tuple_ipv6_common(struct qede_dev *edev, p = &zero_addr; memset(p, 0, sizeof(zero_addr)); + if ((fs->h_u.tcp_ip6_spec.psrc & + fs->m_u.tcp_ip6_spec.psrc) != fs->h_u.tcp_ip6_spec.psrc) { + DP_INFO(edev, "Don't support port-masks\n"); + return -EOPNOTSUPP; + } + + if ((fs->h_u.tcp_ip6_spec.pdst & + fs->m_u.tcp_ip6_spec.pdst) != fs->h_u.tcp_ip6_spec.pdst) { + DP_INFO(edev, "Don't support port-masks\n"); + return -EOPNOTSUPP; + } + + if (fs->h_u.tcp_ip6_spec.tclass) { + DP_INFO(edev, "Don't support tclass\n"); + return -EOPNOTSUPP; + } + t->eth_proto = htons(ETH_P_IPV6); memcpy(&t->src_ipv6, &fs->h_u.tcp_ip6_spec.ip6src, sizeof(struct in6_addr)); @@ -1673,6 +1743,9 @@ static int qede_flow_spec_to_tuple(struct qede_dev *edev, { memset(t, 0, sizeof(*t)); + if (qede_flow_spec_validate_unused(edev, fs)) + return -EOPNOTSUPP; + switch ((fs->flow_type & ~FLOW_EXT)) { case TCP_V4_FLOW: return qede_flow_spec_to_tuple_tcpv4(edev, t, fs); |