API Reference Manual  1.46.0
odp_ipfragreass_ip.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2017-2018 Linaro Limited
3  */
4 
7 #ifndef ODP_FRAGREASS_PP_IP_H_
8 #define ODP_FRAGREASS_PP_IP_H_
9 
10 #include <odp/helper/ip.h>
11 
12 #define IP_HDR_LEN_MIN ODPH_IPV4HDR_LEN
13 #define IP_HDR_LEN_MAX 60
14 #define IP_IHL_MIN ODPH_IPV4HDR_IHL_MIN
15 #define IP_IHL_MAX 15
16 #define IP_OCTET_MAX ((1U << 14U) - 1U) /* 65535 bytes, 8192 octs, 14 bits */
17 #define IP_FRAGOFF_MAX 8192 /* 13 bits */
18 
19 #define IP_FRAG_RESV 0x8000
20 #define IP_FRAG_DONT 0x4000
21 #define IP_FRAG_MORE 0x2000
22 #define IP_FRAG_MASK 0x1fff
24 #define BYTES_TO_OCTS(bytes) (((bytes) + 7U) / 8U)
25 #define OCTS_TO_BYTES(bytes) ((bytes) * 8)
26 #define WORDS_TO_BYTES(words) ((words) * 4)
27 
33 static inline void ipv4hdr_init(odph_ipv4hdr_t *h)
34 {
35  h->ver_ihl = 0x45; /* IHL of 5, Version of 4 [0x45 = 0100 0101] */
36  h->tos = 0;
37  h->tot_len = odp_cpu_to_be_16(IP_HDR_LEN_MIN);
38  h->frag_offset = 0;
39  h->ttl = UINT8_MAX;
40  h->chksum = 0;
41 }
42 
50 static inline uint8_t ipv4hdr_ihl_words(odph_ipv4hdr_t h)
51 {
52  return ODPH_IPV4HDR_IHL(h.ver_ihl);
53 }
54 
62 static inline uint8_t ipv4hdr_ihl(odph_ipv4hdr_t h)
63 {
64  return WORDS_TO_BYTES(ipv4hdr_ihl_words(h));
65 }
66 
73 static inline void ipv4hdr_set_ihl_words(odph_ipv4hdr_t *h, uint8_t ihl)
74 {
75  h->ver_ihl = (ODPH_IPV4HDR_VER(h->ver_ihl) << 4)
76  | ODPH_IPV4HDR_IHL(ihl);
77 }
78 
86 static inline bool ipv4hdr_dont_fragment(odph_ipv4hdr_t h)
87 {
88  return (h.frag_offset & odp_cpu_to_be_16(IP_FRAG_DONT));
89 }
90 
97 static inline void ipv4hdr_set_dont_fragment(odph_ipv4hdr_t *h, bool df)
98 {
99  if (df)
100  h->frag_offset |= odp_cpu_to_be_16(IP_FRAG_DONT);
101  else
102  h->frag_offset &= ~odp_cpu_to_be_16(IP_FRAG_DONT);
103 }
104 
112 static inline bool ipv4hdr_more_fragments(odph_ipv4hdr_t h)
113 {
114  return (h.frag_offset & odp_cpu_to_be_16(IP_FRAG_MORE));
115 }
116 
123 static inline void ipv4hdr_set_more_fragments(odph_ipv4hdr_t *h, bool mf)
124 {
125  if (mf)
126  h->frag_offset |= odp_cpu_to_be_16(IP_FRAG_MORE);
127  else
128  h->frag_offset &= ~odp_cpu_to_be_16(IP_FRAG_MORE);
129 }
130 
138 static inline bool ipv4hdr_is_fragment(odph_ipv4hdr_t h)
139 {
140  return (h.frag_offset & odp_cpu_to_be_16(IP_FRAG_MORE | IP_FRAG_MASK));
141 }
142 
150 static inline uint16_t ipv4hdr_fragment_offset_oct(odph_ipv4hdr_t h)
151 {
152  return (odp_be_to_cpu_16(h.frag_offset) & IP_FRAG_MASK);
153 }
154 
161 static inline void ipv4hdr_set_fragment_offset_oct(odph_ipv4hdr_t *h,
162  uint16_t offset)
163 {
164  h->frag_offset = odp_cpu_to_be_16((odp_be_to_cpu_16(h->frag_offset)
165  & ~IP_FRAG_MASK) | offset);
166 }
167 
175 static inline uint16_t ipv4hdr_payload_len(odph_ipv4hdr_t h)
176 {
177  uint32_t packet_len = odp_be_to_cpu_16(h.tot_len);
178  uint32_t header_size = ipv4hdr_ihl(h);
179 
180  return (uint16_t)(packet_len >= header_size ? (packet_len - header_size)
181  : 0);
182 }
183 
191 static inline uint16_t ipv4hdr_payload_len_oct(odph_ipv4hdr_t h)
192 {
193  return BYTES_TO_OCTS(ipv4hdr_payload_len(h));
194 }
195 
202 static inline void ipv4hdr_set_payload_len(odph_ipv4hdr_t *h, uint16_t len)
203 {
204  h->tot_len = odp_cpu_to_be_16(len + ipv4hdr_ihl(*h));
205 }
206 
218 static inline uint16_t ipv4hdr_reass_payload_len(odph_ipv4hdr_t h)
219 {
220  uint16_t fragment_offset_oct;
221 
222  if (ipv4hdr_more_fragments(h))
223  return UINT16_MAX;
224 
225  fragment_offset_oct = ipv4hdr_fragment_offset_oct(h);
226  return OCTS_TO_BYTES(fragment_offset_oct) + ipv4hdr_payload_len(h);
227 }
228 
240 static inline uint16_t ipv4hdr_reass_payload_len_oct(odph_ipv4hdr_t h)
241 {
242  uint16_t fragment_offset_oct;
243 
244  if (ipv4hdr_more_fragments(h))
245  return IP_OCTET_MAX;
246 
247  fragment_offset_oct = ipv4hdr_fragment_offset_oct(h);
248  return fragment_offset_oct + ipv4hdr_payload_len_oct(h);
249 }
250 
251 #endif
odp_u16be_t odp_cpu_to_be_16(uint16_t cpu16)
Convert cpu native uint16_t to 16bit big endian.
uint16_t odp_be_to_cpu_16(odp_u16be_t be16)
Convert 16bit big endian to cpu native uint16_t.