aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/include/protocols/ip.h
blob: 2b34a753fb68cae6345db34d138548e8b2ffe9e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* Copyright (c) 2016, Linaro Limited
 * All rights reserved.
 *
 * SPDX-License-Identifier:     BSD-3-Clause
 */

/**
 * @file
 *
 * ODP IP header
 */

#ifndef ODP_IP_H_
#define ODP_IP_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <odp_api.h>

/** @addtogroup odp_header ODP HEADER
 *  @{
 */

#define _ODP_IPV4             4  /**< IP version 4 */
#define _ODP_IPV4HDR_LEN     20  /**< Min length of IP header (no options) */
#define _ODP_IPV4HDR_IHL_MIN  5  /**< Minimum IHL value*/
#define _ODP_IPV4ADDR_LEN     4  /**< IPv4 address length in bytes */

/** The one byte IPv4 tos or IPv6 tc field is composed of the following two
 * subfields - a six bit Differentiated Service Code Point (DSCP) and a two
 * bit Explicit Congestion Notification (ECN) subfield.  The following
 * constants can be used to extract or modify these fields.  Despite the
 * name prefix being _ODP_IP_TOS_* these constants apply equally well for
 * the IPv6 Traffic Class (tc) field.
 */
#define _ODP_IP_TOS_MAX_DSCP   63    /**< 6-bit DSCP field has max value 63  */
#define _ODP_IP_TOS_DSCP_MASK  0xFC  /**< DSCP field is in bits <7:2>  */
#define _ODP_IP_TOS_DSCP_SHIFT 2     /**< DSCP field is shifted letf by 2  */
#define _ODP_IP_TOS_MAX_ECN    3     /**< 2-bit ECN field has max value 3  */
#define _ODP_IP_TOS_ECN_MASK   0x03  /**< ECN field is in bits <1:0>  */
#define _ODP_IP_TOS_ECN_SHIFT  0     /**< ECN field is not shifted.  */

/** The following constants give names to the four possible ECN values,
 * as described in RFC 3168.
 */
#define _ODP_IP_ECN_NOT_ECT  0  /**< 0 indicates not participating in ECN */
#define _ODP_IP_ECN_ECT1     1  /**< Indicates no congestion seen yet */
#define _ODP_IP_ECN_ECT0     2  /**< Indicates no congestion seen yet */
#define _ODP_IP_ECN_CE       3  /**< Used to signal Congestion Experienced */

/** @internal Returns IPv4 version */
#define _ODP_IPV4HDR_VER(ver_ihl) (((ver_ihl) & 0xf0) >> 4)

/** @internal Returns IPv4 header length */
#define _ODP_IPV4HDR_IHL(ver_ihl) ((ver_ihl) & 0x0f)

/** @internal Returns IPv4 DSCP */
#define _ODP_IPV4HDR_DSCP(tos) (((tos) & 0xfc) >> 2)

/** @internal Returns IPv4 Don't fragment */
#define _ODP_IPV4HDR_FLAGS_DONT_FRAG(frag_offset)  ((frag_offset) & 0x4000)

/** @internal Returns IPv4 more fragments */
#define _ODP_IPV4HDR_FLAGS_MORE_FRAGS(frag_offset)  ((frag_offset) & 0x2000)

/** @internal Returns IPv4 fragment offset */
#define _ODP_IPV4HDR_FRAG_OFFSET(frag_offset) ((frag_offset) & 0x1fff)

/** @internal Returns true if IPv4 packet is a fragment */
#define _ODP_IPV4HDR_IS_FRAGMENT(frag_offset) ((frag_offset) & 0x3fff)

/** IPv4 header */
typedef struct ODP_PACKED {
	uint8_t    ver_ihl;     /**< Version / Header length */
	uint8_t    tos;         /**< Type of service */
	odp_u16be_t tot_len;    /**< Total length */
	odp_u16be_t id;         /**< ID */
	odp_u16be_t frag_offset;/**< Fragmentation offset */
	uint8_t    ttl;         /**< Time to live */
	uint8_t    proto;       /**< Protocol */
	odp_u16sum_t chksum;    /**< Checksum */
	odp_u32be_t src_addr;   /**< Source address */
	odp_u32be_t dst_addr;   /**< Destination address */
} _odp_ipv4hdr_t;

/** @internal Compile time assert */
ODP_STATIC_ASSERT(sizeof(_odp_ipv4hdr_t) == _ODP_IPV4HDR_LEN,
		  "_ODP_IPV4HDR_T__SIZE_ERROR");

