DPDK patches and discussions
 help / color / mirror / Atom feed
From: Qi Zhang <qi.z.zhang@intel.com>
To: wenzhuo.lu@intel.com, qiming.yang@intel.com
Cc: dev@dpdk.org, xiaolong.ye@intel.com,
	Qi Zhang <qi.z.zhang@intel.com>,
	Dan Nowlin <dan.nowlin@intel.com>,
	Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
Subject: [dpdk-dev] [PATCH 25/63] net/ice/base: add support for GTP and PPPoE protocols
Date: Mon, 26 Aug 2019 18:50:27 +0800	[thread overview]
Message-ID: <20190826105105.19121-26-qi.z.zhang@intel.com> (raw)
In-Reply-To: <20190826105105.19121-1-qi.z.zhang@intel.com>

Added switch protocol segments for both GTP and PPPOE protocols.
Added RSS protocol segments for both GTP and PPPOE protocols.

Signed-off-by: Dan Nowlin <dan.nowlin@intel.com>
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/ice/base/ice_flow.c          | 105 ++++++++++++++++++++++++++-----
 drivers/net/ice/base/ice_flow.h          |  61 ++++++++++++++----
 drivers/net/ice/base/ice_protocol_type.h |  33 +++++++++-
 drivers/net/ice/base/ice_switch.c        |  79 ++++++++++++++++++++++-
 4 files changed, 251 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index 1530a72cc..0f52b3379 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -19,6 +19,8 @@
 #define ICE_FLOW_FLD_SZ_ICMP_CODE	1
 #define ICE_FLOW_FLD_SZ_ARP_OPER	2
 #define ICE_FLOW_FLD_SZ_GRE_KEYID	4
+#define ICE_FLOW_FLD_SZ_GTP_TEID	4
+#define ICE_FLOW_FLD_SZ_PPPOE_SESS_ID   2
 
 /* Protocol header fields are extracted at the word boundaries as word-sized
  * values. Specify the displacement value of some non-word-aligned fields needed
@@ -115,6 +117,23 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
 	/* GRE */
 	/* ICE_FLOW_FIELD_IDX_GRE_KEYID */
 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GRE, 12, ICE_FLOW_FLD_SZ_GRE_KEYID),
