lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 22 Jun 2016 04:25:23 -0400
From:	Manish Chopra <manish.chopra@...gic.com>
To:	<davem@...emloft.net>
CC:	<netdev@...r.kernel.org>, <Ariel.Elior@...gic.com>,
	<Yuval.Mintz@...gic.com>
Subject: [PATCH net-next 2/5] qede: Add support to handle VXLAN hardware GRO packets

This patch adds support to do necessary processing
for hardware assisted VXLAN tunnel GRO packets before
driver delivers them upto the stack.

Signed-off-by: Manish Chopra <manish.chopra@...gic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@...gic.com>
---
 drivers/net/ethernet/qlogic/qede/qede.h      |  1 +
 drivers/net/ethernet/qlogic/qede/qede_main.c | 79 ++++++++++++++++++++++++----
 2 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 1441c8f..d8ec269 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -213,6 +213,7 @@ struct qede_agg_info {
 	struct sk_buff *skb;
 	int frag_id;
 	u16 vlan_tag;
+	u8 tunnel_type;
 };
 
 struct qede_rx_queue {
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 2972742..f94ea16 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -36,6 +36,7 @@
 #include <linux/random.h>
 #include <net/ip6_checksum.h>
 #include <linux/bitops.h>
+#include <net/vxlan.h>
 
 #include "qede.h"
 
@@ -1048,6 +1049,12 @@ out:
 	return -ENOMEM;
 }
 
+static bool qede_tunn_exist(u16 flag)
+{
+	return !!(flag & (PARSING_AND_ERR_FLAGS_TUNNELEXIST_MASK <<
+			  PARSING_AND_ERR_FLAGS_TUNNELEXIST_SHIFT));
+}
+
 static void qede_tpa_start(struct qede_dev *edev,
 			   struct qede_rx_queue *rxq,
 			   struct eth_fast_path_rx_tpa_start_cqe *cqe)
@@ -1065,6 +1072,14 @@ static void qede_tpa_start(struct qede_dev *edev,
 	sw_rx_data_cons = &rxq->sw_rx_ring[rxq->sw_rx_cons & NUM_RX_BDS_MAX];
 	sw_rx_data_prod = &rxq->sw_rx_ring[rxq->sw_rx_prod & NUM_RX_BDS_MAX];
 
+	if (qede_tunn_exist(le16_to_cpu(cqe->pars_flags.flags))) {
+		u8 flags = cqe->tunnel_pars_flags.flags, shift;
+
+		shift = ETH_TUNNEL_PARSING_FLAGS_TYPE_SHIFT;
+		tpa_info->tunnel_type = (flags >> shift) &
+					 ETH_TUNNEL_PARSING_FLAGS_TYPE_MASK;
+	}
+
 	/* Use pre-allocated replacement buffer - we can't release the agg.
 	 * start until its over and we don't want to risk allocation failing
 	 * here, so re-allocate when aggregation will be over.
@@ -1159,12 +1174,55 @@ static void qede_gro_ipv6_csum(struct sk_buff *skb)
 				  &iph->saddr, &iph->daddr, 0);
 	tcp_gro_complete(skb);
 }
+
+static void qede_set_nh_th_offset(struct sk_buff *skb, int off)
+{
+	skb_set_network_header(skb, off);
+
+	if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) {
+		off += sizeof(struct iphdr);
+		skb_set_transport_header(skb, off);
+	} else {
+		off += sizeof(struct ipv6hdr);
+		skb_set_transport_header(skb, off);
+	}
+}
+
+static void qede_handle_vxlan_tunnel_gro(struct sk_buff *skb)
+{
+	switch (skb->protocol) {
+	case htons(ETH_P_IP):
+		qede_set_nh_th_offset(skb, VXLAN_HEADROOM);
+		udp4_gro_complete(skb, sizeof(struct iphdr));
+		break;
+	case htons(ETH_P_IPV6):
+		qede_set_nh_th_offset(skb, VXLAN6_HEADROOM);
+		udp6_gro_complete(skb, sizeof(struct ipv6hdr));
+		break;
+	default:
+		WARN_ONCE(1, "Unsupported VXLAN tunnel GRO proto=0x%x\n",
+			  skb->protocol);
+	}
+}
+
+static void qede_handle_tunnel_gro(struct qede_dev *edev,
+				   struct sk_buff *skb, u8 tunnel_type)
+{
+	switch (tunnel_type) {
+	case ETH_RX_TUNN_VXLAN:
+		qede_handle_vxlan_tunnel_gro(skb);
+		break;
+	default:
+		WARN_ONCE(1, "Unsupported tunnel GRO, tunnel type=0x%x\n",
+			  tunnel_type);
+	}
+}
 #endif
 
 static void qede_gro_receive(struct qede_dev *edev,
 			     struct qede_fastpath *fp,
 			     struct sk_buff *skb,
-			     u16 vlan_tag)
+			     struct qede_agg_info *tpa_info)
 {
 	/* FW can send a single MTU sized packet from gro flow
 	 * due to aggregation timeout/last segment etc. which
@@ -1179,6 +1237,12 @@ static void qede_gro_receive(struct qede_dev *edev,
 
 #ifdef CONFIG_INET
 	if (skb_shinfo(skb)->gso_size) {
+		if (tpa_info->tunnel_type) {
+			qede_handle_tunnel_gro(edev, skb,
+					       tpa_info->tunnel_type);
+			goto send_skb;
+		}
+
 		skb_set_network_header(skb, 0);
 
 		switch (skb->protocol) {
@@ -1198,7 +1262,7 @@ static void qede_gro_receive(struct qede_dev *edev,
 
 send_skb:
 	skb_record_rx_queue(skb, fp->rss_id);
-	qede_skb_receive(edev, fp, skb, vlan_tag);
+	qede_skb_receive(edev, fp, skb, tpa_info->vlan_tag);
 }
 
 static inline void qede_tpa_cont(struct qede_dev *edev,
@@ -1267,10 +1331,10 @@ static void qede_tpa_end(struct qede_dev *edev,
 	 */
 	NAPI_GRO_CB(skb)->count = le16_to_cpu(cqe->num_of_coalesced_segs);
 
-	qede_gro_receive(edev, fp, skb, tpa_info->vlan_tag);
+	qede_gro_receive(edev, fp, skb, tpa_info);
 
 	tpa_info->agg_state = QEDE_AGG_STATE_NONE;
-
+	tpa_info->tunnel_type = 0;
 	return;
 err:
 	/* The BD starting the aggregation is still mapped; Re-use it for
@@ -1283,12 +1347,7 @@ err:
 	tpa_info->agg_state = QEDE_AGG_STATE_NONE;
 	dev_kfree_skb_any(tpa_info->skb);
 	tpa_info->skb = NULL;
-}
-
-static bool qede_tunn_exist(u16 flag)
-{
-	return !!(flag & (PARSING_AND_ERR_FLAGS_TUNNELEXIST_MASK <<
-			  PARSING_AND_ERR_FLAGS_TUNNELEXIST_SHIFT));
+	tpa_info->tunnel_type = 0;
 }
 
 static u8 qede_check_tunn_csum(u16 flag)
-- 
2.7.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