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 158815A1F for ; Thu, 10 Sep 2015 09:11:36 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 10 Sep 2015 00:11:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,502,1437462000"; d="scan'208";a="801435121" Received: from unknown (HELO stargo) ([10.217.248.233]) by orsmga002.jf.intel.com with SMTP; 10 Sep 2015 00:11:33 -0700 Received: by stargo (sSMTP sendmail emulation); Thu, 10 Sep 2015 09:09:37 +0200 From: Piotr Azarewicz To: dev@dpdk.org Date: Thu, 10 Sep 2015 09:09:17 +0200 Message-Id: <1441868957-20479-1-git-send-email-piotrx.t.azarewicz@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1441805945-19889-1-git-send-email-piotrx.t.azarewicz@intel.com> References: <1441805945-19889-1-git-send-email-piotrx.t.azarewicz@intel.com> Subject: [dpdk-dev] [PATCH v4 1/1] ip_frag: fix creating ipv6 fragment extension header X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Sep 2015 07:11:37 -0000 Previous implementation won't work on every environment. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. Solution: used bytes instead of bit fields. v2 changes: - remove useless union - fix process_ipv6 function (due to remove the union above) v3 changes: - add macros to read/set fragment_offset and more_flags values v4 changes: - two additional fixes due to remove the union and due to changes in macros Signed-off-by: Piotr Azarewicz --- lib/librte_ip_frag/rte_ip_frag.h | 27 ++++++++++++++++----------- lib/librte_ip_frag/rte_ipv6_fragmentation.c | 14 +++----------- lib/librte_ip_frag/rte_ipv6_reassembly.c | 3 ++- lib/librte_port/rte_port_ras.c | 7 ++++--- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h index 52f44c9..92cedf2 100644 --- a/lib/librte_ip_frag/rte_ip_frag.h +++ b/lib/librte_ip_frag/rte_ip_frag.h @@ -128,19 +128,24 @@ struct rte_ip_frag_tbl { }; /** IPv6 fragment extension header */ +#define RTE_IPV6_EHDR_MF_SHIFT 0 +#define RTE_IPV6_EHDR_MF_MASK 1 +#define RTE_IPV6_EHDR_FO_SHIFT 3 +#define RTE_IPV6_EHDR_FO_MASK (~((1 << RTE_IPV6_EHDR_FO_SHIFT) - 1)) + +#define RTE_IPV6_FRAG_USED_MASK \ + (RTE_IPV6_EHDR_MF_MASK | RTE_IPV6_EHDR_FO_MASK) + +#define RTE_IPV6_GET_MF(x) ((x) & RTE_IPV6_EHDR_MF_MASK) +#define RTE_IPV6_GET_FO(x) ((x) >> RTE_IPV6_EHDR_FO_SHIFT) + +#define RTE_IPV6_SET_FRAG_DATA(fo, mf) \ + (((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) & RTE_IPV6_EHDR_MF_MASK)) + struct ipv6_extension_fragment { uint8_t next_header; /**< Next header type */ - uint8_t reserved1; /**< Reserved */ - union { - struct { - uint16_t frag_offset:13; /**< Offset from the start of the packet */ - uint16_t reserved2:2; /**< Reserved */ - uint16_t more_frags:1; - /**< 1 if more fragments left, 0 if last fragment */ - }; - uint16_t frag_data; - /**< union of all fragmentation data */ - }; + uint8_t reserved; /**< Reserved */ + uint16_t frag_data; /**< All fragmentation data */ uint32_t id; /**< Packet ID */ } __attribute__((__packed__)); diff --git a/lib/librte_ip_frag/rte_ipv6_fragmentation.c b/lib/librte_ip_frag/rte_ipv6_fragmentation.c index 0e32aa8..1e30004 100644 --- a/lib/librte_ip_frag/rte_ipv6_fragmentation.c +++ b/lib/librte_ip_frag/rte_ipv6_fragmentation.c @@ -46,12 +46,6 @@ * */ -/* Fragment Extension Header */ -#define IPV6_HDR_MF_SHIFT 0 -#define IPV6_HDR_FO_SHIFT 3 -#define IPV6_HDR_MF_MASK (1 << IPV6_HDR_MF_SHIFT) -#define IPV6_HDR_FO_MASK ((1 << IPV6_HDR_FO_SHIFT) - 1) - static inline void __fill_ipv6hdr_frag(struct ipv6_hdr *dst, const struct ipv6_hdr *src, uint16_t len, uint16_t fofs, @@ -65,10 +59,8 @@ __fill_ipv6hdr_frag(struct ipv6_hdr *dst, fh = (struct ipv6_extension_fragment *) ++dst; fh->next_header = src->proto; - fh->reserved1 = 0; - fh->frag_offset = rte_cpu_to_be_16(fofs); - fh->reserved2 = 0; - fh->more_frags = rte_cpu_to_be_16(mf); + fh->reserved = 0; + fh->frag_data = rte_cpu_to_be_16(RTE_IPV6_SET_FRAG_DATA(fofs, mf)); fh->id = 0; } @@ -118,7 +110,7 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in, frag_size = (uint16_t)(mtu_size - sizeof(struct ipv6_hdr)); /* Fragment size should be a multiple of 8. */ - IP_FRAG_ASSERT((frag_size & IPV6_HDR_FO_MASK) == 0); + IP_FRAG_ASSERT((frag_size & ~RTE_IPV6_EHDR_FO_MASK) == 0); /* Check that pkts_out is big enough to hold all fragments */ if (unlikely (frag_size * nb_pkts_out < diff --git a/lib/librte_ip_frag/rte_ipv6_reassembly.c b/lib/librte_ip_frag/rte_ipv6_reassembly.c index 1f1c172..8b4ef8a 100644 --- a/lib/librte_ip_frag/rte_ipv6_reassembly.c +++ b/lib/librte_ip_frag/rte_ipv6_reassembly.c @@ -181,7 +181,8 @@ rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl, "tbl: %p, max_cycles: %" PRIu64 ", entry_mask: %#x, " "max_entries: %u, use_entries: %u\n\n", __func__, __LINE__, - mb, tms, IPv6_KEY_BYTES(key.src_dst), key.id, ip_ofs, ip_len, frag_hdr->more_frags, + mb, tms, IPv6_KEY_BYTES(key.src_dst), key.id, ip_ofs, ip_len, + RTE_IPV6_GET_MF(frag_hdr->frag_data), tbl, tbl->max_cycles, tbl->entry_mask, tbl->max_entries, tbl->use_entries); diff --git a/lib/librte_port/rte_port_ras.c b/lib/librte_port/rte_port_ras.c index 6bd0f8c..8a2e554 100644 --- a/lib/librte_port/rte_port_ras.c +++ b/lib/librte_port/rte_port_ras.c @@ -212,12 +212,13 @@ process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt) struct ipv6_hdr *pkt_hdr = rte_pktmbuf_mtod(pkt, struct ipv6_hdr *); struct ipv6_extension_fragment *frag_hdr; + uint16_t frag_data = 0; frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt_hdr); - uint16_t frag_offset = frag_hdr->frag_offset; - uint16_t frag_flag = frag_hdr->more_frags; + if (frag_hdr != NULL) + frag_data = rte_be_to_cpu_16(frag_hdr->frag_data); /* If it is a fragmented packet, then try to reassemble */ - if ((frag_flag == 0) && (frag_offset == 0)) + if ((frag_data & RTE_IPV6_FRAG_USED_MASK) == 0) p->tx_buf[p->tx_buf_count++] = pkt; else { struct rte_mbuf *mo; -- 1.7.9.5