[dpdk-stable] patch 'ip_frag: fix IPv6 when MTU sizes not aligned to 8 bytes' has been queued to LTS release 18.11.1

Kevin Traynor ktraynor at redhat.com
Fri Jan 4 14:24:07 CET 2019


Hi,

FYI, your patch has been queued to LTS release 18.11.1

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 01/11/19. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Thanks.

Kevin Traynor

---
>From 6b7505c11ae60d81f6d4091719e17f00fe592284 Mon Sep 17 00:00:00 2001
From: Chas Williams <chas3 at att.com>
Date: Mon, 26 Nov 2018 23:56:13 -0500
Subject: [PATCH] ip_frag: fix IPv6 when MTU sizes not aligned to 8 bytes

[ upstream commit 7a838c8798a93fc4b0eb305c4c7d61da54875a14 ]

The same issue was fixed on for the ipv4 version of this routine in
commit 8d4d3a4f7337 ("ip_frag: handle MTU sizes not aligned to 8 bytes").
Briefly, the size of an ipv6 header is always 40 bytes.  With an MTU of
1500, this will never produce a multiple of 8 bytes for the frag_size
and this routine can never succeed. Since RTE_ASSERTS are disabled by
default, this failure is typically ignored.

To fix this, round down to the nearest 8 bytes and use this when
producing the fragments.

Fixes: 0aa31d7a5929 ("ip_frag: add IPv6 fragmentation support")

Signed-off-by: Chas Williams <chas3 at att.com>
Acked-by: Luca Boccassi <bluca at debian.org>
Acked-by: Konstantin Ananyev <konstantin.ananyev at intel.com>
---
 lib/librte_ip_frag/rte_ip_frag.h            |  1 +
 lib/librte_ip_frag/rte_ipv6_fragmentation.c | 18 +++++++++++-------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
index a4ccaf9d1..04fd9df52 100644
--- a/lib/librte_ip_frag/rte_ip_frag.h
+++ b/lib/librte_ip_frag/rte_ip_frag.h
@@ -116,4 +116,5 @@ struct rte_ip_frag_tbl {
 #define	RTE_IPV6_EHDR_FO_SHIFT			3
 #define	RTE_IPV6_EHDR_FO_MASK			(~((1 << RTE_IPV6_EHDR_FO_SHIFT) - 1))
+#define	RTE_IPV6_EHDR_FO_ALIGN			(1 << RTE_IPV6_EHDR_FO_SHIFT)
 
 #define RTE_IPV6_FRAG_USED_MASK			\
diff --git a/lib/librte_ip_frag/rte_ipv6_fragmentation.c b/lib/librte_ip_frag/rte_ipv6_fragmentation.c
index 62a7e4e83..b9437eb11 100644
--- a/lib/librte_ip_frag/rte_ipv6_fragmentation.c
+++ b/lib/librte_ip_frag/rte_ipv6_fragmentation.c
@@ -78,9 +78,12 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in,
 	uint32_t more_in_segs;
 	uint16_t fragment_offset, frag_size;
+	uint64_t frag_bytes_remaining;
 
-	frag_size = (uint16_t)(mtu_size - sizeof(struct ipv6_hdr));
-
-	/* Fragment size should be a multiple of 8. */
-	RTE_ASSERT((frag_size & ~RTE_IPV6_EHDR_FO_MASK) == 0);
+	/*
+	 * Ensure the IP payload length of all fragments (except the
+	 * the last fragment) are a multiple of 8 bytes per RFC2460.
+	 */
+	frag_size = RTE_ALIGN_FLOOR(mtu_size - sizeof(struct ipv6_hdr),
+				    RTE_IPV6_EHDR_FO_ALIGN);
 
 	/* Check that pkts_out is big enough to hold all fragments */
@@ -112,4 +115,5 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in,
 		out_pkt->data_len = sizeof(struct ipv6_hdr) + sizeof(struct ipv6_extension_fragment);
 		out_pkt->pkt_len  = sizeof(struct ipv6_hdr) + sizeof(struct ipv6_extension_fragment);
+		frag_bytes_remaining = frag_size;
 
 		out_seg_prev = out_pkt;
@@ -131,5 +135,5 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in,
 			/* Prepare indirect buffer */
 			rte_pktmbuf_attach(out_seg, in_seg);
-			len = mtu_size - out_pkt->pkt_len;
+			len = frag_bytes_remaining;
 			if (len > (in_seg->data_len - in_seg_data_pos)) {
 				len = in_seg->data_len - in_seg_data_pos;
@@ -141,9 +145,9 @@ rte_ipv6_fragment_packet(struct rte_mbuf *pkt_in,
 			out_pkt->nb_segs += 1;
 			in_seg_data_pos += len;
+			frag_bytes_remaining -= len;
 
 			/* Current output packet (i.e. fragment) done ? */
-			if (unlikely(out_pkt->pkt_len >= mtu_size)) {
+			if (unlikely(frag_bytes_remaining == 0))
 				more_out_segs = 0;
-			}
 
 			/* Current input segment done ? */
-- 
2.19.0

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2019-01-04 13:23:08.050376168 +0000
+++ 0025-ip_frag-fix-IPv6-when-MTU-sizes-not-aligned-to-8-byt.patch	2019-01-04 13:23:07.000000000 +0000
@@ -1,8 +1,10 @@
-From 7a838c8798a93fc4b0eb305c4c7d61da54875a14 Mon Sep 17 00:00:00 2001
+From 6b7505c11ae60d81f6d4091719e17f00fe592284 Mon Sep 17 00:00:00 2001
 From: Chas Williams <chas3 at att.com>
 Date: Mon, 26 Nov 2018 23:56:13 -0500
 Subject: [PATCH] ip_frag: fix IPv6 when MTU sizes not aligned to 8 bytes
 
+[ upstream commit 7a838c8798a93fc4b0eb305c4c7d61da54875a14 ]
+
 The same issue was fixed on for the ipv4 version of this routine in
 commit 8d4d3a4f7337 ("ip_frag: handle MTU sizes not aligned to 8 bytes").
 Briefly, the size of an ipv6 header is always 40 bytes.  With an MTU of
@@ -14,7 +16,6 @@
 producing the fragments.
 
 Fixes: 0aa31d7a5929 ("ip_frag: add IPv6 fragmentation support")
-Cc: stable at dpdk.org
 
 Signed-off-by: Chas Williams <chas3 at att.com>
 Acked-by: Luca Boccassi <bluca at debian.org>


More information about the stable mailing list