]>
Commit | Line | Data |
---|---|---|
064af421 | 1 | /* |
e6cc0bab | 2 | * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. |
064af421 | 3 | * |
a14bc59f BP |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
064af421 | 7 | * |
a14bc59f BP |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
064af421 | 15 | */ |
b9e8b45a | 16 | |
064af421 BP |
17 | #ifndef PACKETS_H |
18 | #define PACKETS_H 1 | |
19 | ||
ab9c78ff | 20 | #include <inttypes.h> |
26233bb4 BP |
21 | #include <sys/types.h> |
22 | #include <netinet/in.h> | |
064af421 BP |
23 | #include <stdint.h> |
24 | #include <string.h> | |
25 | #include "compiler.h" | |
48cecbdc | 26 | #include "flow.h" |
0596e897 | 27 | #include "openvswitch/types.h" |
064af421 BP |
28 | #include "random.h" |
29 | #include "util.h" | |
30 | ||
b9e8b45a | 31 | struct ofpbuf; |
d31f1109 | 32 | struct ds; |
b9e8b45a | 33 | |
76343538 BP |
34 | bool dpid_from_string(const char *s, uint64_t *dpidp); |
35 | ||
064af421 BP |
36 | #define ETH_ADDR_LEN 6 |
37 | ||
67a4917b | 38 | static const uint8_t eth_addr_broadcast[ETH_ADDR_LEN] OVS_UNUSED |
064af421 BP |
39 | = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
40 | ||
ba186119 | 41 | static const uint8_t eth_addr_stp[ETH_ADDR_LEN] OVS_UNUSED |
f740b8f6 | 42 | = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }; |
ba186119 | 43 | |
c25c91fd EJ |
44 | static const uint8_t eth_addr_lacp[ETH_ADDR_LEN] OVS_UNUSED |
45 | = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }; | |
46 | ||
064af421 BP |
47 | static inline bool eth_addr_is_broadcast(const uint8_t ea[6]) |
48 | { | |
49 | return (ea[0] & ea[1] & ea[2] & ea[3] & ea[4] & ea[5]) == 0xff; | |
50 | } | |
51 | ||
064af421 BP |
52 | static inline bool eth_addr_is_multicast(const uint8_t ea[6]) |
53 | { | |
54 | return ea[0] & 1; | |
55 | } | |
d295e8e9 | 56 | static inline bool eth_addr_is_local(const uint8_t ea[6]) |
064af421 | 57 | { |
70150daf JG |
58 | /* Local if it is either a locally administered address or a Nicira random |
59 | * address. */ | |
347d4879 BP |
60 | return ea[0] & 2 |
61 | || (ea[0] == 0x00 && ea[1] == 0x23 && ea[2] == 0x20 && ea[3] & 0x80); | |
064af421 | 62 | } |
d295e8e9 | 63 | static inline bool eth_addr_is_zero(const uint8_t ea[6]) |
064af421 BP |
64 | { |
65 | return !(ea[0] | ea[1] | ea[2] | ea[3] | ea[4] | ea[5]); | |
66 | } | |
3b4d8ad3 JS |
67 | |
68 | static inline int eth_mask_is_exact(const uint8_t ea[ETH_ADDR_LEN]) | |
69 | { | |
70 | return (ea[0] & ea[1] & ea[2] & ea[3] & ea[4] & ea[5]) == 0xff; | |
71 | } | |
72 | ||
130f6e5f EJ |
73 | static inline int eth_addr_compare_3way(const uint8_t a[ETH_ADDR_LEN], |
74 | const uint8_t b[ETH_ADDR_LEN]) | |
75 | { | |
76 | return memcmp(a, b, ETH_ADDR_LEN); | |
77 | } | |
064af421 | 78 | static inline bool eth_addr_equals(const uint8_t a[ETH_ADDR_LEN], |
d295e8e9 | 79 | const uint8_t b[ETH_ADDR_LEN]) |
064af421 | 80 | { |
130f6e5f | 81 | return !eth_addr_compare_3way(a, b); |
064af421 | 82 | } |
3b4d8ad3 JS |
83 | static inline bool eth_addr_equal_except(const uint8_t a[ETH_ADDR_LEN], |
84 | const uint8_t b[ETH_ADDR_LEN], | |
85 | const uint8_t mask[ETH_ADDR_LEN]) | |
86 | { | |
3b842fc2 EJ |
87 | return !(((a[0] ^ b[0]) & mask[0]) |
88 | || ((a[1] ^ b[1]) & mask[1]) | |
89 | || ((a[2] ^ b[2]) & mask[2]) | |
90 | || ((a[3] ^ b[3]) & mask[3]) | |
91 | || ((a[4] ^ b[4]) & mask[4]) | |
92 | || ((a[5] ^ b[5]) & mask[5])); | |
3b4d8ad3 | 93 | } |
064af421 BP |
94 | static inline uint64_t eth_addr_to_uint64(const uint8_t ea[ETH_ADDR_LEN]) |
95 | { | |
96 | return (((uint64_t) ea[0] << 40) | |
97 | | ((uint64_t) ea[1] << 32) | |
98 | | ((uint64_t) ea[2] << 24) | |
99 | | ((uint64_t) ea[3] << 16) | |
100 | | ((uint64_t) ea[4] << 8) | |
101 | | ea[5]); | |
102 | } | |
103 | static inline void eth_addr_from_uint64(uint64_t x, uint8_t ea[ETH_ADDR_LEN]) | |
104 | { | |
105 | ea[0] = x >> 40; | |
106 | ea[1] = x >> 32; | |
107 | ea[2] = x >> 24; | |
108 | ea[3] = x >> 16; | |
109 | ea[4] = x >> 8; | |
110 | ea[5] = x; | |
111 | } | |
112 | static inline void eth_addr_mark_random(uint8_t ea[ETH_ADDR_LEN]) | |
113 | { | |
114 | ea[0] &= ~1; /* Unicast. */ | |
115 | ea[0] |= 2; /* Private. */ | |
116 | } | |
117 | static inline void eth_addr_random(uint8_t ea[ETH_ADDR_LEN]) | |
118 | { | |
119 | random_bytes(ea, ETH_ADDR_LEN); | |
120 | eth_addr_mark_random(ea); | |
121 | } | |
70150daf JG |
122 | static inline void eth_addr_nicira_random(uint8_t ea[ETH_ADDR_LEN]) |
123 | { | |
124 | eth_addr_random(ea); | |
125 | ||
126 | /* Set the OUI to the Nicira one. */ | |
127 | ea[0] = 0x00; | |
128 | ea[1] = 0x23; | |
129 | ea[2] = 0x20; | |
130 | ||
131 | /* Set the top bit to indicate random Nicira address. */ | |
132 | ea[3] |= 0x80; | |
133 | } | |
064af421 | 134 | |
05be4e2c | 135 | bool eth_addr_is_reserved(const uint8_t ea[ETH_ADDR_LEN]); |
76343538 BP |
136 | bool eth_addr_from_string(const char *, uint8_t ea[ETH_ADDR_LEN]); |
137 | ||
2ea838ac | 138 | void compose_rarp(struct ofpbuf *, const uint8_t eth_src[ETH_ADDR_LEN]); |
b9e8b45a | 139 | |
d9065a90 | 140 | void eth_push_vlan(struct ofpbuf *, ovs_be16 tci); |
f4ebc25e | 141 | void eth_pop_vlan(struct ofpbuf *); |
7c66b273 | 142 | |
b02475c5 SH |
143 | uint16_t eth_mpls_depth(const struct ofpbuf *packet); |
144 | ||
145 | void set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type); | |
146 | ||
e22f1753 | 147 | const char *eth_from_hex(const char *hex, struct ofpbuf **packetp); |
3b4d8ad3 JS |
148 | void eth_format_masked(const uint8_t eth[ETH_ADDR_LEN], |
149 | const uint8_t mask[ETH_ADDR_LEN], struct ds *s); | |
150 | void eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN], | |
151 | const uint8_t mask[ETH_ADDR_LEN], | |
152 | uint8_t dst[ETH_ADDR_LEN]); | |
e22f1753 | 153 | |
b02475c5 SH |
154 | void set_mpls_lse(struct ofpbuf *, ovs_be32 label); |
155 | void push_mpls(struct ofpbuf *packet, ovs_be16 ethtype, ovs_be32 lse); | |
156 | void pop_mpls(struct ofpbuf *, ovs_be16 ethtype); | |
157 | ||
b676167a | 158 | void set_mpls_lse_ttl(ovs_be32 *lse, uint8_t ttl); |
b02475c5 SH |
159 | void set_mpls_lse_tc(ovs_be32 *lse, uint8_t tc); |
160 | void set_mpls_lse_label(ovs_be32 *lse, ovs_be32 label); | |
161 | void set_mpls_lse_bos(ovs_be32 *lse, uint8_t bos); | |
162 | ovs_be32 set_mpls_lse_values(uint8_t ttl, uint8_t tc, uint8_t bos, | |
163 | ovs_be32 label); | |
164 | ||
eaa71334 BP |
165 | /* Example: |
166 | * | |
167 | * uint8_t mac[ETH_ADDR_LEN]; | |
168 | * [...] | |
169 | * printf("The Ethernet address is "ETH_ADDR_FMT"\n", ETH_ADDR_ARGS(mac)); | |
170 | * | |
171 | */ | |
064af421 BP |
172 | #define ETH_ADDR_FMT \ |
173 | "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8 | |
174 | #define ETH_ADDR_ARGS(ea) \ | |
175 | (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5] | |
176 | ||
eaa71334 BP |
177 | /* Example: |
178 | * | |
179 | * char *string = "1 00:11:22:33:44:55 2"; | |
180 | * uint8_t mac[ETH_ADDR_LEN]; | |
181 | * int a, b; | |
182 | * | |
183 | * if (sscanf(string, "%d"ETH_ADDR_SCAN_FMT"%d", | |
184 | * &a, ETH_ADDR_SCAN_ARGS(mac), &b) == 1 + ETH_ADDR_SCAN_COUNT + 1) { | |
185 | * ... | |
186 | * } | |
187 | */ | |
188 | #define ETH_ADDR_SCAN_FMT "%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8 | |
189 | #define ETH_ADDR_SCAN_ARGS(ea) \ | |
190 | &(ea)[0], &(ea)[1], &(ea)[2], &(ea)[3], &(ea)[4], &(ea)[5] | |
191 | #define ETH_ADDR_SCAN_COUNT 6 | |
192 | ||
064af421 BP |
193 | #define ETH_TYPE_IP 0x0800 |
194 | #define ETH_TYPE_ARP 0x0806 | |
3e34fbdd IY |
195 | #define ETH_TYPE_VLAN_8021Q 0x8100 |
196 | #define ETH_TYPE_VLAN ETH_TYPE_VLAN_8021Q | |
197 | #define ETH_TYPE_VLAN_8021AD 0x88a8 | |
d31f1109 | 198 | #define ETH_TYPE_IPV6 0x86dd |
c25c91fd | 199 | #define ETH_TYPE_LACP 0x8809 |
38f7147c | 200 | #define ETH_TYPE_RARP 0x8035 |
4fba171d BP |
201 | #define ETH_TYPE_MPLS 0x8847 |
202 | #define ETH_TYPE_MPLS_MCAST 0x8848 | |
064af421 | 203 | |
b02475c5 SH |
204 | static inline bool eth_type_mpls(ovs_be16 eth_type) |
205 | { | |
206 | return eth_type == htons(ETH_TYPE_MPLS) || | |
207 | eth_type == htons(ETH_TYPE_MPLS_MCAST); | |
208 | } | |
209 | ||
36956a7d BP |
210 | /* Minimum value for an Ethernet type. Values below this are IEEE 802.2 frame |
211 | * lengths. */ | |
212 | #define ETH_TYPE_MIN 0x600 | |
213 | ||
064af421 BP |
214 | #define ETH_HEADER_LEN 14 |
215 | #define ETH_PAYLOAD_MIN 46 | |
216 | #define ETH_PAYLOAD_MAX 1500 | |
217 | #define ETH_TOTAL_MIN (ETH_HEADER_LEN + ETH_PAYLOAD_MIN) | |
218 | #define ETH_TOTAL_MAX (ETH_HEADER_LEN + ETH_PAYLOAD_MAX) | |
219 | #define ETH_VLAN_TOTAL_MAX (ETH_HEADER_LEN + VLAN_HEADER_LEN + ETH_PAYLOAD_MAX) | |
13b6bae6 | 220 | OVS_PACKED( |
064af421 BP |
221 | struct eth_header { |
222 | uint8_t eth_dst[ETH_ADDR_LEN]; | |
223 | uint8_t eth_src[ETH_ADDR_LEN]; | |
d5ca4fce | 224 | ovs_be16 eth_type; |
13b6bae6 | 225 | }); |
064af421 BP |
226 | BUILD_ASSERT_DECL(ETH_HEADER_LEN == sizeof(struct eth_header)); |
227 | ||
228 | #define LLC_DSAP_SNAP 0xaa | |
229 | #define LLC_SSAP_SNAP 0xaa | |
230 | #define LLC_CNTL_SNAP 3 | |
231 | ||
232 | #define LLC_HEADER_LEN 3 | |
13b6bae6 | 233 | OVS_PACKED( |
064af421 BP |
234 | struct llc_header { |
235 | uint8_t llc_dsap; | |
236 | uint8_t llc_ssap; | |
237 | uint8_t llc_cntl; | |
13b6bae6 | 238 | }); |
064af421 BP |
239 | BUILD_ASSERT_DECL(LLC_HEADER_LEN == sizeof(struct llc_header)); |
240 | ||
241 | #define SNAP_ORG_ETHERNET "\0\0" /* The compiler adds a null byte, so | |
242 | sizeof(SNAP_ORG_ETHERNET) == 3. */ | |
243 | #define SNAP_HEADER_LEN 5 | |
13b6bae6 | 244 | OVS_PACKED( |
064af421 BP |
245 | struct snap_header { |
246 | uint8_t snap_org[3]; | |
d5ca4fce | 247 | ovs_be16 snap_type; |
13b6bae6 | 248 | }); |
064af421 BP |
249 | BUILD_ASSERT_DECL(SNAP_HEADER_LEN == sizeof(struct snap_header)); |
250 | ||
251 | #define LLC_SNAP_HEADER_LEN (LLC_HEADER_LEN + SNAP_HEADER_LEN) | |
13b6bae6 | 252 | OVS_PACKED( |
064af421 BP |
253 | struct llc_snap_header { |
254 | struct llc_header llc; | |
255 | struct snap_header snap; | |
13b6bae6 | 256 | }); |
064af421 BP |
257 | BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); |
258 | ||
259 | #define VLAN_VID_MASK 0x0fff | |
33ce24ed BP |
260 | #define VLAN_VID_SHIFT 0 |
261 | ||
064af421 | 262 | #define VLAN_PCP_MASK 0xe000 |
33ce24ed | 263 | #define VLAN_PCP_SHIFT 13 |
064af421 | 264 | |
26233bb4 | 265 | #define VLAN_CFI 0x1000 |
e6cc0bab | 266 | #define VLAN_CFI_SHIFT 12 |
26233bb4 BP |
267 | |
268 | /* Given the vlan_tci field from an 802.1Q header, in network byte order, | |
269 | * returns the VLAN ID in host byte order. */ | |
270 | static inline uint16_t | |
d5ca4fce | 271 | vlan_tci_to_vid(ovs_be16 vlan_tci) |
26233bb4 BP |
272 | { |
273 | return (ntohs(vlan_tci) & VLAN_VID_MASK) >> VLAN_VID_SHIFT; | |
274 | } | |
275 | ||
276 | /* Given the vlan_tci field from an 802.1Q header, in network byte order, | |
277 | * returns the priority code point (PCP) in host byte order. */ | |
278 | static inline int | |
d5ca4fce | 279 | vlan_tci_to_pcp(ovs_be16 vlan_tci) |
26233bb4 BP |
280 | { |
281 | return (ntohs(vlan_tci) & VLAN_PCP_MASK) >> VLAN_PCP_SHIFT; | |
282 | } | |
283 | ||
e6cc0bab AZ |
284 | /* Given the vlan_tci field from an 802.1Q header, in network byte order, |
285 | * returns the Canonical Format Indicator (CFI). */ | |
286 | static inline int | |
287 | vlan_tci_to_cfi(ovs_be16 vlan_tci) | |
288 | { | |
289 | return (vlan_tci & htons(VLAN_CFI)) != 0; | |
290 | } | |
291 | ||
064af421 BP |
292 | #define VLAN_HEADER_LEN 4 |
293 | struct vlan_header { | |
d5ca4fce EJ |
294 | ovs_be16 vlan_tci; /* Lowest 12 bits are VLAN ID. */ |
295 | ovs_be16 vlan_next_type; | |
064af421 BP |
296 | }; |
297 | BUILD_ASSERT_DECL(VLAN_HEADER_LEN == sizeof(struct vlan_header)); | |
298 | ||
299 | #define VLAN_ETH_HEADER_LEN (ETH_HEADER_LEN + VLAN_HEADER_LEN) | |
13b6bae6 | 300 | OVS_PACKED( |
064af421 BP |
301 | struct vlan_eth_header { |
302 | uint8_t veth_dst[ETH_ADDR_LEN]; | |
303 | uint8_t veth_src[ETH_ADDR_LEN]; | |
d5ca4fce EJ |
304 | ovs_be16 veth_type; /* Always htons(ETH_TYPE_VLAN). */ |
305 | ovs_be16 veth_tci; /* Lowest 12 bits are VLAN ID. */ | |
306 | ovs_be16 veth_next_type; | |
13b6bae6 | 307 | }); |
064af421 BP |
308 | BUILD_ASSERT_DECL(VLAN_ETH_HEADER_LEN == sizeof(struct vlan_eth_header)); |
309 | ||
b02475c5 SH |
310 | /* MPLS related definitions */ |
311 | #define MPLS_TTL_MASK 0x000000ff | |
312 | #define MPLS_TTL_SHIFT 0 | |
313 | ||
314 | #define MPLS_BOS_MASK 0x00000100 | |
315 | #define MPLS_BOS_SHIFT 8 | |
316 | ||
317 | #define MPLS_TC_MASK 0x00000e00 | |
318 | #define MPLS_TC_SHIFT 9 | |
319 | ||
320 | #define MPLS_LABEL_MASK 0xfffff000 | |
321 | #define MPLS_LABEL_SHIFT 12 | |
322 | ||
323 | #define MPLS_HLEN 4 | |
324 | ||
325 | struct mpls_hdr { | |
326 | ovs_be32 mpls_lse; | |
327 | }; | |
328 | BUILD_ASSERT_DECL(MPLS_HLEN == sizeof(struct mpls_hdr)); | |
329 | ||
330 | /* Given a mpls label stack entry in network byte order | |
331 | * return mpls label in host byte order */ | |
332 | static inline uint32_t | |
333 | mpls_lse_to_label(ovs_be32 mpls_lse) | |
334 | { | |
335 | return (ntohl(mpls_lse) & MPLS_LABEL_MASK) >> MPLS_LABEL_SHIFT; | |
336 | } | |
337 | ||
338 | /* Given a mpls label stack entry in network byte order | |
339 | * return mpls tc */ | |
340 | static inline uint8_t | |
341 | mpls_lse_to_tc(ovs_be32 mpls_lse) | |
342 | { | |
343 | return (ntohl(mpls_lse) & MPLS_TC_MASK) >> MPLS_TC_SHIFT; | |
344 | } | |
345 | ||
346 | /* Given a mpls label stack entry in network byte order | |
347 | * return mpls ttl */ | |
348 | static inline uint8_t | |
349 | mpls_lse_to_ttl(ovs_be32 mpls_lse) | |
350 | { | |
351 | return (ntohl(mpls_lse) & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT; | |
352 | } | |
353 | ||
354 | /* Set TTL in mpls lse. */ | |
355 | static inline void | |
356 | flow_set_mpls_lse_ttl(ovs_be32 *mpls_lse, uint8_t ttl) | |
357 | { | |
358 | *mpls_lse &= ~htonl(MPLS_TTL_MASK); | |
359 | *mpls_lse |= htonl(ttl << MPLS_TTL_SHIFT); | |
360 | } | |
361 | ||
362 | /* Given a mpls label stack entry in network byte order | |
363 | * return mpls BoS bit */ | |
364 | static inline uint8_t | |
365 | mpls_lse_to_bos(ovs_be32 mpls_lse) | |
366 | { | |
367 | return (mpls_lse & htonl(MPLS_BOS_MASK)) != 0; | |
368 | } | |
369 | ||
ed36537e | 370 | #define IP_FMT "%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32 |
064af421 | 371 | #define IP_ARGS(ip) \ |
ed36537e BP |
372 | ntohl(ip) >> 24, \ |
373 | (ntohl(ip) >> 16) & 0xff, \ | |
374 | (ntohl(ip) >> 8) & 0xff, \ | |
375 | ntohl(ip) & 0xff | |
064af421 | 376 | |
3bffc610 BP |
377 | /* Example: |
378 | * | |
379 | * char *string = "1 33.44.55.66 2"; | |
380 | * ovs_be32 ip; | |
381 | * int a, b; | |
382 | * | |
383 | * if (sscanf(string, "%d"IP_SCAN_FMT"%d", | |
384 | * &a, IP_SCAN_ARGS(&ip), &b) == 1 + IP_SCAN_COUNT + 1) { | |
385 | * ... | |
386 | * } | |
387 | */ | |
388 | #define IP_SCAN_FMT "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8 | |
389 | #define IP_SCAN_ARGS(ip) \ | |
390 | ((void) (ovs_be32) *(ip), &((uint8_t *) ip)[0]), \ | |
391 | &((uint8_t *) ip)[1], \ | |
392 | &((uint8_t *) ip)[2], \ | |
393 | &((uint8_t *) ip)[3] | |
394 | #define IP_SCAN_COUNT 4 | |
395 | ||
0596e897 BP |
396 | /* Returns true if 'netmask' is a CIDR netmask, that is, if it consists of N |
397 | * high-order 1-bits and 32-N low-order 0-bits. */ | |
398 | static inline bool | |
399 | ip_is_cidr(ovs_be32 netmask) | |
400 | { | |
401 | uint32_t x = ~ntohl(netmask); | |
402 | return !(x & (x + 1)); | |
403 | } | |
b37e6334 BP |
404 | static inline bool |
405 | ip_is_multicast(ovs_be32 ip) | |
406 | { | |
407 | return (ip & htonl(0xf0000000)) == htonl(0xe0000000); | |
408 | } | |
aad29cd1 BP |
409 | int ip_count_cidr_bits(ovs_be32 netmask); |
410 | void ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *); | |
0596e897 | 411 | |
064af421 BP |
412 | #define IP_VER(ip_ihl_ver) ((ip_ihl_ver) >> 4) |
413 | #define IP_IHL(ip_ihl_ver) ((ip_ihl_ver) & 15) | |
414 | #define IP_IHL_VER(ihl, ver) (((ver) << 4) | (ihl)) | |
415 | ||
6c99379e BP |
416 | #ifndef IPPROTO_SCTP |
417 | #define IPPROTO_SCTP 132 | |
418 | #endif | |
419 | ||
f1193301 | 420 | /* TOS fields. */ |
495fe264 JG |
421 | #define IP_ECN_NOT_ECT 0x0 |
422 | #define IP_ECN_ECT_1 0x01 | |
423 | #define IP_ECN_ECT_0 0x02 | |
424 | #define IP_ECN_CE 0x03 | |
f1193301 BP |
425 | #define IP_ECN_MASK 0x03 |
426 | #define IP_DSCP_MASK 0xfc | |
427 | ||
064af421 BP |
428 | #define IP_VERSION 4 |
429 | ||
430 | #define IP_DONT_FRAGMENT 0x4000 /* Don't fragment. */ | |
431 | #define IP_MORE_FRAGMENTS 0x2000 /* More fragments. */ | |
432 | #define IP_FRAG_OFF_MASK 0x1fff /* Fragment offset. */ | |
433 | #define IP_IS_FRAGMENT(ip_frag_off) \ | |
434 | ((ip_frag_off) & htons(IP_MORE_FRAGMENTS | IP_FRAG_OFF_MASK)) | |
435 | ||
436 | #define IP_HEADER_LEN 20 | |
437 | struct ip_header { | |
438 | uint8_t ip_ihl_ver; | |
439 | uint8_t ip_tos; | |
d5ca4fce EJ |
440 | ovs_be16 ip_tot_len; |
441 | ovs_be16 ip_id; | |
442 | ovs_be16 ip_frag_off; | |
064af421 BP |
443 | uint8_t ip_ttl; |
444 | uint8_t ip_proto; | |
d5ca4fce EJ |
445 | ovs_be16 ip_csum; |
446 | ovs_be32 ip_src; | |
447 | ovs_be32 ip_dst; | |
064af421 BP |
448 | }; |
449 | BUILD_ASSERT_DECL(IP_HEADER_LEN == sizeof(struct ip_header)); | |
450 | ||
c4ccff78 | 451 | #define ICMP_HEADER_LEN 8 |
064af421 BP |
452 | struct icmp_header { |
453 | uint8_t icmp_type; | |
454 | uint8_t icmp_code; | |
d5ca4fce | 455 | ovs_be16 icmp_csum; |
c4ccff78 JG |
456 | union { |
457 | struct { | |
458 | ovs_be16 id; | |
459 | ovs_be16 seq; | |
460 | } echo; | |
461 | struct { | |
462 | ovs_be16 empty; | |
463 | ovs_be16 mtu; | |
464 | } frag; | |
465 | ovs_be32 gateway; | |
466 | } icmp_fields; | |
467 | uint8_t icmp_data[0]; | |
064af421 BP |
468 | }; |
469 | BUILD_ASSERT_DECL(ICMP_HEADER_LEN == sizeof(struct icmp_header)); | |
470 | ||
471 | #define UDP_HEADER_LEN 8 | |
472 | struct udp_header { | |
d5ca4fce EJ |
473 | ovs_be16 udp_src; |
474 | ovs_be16 udp_dst; | |
475 | ovs_be16 udp_len; | |
476 | ovs_be16 udp_csum; | |
064af421 BP |
477 | }; |
478 | BUILD_ASSERT_DECL(UDP_HEADER_LEN == sizeof(struct udp_header)); | |
479 | ||
480 | #define TCP_FIN 0x01 | |
481 | #define TCP_SYN 0x02 | |
482 | #define TCP_RST 0x04 | |
483 | #define TCP_PSH 0x08 | |
484 | #define TCP_ACK 0x10 | |
485 | #define TCP_URG 0x20 | |
486 | ||
df9b6612 | 487 | #define TCP_CTL(flags, offset) (htons((flags) | ((offset) << 12))) |
d84d4b88 BP |
488 | #define TCP_FLAGS(tcp_ctl) (ntohs(tcp_ctl) & 0x003f) |
489 | #define TCP_OFFSET(tcp_ctl) (ntohs(tcp_ctl) >> 12) | |
064af421 BP |
490 | |
491 | #define TCP_HEADER_LEN 20 | |
492 | struct tcp_header { | |
d5ca4fce EJ |
493 | ovs_be16 tcp_src; |
494 | ovs_be16 tcp_dst; | |
495 | ovs_be32 tcp_seq; | |
496 | ovs_be32 tcp_ack; | |
497 | ovs_be16 tcp_ctl; | |
498 | ovs_be16 tcp_winsz; | |
499 | ovs_be16 tcp_csum; | |
500 | ovs_be16 tcp_urg; | |
064af421 BP |
501 | }; |
502 | BUILD_ASSERT_DECL(TCP_HEADER_LEN == sizeof(struct tcp_header)); | |
503 | ||
504 | #define ARP_HRD_ETHERNET 1 | |
505 | #define ARP_PRO_IP 0x0800 | |
506 | #define ARP_OP_REQUEST 1 | |
507 | #define ARP_OP_REPLY 2 | |
7cb57d10 | 508 | #define ARP_OP_RARP 3 |
064af421 BP |
509 | |
510 | #define ARP_ETH_HEADER_LEN 28 | |
13b6bae6 | 511 | OVS_PACKED( |
064af421 BP |
512 | struct arp_eth_header { |
513 | /* Generic members. */ | |
d5ca4fce EJ |
514 | ovs_be16 ar_hrd; /* Hardware type. */ |
515 | ovs_be16 ar_pro; /* Protocol type. */ | |
064af421 BP |
516 | uint8_t ar_hln; /* Hardware address length. */ |
517 | uint8_t ar_pln; /* Protocol address length. */ | |
d5ca4fce | 518 | ovs_be16 ar_op; /* Opcode. */ |
064af421 BP |
519 | |
520 | /* Ethernet+IPv4 specific members. */ | |
521 | uint8_t ar_sha[ETH_ADDR_LEN]; /* Sender hardware address. */ | |
d5ca4fce | 522 | ovs_be32 ar_spa; /* Sender protocol address. */ |
064af421 | 523 | uint8_t ar_tha[ETH_ADDR_LEN]; /* Target hardware address. */ |
d5ca4fce | 524 | ovs_be32 ar_tpa; /* Target protocol address. */ |
13b6bae6 | 525 | }); |
064af421 BP |
526 | BUILD_ASSERT_DECL(ARP_ETH_HEADER_LEN == sizeof(struct arp_eth_header)); |
527 | ||
fa8223b7 JP |
528 | /* The IPv6 flow label is in the lower 20 bits of the first 32-bit word. */ |
529 | #define IPV6_LABEL_MASK 0x000fffff | |
530 | ||
3bffc610 BP |
531 | /* Example: |
532 | * | |
533 | * char *string = "1 ::1 2"; | |
534 | * char ipv6_s[IPV6_SCAN_LEN + 1]; | |
535 | * struct in6_addr ipv6; | |
536 | * | |
537 | * if (sscanf(string, "%d"IPV6_SCAN_FMT"%d", &a, ipv6_s, &b) == 3 | |
538 | * && inet_pton(AF_INET6, ipv6_s, &ipv6) == 1) { | |
539 | * ... | |
540 | * } | |
541 | */ | |
542 | #define IPV6_SCAN_FMT "%46[0123456789abcdefABCDEF:.]" | |
543 | #define IPV6_SCAN_LEN 46 | |
544 | ||
d31f1109 JP |
545 | extern const struct in6_addr in6addr_exact; |
546 | #define IN6ADDR_EXACT_INIT { { { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \ | |
547 | 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } } } | |
548 | ||
549 | static inline bool ipv6_addr_equals(const struct in6_addr *a, | |
550 | const struct in6_addr *b) | |
551 | { | |
552 | #ifdef IN6_ARE_ADDR_EQUAL | |
553 | return IN6_ARE_ADDR_EQUAL(a, b); | |
554 | #else | |
555 | return !memcmp(a, b, sizeof(*a)); | |
556 | #endif | |
557 | } | |
558 | ||
559 | static inline bool ipv6_mask_is_any(const struct in6_addr *mask) { | |
560 | return ipv6_addr_equals(mask, &in6addr_any); | |
561 | } | |
562 | ||
563 | static inline bool ipv6_mask_is_exact(const struct in6_addr *mask) { | |
564 | return ipv6_addr_equals(mask, &in6addr_exact); | |
565 | } | |
566 | ||
e8c16d83 SH |
567 | static inline bool dl_type_is_ip_any(ovs_be16 dl_type) |
568 | { | |
569 | return dl_type == htons(ETH_TYPE_IP) | |
570 | || dl_type == htons(ETH_TYPE_IPV6); | |
571 | } | |
572 | ||
48cecbdc EJ |
573 | static inline bool is_ip_any(const struct flow *flow) |
574 | { | |
e8c16d83 | 575 | return dl_type_is_ip_any(flow->dl_type); |
48cecbdc EJ |
576 | } |
577 | ||
d31f1109 JP |
578 | void format_ipv6_addr(char *addr_str, const struct in6_addr *addr); |
579 | void print_ipv6_addr(struct ds *string, const struct in6_addr *addr); | |
aad29cd1 BP |
580 | void print_ipv6_masked(struct ds *string, const struct in6_addr *addr, |
581 | const struct in6_addr *mask); | |
d31f1109 JP |
582 | struct in6_addr ipv6_addr_bitand(const struct in6_addr *src, |
583 | const struct in6_addr *mask); | |
584 | struct in6_addr ipv6_create_mask(int mask); | |
585 | int ipv6_count_cidr_bits(const struct in6_addr *netmask); | |
586 | bool ipv6_is_cidr(const struct in6_addr *netmask); | |
587 | ||
5de1bb5c BP |
588 | void *eth_compose(struct ofpbuf *, const uint8_t eth_dst[ETH_ADDR_LEN], |
589 | const uint8_t eth_src[ETH_ADDR_LEN], uint16_t eth_type, | |
590 | size_t size); | |
591 | void *snap_compose(struct ofpbuf *, const uint8_t eth_dst[ETH_ADDR_LEN], | |
592 | const uint8_t eth_src[ETH_ADDR_LEN], | |
593 | unsigned int oui, uint16_t snap_type, size_t size); | |
c97664b3 EJ |
594 | void packet_set_ipv4(struct ofpbuf *, ovs_be32 src, ovs_be32 dst, uint8_t tos, |
595 | uint8_t ttl); | |
bc7a5acd AA |
596 | void packet_set_ipv6(struct ofpbuf *, uint8_t proto, const ovs_be32 src[4], |
597 | const ovs_be32 dst[4], uint8_t tc, | |
038341d1 | 598 | ovs_be32 fl, uint8_t hlmit); |
c97664b3 EJ |
599 | void packet_set_tcp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst); |
600 | void packet_set_udp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst); | |
40f78b38 | 601 | |
12113c39 | 602 | uint8_t packet_get_tcp_flags(const struct ofpbuf *, const struct flow *); |
7393104d | 603 | void packet_format_tcp_flags(struct ds *, uint8_t); |
12113c39 | 604 | |
064af421 | 605 | #endif /* packets.h */ |