+	/* GTP */
+	/* ICE_FLOW_FIELD_IDX_GTPC_TEID */
+	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPC_TEID, 12,
+			  ICE_FLOW_FLD_SZ_GTP_TEID),
+	/* ICE_FLOW_FIELD_IDX_GTPU_IP_TEID */
+	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_IP, 12,
+			  ICE_FLOW_FLD_SZ_GTP_TEID),
+	/* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
+	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12,
+			  ICE_FLOW_FLD_SZ_GTP_TEID),
+	/* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
+	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12,
+			  ICE_FLOW_FLD_SZ_GTP_TEID),
+	/* PPPOE */
+	/* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
+	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2,
+			  ICE_FLOW_FLD_SZ_PPPOE_SESS_ID),
 };
 
 /* Bitmaps indicating relevant packet types for a particular protocol header
@@ -290,6 +309,42 @@ static const u32 ice_ptypes_mac_il[] = {
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 };
 
+/* Packet types for GTPC */
+static const u32 ice_ptypes_gtpc[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000180, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+/* Packet types for GTPC with TEID */
+static const u32 ice_ptypes_gtpc_tid[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000060, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+/* Packet types for GTPU */
+static const u32 ice_ptypes_gtpu[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x7FFFF800, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
 /* Manage parameters and info. used during the creation of a flow profile */
 struct ice_flow_prof_params {
 	enum ice_block blk;
@@ -317,10 +372,13 @@ static bool ice_is_pow2(u64 val)
 #define ICE_FLOW_SEG_HDRS_L2_MASK	\
 	(ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN)
 #define ICE_FLOW_SEG_HDRS_L3_MASK	\
-	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_ARP)
+	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | \
+	 ICE_FLOW_SEG_HDR_ARP | ICE_FLOW_SEG_HDR_PPPOE)
 #define ICE_FLOW_SEG_HDRS_L4_MASK	\
 	(ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
-	 ICE_FLOW_SEG_HDR_SCTP)
+	 ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_GTPC | \
+	 ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU_IP | \
+	 ICE_FLOW_SEG_HDR_GTPU_UP | ICE_FLOW_SEG_HDR_GTPU_DWN)
 
 /**
  * ice_flow_val_hdrs - validates packet segments for valid protocol headers
@@ -431,21 +489,18 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
 				(const ice_bitmap_t *)ice_ptypes_mac_il;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_ETH;
 		}
 
 		if (i && hdrs & ICE_FLOW_SEG_HDR_VLAN) {
 			src = (const ice_bitmap_t *)ice_ptypes_macvlan_il;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_VLAN;
 		}
 
 		if (!i && hdrs & ICE_FLOW_SEG_HDR_ARP) {
 			ice_and_bitmap(params->ptypes, params->ptypes,
 				       (const ice_bitmap_t *)ice_ptypes_arp_of,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_ARP;
 		}
 
 		if (hdrs & ICE_FLOW_SEG_HDR_IPV4) {
@@ -453,13 +508,11 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
 				(const ice_bitmap_t *)ice_ptypes_ipv4_il;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_IPV4;
 		} else if (hdrs & ICE_FLOW_SEG_HDR_IPV6) {
 			src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv6_ofos :
 				(const ice_bitmap_t *)ice_ptypes_ipv6_il;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_IPV6;
 		}
 
 		if (hdrs & ICE_FLOW_SEG_HDR_ICMP) {
@@ -467,29 +520,42 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
 				(const ice_bitmap_t *)ice_ptypes_icmp_il;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_ICMP;
 		} else if (hdrs & ICE_FLOW_SEG_HDR_UDP) {
 			src = (const ice_bitmap_t *)ice_ptypes_udp_il;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_UDP;
 		} else if (hdrs & ICE_FLOW_SEG_HDR_TCP) {
 			ice_and_bitmap(params->ptypes, params->ptypes,
 				       (const ice_bitmap_t *)ice_ptypes_tcp_il,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_TCP;
 		} else if (hdrs & ICE_FLOW_SEG_HDR_SCTP) {
 			src = (const ice_bitmap_t *)ice_ptypes_sctp_il;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
-			hdrs &= ~ICE_FLOW_SEG_HDR_SCTP;
 		} else if (hdrs & ICE_FLOW_SEG_HDR_GRE) {
 			if (!i) {
 				src = (const ice_bitmap_t *)ice_ptypes_gre_of;
 				ice_and_bitmap(params->ptypes, params->ptypes,
 					       src, ICE_FLOW_PTYPE_MAX);
 			}
-			hdrs &= ~ICE_FLOW_SEG_HDR_GRE;
+		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC) {
+			if (!i) {
+				src = (const ice_bitmap_t *)ice_ptypes_gtpc;
+				ice_and_bitmap(params->ptypes, params->ptypes,
+					       src, ICE_FLOW_PTYPE_MAX);
+			}
+		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPC_TEID) {
+			if (!i) {
+				src = (const ice_bitmap_t *)ice_ptypes_gtpc_tid;
+				ice_and_bitmap(params->ptypes, params->ptypes,
+					       src, ICE_FLOW_PTYPE_MAX);
+			}
+		} else if (hdrs & ICE_FLOW_SEG_HDR_GTPU) {
+			if (!i) {
+				src = (const ice_bitmap_t *)ice_ptypes_gtpu;
+				ice_and_bitmap(params->ptypes, params->ptypes,
+					       src, ICE_FLOW_PTYPE_MAX);
+			}
 		}
 	}
 
@@ -619,6 +685,16 @@ ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
 	case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT:
 		prot_id = ICE_PROT_SCTP_IL;
 		break;
+	case ICE_FLOW_FIELD_IDX_GTPC_TEID:
+	case ICE_FLOW_FIELD_IDX_GTPU_IP_TEID:
+	case ICE_FLOW_FIELD_IDX_GTPU_UP_TEID:
+	case ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID:
+		/* GTP is accessed through UDP OF protocol */
+		prot_id = ICE_PROT_UDP_OF;
+		break;
+	case ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID:
+		prot_id = ICE_PROT_PPPOE;
+		break;
 	case ICE_FLOW_FIELD_IDX_ARP_SIP:
 	case ICE_FLOW_FIELD_IDX_ARP_DIP:
 	case ICE_FLOW_FIELD_IDX_ARP_SHA:
@@ -1601,11 +1677,12 @@ ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len,
 }
 
 #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
