[dpdk-dev] [PATCH v2 1/1] ip_frag: fix creating ipv6 fragment extension header
Piotr Azarewicz
piotrx.t.azarewicz at intel.com
Tue Sep 8 16:07:47 CEST 2015
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)
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz at intel.com>
---
lib/librte_ip_frag/rte_ip_frag.h | 13 ++-----------
lib/librte_ip_frag/rte_ipv6_fragmentation.c | 6 ++----
lib/librte_port/rte_port_ras.c | 10 +++++++---
3 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
index 52f44c9..f3ca566 100644
--- a/lib/librte_ip_frag/rte_ip_frag.h
+++ b/lib/librte_ip_frag/rte_ip_frag.h
@@ -130,17 +130,8 @@ struct rte_ip_frag_tbl {
/** IPv6 fragment extension header */
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..ab62efd 100644
--- a/lib/librte_ip_frag/rte_ipv6_fragmentation.c
+++ b/lib/librte_ip_frag/rte_ipv6_fragmentation.c
@@ -65,10 +65,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((fofs & ~IPV6_HDR_FO_MASK) | mf);
fh->id = 0;
}
diff --git a/lib/librte_port/rte_port_ras.c b/lib/librte_port/rte_port_ras.c
index 6bd0f8c..3dbd5be 100644
--- a/lib/librte_port/rte_port_ras.c
+++ b/lib/librte_port/rte_port_ras.c
@@ -205,6 +205,9 @@ process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
}
}
+#define MORE_FRAGS(x) ((x) & 0x0001)
+#define FRAG_OFFSET(x) ((x) >> 3)
+
static void
process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
{
@@ -212,12 +215,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 ((MORE_FRAGS(frag_data) == 0) && (FRAG_OFFSET(frag_data) == 0))
p->tx_buf[p->tx_buf_count++] = pkt;
else {
struct rte_mbuf *mo;
--
1.7.9.5
More information about the dev
mailing list