From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id E898A1B24D for ; Wed, 10 Jan 2018 14:59:24 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Jan 2018 05:59:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,340,1511856000"; d="scan'208";a="26046666" Received: from dpdk15.sh.intel.com ([10.67.111.77]) by orsmga002.jf.intel.com with ESMTP; 10 Jan 2018 05:59:23 -0800 From: Jiayu Hu To: dev@dpdk.org Cc: thomas@monjalon.net, junjie.j.chen@intel.com, jianfeng.tan@intel.com, lei.a.yao@intel.com, Jiayu Hu Date: Wed, 10 Jan 2018 22:03:11 +0800 Message-Id: <1515592992-70278-3-git-send-email-jiayu.hu@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515592992-70278-1-git-send-email-jiayu.hu@intel.com> References: <1515132769-52572-1-git-send-email-jiayu.hu@intel.com> <1515592992-70278-1-git-send-email-jiayu.hu@intel.com> Subject: [dpdk-dev] [PATCH v5 2/3] gro: comply RFC 6864 to process IPv4 ID X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jan 2018 13:59:25 -0000 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 Reviewed-by: Junjie Chen --- .../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