DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jiayu Hu <jiayu.hu@intel.com>
To: dev@dpdk.org
Cc: thomas@monjalon.net, junjie.j.chen@intel.com,
	jianfeng.tan@intel.com, lei.a.yao@intel.com,
	Jiayu Hu <jiayu.hu@intel.com>
Subject: [dpdk-dev] [PATCH v5 2/3] gro: comply RFC 6864 to process IPv4 ID
Date: Wed, 10 Jan 2018 22:03:11 +0800	[thread overview]
Message-ID: <1515592992-70278-3-git-send-email-jiayu.hu@intel.com> (raw)
In-Reply-To: <1515592992-70278-1-git-send-email-jiayu.hu@intel.com>

This patch complies RFC 6864 to process IPv4 ID fields. Specifically, GRO
ingores IPv4 ID fields for the packets whose DF bit is 1, and checks IPv4
ID fields for the packets whose DF bit is 0.

Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
Reviewed-by: Junjie Chen <junjie.j.chen@intel.com>
---
 .../prog_guide/generic_receive_offload_lib.rst     | 14 ++++++--
 lib/librte_gro/gro_tcp4.c                          | 39 ++++++++++++++++------
 lib/librte_gro/gro_tcp4.h                          |  2 ++
 3 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/doc/guides/prog_guide/generic_receive_offload_lib.rst b/doc/guides/prog_guide/generic_receive_offload_lib.rst
index 1652e64..c2d7a41 100644
--- a/doc/guides/prog_guide/generic_receive_offload_lib.rst
+++ b/doc/guides/prog_guide/generic_receive_offload_lib.rst
@@ -54,8 +54,8 @@ corresponding GRO functions by MBUF->packet_type.
 The GRO library doesn't check if input packets have correct checksums and
 doesn't re-calculate checksums for merged packets. The GRO library
 assumes the packets are complete (i.e., MF==0 && frag_off==0), when IP
-fragmentation is possible (i.e., DF==0). Additionally, it requires IPv4
-ID to be increased by one.
+fragmentation is possible (i.e., DF==0). Additionally, it complies RFC
+6864 to process the IPv4 ID field.
 
 Currently, the GRO library provides GRO supports for TCP/IPv4 packets.
 
@@ -182,4 +182,12 @@ Header fields deciding if two packets are neighbors include:
 
 - TCP sequence number
 
-- IPv4 ID. The IPv4 ID fields of the packets should be increased by 1.
+- IPv4 ID. The IPv4 ID fields of the packets, whose DF bit is 0, should
+  be increased by 1.
+
+.. note::
+        We comply RFC 6864 to process the IPv4 ID field. Specifically,
+        we check IPv4 ID fields for the packets whose DF bit is 0 and
+        ignore IPv4 ID fields for the packets whose DF bit is 1.
+        Additionally, packets which have different value of DF bit can't
+        be merged.
diff --git a/lib/librte_gro/gro_tcp4.c b/lib/librte_gro/gro_tcp4.c
index a38a06e..309cdc7 100644
--- a/lib/librte_gro/gro_tcp4.c
+++ b/lib/librte_gro/gro_tcp4.c
@@ -138,7 +138,8 @@ check_seq_option(struct gro_tcp4_item *item,
 		uint32_t sent_seq,
 		uint16_t ip_id,
 		uint16_t tcp_hl,
-		uint16_t tcp_dl)
+		uint16_t tcp_dl,
+		uint8_t is_atomic)
 {
 	struct rte_mbuf *pkt_orig = item->firstseg;
 	struct ipv4_hdr *iph_orig;
@@ -157,14 +158,19 @@ check_seq_option(struct gro_tcp4_item *item,
 					len) != 0)))
 		return 0;
 
+	/* Don't merge packets whose DF bits are different */
+	if (unlikely(item->is_atomic ^ is_atomic))
+		return 0;
+
 	/* check if the two packets are neighbors */
 	len = pkt_orig->pkt_len - pkt_orig->l2_len - pkt_orig->l3_len -
 		tcp_hl_orig;