/** IPv6 version */
#define _ODP_IPV6 6

/** IPv6 header length */
#define _ODP_IPV6HDR_LEN 40

/** IPv6 address length in bytes */
#define _ODP_IPV6ADDR_LEN 16

/** The following constants can be used to access the three subfields
 * of the 4 byte ver_tc_flow field - namely the four bit Version subfield,
 * the eight bit Traffic Class subfield (TC) and the twenty bit Flow Label
 * subfield.  Note that the IPv6 TC field is analogous to the IPv4 TOS
 * field and is composed of the DSCP and ECN subfields.  Use the _ODP_IP_TOS_*
 * constants above to access these subfields.
 */
#define _ODP_IPV6HDR_VERSION_MASK     0xF0000000 /**< Version field bit mask */
#define _ODP_IPV6HDR_VERSION_SHIFT    28         /**< Version field shift */
#define _ODP_IPV6HDR_TC_MASK          0x0FF00000 /**< TC field bit mask */
#define _ODP_IPV6HDR_TC_SHIFT         20         /**< TC field shift */
#define _ODP_IPV6HDR_FLOW_LABEL_MASK  0x000FFFFF /**< Flow Label bit mask */
#define _ODP_IPV6HDR_FLOW_LABEL_SHIFT 0          /**< Flow Label shift */

/** @internal Returns IPv6 DSCP */
#define _ODP_IPV6HDR_DSCP(ver_tc_flow) \
	(uint8_t)((((ver_tc_flow) & 0x0fc00000) >> 22) & 0xff)

/**
 * Ipv6 address
 */
typedef union ODP_PACKED {
	uint8_t		u8[16];
	odp_u16be_t	u16[8];
	odp_u32be_t	u32[4];
	odp_u64be_t	u64[2];
} _odp_ipv6_addr_t;

/**
 * IPv6 header
 */
typedef struct ODP_PACKED {
	odp_u32be_t ver_tc_flow; /**< Version / Traffic class / Flow label */
	odp_u16be_t payload_len; /**< Payload length */
	uint8_t    next_hdr;     /**< Next header */
	uint8_t    hop_limit;    /**< Hop limit */
	_odp_ipv6_addr_t src_addr; /**< Source address */
	_odp_ipv6_addr_t dst_addr; /**< Destination address */
} _odp_ipv6hdr_t;

/** @internal Compile time assert */
ODP_STATIC_ASSERT(sizeof(_odp_ipv6hdr_t) == _ODP_IPV6HDR_LEN,
		  "_ODP_IPV6HDR_T__SIZE_ERROR");

/**
 * IPv6 Header extensions
 */
typedef struct ODP_PACKED {
	uint8_t    next_hdr;     /**< Protocol of next header */
	uint8_t    ext_len;      /**< Length of this extension in 8 byte units,
				    not counting first 8 bytes, so 0 = 8 bytes
				    1 = 16 bytes, etc. */
	uint8_t    filler[6];    /**< Fill out first 8 byte segment */
} _odp_ipv6hdr_ext_t;

/** @name
 * IP protocol values (IPv4:'proto' or IPv6:'next_hdr')
 * @{*/
#define _ODP_IPPROTO_HOPOPTS 0x00 /**< IPv6 hop-by-hop options */
#define _ODP_IPPROTO_ICMPv4  0x01 /**< Internet Control Message Protocol (1) */
#define _ODP_IPPROTO_TCP     0x06 /**< Transmission Control Protocol (6) */
#define _ODP_IPPROTO_UDP     0x11 /**< User Datagram Protocol (17) */
#define _ODP_IPPROTO_ROUTE   0x2B /**< IPv6 Routing header (43) */
#define _ODP_IPPROTO_FRAG    0x2C /**< IPv6 Fragment (44) */
#define _ODP_IPPROTO_AH      0x33 /**< Authentication Header (51) */
#define _ODP_IPPROTO_ESP     0x32 /**< Encapsulating Security Payload (50) */
#define _ODP_IPPROTO_ICMPv6  0x3A /**< Internet Control Message Protocol (58) */
#define _ODP_IPPROTO_SCTP    0x84 /**< Stream Control Transmission protocol
				       (132) */
#define _ODP_IPPROTO_INVALID 0xFF /**< Reserved invalid by IANA */

/**@}*/

/**
 * @}
 */
#ifdef __cplusplus
}
#endif

#endif