summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/chelsio
diff options
context:
space:
mode:
authorKumar Sanghvi <kumaras@chelsio.com>2017-10-18 17:19:07 +0200
committerDavid S. Miller <davem@davemloft.net>2017-10-20 14:06:52 +0200
commitbda1e229153fbdd0efd22a14c1c76a28c05d1b27 (patch)
treeb5d5e4014b4068551ec6ffed7fded24eb5622582 /drivers/net/ethernet/chelsio
parenttcp: Remove use of inet6_sk and add IPv6 checks to tracepoint (diff)
downloadlinux-bda1e229153fbdd0efd22a14c1c76a28c05d1b27.tar.xz
linux-bda1e229153fbdd0efd22a14c1c76a28c05d1b27.zip
cxgb4: add tc flower match support for TOS
Add support for matching on IP TOS. Also check on ethtype value to be either IPv4 or IPv6. Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/chelsio')
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index 92a311767381..647c86ae343d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -147,6 +147,19 @@ static void cxgb4_process_flow_match(struct net_device *dev,
fs->mask.fport = cpu_to_be16(mask->src);
}
+ if (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_IP)) {
+ struct flow_dissector_key_ip *key, *mask;
+
+ key = skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_IP,
+ cls->key);
+ mask = skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_IP,
+ cls->mask);
+ fs->val.tos = key->tos;
+ fs->mask.tos = mask->tos;
+ }
+
/* Match only packets coming from the ingress port where this
* filter will be created.
*/
@@ -157,16 +170,52 @@ static void cxgb4_process_flow_match(struct net_device *dev,
static int cxgb4_validate_flow_match(struct net_device *dev,
struct tc_cls_flower_offload *cls)
{
+ u16 ethtype_mask = 0;
+ u16 ethtype_key = 0;
+
if (cls->dissector->used_keys &
~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
BIT(FLOW_DISSECTOR_KEY_BASIC) |
BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
- BIT(FLOW_DISSECTOR_KEY_PORTS))) {
+ BIT(FLOW_DISSECTOR_KEY_PORTS) |
+ BIT(FLOW_DISSECTOR_KEY_IP))) {
netdev_warn(dev, "Unsupported key used: 0x%x\n",
cls->dissector->used_keys);
return -EOPNOTSUPP;
}
+
+ if (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
+ struct flow_dissector_key_basic *key =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ cls->key);
+ struct flow_dissector_key_basic *mask =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ cls->mask);
+ ethtype_key = ntohs(key->n_proto);
+ ethtype_mask = ntohs(mask->n_proto);
+ }
+
+ if (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_IP)) {
+ u16 eth_ip_type = ethtype_key & ethtype_mask;
+ struct flow_dissector_key_ip *mask;
+
+ if (eth_ip_type != ETH_P_IP && eth_ip_type != ETH_P_IPV6) {
+ netdev_err(dev, "IP Key supported only with IPv4/v6");
+ return -EINVAL;
+ }
+
+ mask = skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_IP,
+ cls->mask);
+ if (mask->ttl) {
+ netdev_warn(dev, "ttl match unsupported for offload");
+ return -EOPNOTSUPP;
+ }
+ }
+
return 0;
}