All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
To: Huichao Cai <chcchc88@163.com>, "dev@dpdk.org" <dev@dpdk.org>
Subject: RE: [PATCH v2] ip_frag: add IPv4 options fragment and test data
Date: Fri, 18 Feb 2022 19:04:52 +0000	[thread overview]
Message-ID: <DM6PR11MB44915F34A2C1339BF81527E69A379@DM6PR11MB4491.namprd11.prod.outlook.com> (raw)
In-Reply-To: <1644915055-38172-1-git-send-email-chcchc88@163.com>

Hi Huichao,
 
> 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.Add some test data for the IPv4 header optional
> field fragmenting.
> 

...

> diff --git a/lib/ip_frag/rte_ipv4_fragmentation.c b/lib/ip_frag/rte_ipv4_fragmentation.c
> index 2e7739d..82c070b 100644
> --- a/lib/ip_frag/rte_ipv4_fragmentation.c
> +++ b/lib/ip_frag/rte_ipv4_fragmentation.c
> @@ -12,6 +12,12 @@
> 
>  #include "ip_frag_common.h"
> 
> +/* IP options */
> +#define RTE_IPOPT_EOL				0
> +#define RTE_IPOPT_NOP				1
> +#define RTE_IPOPT_COPIED(v)			((v) & 0x80)
> +#define RTE_IPOPT_MAX_LEN			40
> +
>  /* Fragment Offset */
>  #define	RTE_IPV4_HDR_DF_SHIFT			14
>  #define	RTE_IPV4_HDR_MF_SHIFT			13
> @@ -22,6 +28,8 @@
> 
>  #define	IPV4_HDR_FO_ALIGN			(1 << RTE_IPV4_HDR_FO_SHIFT)
> 
> +#define	RTE_IPV4_HDR_MAX_LEN		60
> +
>  static inline void __fill_ipv4hdr_frag(struct rte_ipv4_hdr *dst,
>  		const struct rte_ipv4_hdr *src, uint16_t header_len,
>  		uint16_t len, uint16_t fofs, uint16_t dofs, uint32_t mf)
> @@ -41,6 +49,58 @@ static inline void __free_fragments(struct rte_mbuf *mb[], uint32_t num)
>  		rte_pktmbuf_free(mb[i]);
>  }
> 
> +static inline void __create_ipopt_frag_hdr(uint8_t *iph,
> +	uint16_t *ipopt_len, uint8_t *ipopt_frag_hdr)
> +{
> +	uint16_t len = *ipopt_len;
> +	struct rte_ipv4_hdr *iph_opt = (struct rte_ipv4_hdr *)ipopt_frag_hdr;
> +
> +	*ipopt_len = 0;
> +	rte_memcpy(ipopt_frag_hdr, iph, sizeof(struct rte_ipv4_hdr));
> +	iph_opt->ihl = sizeof(struct rte_ipv4_hdr) / RTE_IPV4_IHL_MULTIPLIER;
> +	ipopt_frag_hdr += sizeof(struct rte_ipv4_hdr);
> +
> +	if (unlikely(len > RTE_IPOPT_MAX_LEN))
> +		return;
> +
> +	uint8_t *p_opt = iph + sizeof(struct rte_ipv4_hdr);
> +
> +	while (len > 0) {
> +		if (unlikely(*p_opt == RTE_IPOPT_NOP)) {
> +			len--;
> +			p_opt++;
> +#ifdef RTE_IPOPT_KEEP_IP_HLEN

Who will define this macro and when?
In general we trying to avoid conditional compilations within DPDK.
Can we always use one way or another?
As you are doing a copy anyway, probably no harm just
completely remove RTE_IPOPT_KEEP_IP_HLEN and related behaviour
and copy only options that need to be copied.
WDYT?


> +			ipopt_frag_hdr[(*ipopt_len)++] = RTE_IPOPT_NOP;
> +#endif
> +			continue;
> +		} else if (unlikely(*p_opt == RTE_IPOPT_EOL))
> +			break;
> +
> +		if (p_opt[1] < 2 || p_opt[1] > len)
> +			break;
> +		if (RTE_IPOPT_COPIED(*p_opt)) {
> +			rte_memcpy(ipopt_frag_hdr + *ipopt_len,
> +				p_opt, p_opt[1]);
> +			*ipopt_len += p_opt[1];
> +#ifdef RTE_IPOPT_KEEP_IP_HLEN
> +		} else {
> +			memset(ipopt_frag_hdr + *ipopt_len,
> +				RTE_IPOPT_NOP, p_opt[1]);
> +			*ipopt_len += p_opt[1];
> +#endif
> +		}
> +
> +		len -= p_opt[1];
> +		p_opt += p_opt[1];
> +	}
> +
> +	len = RTE_ALIGN_CEIL(*ipopt_len, RTE_IPV4_IHL_MULTIPLIER);
> +	memset(ipopt_frag_hdr + *ipopt_len,
> +		RTE_IPOPT_EOL, len - *ipopt_len);
> +	*ipopt_len = len;
> +	iph_opt->ihl += len / RTE_IPV4_IHL_MULTIPLIER;
> +}
> +
>  /**
>   * IPv4 fragmentation.
>   *
> @@ -76,6 +136,8 @@ static inline void __free_fragments(struct rte_mbuf *mb[], uint32_t num)
>  	uint32_t more_in_segs;
>  	uint16_t fragment_offset, flag_offset, frag_size, header_len;
>  	uint16_t frag_bytes_remaining;
> +	uint8_t ipopt_frag_hdr[RTE_IPV4_HDR_MAX_LEN];
> +	uint16_t ipopt_len;
> 
>  	/*
>  	 * Formal parameter checking.
> @@ -117,6 +179,7 @@ static inline void __free_fragments(struct rte_mbuf *mb[], uint32_t num)
>  	in_seg_data_pos = header_len;
>  	out_pkt_pos = 0;
>  	fragment_offset = 0;
> +	ipopt_len = header_len - sizeof(struct rte_ipv4_hdr);
> 
>  	more_in_segs = 1;
>  	while (likely(more_in_segs)) {
> @@ -188,10 +251,26 @@ 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);
> 
> -		fragment_offset = (uint16_t)(fragment_offset +
> -		    out_pkt->pkt_len - header_len);
> +		/* Create a separate IP header to handle frag options. */
> +		if (unlikely((fragment_offset == 0) &&
> +			    ((flag_offset & RTE_IPV4_HDR_OFFSET_MASK) == 0) &&
> +			    (ipopt_len))) {
> +			__create_ipopt_frag_hdr((uint8_t *)in_hdr,
> +				&ipopt_len, ipopt_frag_hdr);
> +
> +			fragment_offset = (uint16_t)(fragment_offset +
> +				out_pkt->pkt_len - header_len);
> 
> -		out_pkt->l3_len = header_len;
> +			out_pkt->l3_len = header_len;
> +
> +			header_len = sizeof(struct rte_ipv4_hdr) + ipopt_len;
> +			in_hdr = (struct rte_ipv4_hdr *)ipopt_frag_hdr;
> +		} else {
> +			fragment_offset = (uint16_t)(fragment_offset +
> +			    out_pkt->pkt_len - header_len);
> +
> +			out_pkt->l3_len = header_len;
> +		}
> 
>  		/* Write the fragment to the output list */
>  		pkts_out[out_pkt_pos] = out_pkt;
> --
> 1.8.3.1


  reply	other threads:[~2022-02-18 19:05 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-24  8:47 [PATCH] ip_frag: add IPv4 options fragment and unit test data Huichao Cai
2021-12-01 11:49 ` Dariusz Sosnowski
2021-12-02  2:24   ` Huichao Cai
2022-02-15  8:50 ` [PATCH v2] ip_frag: add IPv4 options fragment and " Huichao Cai
2022-02-18 19:04   ` Ananyev, Konstantin [this message]
2022-02-21  2:34     ` Huichao Cai
2022-02-21  3:17   ` [PATCH v3] " Huichao Cai
2022-02-25 14:33     ` Ananyev, Konstantin
2022-02-28 12:39       ` Huichao Cai
2022-03-15  7:22     ` [PATCH v4] " Huichao Cai
2022-03-21 14:24       ` Ananyev, Konstantin
2022-03-22  1:25         ` Huichao Cai
2022-03-22  3:09       ` [PATCH v5] " Huichao Cai
2022-03-23 12:52         ` Ananyev, Konstantin
2022-04-06  1:22           ` Huichao Cai
2022-04-06 16:47             ` Ananyev, Konstantin
2022-04-07 14:08               ` Aaron Conole
2022-04-13  2:49                 ` Huichao Cai
2022-04-11  3:55         ` [PATCH v6] " Huichao Cai
2022-04-14 13:14           ` Thomas Monjalon
2022-04-14 13:26             ` Thomas Monjalon
2022-04-15  1:52               ` Huichao Cai
2022-04-15  3:26           ` [PATCH v7] " Huichao Cai
2022-04-15  8:29             ` Ananyev, Konstantin
2022-05-29  8:50               ` Huichao Cai
2022-05-29  8:57               ` Huichao Cai
2022-05-29 10:38                 ` Konstantin Ananyev
2022-05-31 21:23               ` Thomas Monjalon
2022-06-16 15:10             ` David Marchand
2022-06-16 16:31               ` Stephen Hemminger
2022-06-17  3:52                 ` Huichao Cai
2022-06-17 16:31                   ` Stephen Hemminger
2022-06-18 11:01                     ` Huichao Cai

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=DM6PR11MB44915F34A2C1339BF81527E69A379@DM6PR11MB4491.namprd11.prod.outlook.com \
    --to=konstantin.ananyev@intel.com \
    --cc=chcchc88@163.com \
    --cc=dev@dpdk.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.