From: Huichao Cai <chcchc88@163.com>
To: dev@dpdk.org
Cc: konstantin.ananyev@intel.com
Subject: [PATCH] ip_frag: add fragmenting IPv4 header optional field
Date: Wed, 24 Nov 2021 14:24:55 +0800 [thread overview]
Message-ID: <1637735095-16900-1-git-send-email-chcchc88@163.com> (raw)
According to RFC791,the options may appear or not in datagrams.
They must be implemented by all IP modules (host and gateways).
What is optional is their transmission in any particular datagram,
not their implementation.So we have to deal with it during the
fragmenting process.
Signed-off-by: Huichao Cai <chcchc88@163.com>
---
lib/ip_frag/rte_ipv4_fragmentation.c | 52 +++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/lib/ip_frag/rte_ipv4_fragmentation.c b/lib/ip_frag/rte_ipv4_fragmentation.c
index 2e7739d..bcafa29 100644
--- a/lib/ip_frag/rte_ipv4_fragmentation.c
+++ b/lib/ip_frag/rte_ipv4_fragmentation.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: BSD-3-Clause
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
* Copyright(c) 2010-2014 Intel Corporation
*/
@@ -12,6 +12,13 @@
#include "ip_frag_common.h"
+/* IP options */
+#define RTE_IPOPT_COPY 0x80
+#define RTE_IPOPT_CONTROL 0x00
+#define RTE_IPOPT_END (0 | RTE_IPOPT_CONTROL)
+#define RTE_IPOPT_NOOP (1 | RTE_IPOPT_CONTROL)
+#define RTE_IPOPT_COPIED(o) ((o) & RTE_IPOPT_COPY)
+
/* Fragment Offset */
#define RTE_IPV4_HDR_DF_SHIFT 14
#define RTE_IPV4_HDR_MF_SHIFT 13
@@ -41,6 +48,38 @@ static inline void __free_fragments(struct rte_mbuf *mb[], uint32_t num)
rte_pktmbuf_free(mb[i]);
}
+/*
+ * Options "fragmenting", just fill options not
+ * allowed in fragments with NOOPs.
+ * Simple and stupid 8), but the most efficient way.
+ */
+static inline void ip_options_fragment(struct rte_ipv4_hdr *iph)
+{
+ unsigned char *optptr = (unsigned char *)iph +
+ sizeof(struct rte_ipv4_hdr);
+ int l = (iph->version_ihl & RTE_IPV4_HDR_IHL_MASK) *
+ RTE_IPV4_IHL_MULTIPLIER - sizeof(struct rte_ipv4_hdr);
+ int optlen;
+
+ while (l > 0) {
+ switch (*optptr) {
+ case RTE_IPOPT_END:
+ return;
+ case RTE_IPOPT_NOOP:
+ l--;
+ optptr++;
+ continue;
+ }
+ optlen = optptr[1];
+ if (optlen < 2 || optlen > l)
+ return;
+ if (!RTE_IPOPT_COPIED(*optptr))
+ memset(optptr, RTE_IPOPT_NOOP, optlen);
+ l -= optlen;
+ optptr += optlen;
+ }
+}
+
/**
* IPv4 fragmentation.
*
@@ -188,6 +227,17 @@ static inline void __free_fragments(struct rte_mbuf *mb[], uint32_t num)
(uint16_t)out_pkt->pkt_len,
flag_offset, fragment_offset, more_in_segs);
+ /*
+ * ANK: dirty, but effective trick. Upgrade options only if
+ * the segment to be fragmented was THE FIRST (otherwise,
+ * options are already fixed) and make it ONCE
+ * on the initial mbuf, so that all the following fragments
+ * will inherit fixed options.
+ */
+ if ((fragment_offset == 0) &&
+ ((flag_offset & RTE_IPV4_HDR_OFFSET_MASK) == 0))
+ ip_options_fragment(in_hdr);
+
fragment_offset = (uint16_t)(fragment_offset +
out_pkt->pkt_len - header_len);
--
1.8.3.1
reply other threads:[~2021-11-24 6:25 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1637735095-16900-1-git-send-email-chcchc88@163.com \
--to=chcchc88@163.com \
--cc=dev@dpdk.org \
--cc=konstantin.ananyev@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).