-	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
+	(ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_PPPOE)
 
 #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \
 	(ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \
-	 ICE_FLOW_SEG_HDR_SCTP)
+	 ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_GTPC_TEID)
+
 
 #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \
 	(ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index 3a0fd23c4..eb8e1b733 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -41,6 +41,17 @@
 #define ICE_HASH_SCTP_IPV4	(ICE_FLOW_HASH_IPV4 | ICE_FLOW_HASH_SCTP_PORT)
 #define ICE_HASH_SCTP_IPV6	(ICE_FLOW_HASH_IPV6 | ICE_FLOW_HASH_SCTP_PORT)
 
+#define ICE_FLOW_HASH_GTP_TEID \
+	(ICE_FLOW_HASH_FLD(ICE_FLOW_FIELD_IDX_GTPC_TEID))
+
+#define ICE_FLOW_HASH_GTP_IPV4_TEID \
+	(ICE_FLOW_HASH_IPV4 | ICE_FLOW_HASH_GTP_TEID)
+#define ICE_FLOW_HASH_GTP_IPV6_TEID \
+	(ICE_FLOW_HASH_IPV6 | ICE_FLOW_HASH_GTP_TEID)
+
+#define ICE_FLOW_HASH_PPPOE_SESS_ID \
+	(ICE_FLOW_HASH_FLD(ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID))
+
 /* Protocol header fields within a packet segment. A segment consists of one or
  * more protocol headers that make up a logical group of protocol headers. Each
  * logical group of protocol headers encapsulates or is encapsulated using/by
@@ -48,19 +59,37 @@
  * VxLAN, etc.
  */
 enum ice_flow_seg_hdr {
-	ICE_FLOW_SEG_HDR_NONE	= 0x00000000,
-	ICE_FLOW_SEG_HDR_ETH	= 0x00000001,
-	ICE_FLOW_SEG_HDR_VLAN	= 0x00000002,
-	ICE_FLOW_SEG_HDR_IPV4	= 0x00000004,
-	ICE_FLOW_SEG_HDR_IPV6	= 0x00000008,
-	ICE_FLOW_SEG_HDR_ARP	= 0x00000010,
-	ICE_FLOW_SEG_HDR_ICMP	= 0x00000020,
-	ICE_FLOW_SEG_HDR_TCP	= 0x00000040,
-	ICE_FLOW_SEG_HDR_UDP	= 0x00000080,
-	ICE_FLOW_SEG_HDR_SCTP	= 0x00000100,
-	ICE_FLOW_SEG_HDR_GRE	= 0x00000200,
+	ICE_FLOW_SEG_HDR_NONE		= 0x00000000,
+	ICE_FLOW_SEG_HDR_ETH		= 0x00000001,
+	ICE_FLOW_SEG_HDR_VLAN		= 0x00000002,
+	ICE_FLOW_SEG_HDR_IPV4		= 0x00000004,
+	ICE_FLOW_SEG_HDR_IPV6		= 0x00000008,
+	ICE_FLOW_SEG_HDR_ARP		= 0x00000010,
+	ICE_FLOW_SEG_HDR_ICMP		= 0x00000020,
+	ICE_FLOW_SEG_HDR_TCP		= 0x00000040,
+	ICE_FLOW_SEG_HDR_UDP		= 0x00000080,
+	ICE_FLOW_SEG_HDR_SCTP		= 0x00000100,
+	ICE_FLOW_SEG_HDR_GRE		= 0x00000200,
+	ICE_FLOW_SEG_HDR_GTPC		= 0x00000400,
+	ICE_FLOW_SEG_HDR_GTPC_TEID	= 0x00000800,
+	ICE_FLOW_SEG_HDR_GTPU_IP	= 0x00001000,
+	ICE_FLOW_SEG_HDR_GTPU_DWN	= 0x00002000,
+	ICE_FLOW_SEG_HDR_GTPU_UP	= 0x00004000,
+	ICE_FLOW_SEG_HDR_PPPOE		= 0x00008000,
 };
 
+/* These segements all have the same PTYPES, but are otherwise distinguished by
+ * the value of the gtp_eh_pdu and gtp_eh_pdu_link flags:
+ *
+ *                                gtp_eh_pdu     gtp_eh_pdu_link
+ * ICE_FLOW_SEG_HDR_GTPU_IP           0              0
+ * ICE_FLOW_SEG_HDR_GTPU_DWN          1              0
+ * ICE_FLOW_SEG_HDR_GTPU_UP           1              1
+ */
+#define ICE_FLOW_SEG_HDR_GTPU (ICE_FLOW_SEG_HDR_GTPU_IP | \
+			       ICE_FLOW_SEG_HDR_GTPU_DWN | \
+			       ICE_FLOW_SEG_HDR_GTPU_UP)
+
 enum ice_flow_field {
 	/* L2 */
 	ICE_FLOW_FIELD_IDX_ETH_DA,
@@ -95,6 +124,16 @@ enum ice_flow_field {
 	ICE_FLOW_FIELD_IDX_ICMP_CODE,
 	/* GRE */
 	ICE_FLOW_FIELD_IDX_GRE_KEYID,
+	/* GTPC_TEID */
+	ICE_FLOW_FIELD_IDX_GTPC_TEID,
+	/* GTPU_IP */
+	ICE_FLOW_FIELD_IDX_GTPU_IP_TEID,
+	/* GTPU_UP */
+	ICE_FLOW_FIELD_IDX_GTPU_UP_TEID,
+	/* GTPU_DWN */
+	ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID,
+	/* PPPOE */
+	ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID,
 	 /* The total number of enums must not exceed 64 */
 	ICE_FLOW_FIELD_IDX_MAX
 };
diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h
index cfbe3fbfa..29375d3ae 100644
--- a/drivers/net/ice/base/ice_protocol_type.h
+++ b/drivers/net/ice/base/ice_protocol_type.h
@@ -43,6 +43,8 @@ enum ice_protocol_type {
 	ICE_GENEVE,
 	ICE_VXLAN_GPE,
 	ICE_NVGRE,
+	ICE_GTP,
+	ICE_PPPOE,
 	ICE_PROTOCOL_LAST
 };
 
@@ -55,6 +57,8 @@ enum ice_sw_tunnel_type {
 	ICE_SW_TUN_UDP, /* This means all "UDP" tunnel types: VXLAN-GPE, VXLAN
 			 * and GENEVE
 			 */
+	ICE_SW_TUN_GTP,
+	ICE_SW_TUN_PPPOE,
 	ICE_ALL_TUNNELS /* All tunnel types including NVGRE */
 };
 
@@ -97,6 +101,7 @@ enum ice_prot_id {
 	ICE_PROT_ICMPV6_IL	= 100,
 	ICE_PROT_VRRP_F		= 101,
 	ICE_PROT_OSPF		= 102,
+	ICE_PROT_PPPOE		= 103,
 	ICE_PROT_ATAOE_OF	= 114,
 	ICE_PROT_CTRL_OF	= 116,
 	ICE_PROT_LLDP_OF	= 117,
@@ -115,9 +120,9 @@ enum ice_prot_id {
 #define ICE_IPV6_OFOS_HW	40
 #define ICE_IPV6_IL_HW		41
 #define ICE_TCP_IL_HW		49
-#define ICE_UDP_OF_HW		52
 #define ICE_UDP_ILOS_HW		53
 #define ICE_SCTP_IL_HW		96
+#define ICE_PPPOE_HW		103
 
 /* ICE_UDP_OF is used to identify all 3 tunnel types
  * VXLAN, GENEVE and VXLAN_GPE. To differentiate further
@@ -198,6 +203,30 @@ struct ice_udp_tnl_hdr {
 	u32 vni;	/* only use lower 24-bits */
 };
 
+#pragma pack(1)
+struct ice_udp_gtp_hdr {
+	u8 flags;
+	u8 msg_type;
+	u16 rsrvd_len;
+	u32 teid;
+	u16 rsrvd_seq_nbr;
+	u8 rsrvd_n_pdu_nbr;
+	u8 rsrvd_next_ext;
+	u8 rsvrd_ext_len;
+	u8 pdu_type;
+	u8 qfi;
+	u8 rsvrd;
+};
+
+struct ice_pppoe_hdr {
+	u8 rsrvd_ver_type;
+	u8 rsrved_code;
+	u16 session_id;
+	u16 length;
+	u16 ppp_prot_id; /* control and data only */
+};
+#pragma pack()
+
 struct ice_nvgre {
 	u16 flags;
 	u16 protocol;
@@ -213,6 +242,8 @@ union ice_prot_hdr {
 	struct ice_sctp_hdr sctp_hdr;
 	struct ice_udp_tnl_hdr tnl_hdr;
 	struct ice_nvgre nvgre_hdr;
+	struct ice_udp_gtp_hdr gtp_hdr;
+	struct ice_pppoe_hdr pppoe_hdr;
 };
 
 /* This is mapping table entry that maps every word within a given protocol
diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c
index b249a3036..f88addec6 100644
--- a/drivers/net/ice/base/ice_switch.c
+++ b/drivers/net/ice/base/ice_switch.c
@@ -380,7 +380,64 @@ dummy_udp_ipv6_packet[] = {
 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
 };
 
-/* this is a recipe to profile bitmap association */
+static const
+struct ice_dummy_pkt_offsets dummy_udp_gtp_packet_offsets[] = {
+	{ ICE_MAC_OFOS,		0 },
+	{ ICE_IPV4_OFOS,	14 },
+	{ ICE_UDP_OF,		34 },
+	{ ICE_GTP,		42 },
+	{ ICE_PROTOCOL_LAST,	0 },
+};
+
+static const u8
+dummy_udp_gtp_packet[] = {
+	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00,
+
+	0x45, 0x00, 0x00, 0x30, /* ICE_IPV4_OFOS 14 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x11, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x08, 0x68, /* ICE_UDP_OF 34 */
+	0x00, 0x1c, 0x00, 0x00,
+
+	0x34, 0xff, 0x00, 0x0c, /* ICE_GTP 42 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x85,
+
+	0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static const
+struct ice_dummy_pkt_offsets dummy_pppoe_packet_offsets[] = {
+	{ ICE_MAC_OFOS,			0 },
+	{ ICE_PPPOE,			14 },
+	{ ICE_PROTOCOL_LAST,	0 },
+};
+
+static const u8
+dummy_pppoe_packet[] = {
+	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x88, 0x64,
+
+	0x11, 0x00, 0x00, 0x01, /* ICE_PPPOE 14 */
+	0x00, 0x4e, 0x00, 0x21,
+
+	0x45, 0x00, 0x00, 0x30, /* PDU */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x11, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+/* this is a recipe to profile association bitmap */
 static ice_declare_bitmap(recipe_to_profile[ICE_MAX_NUM_RECIPES],
 			  ICE_MAX_NUM_PROFILES);
 static ice_declare_bitmap(available_result_ids, ICE_CHAIN_FV_INDEX_START + 1);
@@ -4541,6 +4598,8 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[] = {
 	{ ICE_GENEVE,		{ 8, 10, 12, 14 } },
 	{ ICE_VXLAN_GPE,	{ 0, 2, 4 } },
 	{ ICE_NVGRE,		{ 0, 2, 4, 6 } },
+	{ ICE_GTP,		{ 8, 10, 12, 14, 16, 18, 20 } },
+	{ ICE_PPPOE,		{ 0, 2, 4, 6 } },
 	{ ICE_PROTOCOL_LAST,	{ 0 } }
 };
 
@@ -4577,6 +4636,8 @@ static const struct ice_protocol_entry ice_prot_id_tbl[] = {
 	{ ICE_GENEVE,		ICE_UDP_OF_HW },
 	{ ICE_VXLAN_GPE,	ICE_UDP_OF_HW },
 	{ ICE_NVGRE,		ICE_GRE_OF_HW },
+	{ ICE_GTP,		ICE_UDP_OF_HW },
+	{ ICE_PPPOE,		ICE_PPPOE_HW },
 	{ ICE_PROTOCOL_LAST,	0 }
 };
 
@@ -5418,6 +5479,18 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 	bool tcp = false, udp = false, ipv6 = false;
 	u16 i;
 
+	if (tun_type == ICE_SW_TUN_GTP) {
+		*pkt = dummy_udp_gtp_packet;
+		*pkt_len = sizeof(dummy_udp_gtp_packet);
+		*offsets = dummy_udp_gtp_packet_offsets;
+		return;
+	}
+	if (tun_type == ICE_SW_TUN_PPPOE) {
+		*pkt = dummy_pppoe_packet;
+		*pkt_len = sizeof(dummy_pppoe_packet);
+		*offsets = dummy_pppoe_packet_offsets;
+		return;
+	}
 	for (i = 0; i < lkups_cnt; i++) {
 		if (lkups[i].type == ICE_UDP_ILOS)
 			udp = true;
@@ -5564,6 +5637,10 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 		case ICE_VXLAN_GPE:
 			len = sizeof(struct ice_udp_tnl_hdr);
 			break;
+
+		case ICE_GTP:
+			len = sizeof(struct ice_udp_gtp_hdr);
+			break;
 		default:
 			return ICE_ERR_PARAM;
 		}
-- 
2.13.6


  parent reply	other threads:[~2019-08-26 10:52 UTC|newest]

Thread overview: 130+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-26 10:50 [dpdk-dev] [PATCH 00/63] net/ice/base: update base code Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 01/63] net/ice/base: enhance NVM read Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 02/63] net/ice/base: add function to get FW mode Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 03/63] net/ice/base: add support for NVM rollback detection Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 04/63] net/ice/base: add support to init RXDID descs fields Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 05/63] net/ice/base: store number of functions for the device Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 06/63] net/ice/base: add read PBA module function Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 07/63] net/ice/base: correct argument port info Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 08/63] net/ice/base: remove debug code Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 09/63] net/ice/base: add SFF EEPROM AQ Command Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 10/63] net/ice/base: improve debug print message Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 11/63] net/ice/base: add capabilities when in safe mode Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 12/63] net/ice/base: add helper functions for PHY caching Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 13/63] net/ice/base: add support for reading REPC statistics Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 14/63] net/ice/base: adjust DCB INIT for SW mode Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 15/63] net/ice/base: add NVM pkg flag Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 16/63] net/ice/base: move VSI to VSI group Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 17/63] net/ice/base: enable masking for RSS and FD field vectors Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 18/63] net/ice/base: resolve static analysis issues Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 19/63] net/ice/base: fix memory leak issue Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 20/63] net/ice/base: check root pointer for validity Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 21/63] net/ice/base: fix type-mismatch Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 22/63] net/ice/base: correct overrun Coverty hit Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 23/63] net/ice/base: update Boot Configuration Section read of NVM Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 24/63] net/ice/base: add support for NVM access commands Qi Zhang
2019-08-26 10:50 ` Qi Zhang [this message]
2019-08-26 10:50 ` [dpdk-dev] [PATCH 26/63] net/ice/base: add locks for flow functions Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 27/63] net/ice/base: improve switch advanced rule Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 28/63] net/ice/base: move function declaration Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 29/63] net/ice/base: add 16-byte Flex Rx Descriptor Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 30/63] net/ice/base: add 32-byte Flex Rx Desc for Comms package Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 31/63] net/ice/base: update flag bits to current specification Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 32/63] net/ice/base: add more opcode and macros Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 33/63] net/ice/base: set status when global cfg lock is unavailable Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 34/63] net/ice/base: initialize driver NVM data earlier Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 35/63] net/ice/base: add function to configure Tx AQ command Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 36/63] net/ice/base: add support for not locking sideband queue Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 37/63] net/ice/base: associate recipes by profile type Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 38/63] net/ice/base: return switch error on invalid match criteria Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 39/63] net/ice/base: update UDP tunnel switch training packets Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 40/63] net/ice/base: improve switch chained recipe Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 41/63] net/ice/base: move and add some help function and macros Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 42/63] net/ice/base: add routine for tunnel port query Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 43/63] net/ice/base: ptype group consolidation Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 44/63] net/ice/base: fix for RSS hash on inner UDP port Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 45/63] net/ice/base: packet encapsulation for RSS Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 46/63] net/ice/base: add RSS support for PPPoE and GTPU Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 47/63] net/ice/base: remove unnecessary conditional check Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 48/63] net/ice/base: fix flag settings in AQ call Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 49/63] net/ice/base: refactor removal of VLAN promiscuous rules Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 50/63] net/ice/base: maximize switch recipe words per line Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 51/63] net/ice/base: update switch training packets with open ports Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 52/63] net/ice/base: remove unnecessary dummy packet finding Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 53/63] net/ice/base: remove unnecessary if branch Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 54/63] net/ice/base: correct abbreviations Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 55/63] net/ice/base: update to register definition file Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 56/63] net/ice/base: replace open-code duplication Qi Zhang
2019-08-26 10:50 ` [dpdk-dev] [PATCH 57/63] net/ice/base: delay less Qi Zhang
2019-08-26 10:51 ` [dpdk-dev] [PATCH 58/63] net/ice/base: add AQC get link topology handle support Qi Zhang
2019-08-26 10:51 ` [dpdk-dev] [PATCH 59/63] net/ice/base: remove Rx flex descriptor programming Qi Zhang
2019-08-26 10:51 ` [dpdk-dev] [PATCH 60/63] net/ice/base: enable RSS with ether layer for PPPoE Qi Zhang
2019-08-26 10:51 ` [dpdk-dev] [PATCH 61/63] net/ice/base: add GENEVE offset Qi Zhang
2019-08-26 17:53   ` Dziggel, Douglas A
2019-08-26 10:51 ` [dpdk-dev] [PATCH 62/63] net/ice/base: update profile to recipe bitmap array Qi Zhang
2019-08-26 10:51 ` [dpdk-dev] [PATCH 63/63] net/ice/base: ignore inverse switch recipes Qi Zhang
2019-08-29  2:35 ` [dpdk-dev] [PATCH 00/63 v2] net/ice/base: update base code Qi Zhang
2019-08-29  2:35   ` [dpdk-dev] [PATCH v2 01/63] net/ice/base: enhance NVM read Qi Zhang
2019-08-29  2:35   ` [dpdk-dev] [PATCH v2 02/63] net/ice/base: add function to get FW mode Qi Zhang
2019-08-29  2:35   ` [dpdk-dev] [PATCH v2 03/63] net/ice/base: add support for NVM rollback detection Qi Zhang
2019-08-29  2:35   ` [dpdk-dev] [PATCH v2 04/63] net/ice/base: add support to init RXDID descs fields Qi Zhang
2019-08-29  2:35   ` [dpdk-dev] [PATCH v2 05/63] net/ice/base: store number of functions for the device Qi Zhang
2019-08-29  2:35   ` [dpdk-dev] [PATCH v2 06/63] net/ice/base: add read PBA module function Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 07/63] net/ice/base: correct argument port info Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 08/63] net/ice/base: remove debug code Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 09/63] net/ice/base: add SFF EEPROM AQ Command Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 10/63] net/ice/base: improve debug print message Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 11/63] net/ice/base: add capabilities when in safe mode Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 12/63] net/ice/base: add helper functions for PHY caching Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 13/63] net/ice/base: add support for reading REPC statistics Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 14/63] net/ice/base: adjust DCB INIT for SW mode Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 15/63] net/ice/base: add NVM pkg flag Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 16/63] net/ice/base: move VSI to VSI group Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 17/63] net/ice/base: enable masking for RSS and FD field vectors Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 18/63] net/ice/base: resolve static analysis issues Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 19/63] net/ice/base: fix memory leak issue Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 20/63] net/ice/base: check root pointer for validity Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 21/63] net/ice/base: fix type-mismatch Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 22/63] net/ice/base: correct overrun Coverty hit Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 23/63] net/ice/base: update Boot Configuration Section read of NVM Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 24/63] net/ice/base: add support for NVM access commands Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 25/63] net/ice/base: add support for GTP and PPPoE protocols Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 26/63] net/ice/base: add locks for flow functions Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 27/63] net/ice/base: improve switch advanced rule Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 28/63] net/ice/base: move function declaration Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 29/63] net/ice/base: add 16-byte Flex Rx Descriptor Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 30/63] net/ice/base: add 32-byte Flex Rx Desc Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 31/63] net/ice/base: update flag bits Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 32/63] net/ice/base: add more opcode and macros Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 33/63] net/ice/base: set status when global cfg lock is unavailable Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 34/63] net/ice/base: initialize driver NVM data earlier Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 35/63] net/ice/base: add function to configure Tx AQ command Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 36/63] net/ice/base: add support for not locking sideband queue Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 37/63] net/ice/base: associate recipes by profile type Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 38/63] net/ice/base: return switch error on invalid match criteria Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 39/63] net/ice/base: update UDP tunnel switch training packets Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 40/63] net/ice/base: improve switch chained recipe Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 41/63] net/ice/base: move and add some help function and macros Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 42/63] net/ice/base: add routine for tunnel port query Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 43/63] net/ice/base: ptype group consolidation Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 44/63] net/ice/base: fix for RSS hash on inner UDP port Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 45/63] net/ice/base: packet encapsulation for RSS Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 46/63] net/ice/base: add RSS support for PPPoE and GTPU Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 47/63] net/ice/base: remove unnecessary conditional check Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 48/63] net/ice/base: fix flag settings in AQ call Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 49/63] net/ice/base: refactor removal of VLAN promiscuous rules Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 50/63] net/ice/base: maximize switch recipe words per line Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 51/63] net/ice/base: update switch training packets with open ports Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 52/63] net/ice/base: remove unnecessary dummy packet finding Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 53/63] net/ice/base: remove unnecessary if branch Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 54/63] net/ice/base: correct abbreviations Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 55/63] net/ice/base: update to register definition file Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 56/63] net/ice/base: replace open-code duplication Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 57/63] net/ice/base: delay less Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 58/63] net/ice/base: add AQC get link topology handle support Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 59/63] net/ice/base: remove Rx flex descriptor programming Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 60/63] net/ice/base: enable RSS with ether layer for PPPoE Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 61/63] net/ice/base: add GENEVE offset Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 62/63] net/ice/base: update profile to recipe bitmap array Qi Zhang
2019-08-29  2:36   ` [dpdk-dev] [PATCH v2 63/63] net/ice/base: ignore inverse switch recipes Qi Zhang
2019-08-30  9:44   ` [dpdk-dev] [PATCH 00/63 v2] net/ice/base: update base code Ye Xiaolong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190826105105.19121-26-qi.z.zhang@intel.com \
    --to=qi.z.zhang@intel.com \
    --cc=dan.nowlin@intel.com \
    --cc=dev@dpdk.org \
    --cc=paul.m.stillwell.jr@intel.com \
    --cc=qiming.yang@intel.com \
    --cc=wenzhuo.lu@intel.com \
    --cc=xiaolong.ye@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).