From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 90380A0C55; Wed, 24 Nov 2021 07:25:28 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1968840A4B; Wed, 24 Nov 2021 07:25:28 +0100 (CET) Received: from m12-12.163.com (m12-12.163.com [220.181.12.12]) by mails.dpdk.org (Postfix) with ESMTP id C6A3C40696 for ; Wed, 24 Nov 2021 07:25:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id; bh=S9WRAY0a9QGilvdEsW Hq6UIz2ONcuaeKvqJsF0vZ1Uw=; b=bLG7Zl0Xq3ajoyZL6RcfQs6xYgseov0cFR tS1IzZNWfsT1ngeKfzrAA2+JvYEn5NAnLG84LZ6ptlc2CsYIw5TlS7FWYUCDn6/+ uj7o+r5l2I4of8ZMak9y4Wzi8A0DrFbNYjDqi5kq5KVkfxiNZARUZ0vesatx6Hpo G7xY5R6yg= Received: from bogon.localdomain (unknown [36.111.88.18]) by smtp8 (Coremail) with SMTP id DMCowAC3b6_D2p1hFOu_CQ--.59680S2; Wed, 24 Nov 2021 14:25:21 +0800 (CST) From: Huichao Cai 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 Message-Id: <1637735095-16900-1-git-send-email-chcchc88@163.com> X-Mailer: git-send-email 1.8.3.1 X-CM-TRANSID: DMCowAC3b6_D2p1hFOu_CQ--.59680S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxAr47uF1xZr4UXr17Wr1Utrb_yoW5WF17pF ykGrW5Xr15J3Z7W3yfXF4vqw4rKas2qF42yr9Ig3yxAF4kKFyvyayYyr13Kr12qr1kJw1v vwsIy3W5uF47Aw7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UGeHkUUUUU= X-Originating-IP: [36.111.88.18] X-CM-SenderInfo: pfkfuxrfyyqiywtou0bp/xtbBDhJVF1rbNPy-nAAAs0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org 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 --- 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