From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 56B1B567E for ; Wed, 9 Sep 2015 15:41:50 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP; 09 Sep 2015 06:41:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,496,1437462000"; d="scan'208";a="800865673" Received: from unknown (HELO stargo) ([10.217.248.233]) by orsmga002.jf.intel.com with SMTP; 09 Sep 2015 06:41:26 -0700 Received: by stargo (sSMTP sendmail emulation); Wed, 09 Sep 2015 15:39:30 +0200 From: Piotr Azarewicz To: dev@dpdk.org Date: Wed, 9 Sep 2015 15:39:05 +0200 Message-Id: <1441805945-19889-1-git-send-email-piotrx.t.azarewicz@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1441721267-19142-1-git-send-email-piotrx.t.azarewicz@intel.com> References: <1441721267-19142-1-git-send-email-piotrx.t.azarewicz@intel.com> Subject: [dpdk-dev] [PATCH v3 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: Wed, 09 Sep 2015 13:41:51 -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 Signed-off-by: Piotr Azarewicz --- lib/librte_ip_frag/rte_ip_frag.h | 27 ++++++++++++++++----------- lib/librte_ip_frag/rte_ipv6_fragmentation.c | 12 ++---------- lib/librte_port/rte_port_ras.c | 7 ++++--- 3 files changed, 22 insertions(+), 24 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..251a4b8 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; } 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