Helper Reference Manual  1.7.1
ip.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2014-2018 Linaro Limited
3  */
4 
11 #ifndef ODPH_IP_H_
12 #define ODPH_IP_H_
13 
14 #include <odp_api.h>
15 #include <odp/helper/chksum.h>
16 
17 #include <string.h>
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
28 #define ODPH_IPV4 4
29 #define ODPH_IPV4HDR_LEN 20
30 #define ODPH_IPV4HDR_IHL_MIN 5
31 #define ODPH_IPV4ADDR_LEN 4
40 #define ODPH_IP_TOS_MAX_DSCP 63
41 #define ODPH_IP_TOS_DSCP_MASK 0xFC
42 #define ODPH_IP_TOS_DSCP_SHIFT 2
43 #define ODPH_IP_TOS_MAX_ECN 3
44 #define ODPH_IP_TOS_ECN_MASK 0x03
45 #define ODPH_IP_TOS_ECN_SHIFT 0
50 #define ODPH_IP_ECN_NOT_ECT 0
51 #define ODPH_IP_ECN_ECT1 1
52 #define ODPH_IP_ECN_ECT0 2
53 #define ODPH_IP_ECN_CE 3
56 #define ODPH_IPV4HDR_VER(ver_ihl) (((ver_ihl) & 0xf0) >> 4)
57 
59 #define ODPH_IPV4HDR_IHL(ver_ihl) ((ver_ihl) & 0x0f)
60 
62 #define ODPH_IPV4HDR_DSCP(tos) (((tos) & 0xfc) >> 2)
63 
65 #define ODPH_IPV4HDR_FLAGS_DONT_FRAG(frag_offset) ((frag_offset) & 0x4000)
66 
68 #define ODPH_IPV4HDR_FLAGS_MORE_FRAGS(frag_offset) ((frag_offset) & 0x2000)
69 
71 #define ODPH_IPV4HDR_FRAG_OFFSET(frag_offset) ((frag_offset) & 0x1fff)
72 
74 #define ODPH_IPV4HDR_IS_FRAGMENT(frag_offset) ((frag_offset) & 0x3fff)
75 
77 #define ODPH_IPV4HDR_CSUM_OFFSET 10
78 
80 typedef struct ODP_PACKED {
81  uint8_t ver_ihl;
82  uint8_t tos;
83  odp_u16be_t tot_len;
84  odp_u16be_t id;
85  odp_u16be_t frag_offset;
86  uint8_t ttl;
87  uint8_t proto;
88  odp_u16sum_t chksum;
89  odp_u32be_t src_addr;
90  odp_u32be_t dst_addr;
92 
94 ODP_STATIC_ASSERT(sizeof(odph_ipv4hdr_t) == ODPH_IPV4HDR_LEN,
95  "ODPH_IPV4HDR_T__SIZE_ERROR");
109 static inline int odph_ipv4_csum(odp_packet_t pkt,
110  uint32_t offset,
111  odph_ipv4hdr_t *ip,
112  odp_u16sum_t *chksum)
113 {
114  uint32_t nleft = (uint32_t)(ODPH_IPV4HDR_IHL(ip->ver_ihl) * 4);
115  const int max_ip_header_len = 15 * 4;
116  uint16_t buf[max_ip_header_len];
117  int res;
118 
119  if (odp_unlikely(nleft < sizeof(*ip)))
120  return -1;
121  ip->chksum = 0;
122  memcpy(buf, ip, sizeof(*ip));
123  res = odp_packet_copy_to_mem(pkt, offset + (uint32_t)sizeof(*ip),
124  nleft - (uint32_t)sizeof(*ip),
125  buf + sizeof(*ip) / 2);
126  if (odp_unlikely(res < 0))
127  return res;
128 
129  *chksum = (odp_u16sum_t)~odp_chksum_ones_comp16(buf, nleft);
130 
131  return 0;
132 }
133 
141 static inline int odph_ipv4_csum_valid(odp_packet_t pkt)
142 {
143  uint32_t offset;
144  int res;
145  odph_ipv4hdr_t ip;
146  odp_u16sum_t chksum, cur_chksum;
147 
148  offset = odp_packet_l3_offset(pkt);
149  if (offset == ODP_PACKET_OFFSET_INVALID)
150  return 0;
151 
152  res = odp_packet_copy_to_mem(pkt, offset, sizeof(odph_ipv4hdr_t), &ip);
153  if (odp_unlikely(res < 0))
154  return 0;
155 
156  chksum = ip.chksum;
157 
158  res = odph_ipv4_csum(pkt, offset, &ip, &cur_chksum);
159  if (odp_unlikely(res < 0))
160  return 0;
161 
162  return (cur_chksum == chksum) ? 1 : 0;
163 }
164 
173 static inline int odph_ipv4_csum_update(odp_packet_t pkt)
174 {
175  uint32_t offset;
176  odph_ipv4hdr_t ip;
177  odp_u16sum_t chksum;
178  int res;
179 
180  offset = odp_packet_l3_offset(pkt);
181  if (offset == ODP_PACKET_OFFSET_INVALID)
182  return -1;
183 
184  res = odp_packet_copy_to_mem(pkt, offset, sizeof(ip), &ip);
185  if (odp_unlikely(res < 0))
186  return res;
187 
188  res = odph_ipv4_csum(pkt, offset, &ip, &chksum);
189  if (odp_unlikely(res < 0))
190  return res;
191 
192  return odp_packet_copy_from_mem(pkt,
193  offset + ODPH_IPV4HDR_CSUM_OFFSET,
194  2, &chksum);
195 }
196 
198 #define ODPH_IPV6 6
199 
201 #define ODPH_IPV6HDR_LEN 40
202 
204 #define ODPH_IPV6ADDR_LEN 16
205 
213 #define ODPH_IPV6HDR_VERSION_MASK 0xF0000000
214 #define ODPH_IPV6HDR_VERSION_SHIFT 28
215 #define ODPH_IPV6HDR_TC_MASK 0x0FF00000
216 #define ODPH_IPV6HDR_TC_SHIFT 20
217 #define ODPH_IPV6HDR_FLOW_LABEL_MASK 0x000FFFFF
218 #define ODPH_IPV6HDR_FLOW_LABEL_SHIFT 0
221 #define ODPH_IPV6HDR_DSCP(ver_tc_flow) \
222  (uint8_t)((((ver_tc_flow) & 0x0fc00000) >> 22) & 0xff)
223 
227 typedef struct ODP_PACKED {
228  odp_u32be_t ver_tc_flow;
229  odp_u16be_t payload_len;
230  uint8_t next_hdr;
231  uint8_t hop_limit;
232  uint8_t src_addr[16];
233  uint8_t dst_addr[16];
235 
237 ODP_STATIC_ASSERT(sizeof(odph_ipv6hdr_t) == ODPH_IPV6HDR_LEN,
238  "ODPH_IPV6HDR_T__SIZE_ERROR");
244 typedef struct ODP_PACKED {
245  uint8_t next_hdr;
246  uint8_t ext_len;
249  uint8_t filler[6];
251 
252 /*
253  * IP protocol values (IPv4:'proto' or IPv6:'next_hdr')
254  */
255 #define ODPH_IPPROTO_HOPOPTS 0x00
256 #define ODPH_IPPROTO_ICMPV4 0x01
257 #define ODPH_IPPROTO_IGMP 0x02
258 #define ODPH_IPPROTO_TCP 0x06
259 #define ODPH_IPPROTO_UDP 0x11
260 #define ODPH_IPPROTO_ROUTE 0x2B
261 #define ODPH_IPPROTO_FRAG 0x2C
262 #define ODPH_IPPROTO_AH 0x33
263 #define ODPH_IPPROTO_ESP 0x32
264 #define ODPH_IPPROTO_ICMPV6 0x3A
265 #define ODPH_IPPROTO_SCTP 0x84
267 #define ODPH_IPPROTO_INVALID 0xFF
286 int odph_ipv4_addr_parse(uint32_t *ip_addr, const char *str);
287 
291 #ifdef __cplusplus
292 }
293 #endif
294 
295 #endif
ODP checksum helper.
static int odph_ipv4_csum(odp_packet_t pkt, uint32_t offset, odph_ipv4hdr_t *ip, odp_u16sum_t *chksum)
Calculate IPv4 header checksum.
Definition: ip.h:109
#define ODPH_IPV4HDR_IHL(ver_ihl)
Definition: ip.h:59
static int odph_ipv4_csum_valid(odp_packet_t pkt)
Check if IPv4 checksum is valid.
Definition: ip.h:141
#define ODPH_IPV6HDR_LEN
IPv6 header length.
Definition: ip.h:201
#define ODPH_IPV4HDR_LEN
Min length of IP header (no options)
Definition: ip.h:29
struct ODP_PACKED odph_ipv6hdr_ext_t
IPv6 Header extensions.
#define ODPH_IPV4HDR_CSUM_OFFSET
Definition: ip.h:77
static int odph_ipv4_csum_update(odp_packet_t pkt)
Calculate and fill in IPv4 checksum.
Definition: ip.h:173
struct ODP_PACKED odph_ipv6hdr_t
IPv6 header.
struct ODP_PACKED odph_ipv4hdr_t
IPv4 header.
int odph_ipv4_addr_parse(uint32_t *ip_addr, const char *str)
Parse IPv4 address from a string.
ODP string helper.
Ethernet MAC address.
Definition: eth.h:54
uint8_t proto
Protocol.
Definition: ip.h:87
odp_u32be_t src_addr
Source address.
Definition: ip.h:89
uint8_t hop_limit
Hop limit.
Definition: ip.h:231
odp_u32be_t dst_addr
Destination address.
Definition: ip.h:90
odp_u16be_t tot_len
Total length.
Definition: ip.h:83
uint8_t ver_ihl
Version / Header length.
Definition: ip.h:81
uint8_t ttl
Time to live.
Definition: ip.h:86
odp_u16sum_t chksum
checksum of icmp header
Definition: icmp.h:33
uint8_t tos
Type of service.
Definition: ip.h:82
odp_u16be_t frag_offset
Fragmentation offset.
Definition: ip.h:85
odp_u32be_t ver_tc_flow
Version / Traffic class / Flow label.
Definition: ip.h:228
uint8_t ext_len
Length of this extension in 8 byte units, not counting first 8 bytes, so 0 = 8 bytes 1 = 16 bytes,...
Definition: ip.h:246
odp_u16be_t id
id
Definition: icmp.h:38
uint8_t next_hdr
Next header.
Definition: ip.h:230
uint8_t filler[6]
Fill out first 8 byte segment.
Definition: ip.h:249
odp_u16be_t payload_len
Payload length.
Definition: ip.h:229