-	if ((sent_seq == item->sent_seq + len) && (ip_id == item->ip_id + 1))
+	if ((sent_seq == item->sent_seq + len) && (is_atomic ||
+				(ip_id == item->ip_id + 1)))
 		/* append the new packet */
 		return 1;
-	else if ((sent_seq + tcp_dl == item->sent_seq) &&
-			(ip_id + item->nb_merged == item->ip_id))
+	else if ((sent_seq + tcp_dl == item->sent_seq) && (is_atomic ||
+			(ip_id + item->nb_merged == item->ip_id)))
 		/* pre-pend the new packet */
 		return -1;
 
@@ -201,7 +207,8 @@ insert_new_item(struct gro_tcp4_tbl *tbl,
 		uint64_t start_time,
 		uint32_t prev_idx,
 		uint32_t sent_seq,
-		uint16_t ip_id)
+		uint16_t ip_id,
+		uint8_t is_atomic)
 {
 	uint32_t item_idx;
 
@@ -216,6 +223,7 @@ insert_new_item(struct gro_tcp4_tbl *tbl,
 	tbl->items[item_idx].sent_seq = sent_seq;
 	tbl->items[item_idx].ip_id = ip_id;
 	tbl->items[item_idx].nb_merged = 1;
+	tbl->items[item_idx].is_atomic = is_atomic;
 	tbl->item_num++;
 
 	/* if the previous packet exists, chain them together. */
@@ -310,7 +318,8 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
 	struct ipv4_hdr *ipv4_hdr;
 	struct tcp_hdr *tcp_hdr;
 	uint32_t sent_seq;
-	uint16_t tcp_dl, ip_id, hdr_len;
+	uint16_t tcp_dl, ip_id, hdr_len, frag_off;
+	uint8_t is_atomic;
 
 	struct tcp4_flow_key key;
 	uint32_t cur_idx, prev_idx, item_idx;
@@ -337,7 +346,13 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
 	if (tcp_dl <= 0)
 		return -1;
 
-	ip_id = rte_be_to_cpu_16(ipv4_hdr->packet_id);
+	/*
+	 * Save IPv4 ID for the packet whose DF bit is 0. For the packet
+	 * whose DF bit is 1, IPv4 ID is ignored.
+	 */
+	frag_off = rte_be_to_cpu_16(ipv4_hdr->fragment_offset);
+	is_atomic = (frag_off & IPV4_HDR_DF_FLAG) == IPV4_HDR_DF_FLAG;
+	ip_id = is_atomic ? 0 : rte_be_to_cpu_16(ipv4_hdr->packet_id);
 	sent_seq = rte_be_to_cpu_32(tcp_hdr->sent_seq);
 
 	ether_addr_copy(&(eth_hdr->s_addr), &(key.eth_saddr));
@@ -368,7 +383,8 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
 	 */
 	if (find == 0) {
 		item_idx = insert_new_item(tbl, pkt, start_time,
-				INVALID_ARRAY_INDEX, sent_seq, ip_id);
+				INVALID_ARRAY_INDEX, sent_seq, ip_id,
+				is_atomic);
 		if (item_idx == INVALID_ARRAY_INDEX)
 			return -1;
 		if (insert_new_flow(tbl, &key, item_idx) ==
@@ -391,7 +407,8 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
 	prev_idx = cur_idx;
 	do {
 		cmp = check_seq_option(&(tbl->items[cur_idx]), tcp_hdr,
-				sent_seq, ip_id, pkt->l4_len, tcp_dl);
+				sent_seq, ip_id, pkt->l4_len, tcp_dl,
+				is_atomic);
 		if (cmp) {
 			if (merge_two_tcp4_packets(&(tbl->items[cur_idx]),
 						pkt, cmp, sent_seq, ip_id))
@@ -402,7 +419,7 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
 			 * the packet into the flow.
 			 */
 			if (insert_new_item(tbl, pkt, start_time, prev_idx,
-						sent_seq, ip_id) ==
+						sent_seq, ip_id, is_atomic) ==
 					INVALID_ARRAY_INDEX)
 				return -1;
 			return 0;
@@ -413,7 +430,7 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
 
 	/* Fail to find a neighbor, so store the packet into the flow. */
 	if (insert_new_item(tbl, pkt, start_time, prev_idx, sent_seq,
-				ip_id) == INVALID_ARRAY_INDEX)
+				ip_id, is_atomic) == INVALID_ARRAY_INDEX)
 		return -1;
 
 	return 0;
diff --git a/lib/librte_gro/gro_tcp4.h b/lib/librte_gro/gro_tcp4.h
index 49e03b4..af128c9 100644
--- a/lib/librte_gro/gro_tcp4.h
+++ b/lib/librte_gro/gro_tcp4.h
@@ -61,6 +61,8 @@ struct gro_tcp4_item {
 	uint16_t ip_id;
 	/* the number of merged packets */
 	uint16_t nb_merged;
+	/* Indicate if IPv4 ID can be ignored */
+	uint8_t is_atomic;
 };
 
 /*
-- 
2.7.4

  parent reply	other threads:[~2018-01-10 13:59 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-25  3:17 [dpdk-dev] [PATCH 0/2] Support VxLAN GRO Jiayu Hu
2017-11-25  3:17 ` [dpdk-dev] [PATCH 1/2] gro: TCP/IPV4 GRO codes cleanup Jiayu Hu
2017-11-25  3:17 ` [dpdk-dev] [PATCH 2/2] gro: support VxLAN GRO Jiayu Hu
2017-12-14  2:49 ` [dpdk-dev] [PATCH v2 0/2] Support " Jiayu Hu
2017-12-14  2:49   ` [dpdk-dev] [PATCH v2 1/2] gro: code cleanup Jiayu Hu
2017-12-14  2:49   ` [dpdk-dev] [PATCH v2 2/2] gro: support VxLAN GRO Jiayu Hu
2017-12-14  2:58     ` Stephen Hemminger
2017-12-14  3:02     ` Stephen Hemminger
2017-12-14  4:37       ` Hu, Jiayu
2017-12-22  7:25   ` [dpdk-dev] [PATCH v3 0/2] Support " Jiayu Hu
2017-12-22  7:25     ` [dpdk-dev] [PATCH v3 1/2] gro: code cleanup Jiayu Hu
2017-12-29  3:53       ` Chen, Junjie J
2018-01-02 11:26       ` Bruce Richardson
2018-01-03  1:07         ` Tan, Jianfeng
2018-01-03  1:27           ` Stephen Hemminger
2017-12-22  7:25     ` [dpdk-dev] [PATCH v3 2/2] gro: support VxLAN GRO Jiayu Hu
2017-12-22  8:17       ` Chen, Junjie J
2017-12-25  6:36         ` Jiayu Hu
2017-12-29  3:53       ` Chen, Junjie J
2017-12-29  3:52     ` [dpdk-dev] [PATCH v3 0/2] Support " Chen, Junjie J
2018-01-05  6:12     ` [dpdk-dev] [PATCH v4 " Jiayu Hu
2018-01-05  6:12       ` [dpdk-dev] [PATCH v4 1/2] gro: code cleanup Jiayu Hu
2018-01-08  1:15         ` Yao, Lei A
2018-01-10  0:09         ` Thomas Monjalon
2018-01-10  1:55           ` Hu, Jiayu
2018-01-05  6:12       ` [dpdk-dev] [PATCH v4 2/2] gro: support VxLAN GRO Jiayu Hu
2018-01-10 14:03       ` [dpdk-dev] [PATCH v5 0/3] Support " Jiayu Hu
2018-01-10 14:03         ` [dpdk-dev] [PATCH v5 1/3] gro: codes cleanup Jiayu Hu
2018-01-10 14:03         ` Jiayu Hu [this message]
2018-01-10 14:03         ` [dpdk-dev] [PATCH v5 3/3] gro: support VxLAN GRO Jiayu Hu
2018-01-11 22:15         ` [dpdk-dev] [PATCH v5 0/3] Support " Thomas Monjalon

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=1515592992-70278-3-git-send-email-jiayu.hu@intel.com \
    --to=jiayu.hu@intel.com \
    --cc=dev@dpdk.org \
    --cc=jianfeng.tan@intel.com \
    --cc=junjie.j.chen@intel.com \
    --cc=lei.a.yao@intel.com \
    --cc=thomas@monjalon.net \
    /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).