Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
3 : : *
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:
7 : : *
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.
15 : : */
16 : : #include <config.h>
17 : : #include <sys/types.h>
18 : : #include "flow.h"
19 : : #include <errno.h>
20 : : #include <inttypes.h>
21 : : #include <limits.h>
22 : : #include <netinet/in.h>
23 : : #include <netinet/icmp6.h>
24 : : #include <netinet/ip6.h>
25 : : #include <stdint.h>
26 : : #include <stdlib.h>
27 : : #include <string.h>
28 : : #include "byte-order.h"
29 : : #include "colors.h"
30 : : #include "coverage.h"
31 : : #include "csum.h"
32 : : #include "openvswitch/dynamic-string.h"
33 : : #include "hash.h"
34 : : #include "jhash.h"
35 : : #include "openvswitch/match.h"
36 : : #include "dp-packet.h"
37 : : #include "openflow/openflow.h"
38 : : #include "packets.h"
39 : : #include "odp-util.h"
40 : : #include "random.h"
41 : : #include "unaligned.h"
42 : : #include "util.h"
43 : :
44 : 207462 : COVERAGE_DEFINE(flow_extract);
45 : 3974712 : COVERAGE_DEFINE(miniflow_malloc);
46 : :
47 : : /* U64 indices for segmented flow classification. */
48 : : const uint8_t flow_segment_u64s[4] = {
49 : : FLOW_SEGMENT_1_ENDS_AT / sizeof(uint64_t),
50 : : FLOW_SEGMENT_2_ENDS_AT / sizeof(uint64_t),
51 : : FLOW_SEGMENT_3_ENDS_AT / sizeof(uint64_t),
52 : : FLOW_U64S
53 : : };
54 : :
55 : : /* Asserts that field 'f1' follows immediately after 'f0' in struct flow,
56 : : * without any intervening padding. */
57 : : #define ASSERT_SEQUENTIAL(f0, f1) \
58 : : BUILD_ASSERT_DECL(offsetof(struct flow, f0) \
59 : : + MEMBER_SIZEOF(struct flow, f0) \
60 : : == offsetof(struct flow, f1))
61 : :
62 : : /* Asserts that fields 'f0' and 'f1' are in the same 32-bit aligned word within
63 : : * struct flow. */
64 : : #define ASSERT_SAME_WORD(f0, f1) \
65 : : BUILD_ASSERT_DECL(offsetof(struct flow, f0) / 4 \
66 : : == offsetof(struct flow, f1) / 4)
67 : :
68 : : /* Asserts that 'f0' and 'f1' are both sequential and within the same 32-bit
69 : : * aligned word in struct flow. */
70 : : #define ASSERT_SEQUENTIAL_SAME_WORD(f0, f1) \
71 : : ASSERT_SEQUENTIAL(f0, f1); \
72 : : ASSERT_SAME_WORD(f0, f1)
73 : :
74 : : /* miniflow_extract() assumes the following to be true to optimize the
75 : : * extraction process. */
76 : : ASSERT_SEQUENTIAL_SAME_WORD(dl_type, vlan_tci);
77 : :
78 : : ASSERT_SEQUENTIAL_SAME_WORD(nw_frag, nw_tos);
79 : : ASSERT_SEQUENTIAL_SAME_WORD(nw_tos, nw_ttl);
80 : : ASSERT_SEQUENTIAL_SAME_WORD(nw_ttl, nw_proto);
81 : :
82 : : /* TCP flags in the middle of a BE64, zeroes in the other half. */
83 : : BUILD_ASSERT_DECL(offsetof(struct flow, tcp_flags) % 8 == 4);
84 : :
85 : : #if WORDS_BIGENDIAN
86 : : #define TCP_FLAGS_BE32(tcp_ctl) ((OVS_FORCE ovs_be32)TCP_FLAGS_BE16(tcp_ctl) \
87 : : << 16)
88 : : #else
89 : : #define TCP_FLAGS_BE32(tcp_ctl) ((OVS_FORCE ovs_be32)TCP_FLAGS_BE16(tcp_ctl))
90 : : #endif
91 : :
92 : : ASSERT_SEQUENTIAL_SAME_WORD(tp_src, tp_dst);
93 : :
94 : : /* Removes 'size' bytes from the head end of '*datap', of size '*sizep', which
95 : : * must contain at least 'size' bytes of data. Returns the first byte of data
96 : : * removed. */
97 : : static inline const void *
98 : 113301 : data_pull(const void **datap, size_t *sizep, size_t size)
99 : : {
100 : 113301 : const char *data = *datap;
101 : 113301 : *datap = data + size;
102 : 113301 : *sizep -= size;
103 : 113301 : return data;
104 : : }
105 : :
106 : : /* If '*datap' has at least 'size' bytes of data, removes that many bytes from
107 : : * the head end of '*datap' and returns the first byte removed. Otherwise,
108 : : * returns a null pointer without modifying '*datap'. */
109 : : static inline const void *
110 : 9825 : data_try_pull(const void **datap, size_t *sizep, size_t size)
111 : : {
112 [ + + ]: 9825 : return OVS_LIKELY(*sizep >= size) ? data_pull(datap, sizep, size) : NULL;
113 : : }
114 : :
115 : : /* Context for pushing data to a miniflow. */
116 : : struct mf_ctx {
117 : : struct flowmap map;
118 : : uint64_t *data;
119 : : uint64_t * const end;
120 : : };
121 : :
122 : : /* miniflow_push_* macros allow filling in a miniflow data values in order.
123 : : * Assertions are needed only when the layout of the struct flow is modified.
124 : : * 'ofs' is a compile-time constant, which allows most of the code be optimized
125 : : * away. Some GCC versions gave warnings on ALWAYS_INLINE, so these are
126 : : * defined as macros. */
127 : :
128 : : #if (FLOW_WC_SEQ != 36)
129 : : #define MINIFLOW_ASSERT(X) ovs_assert(X)
130 : : BUILD_MESSAGE("FLOW_WC_SEQ changed: miniflow_extract() will have runtime "
131 : : "assertions enabled. Consider updating FLOW_WC_SEQ after "
132 : : "testing")
133 : : #else
134 : : #define MINIFLOW_ASSERT(X)
135 : : #endif
136 : :
137 : : /* True if 'IDX' and higher bits are not set. */
138 : : #define ASSERT_FLOWMAP_NOT_SET(FM, IDX) \
139 : : { \
140 : : MINIFLOW_ASSERT(!((FM)->bits[(IDX) / MAP_T_BITS] & \
141 : : (MAP_MAX << ((IDX) % MAP_T_BITS)))); \
142 : : for (size_t i = (IDX) / MAP_T_BITS + 1; i < FLOWMAP_UNITS; i++) { \
143 : : MINIFLOW_ASSERT(!(FM)->bits[i]); \
144 : : } \
145 : : }
146 : :
147 : : #define miniflow_set_map(MF, OFS) \
148 : : { \
149 : : ASSERT_FLOWMAP_NOT_SET(&MF.map, (OFS)); \
150 : : flowmap_set(&MF.map, (OFS), 1); \
151 : : }
152 : :
153 : : #define miniflow_assert_in_map(MF, OFS) \
154 : : MINIFLOW_ASSERT(flowmap_is_set(&MF.map, (OFS))); \
155 : : ASSERT_FLOWMAP_NOT_SET(&MF.map, (OFS) + 1)
156 : :
157 : : #define miniflow_push_uint64_(MF, OFS, VALUE) \
158 : : { \
159 : : MINIFLOW_ASSERT(MF.data < MF.end && (OFS) % 8 == 0); \
160 : : *MF.data++ = VALUE; \
161 : : miniflow_set_map(MF, OFS / 8); \
162 : : }
163 : :
164 : : #define miniflow_push_be64_(MF, OFS, VALUE) \
165 : : miniflow_push_uint64_(MF, OFS, (OVS_FORCE uint64_t)(VALUE))
166 : :
167 : : #define miniflow_push_uint32_(MF, OFS, VALUE) \
168 : : { \
169 : : MINIFLOW_ASSERT(MF.data < MF.end); \
170 : : \
171 : : if ((OFS) % 8 == 0) { \
172 : : miniflow_set_map(MF, OFS / 8); \
173 : : *(uint32_t *)MF.data = VALUE; \
174 : : } else if ((OFS) % 8 == 4) { \
175 : : miniflow_assert_in_map(MF, OFS / 8); \
176 : : *((uint32_t *)MF.data + 1) = VALUE; \
177 : : MF.data++; \
178 : : } \
179 : : }
180 : :
181 : : #define miniflow_push_be32_(MF, OFS, VALUE) \
182 : : miniflow_push_uint32_(MF, OFS, (OVS_FORCE uint32_t)(VALUE))
183 : :
184 : : #define miniflow_push_uint16_(MF, OFS, VALUE) \
185 : : { \
186 : : MINIFLOW_ASSERT(MF.data < MF.end); \
187 : : \
188 : : if ((OFS) % 8 == 0) { \
189 : : miniflow_set_map(MF, OFS / 8); \
190 : : *(uint16_t *)MF.data = VALUE; \
191 : : } else if ((OFS) % 8 == 2) { \
192 : : miniflow_assert_in_map(MF, OFS / 8); \
193 : : *((uint16_t *)MF.data + 1) = VALUE; \
194 : : } else if ((OFS) % 8 == 4) { \
195 : : miniflow_assert_in_map(MF, OFS / 8); \
196 : : *((uint16_t *)MF.data + 2) = VALUE; \
197 : : } else if ((OFS) % 8 == 6) { \
198 : : miniflow_assert_in_map(MF, OFS / 8); \
199 : : *((uint16_t *)MF.data + 3) = VALUE; \
200 : : MF.data++; \
201 : : } \
202 : : }
203 : :
204 : : #define miniflow_push_uint8_(MF, OFS, VALUE) \
205 : : { \
206 : : MINIFLOW_ASSERT(MF.data < MF.end); \
207 : : \
208 : : if ((OFS) % 8 == 0) { \
209 : : miniflow_set_map(MF, OFS / 8); \
210 : : *(uint8_t *)MF.data = VALUE; \
211 : : } else if ((OFS) % 8 == 7) { \
212 : : miniflow_assert_in_map(MF, OFS / 8); \
213 : : *((uint8_t *)MF.data + 7) = VALUE; \
214 : : MF.data++; \
215 : : } else { \
216 : : miniflow_assert_in_map(MF, OFS / 8); \
217 : : *((uint8_t *)MF.data + ((OFS) % 8)) = VALUE; \
218 : : } \
219 : : }
220 : :
221 : : #define miniflow_pad_to_64_(MF, OFS) \
222 : : { \
223 : : MINIFLOW_ASSERT((OFS) % 8 != 0); \
224 : : miniflow_assert_in_map(MF, OFS / 8); \
225 : : \
226 : : memset((uint8_t *)MF.data + (OFS) % 8, 0, 8 - (OFS) % 8); \
227 : : MF.data++; \
228 : : }
229 : :
230 : : #define miniflow_pad_from_64_(MF, OFS) \
231 : : { \
232 : : MINIFLOW_ASSERT(MF.data < MF.end); \
233 : : \
234 : : MINIFLOW_ASSERT((OFS) % 8 != 0); \
235 : : miniflow_set_map(MF, OFS / 8); \
236 : : \
237 : : memset((uint8_t *)MF.data, 0, (OFS) % 8); \
238 : : }
239 : :
240 : : #define miniflow_push_be16_(MF, OFS, VALUE) \
241 : : miniflow_push_uint16_(MF, OFS, (OVS_FORCE uint16_t)VALUE);
242 : :
243 : : #define miniflow_push_be8_(MF, OFS, VALUE) \
244 : : miniflow_push_uint8_(MF, OFS, (OVS_FORCE uint8_t)VALUE);
245 : :
246 : : #define miniflow_set_maps(MF, OFS, N_WORDS) \
247 : : { \
248 : : size_t ofs = (OFS); \
249 : : size_t n_words = (N_WORDS); \
250 : : \
251 : : MINIFLOW_ASSERT(n_words && MF.data + n_words <= MF.end); \
252 : : ASSERT_FLOWMAP_NOT_SET(&MF.map, ofs); \
253 : : flowmap_set(&MF.map, ofs, n_words); \
254 : : }
255 : :
256 : : /* Data at 'valuep' may be unaligned. */
257 : : #define miniflow_push_words_(MF, OFS, VALUEP, N_WORDS) \
258 : : { \
259 : : MINIFLOW_ASSERT((OFS) % 8 == 0); \
260 : : miniflow_set_maps(MF, (OFS) / 8, (N_WORDS)); \
261 : : memcpy(MF.data, (VALUEP), (N_WORDS) * sizeof *MF.data); \
262 : : MF.data += (N_WORDS); \
263 : : }
264 : :
265 : : /* Push 32-bit words padded to 64-bits. */
266 : : #define miniflow_push_words_32_(MF, OFS, VALUEP, N_WORDS) \
267 : : { \
268 : : miniflow_set_maps(MF, (OFS) / 8, DIV_ROUND_UP(N_WORDS, 2)); \
269 : : memcpy(MF.data, (VALUEP), (N_WORDS) * sizeof(uint32_t)); \
270 : : MF.data += DIV_ROUND_UP(N_WORDS, 2); \
271 : : if ((N_WORDS) & 1) { \
272 : : *((uint32_t *)MF.data - 1) = 0; \
273 : : } \
274 : : }
275 : :
276 : : /* Data at 'valuep' may be unaligned. */
277 : : /* MACs start 64-aligned, and must be followed by other data or padding. */
278 : : #define miniflow_push_macs_(MF, OFS, VALUEP) \
279 : : { \
280 : : miniflow_set_maps(MF, (OFS) / 8, 2); \
281 : : memcpy(MF.data, (VALUEP), 2 * ETH_ADDR_LEN); \
282 : : MF.data += 1; /* First word only. */ \
283 : : }
284 : :
285 : : #define miniflow_push_uint32(MF, FIELD, VALUE) \
286 : : miniflow_push_uint32_(MF, offsetof(struct flow, FIELD), VALUE)
287 : :
288 : : #define miniflow_push_be32(MF, FIELD, VALUE) \
289 : : miniflow_push_be32_(MF, offsetof(struct flow, FIELD), VALUE)
290 : :
291 : : #define miniflow_push_uint16(MF, FIELD, VALUE) \
292 : : miniflow_push_uint16_(MF, offsetof(struct flow, FIELD), VALUE)
293 : :
294 : : #define miniflow_push_be16(MF, FIELD, VALUE) \
295 : : miniflow_push_be16_(MF, offsetof(struct flow, FIELD), VALUE)
296 : :
297 : : #define miniflow_push_uint8(MF, FIELD, VALUE) \
298 : : miniflow_push_uint8_(MF, offsetof(struct flow, FIELD), VALUE)
299 : :
300 : : #define miniflow_pad_to_64(MF, FIELD) \
301 : : miniflow_pad_to_64_(MF, OFFSETOFEND(struct flow, FIELD))
302 : :
303 : : #define miniflow_pad_from_64(MF, FIELD) \
304 : : miniflow_pad_from_64_(MF, offsetof(struct flow, FIELD))
305 : :
306 : : #define miniflow_push_words(MF, FIELD, VALUEP, N_WORDS) \
307 : : miniflow_push_words_(MF, offsetof(struct flow, FIELD), VALUEP, N_WORDS)
308 : :
309 : : #define miniflow_push_words_32(MF, FIELD, VALUEP, N_WORDS) \
310 : : miniflow_push_words_32_(MF, offsetof(struct flow, FIELD), VALUEP, N_WORDS)
311 : :
312 : : #define miniflow_push_macs(MF, FIELD, VALUEP) \
313 : : miniflow_push_macs_(MF, offsetof(struct flow, FIELD), VALUEP)
314 : :
315 : : /* Pulls the MPLS headers at '*datap' and returns the count of them. */
316 : : static inline int
317 : 2013 : parse_mpls(const void **datap, size_t *sizep)
318 : : {
319 : : const struct mpls_hdr *mh;
320 : 2013 : int count = 0;
321 : :
322 [ + - ]: 3754 : while ((mh = data_try_pull(datap, sizep, sizeof *mh))) {
323 : 3754 : count++;
324 [ + + ]: 3754 : if (mh->mpls_lse.lo & htons(1 << MPLS_BOS_SHIFT)) {
325 : 2013 : break;
326 : : }
327 : : }
328 : 2013 : return MIN(count, FLOW_MAX_MPLS_LABELS);
329 : : }
330 : :
331 : : static inline ALWAYS_INLINE ovs_be16
332 : : parse_vlan(const void **datap, size_t *sizep)
333 : : {
334 : 39044 : const struct eth_header *eth = *datap;
335 : :
336 : : struct qtag_prefix {
337 : : ovs_be16 eth_type; /* ETH_TYPE_VLAN */
338 : : ovs_be16 tci;
339 : : };
340 : :
341 : 39044 : data_pull(datap, sizep, ETH_ADDR_LEN * 2);
342 : :
343 [ # # + + ]: 39044 : if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
344 [ # # ][ + - ]: 619 : if (OVS_LIKELY(*sizep
345 : : >= sizeof(struct qtag_prefix) + sizeof(ovs_be16))) {
346 : 619 : const struct qtag_prefix *qp = data_pull(datap, sizep, sizeof *qp);
347 : 619 : return qp->tci | htons(VLAN_CFI);
348 : : }
349 : : }
350 : 38425 : return 0;
351 : : }
352 : :
353 : : static inline ALWAYS_INLINE ovs_be16
354 : : parse_ethertype(const void **datap, size_t *sizep)
355 : : {
356 : : const struct llc_snap_header *llc;
357 : : ovs_be16 proto;
358 : :
359 : 39044 : proto = *(ovs_be16 *) data_pull(datap, sizep, sizeof proto);
360 [ # # + + ]: 39044 : if (OVS_LIKELY(ntohs(proto) >= ETH_TYPE_MIN)) {
361 : 36035 : return proto;
362 : : }
363 : :
364 [ # # ][ + + ]: 3009 : if (OVS_UNLIKELY(*sizep < sizeof *llc)) {
365 : 2831 : return htons(FLOW_DL_TYPE_NONE);
366 : : }
367 : :
368 : 178 : llc = *datap;
369 [ # # ][ # # ]: 178 : if (OVS_UNLIKELY(llc->llc.llc_dsap != LLC_DSAP_SNAP
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ][ - + ]
[ + + ][ - + ]
[ + + ][ - + ]
370 : : || llc->llc.llc_ssap != LLC_SSAP_SNAP
371 : : || llc->llc.llc_cntl != LLC_CNTL_SNAP
372 : : || memcmp(llc->snap.snap_org, SNAP_ORG_ETHERNET,
373 : : sizeof llc->snap.snap_org))) {
374 : 55 : return htons(FLOW_DL_TYPE_NONE);
375 : : }
376 : :
377 : 123 : data_pull(datap, sizep, sizeof *llc);
378 : :
379 [ # # + - ]: 123 : if (OVS_LIKELY(ntohs(llc->snap.snap_type) >= ETH_TYPE_MIN)) {
380 : 123 : return llc->snap.snap_type;
381 : : }
382 : :
383 : 0 : return htons(FLOW_DL_TYPE_NONE);
384 : : }
385 : :
386 : : static inline void
387 : 1310 : parse_icmpv6(const void **datap, size_t *sizep, const struct icmp6_hdr *icmp,
388 : : const struct in6_addr **nd_target,
389 : : struct eth_addr arp_buf[2])
390 : : {
391 [ + - ][ + + ]: 1310 : if (icmp->icmp6_code == 0 &&
392 [ + + ]: 1020 : (icmp->icmp6_type == ND_NEIGHBOR_SOLICIT ||
393 : 1020 : icmp->icmp6_type == ND_NEIGHBOR_ADVERT)) {
394 : :
395 : 309 : *nd_target = data_try_pull(datap, sizep, sizeof **nd_target);
396 [ + + ]: 309 : if (OVS_UNLIKELY(!*nd_target)) {
397 : 5 : return;
398 : : }
399 : :
400 [ + + ]: 354 : while (*sizep >= 8) {
401 : : /* The minimum size of an option is 8 bytes, which also is
402 : : * the size of Ethernet link-layer options. */
403 : 50 : const struct ovs_nd_opt *nd_opt = *datap;
404 : 50 : int opt_len = nd_opt->nd_opt_len * ND_OPT_LEN;
405 : :
406 [ + - ][ - + ]: 50 : if (!opt_len || opt_len > *sizep) {
407 : 0 : return;
408 : : }
409 : :
410 : : /* Store the link layer address if the appropriate option is
411 : : * provided. It is considered an error if the same link
412 : : * layer option is specified twice. */
413 [ + + ]: 50 : if (nd_opt->nd_opt_type == ND_OPT_SOURCE_LINKADDR
414 [ + - ]: 31 : && opt_len == 8) {
415 [ + - ]: 62 : if (OVS_LIKELY(eth_addr_is_zero(arp_buf[0]))) {
416 : 31 : arp_buf[0] = nd_opt->nd_opt_mac;
417 : : } else {
418 : 0 : goto invalid;
419 : : }
420 [ + - ]: 19 : } else if (nd_opt->nd_opt_type == ND_OPT_TARGET_LINKADDR
421 [ + - ]: 19 : && opt_len == 8) {
422 [ + - ]: 19 : if (OVS_LIKELY(eth_addr_is_zero(arp_buf[1]))) {
423 : 19 : arp_buf[1] = nd_opt->nd_opt_mac;
424 : : } else {
425 : 0 : goto invalid;
426 : : }
427 : : }
428 : :
429 [ - + ]: 50 : if (OVS_UNLIKELY(!data_try_pull(datap, sizep, opt_len))) {
430 : 0 : return;
431 : : }
432 : : }
433 : : }
434 : :
435 : 1305 : return;
436 : :
437 : : invalid:
438 : 0 : *nd_target = NULL;
439 : 0 : arp_buf[0] = eth_addr_zero;
440 : 0 : arp_buf[1] = eth_addr_zero;
441 : : }
442 : :
443 : : static inline bool
444 : 1520 : parse_ipv6_ext_hdrs__(const void **datap, size_t *sizep, uint8_t *nw_proto,
445 : : uint8_t *nw_frag)
446 : : {
447 : : while (1) {
448 [ + + ][ + - ]: 2174 : if (OVS_LIKELY((*nw_proto != IPPROTO_HOPOPTS)
[ + + ][ + - ]
[ + + ][ + - ]
[ + + ][ + + ]
449 : : && (*nw_proto != IPPROTO_ROUTING)
450 : : && (*nw_proto != IPPROTO_DSTOPTS)
451 : : && (*nw_proto != IPPROTO_AH)
452 : : && (*nw_proto != IPPROTO_FRAGMENT))) {
453 : : /* It's either a terminal header (e.g., TCP, UDP) or one we
454 : : * don't understand. In either case, we're done with the
455 : : * packet, so use it to fill in 'nw_proto'. */
456 : 1469 : return true;
457 : : }
458 : :
459 : : /* We only verify that at least 8 bytes of the next header are
460 : : * available, but many of these headers are longer. Ensure that
461 : : * accesses within the extension header are within those first 8
462 : : * bytes. All extension headers are required to be at least 8
463 : : * bytes. */
464 [ - + ]: 705 : if (OVS_UNLIKELY(*sizep < 8)) {
465 : 0 : return false;
466 : : }
467 : :
468 [ + + ]: 705 : if ((*nw_proto == IPPROTO_HOPOPTS)
469 [ + - ]: 90 : || (*nw_proto == IPPROTO_ROUTING)
470 [ - + ]: 705 : || (*nw_proto == IPPROTO_DSTOPTS)) {
471 : : /* These headers, while different, have the fields we care
472 : : * about in the same location and with the same
473 : : * interpretation. */
474 : 615 : const struct ip6_ext *ext_hdr = *datap;
475 : 615 : *nw_proto = ext_hdr->ip6e_nxt;
476 [ - + ]: 615 : if (OVS_UNLIKELY(!data_try_pull(datap, sizep,
477 : : (ext_hdr->ip6e_len + 1) * 8))) {
478 : 0 : return false;
479 : : }
480 [ - + ]: 90 : } else if (*nw_proto == IPPROTO_AH) {
481 : : /* A standard AH definition isn't available, but the fields
482 : : * we care about are in the same location as the generic
483 : : * option header--only the header length is calculated
484 : : * differently. */
485 : 0 : const struct ip6_ext *ext_hdr = *datap;
486 : 0 : *nw_proto = ext_hdr->ip6e_nxt;
487 [ # # ]: 0 : if (OVS_UNLIKELY(!data_try_pull(datap, sizep,
488 : : (ext_hdr->ip6e_len + 2) * 4))) {
489 : 0 : return false;
490 : : }
491 [ + - ]: 90 : } else if (*nw_proto == IPPROTO_FRAGMENT) {
492 : 90 : const struct ovs_16aligned_ip6_frag *frag_hdr = *datap;
493 : :
494 : 90 : *nw_proto = frag_hdr->ip6f_nxt;
495 [ - + ]: 90 : if (!data_try_pull(datap, sizep, sizeof *frag_hdr)) {
496 : 0 : return false;
497 : : }
498 : :
499 : : /* We only process the first fragment. */
500 [ + - ]: 90 : if (frag_hdr->ip6f_offlg != htons(0)) {
501 : 90 : *nw_frag = FLOW_NW_FRAG_ANY;
502 [ + + ]: 90 : if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) {
503 : 51 : *nw_frag |= FLOW_NW_FRAG_LATER;
504 : 51 : *nw_proto = IPPROTO_FRAGMENT;
505 : 51 : return true;
506 : : }
507 : : }
508 : : }
509 : 654 : }
510 : : }
511 : :
512 : : bool
513 : 45 : parse_ipv6_ext_hdrs(const void **datap, size_t *sizep, uint8_t *nw_proto,
514 : : uint8_t *nw_frag)
515 : : {
516 : 45 : return parse_ipv6_ext_hdrs__(datap, sizep, nw_proto, nw_frag);
517 : : }
518 : :
519 : : /* Initializes 'flow' members from 'packet' and 'md'
520 : : *
521 : : * Initializes 'packet' header l2 pointer to the start of the Ethernet
522 : : * header, and the layer offsets as follows:
523 : : *
524 : : * - packet->l2_5_ofs to the start of the MPLS shim header, or UINT16_MAX
525 : : * when there is no MPLS shim header.
526 : : *
527 : : * - packet->l3_ofs to just past the Ethernet header, or just past the
528 : : * vlan_header if one is present, to the first byte of the payload of the
529 : : * Ethernet frame. UINT16_MAX if the frame is too short to contain an
530 : : * Ethernet header.
531 : : *
532 : : * - packet->l4_ofs to just past the IPv4 header, if one is present and
533 : : * has at least the content used for the fields of interest for the flow,
534 : : * otherwise UINT16_MAX.
535 : : */
536 : : void
537 : 19106 : flow_extract(struct dp_packet *packet, struct flow *flow)
538 : : {
539 : : struct {
540 : : struct miniflow mf;
541 : : uint64_t buf[FLOW_U64S];
542 : : } m;
543 : :
544 : 19106 : COVERAGE_INC(flow_extract);
545 : :
546 : 19106 : miniflow_extract(packet, &m.mf);
547 : 19106 : miniflow_expand(&m.mf, flow);
548 : 19106 : }
549 : :
550 : : /* Caller is responsible for initializing 'dst' with enough storage for
551 : : * FLOW_U64S * 8 bytes. */
552 : : void
553 : 39044 : miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
554 : : {
555 : 39044 : const struct pkt_metadata *md = &packet->md;
556 : 39044 : const void *data = dp_packet_data(packet);
557 : 39044 : size_t size = dp_packet_size(packet);
558 : 39044 : uint64_t *values = miniflow_values(dst);
559 : 78088 : struct mf_ctx mf = { FLOWMAP_EMPTY_INITIALIZER, values,
560 : 39044 : values + FLOW_U64S };
561 : : const char *l2;
562 : : ovs_be16 dl_type;
563 : : uint8_t nw_frag, nw_tos, nw_ttl, nw_proto;
564 : :
565 : : /* Metadata. */
566 [ + + ]: 39044 : if (flow_tnl_dst_is_set(&md->tunnel)) {
567 [ + + ]: 3954 : miniflow_push_words(mf, tunnel, &md->tunnel,
568 : : offsetof(struct flow_tnl, metadata) /
569 : : sizeof(uint64_t));
570 : :
571 [ + + ]: 1977 : if (!(md->tunnel.flags & FLOW_TNL_F_UDPIF)) {
572 [ - + ]: 115 : if (md->tunnel.metadata.present.map) {
573 [ # # ]: 115 : miniflow_push_words(mf, tunnel.metadata, &md->tunnel.metadata,
574 : : sizeof md->tunnel.metadata /
575 : : sizeof(uint64_t));
576 : : }
577 : : } else {
578 [ + - ]: 1862 : if (md->tunnel.metadata.present.len) {
579 [ + + ]: 3724 : miniflow_push_words(mf, tunnel.metadata.present,
580 : : &md->tunnel.metadata.present, 1);
581 [ + + ]: 3724 : miniflow_push_words(mf, tunnel.metadata.opts.gnv,
582 : : md->tunnel.metadata.opts.gnv,
583 : : DIV_ROUND_UP(md->tunnel.metadata.present.len,
584 : : sizeof(uint64_t)));
585 : : }
586 : : }
587 : : }
588 [ + + ][ - + ]: 39044 : if (md->skb_priority || md->pkt_mark) {
589 [ + + ]: 48 : miniflow_push_uint32(mf, skb_priority, md->skb_priority);
590 [ + + ]: 39068 : miniflow_push_uint32(mf, pkt_mark, md->pkt_mark);
591 : : }
592 [ + + ]: 78088 : miniflow_push_uint32(mf, dp_hash, md->dp_hash);
593 [ + + ]: 78088 : miniflow_push_uint32(mf, in_port, odp_to_u32(md->in_port.odp_port));
594 [ + + ][ + + ]: 39044 : if (md->recirc_id || md->ct_state) {
595 [ + + ]: 4656 : miniflow_push_uint32(mf, recirc_id, md->recirc_id);
596 [ + + ]: 4656 : miniflow_push_uint16(mf, ct_state, md->ct_state);
597 [ + + ]: 4656 : miniflow_push_uint16(mf, ct_zone, md->ct_zone);
598 : : }
599 : :
600 [ + + ]: 39044 : if (md->ct_state) {
601 [ + + ]: 2810 : miniflow_push_uint32(mf, ct_mark, md->ct_mark);
602 [ + + ]: 2810 : miniflow_pad_to_64(mf, ct_mark);
603 : :
604 [ + + ]: 1405 : if (!ovs_u128_is_zero(md->ct_label)) {
605 [ + + ]: 142 : miniflow_push_words(mf, ct_label, &md->ct_label,
606 : : sizeof md->ct_label / sizeof(uint64_t));
607 : : }
608 : : }
609 : :
610 : : /* Initialize packet's layer pointer and offsets. */
611 : 39044 : l2 = data;
612 : 39044 : dp_packet_reset_offsets(packet);
613 : :
614 : : /* Must have full Ethernet header to proceed. */
615 [ - + ]: 39044 : if (OVS_UNLIKELY(size < sizeof(struct eth_header))) {
616 : 0 : goto out;
617 : : } else {
618 : : ovs_be16 vlan_tci;
619 : :
620 : : /* Link layer. */
621 : : ASSERT_SEQUENTIAL(dl_dst, dl_src);
622 [ + + ]: 78088 : miniflow_push_macs(mf, dl_dst, data);
623 : : /* dl_type, vlan_tci. */
624 : 39044 : vlan_tci = parse_vlan(&data, &size);
625 : 39044 : dl_type = parse_ethertype(&data, &size);
626 [ + + ]: 78088 : miniflow_push_be16(mf, dl_type, dl_type);
627 [ + + ]: 78088 : miniflow_push_be16(mf, vlan_tci, vlan_tci);
628 : : }
629 : :
630 : : /* Parse mpls. */
631 [ + + ]: 39044 : if (OVS_UNLIKELY(eth_type_mpls(dl_type))) {
632 : : int count;
633 : 2013 : const void *mpls = data;
634 : :
635 : 2013 : packet->l2_5_ofs = (char *)data - l2;
636 : 2013 : count = parse_mpls(&data, &size);
637 [ + + ][ + + ]: 4026 : miniflow_push_words_32(mf, mpls_lse, mpls, count);
638 : : }
639 : :
640 : : /* Network layer. */
641 : 39044 : packet->l3_ofs = (char *)data - l2;
642 : :
643 : 39044 : nw_frag = 0;
644 [ + + ]: 39044 : if (OVS_LIKELY(dl_type == htons(ETH_TYPE_IP))) {
645 : 21893 : const struct ip_header *nh = data;
646 : : int ip_len;
647 : : uint16_t tot_len;
648 : :
649 [ - + ]: 21893 : if (OVS_UNLIKELY(size < IP_HEADER_LEN)) {
650 : 0 : goto out;
651 : : }
652 : 21893 : ip_len = IP_IHL(nh->ip_ihl_ver) * 4;
653 : :
654 [ - + ]: 21893 : if (OVS_UNLIKELY(ip_len < IP_HEADER_LEN)) {
655 : 0 : goto out;
656 : : }
657 [ - + ]: 21893 : if (OVS_UNLIKELY(size < ip_len)) {
658 : 0 : goto out;
659 : : }
660 : 21893 : tot_len = ntohs(nh->ip_tot_len);
661 [ + + ][ + - ]: 21893 : if (OVS_UNLIKELY(tot_len > size || ip_len > tot_len)) {
662 : : goto out;
663 : : }
664 [ - + ]: 21866 : if (OVS_UNLIKELY(size - tot_len > UINT8_MAX)) {
665 : 0 : goto out;
666 : : }
667 : 21866 : dp_packet_set_l2_pad_size(packet, size - tot_len);
668 : 21866 : size = tot_len; /* Never pull padding. */
669 : :
670 : : /* Push both source and destination address at once. */
671 [ + + ]: 43732 : miniflow_push_words(mf, nw_src, &nh->ip_src, 1);
672 : :
673 [ - + ]: 21866 : miniflow_push_be32(mf, ipv6_label, 0); /* Padding for IPv4. */
674 : :
675 : 21866 : nw_tos = nh->ip_tos;
676 : 21866 : nw_ttl = nh->ip_ttl;
677 : 21866 : nw_proto = nh->ip_proto;
678 [ + + ]: 21866 : if (OVS_UNLIKELY(IP_IS_FRAGMENT(nh->ip_frag_off))) {
679 : 423 : nw_frag = FLOW_NW_FRAG_ANY;
680 [ + + ]: 423 : if (nh->ip_frag_off & htons(IP_FRAG_OFF_MASK)) {
681 : 261 : nw_frag |= FLOW_NW_FRAG_LATER;
682 : : }
683 : : }
684 : 21866 : data_pull(&data, &size, ip_len);
685 [ + + ]: 17151 : } else if (dl_type == htons(ETH_TYPE_IPV6)) {
686 : : const struct ovs_16aligned_ip6_hdr *nh;
687 : : ovs_be32 tc_flow;
688 : : uint16_t plen;
689 : :
690 [ - + ]: 1475 : if (OVS_UNLIKELY(size < sizeof *nh)) {
691 : 0 : goto out;
692 : : }
693 : 1475 : nh = data_pull(&data, &size, sizeof *nh);
694 : :
695 : 1475 : plen = ntohs(nh->ip6_plen);
696 [ - + ]: 1475 : if (OVS_UNLIKELY(plen > size)) {
697 : 0 : goto out;
698 : : }
699 : : /* Jumbo Payload option not supported yet. */
700 [ - + ]: 1475 : if (OVS_UNLIKELY(size - plen > UINT8_MAX)) {
701 : 0 : goto out;
702 : : }
703 : 1475 : dp_packet_set_l2_pad_size(packet, size - plen);
704 : 1475 : size = plen; /* Never pull padding. */
705 : :
706 [ + + ]: 2950 : miniflow_push_words(mf, ipv6_src, &nh->ip6_src,
707 : : sizeof nh->ip6_src / 8);
708 [ - + ]: 1475 : miniflow_push_words(mf, ipv6_dst, &nh->ip6_dst,
709 : : sizeof nh->ip6_dst / 8);
710 : :
711 : 1475 : tc_flow = get_16aligned_be32(&nh->ip6_flow);
712 : : {
713 : 1475 : ovs_be32 label = tc_flow & htonl(IPV6_LABEL_MASK);
714 [ - + ]: 1475 : miniflow_push_be32(mf, ipv6_label, label);
715 : : }
716 : :
717 : 1475 : nw_tos = ntohl(tc_flow) >> 20;
718 : 1475 : nw_ttl = nh->ip6_hlim;
719 : 1475 : nw_proto = nh->ip6_nxt;
720 : :
721 [ - + ]: 1475 : if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag)) {
722 : 1475 : goto out;
723 : : }
724 : : } else {
725 [ + + + + ]: 26363 : if (dl_type == htons(ETH_TYPE_ARP) ||
726 : 10687 : dl_type == htons(ETH_TYPE_RARP)) {
727 : : struct eth_addr arp_buf[2];
728 : 5007 : const struct arp_eth_header *arp = (const struct arp_eth_header *)
729 : : data_try_pull(&data, &size, ARP_ETH_HEADER_LEN);
730 : :
731 [ + - ][ + + ]: 5007 : if (OVS_LIKELY(arp) && OVS_LIKELY(arp->ar_hrd == htons(1))
732 [ + - ]: 5004 : && OVS_LIKELY(arp->ar_pro == htons(ETH_TYPE_IP))
733 [ + - ]: 5004 : && OVS_LIKELY(arp->ar_hln == ETH_ADDR_LEN)
734 [ + - ]: 5004 : && OVS_LIKELY(arp->ar_pln == 4)) {
735 [ + + ]: 10008 : miniflow_push_be32(mf, nw_src,
736 : : get_16aligned_be32(&arp->ar_spa));
737 [ + + ]: 10008 : miniflow_push_be32(mf, nw_dst,
738 : : get_16aligned_be32(&arp->ar_tpa));
739 : :
740 : : /* We only match on the lower 8 bits of the opcode. */
741 [ + - ]: 5004 : if (OVS_LIKELY(ntohs(arp->ar_op) <= 0xff)) {
742 [ - + ]: 5004 : miniflow_push_be32(mf, ipv6_label, 0); /* Pad with ARP. */
743 [ - + ]: 5004 : miniflow_push_be32(mf, nw_frag, htonl(ntohs(arp->ar_op)));
744 : : }
745 : :
746 : : /* Must be adjacent. */
747 : : ASSERT_SEQUENTIAL(arp_sha, arp_tha);
748 : :
749 : 5004 : arp_buf[0] = arp->ar_sha;
750 : 5004 : arp_buf[1] = arp->ar_tha;
751 [ - + ]: 5004 : miniflow_push_macs(mf, arp_sha, arp_buf);
752 [ - + ]: 5007 : miniflow_pad_to_64(mf, arp_tha);
753 : : }
754 : : }
755 : 15676 : goto out;
756 : : }
757 : :
758 : 23341 : packet->l4_ofs = (char *)data - l2;
759 [ - + ]: 23341 : miniflow_push_be32(mf, nw_frag,
760 : : BYTES_TO_BE32(nw_frag, nw_tos, nw_ttl, nw_proto));
761 : :
762 [ + + ]: 23341 : if (OVS_LIKELY(!(nw_frag & FLOW_NW_FRAG_LATER))) {
763 [ + + ]: 23029 : if (OVS_LIKELY(nw_proto == IPPROTO_TCP)) {
764 [ + + ]: 3137 : if (OVS_LIKELY(size >= TCP_HEADER_LEN)) {
765 : 3129 : const struct tcp_header *tcp = data;
766 : :
767 [ - + ]: 3129 : miniflow_push_be32(mf, arp_tha.ea[2], 0);
768 [ - + ]: 3129 : miniflow_push_be32(mf, tcp_flags,
769 : : TCP_FLAGS_BE32(tcp->tcp_ctl));
770 [ - + ]: 3129 : miniflow_push_be16(mf, tp_src, tcp->tcp_src);
771 [ - + ]: 3129 : miniflow_push_be16(mf, tp_dst, tcp->tcp_dst);
772 [ - + ]: 3137 : miniflow_pad_to_64(mf, tp_dst);
773 : : }
774 [ + + ]: 19892 : } else if (OVS_LIKELY(nw_proto == IPPROTO_UDP)) {
775 [ + - ]: 14419 : if (OVS_LIKELY(size >= UDP_HEADER_LEN)) {
776 : 14419 : const struct udp_header *udp = data;
777 : :
778 [ - + ]: 14419 : miniflow_push_be16(mf, tp_src, udp->udp_src);
779 [ - + ]: 14419 : miniflow_push_be16(mf, tp_dst, udp->udp_dst);
780 [ - + ]: 14419 : miniflow_pad_to_64(mf, tp_dst);
781 : : }
782 [ + + ]: 5473 : } else if (OVS_LIKELY(nw_proto == IPPROTO_SCTP)) {
783 [ + - ]: 19 : if (OVS_LIKELY(size >= SCTP_HEADER_LEN)) {
784 : 19 : const struct sctp_header *sctp = data;
785 : :
786 [ - + ]: 19 : miniflow_push_be16(mf, tp_src, sctp->sctp_src);
787 [ - + ]: 19 : miniflow_push_be16(mf, tp_dst, sctp->sctp_dst);
788 [ - + ]: 19 : miniflow_pad_to_64(mf, tp_dst);
789 : : }
790 [ + + ]: 5454 : } else if (OVS_LIKELY(nw_proto == IPPROTO_ICMP)) {
791 [ + - ]: 3865 : if (OVS_LIKELY(size >= ICMP_HEADER_LEN)) {
792 : 3865 : const struct icmp_header *icmp = data;
793 : :
794 [ - + ]: 3865 : miniflow_push_be16(mf, tp_src, htons(icmp->icmp_type));
795 [ - + ]: 3865 : miniflow_push_be16(mf, tp_dst, htons(icmp->icmp_code));
796 [ - + ]: 3865 : miniflow_pad_to_64(mf, tp_dst);
797 : : }
798 [ - + ]: 1589 : } else if (OVS_LIKELY(nw_proto == IPPROTO_IGMP)) {
799 [ # # ]: 0 : if (OVS_LIKELY(size >= IGMP_HEADER_LEN)) {
800 : 0 : const struct igmp_header *igmp = data;
801 : :
802 [ # # ]: 0 : miniflow_push_be16(mf, tp_src, htons(igmp->igmp_type));
803 [ # # ]: 0 : miniflow_push_be16(mf, tp_dst, htons(igmp->igmp_code));
804 [ # # ]: 0 : miniflow_push_be32(mf, igmp_group_ip4,
805 : : get_16aligned_be32(&igmp->group));
806 : : }
807 [ + + ]: 1589 : } else if (OVS_LIKELY(nw_proto == IPPROTO_ICMPV6)) {
808 [ + - ]: 1310 : if (OVS_LIKELY(size >= sizeof(struct icmp6_hdr))) {
809 : 1310 : const struct in6_addr *nd_target = NULL;
810 : 1310 : struct eth_addr arp_buf[2] = { { { { 0 } } } };
811 : 1310 : const struct icmp6_hdr *icmp = data_pull(&data, &size,
812 : : sizeof *icmp);
813 : 1310 : parse_icmpv6(&data, &size, icmp, &nd_target, arp_buf);
814 [ + + ]: 1310 : if (nd_target) {
815 [ - + ]: 304 : miniflow_push_words(mf, nd_target, nd_target,
816 : : sizeof *nd_target / sizeof(uint64_t));
817 : : }
818 [ - + ]: 1310 : miniflow_push_macs(mf, arp_sha, arp_buf);
819 [ - + ]: 1310 : miniflow_pad_to_64(mf, arp_tha);
820 [ - + ]: 1310 : miniflow_push_be16(mf, tp_src, htons(icmp->icmp6_type));
821 [ - + ]: 1310 : miniflow_push_be16(mf, tp_dst, htons(icmp->icmp6_code));
822 [ - + ]: 1310 : miniflow_pad_to_64(mf, tp_dst);
823 : : }
824 : : }
825 : : }
826 : : out:
827 : 39044 : dst->map = mf.map;
828 : 39044 : }
829 : :
830 : : ovs_be16
831 : 0 : parse_dl_type(const struct eth_header *data_, size_t size)
832 : : {
833 : 0 : const void *data = data_;
834 : :
835 : : parse_vlan(&data, &size);
836 : :
837 : 0 : return parse_ethertype(&data, &size);
838 : : }
839 : :
840 : : /* For every bit of a field that is wildcarded in 'wildcards', sets the
841 : : * corresponding bit in 'flow' to zero. */
842 : : void
843 : 14501 : flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
844 : : {
845 : 14501 : uint64_t *flow_u64 = (uint64_t *) flow;
846 : 14501 : const uint64_t *wc_u64 = (const uint64_t *) &wildcards->masks;
847 : : size_t i;
848 : :
849 [ + + ]: 1073074 : for (i = 0; i < FLOW_U64S; i++) {
850 : 1058573 : flow_u64[i] &= wc_u64[i];
851 : : }
852 : 14501 : }
853 : :
854 : : void
855 : 1237941 : flow_unwildcard_tp_ports(const struct flow *flow, struct flow_wildcards *wc)
856 : : {
857 [ + + ]: 1237941 : if (flow->nw_proto != IPPROTO_ICMP) {
858 : 1236899 : memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
859 : 1236899 : memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
860 : : } else {
861 : 1042 : wc->masks.tp_src = htons(0xff);
862 : 1042 : wc->masks.tp_dst = htons(0xff);
863 : : }
864 : 1237941 : }
865 : :
866 : : /* Initializes 'flow_metadata' with the metadata found in 'flow'. */
867 : : void
868 : 1051 : flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
869 : : {
870 : : int i;
871 : :
872 : : BUILD_ASSERT_DECL(FLOW_WC_SEQ == 36);
873 : :
874 : 1051 : match_init_catchall(flow_metadata);
875 [ + + ]: 1051 : if (flow->tunnel.tun_id != htonll(0)) {
876 : 15 : match_set_tun_id(flow_metadata, flow->tunnel.tun_id);
877 : : }
878 [ - + ]: 1051 : if (flow->tunnel.flags & FLOW_TNL_PUB_F_MASK) {
879 : 0 : match_set_tun_flags(flow_metadata,
880 : 0 : flow->tunnel.flags & FLOW_TNL_PUB_F_MASK);
881 : : }
882 [ + + ]: 1051 : if (flow->tunnel.ip_src) {
883 : 2 : match_set_tun_src(flow_metadata, flow->tunnel.ip_src);
884 : : }
885 [ + + ]: 1051 : if (flow->tunnel.ip_dst) {
886 : 2 : match_set_tun_dst(flow_metadata, flow->tunnel.ip_dst);
887 : : }
888 [ + + ]: 1051 : if (ipv6_addr_is_set(&flow->tunnel.ipv6_src)) {
889 : 1 : match_set_tun_ipv6_src(flow_metadata, &flow->tunnel.ipv6_src);
890 : : }
891 [ + + ]: 1051 : if (ipv6_addr_is_set(&flow->tunnel.ipv6_dst)) {
892 : 1 : match_set_tun_ipv6_dst(flow_metadata, &flow->tunnel.ipv6_dst);
893 : : }
894 [ - + ]: 1051 : if (flow->tunnel.gbp_id != htons(0)) {
895 : 0 : match_set_tun_gbp_id(flow_metadata, flow->tunnel.gbp_id);
896 : : }
897 [ - + ]: 1051 : if (flow->tunnel.gbp_flags) {
898 : 0 : match_set_tun_gbp_flags(flow_metadata, flow->tunnel.gbp_flags);
899 : : }
900 : 1051 : tun_metadata_get_fmd(&flow->tunnel, flow_metadata);
901 [ + + ]: 1051 : if (flow->metadata != htonll(0)) {
902 : 457 : match_set_metadata(flow_metadata, flow->metadata);
903 : : }
904 : :
905 [ + + ]: 17867 : for (i = 0; i < FLOW_N_REGS; i++) {
906 [ + + ]: 16816 : if (flow->regs[i]) {
907 : 1686 : match_set_reg(flow_metadata, i, flow->regs[i]);
908 : : }
909 : : }
910 : :
911 [ + + ]: 1051 : if (flow->pkt_mark != 0) {
912 : 2 : match_set_pkt_mark(flow_metadata, flow->pkt_mark);
913 : : }
914 : :
915 : 1051 : match_set_in_port(flow_metadata, flow->in_port.ofp_port);
916 [ + + ]: 1051 : if (flow->ct_state != 0) {
917 : 21 : match_set_ct_state(flow_metadata, flow->ct_state);
918 : : }
919 [ + + ]: 1051 : if (flow->ct_zone != 0) {
920 : 1 : match_set_ct_zone(flow_metadata, flow->ct_zone);
921 : : }
922 [ + + ]: 1051 : if (flow->ct_mark != 0) {
923 : 5 : match_set_ct_mark(flow_metadata, flow->ct_mark);
924 : : }
925 [ + + ]: 1051 : if (!ovs_u128_is_zero(flow->ct_label)) {
926 : 2 : match_set_ct_label(flow_metadata, flow->ct_label);
927 : : }
928 : 1051 : }
929 : :
930 : 2423 : const char *ct_state_to_string(uint32_t state)
931 : : {
932 [ + + + + : 2423 : switch (state) {
+ + - -
- ]
933 : : case CS_REPLY_DIR:
934 : 302 : return "rpl";
935 : : case CS_TRACKED:
936 : 575 : return "trk";
937 : : case CS_NEW:
938 : 495 : return "new";
939 : : case CS_ESTABLISHED:
940 : 467 : return "est";
941 : : case CS_RELATED:
942 : 313 : return "rel";
943 : : case CS_INVALID:
944 : 271 : return "inv";
945 : : case CS_SRC_NAT:
946 : 0 : return "snat";
947 : : case CS_DST_NAT:
948 : 0 : return "dnat";
949 : : default:
950 : 0 : return NULL;
951 : : }
952 : : }
953 : :
954 : : char *
955 : 1684 : flow_to_string(const struct flow *flow)
956 : : {
957 : 1684 : struct ds ds = DS_EMPTY_INITIALIZER;
958 : 1684 : flow_format(&ds, flow);
959 : 1684 : return ds_cstr(&ds);
960 : : }
961 : :
962 : : const char *
963 : 1603 : flow_tun_flag_to_string(uint32_t flags)
964 : : {
965 [ + + + + : 1603 : switch (flags) {
- ]
966 : : case FLOW_TNL_F_DONT_FRAGMENT:
967 : 369 : return "df";
968 : : case FLOW_TNL_F_CSUM:
969 : 438 : return "csum";
970 : : case FLOW_TNL_F_KEY:
971 : 503 : return "key";
972 : : case FLOW_TNL_F_OAM:
973 : 293 : return "oam";
974 : : default:
975 : 0 : return NULL;
976 : : }
977 : : }
978 : :
979 : : void
980 : 1950 : format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t),
981 : : uint32_t flags, char del)
982 : : {
983 : 1950 : uint32_t bad = 0;
984 : :
985 [ + + ]: 1950 : if (!flags) {
986 : 630 : ds_put_char(ds, '0');
987 : 630 : return;
988 : : }
989 [ + + ]: 2940 : while (flags) {
990 : 1620 : uint32_t bit = rightmost_1bit(flags);
991 : : const char *s;
992 : :
993 : 1620 : s = bit_to_string(bit);
994 [ + - ]: 1620 : if (s) {
995 : 1620 : ds_put_format(ds, "%s%c", s, del);
996 : : } else {
997 : 0 : bad |= bit;
998 : : }
999 : :
1000 : 1620 : flags &= ~bit;
1001 : : }
1002 : :
1003 [ - + ]: 1320 : if (bad) {
1004 : 0 : ds_put_format(ds, "0x%"PRIx32"%c", bad, del);
1005 : : }
1006 : 1320 : ds_chomp(ds, del);
1007 : : }
1008 : :
1009 : : void
1010 : 2216 : format_flags_masked(struct ds *ds, const char *name,
1011 : : const char *(*bit_to_string)(uint32_t), uint32_t flags,
1012 : : uint32_t mask, uint32_t max_mask)
1013 : : {
1014 [ + + ]: 2216 : if (name) {
1015 : 1318 : ds_put_format(ds, "%s%s=%s", colors.param, name, colors.end);
1016 : : }
1017 : :
1018 [ + + ]: 2216 : if (mask == max_mask) {
1019 : 964 : format_flags(ds, bit_to_string, flags, '|');
1020 : 964 : return;
1021 : : }
1022 : :
1023 [ + + ]: 1252 : if (!mask) {
1024 : 2 : ds_put_cstr(ds, "0/0");
1025 : 2 : return;
1026 : : }
1027 : :
1028 [ + + ]: 8420 : while (mask) {
1029 : 7170 : uint32_t bit = rightmost_1bit(mask);
1030 : 7170 : const char *s = bit_to_string(bit);
1031 : :
1032 [ + - ][ + + ]: 7170 : ds_put_format(ds, "%s%s", (flags & bit) ? "+" : "-",
1033 : : s ? s : "[Unknown]");
1034 : 7170 : mask &= ~bit;
1035 : : }
1036 : : }
1037 : :
1038 : : /* Scans a string 's' of flags to determine their numerical value and
1039 : : * returns the number of characters parsed using 'bit_to_string' to
1040 : : * lookup flag names. Scanning continues until the character 'end' is
1041 : : * reached.
1042 : : *
1043 : : * In the event of a failure, a negative error code will be returned. In
1044 : : * addition, if 'res_string' is non-NULL then a descriptive string will
1045 : : * be returned incorporating the identifying string 'field_name'. This
1046 : : * error string must be freed by the caller.
1047 : : *
1048 : : * Upon success, the flag values will be stored in 'res_flags' and
1049 : : * optionally 'res_mask', if it is non-NULL (if it is NULL then any masks
1050 : : * present in the original string will be considered an error). The
1051 : : * caller may restrict the acceptable set of values through the mask
1052 : : * 'allowed'. */
1053 : : int
1054 : 792 : parse_flags(const char *s, const char *(*bit_to_string)(uint32_t),
1055 : : char end, const char *field_name, char **res_string,
1056 : : uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask)
1057 : : {
1058 : 792 : uint32_t result = 0;
1059 : : int n;
1060 : :
1061 : : /* Parse masked flags in numeric format? */
1062 [ + + ][ + + ]: 792 : if (res_mask && ovs_scan(s, "%"SCNi32"/%"SCNi32"%n",
1063 [ + - ]: 2 : res_flags, res_mask, &n) && n > 0) {
1064 [ + - ][ + - ]: 2 : if (*res_flags & ~allowed || *res_mask & ~allowed) {
1065 : : goto unknown;
1066 : : }
1067 : 2 : return n;
1068 : : }
1069 : :
1070 : 790 : n = 0;
1071 : :
1072 [ + + ][ + + ]: 790 : if (res_mask && (*s == '+' || *s == '-')) {
[ + + ]
1073 : 306 : uint32_t flags = 0, mask = 0;
1074 : :
1075 : : /* Parse masked flags. */
1076 [ + + ]: 766 : while (s[0] != end) {
1077 : : bool set;
1078 : : uint32_t bit;
1079 : : size_t len;
1080 : :
1081 [ + + ]: 461 : if (s[0] == '+') {
1082 : 319 : set = true;
1083 [ + - ]: 142 : } else if (s[0] == '-') {
1084 : 142 : set = false;
1085 : : } else {
1086 [ # # ]: 0 : if (res_string) {
1087 : 0 : *res_string = xasprintf("%s: %s must be preceded by '+' "
1088 : : "(for SET) or '-' (NOT SET)", s,
1089 : : field_name);
1090 : : }
1091 : 0 : return -EINVAL;
1092 : : }
1093 : 461 : s++;
1094 : 461 : n++;
1095 : :
1096 [ + - ]: 1962 : for (bit = 1; bit; bit <<= 1) {
1097 : 1962 : const char *fname = bit_to_string(bit);
1098 : :
1099 [ - + ]: 1962 : if (!fname) {
1100 : 0 : continue;
1101 : : }
1102 : :
1103 : 1962 : len = strlen(fname);
1104 [ + + ][ + + ]: 1962 : if (strncmp(s, fname, len) ||
1105 [ + + ][ - + ]: 336 : (s[len] != '+' && s[len] != '-' && s[len] != end)) {
1106 : 1501 : continue;
1107 : : }
1108 : :
1109 [ + + ]: 461 : if (mask & bit) {
1110 : : /* bit already set. */
1111 [ + - ]: 1 : if (res_string) {
1112 : 1 : *res_string = xasprintf("%s: Each %s flag can be "
1113 : : "specified only once", s,
1114 : : field_name);
1115 : : }
1116 : 1 : return -EINVAL;
1117 : : }
1118 [ - + ]: 460 : if (!(bit & allowed)) {
1119 : 0 : goto unknown;
1120 : : }
1121 [ + + ]: 460 : if (set) {
1122 : 319 : flags |= bit;
1123 : : }
1124 : 460 : mask |= bit;
1125 : 460 : break;
1126 : : }
1127 : :
1128 [ - + ]: 460 : if (!bit) {
1129 : 0 : goto unknown;
1130 : : }
1131 : 460 : s += len;
1132 : 460 : n += len;
1133 : : }
1134 : :
1135 : 305 : *res_flags = flags;
1136 : 305 : *res_mask = mask;
1137 : 305 : return n;
1138 : : }
1139 : :
1140 : : /* Parse unmasked flags. If a flag is present, it is set, otherwise
1141 : : * it is not set. */
1142 [ + + ]: 1040 : while (s[n] != end) {
1143 : : unsigned long long int flags;
1144 : : uint32_t bit;
1145 : : int n0;
1146 : :
1147 [ + + ]: 559 : if (ovs_scan(&s[n], "%lli%n", &flags, &n0)) {
1148 [ - + ]: 67 : if (flags & ~allowed) {
1149 : 3 : goto unknown;
1150 : : }
1151 : 67 : n += n0 + (s[n + n0] == '|');
1152 : 67 : result |= flags;
1153 : 67 : continue;
1154 : : }
1155 : :
1156 [ + + ]: 2180 : for (bit = 1; bit; bit <<= 1) {
1157 : 2177 : const char *name = bit_to_string(bit);
1158 : : size_t len;
1159 : :
1160 [ + + ]: 2177 : if (!name) {
1161 : 60 : continue;
1162 : : }
1163 : :
1164 : 2117 : len = strlen(name);
1165 [ + + ][ + + ]: 2117 : if (!strncmp(s + n, name, len) &&
1166 [ + + ]: 407 : (s[n + len] == '|' || s[n + len] == end)) {
1167 [ - + ]: 489 : if (!(bit & allowed)) {
1168 : 0 : goto unknown;
1169 : : }
1170 : 489 : result |= bit;
1171 : 489 : n += len + (s[n + len] == '|');
1172 : 489 : break;
1173 : : }
1174 : : }
1175 : :
1176 [ + + ]: 492 : if (!bit) {
1177 : 492 : goto unknown;
1178 : : }
1179 : : }
1180 : :
1181 : 481 : *res_flags = result;
1182 [ + + ]: 481 : if (res_mask) {
1183 : 477 : *res_mask = UINT32_MAX;
1184 : : }
1185 [ + + ]: 481 : if (res_string) {
1186 : 1 : *res_string = NULL;
1187 : : }
1188 : 481 : return n;
1189 : :
1190 : : unknown:
1191 [ - + ]: 3 : if (res_string) {
1192 : 0 : *res_string = xasprintf("%s: unknown %s flag(s)", s, field_name);
1193 : : }
1194 : 792 : return -EINVAL;
1195 : : }
1196 : :
1197 : : void
1198 : 6478 : flow_format(struct ds *ds, const struct flow *flow)
1199 : : {
1200 : : struct match match;
1201 : 6478 : struct flow_wildcards *wc = &match.wc;
1202 : :
1203 : 6478 : match_wc_init(&match, flow);
1204 : :
1205 : : /* As this function is most often used for formatting a packet in a
1206 : : * packet-in message, skip formatting the packet context fields that are
1207 : : * all-zeroes to make the print-out easier on the eyes. This means that a
1208 : : * missing context field implies a zero value for that field. This is
1209 : : * similar to OpenFlow encoding of these fields, as the specification
1210 : : * states that all-zeroes context fields should not be encoded in the
1211 : : * packet-in messages. */
1212 [ + + ]: 6478 : if (!flow->in_port.ofp_port) {
1213 : 3740 : WC_UNMASK_FIELD(wc, in_port);
1214 : : }
1215 [ + + ]: 6478 : if (!flow->skb_priority) {
1216 : 6475 : WC_UNMASK_FIELD(wc, skb_priority);
1217 : : }
1218 [ + + ]: 6478 : if (!flow->pkt_mark) {
1219 : 6471 : WC_UNMASK_FIELD(wc, pkt_mark);
1220 : : }
1221 [ + + ]: 6478 : if (!flow->recirc_id) {
1222 : 6466 : WC_UNMASK_FIELD(wc, recirc_id);
1223 : : }
1224 [ + - ]: 6478 : if (!flow->dp_hash) {
1225 : 6478 : WC_UNMASK_FIELD(wc, dp_hash);
1226 : : }
1227 [ + - ]: 6478 : if (!flow->ct_state) {
1228 : 6478 : WC_UNMASK_FIELD(wc, ct_state);
1229 : : }
1230 [ + - ]: 6478 : if (!flow->ct_zone) {
1231 : 6478 : WC_UNMASK_FIELD(wc, ct_zone);
1232 : : }
1233 [ + - ]: 6478 : if (!flow->ct_mark) {
1234 : 6478 : WC_UNMASK_FIELD(wc, ct_mark);
1235 : : }
1236 [ + - ]: 6478 : if (ovs_u128_is_zero(flow->ct_label)) {
1237 : 6478 : WC_UNMASK_FIELD(wc, ct_label);
1238 : : }
1239 [ + + ]: 110126 : for (int i = 0; i < FLOW_N_REGS; i++) {
1240 [ + + ]: 103648 : if (!flow->regs[i]) {
1241 : 103482 : WC_UNMASK_FIELD(wc, regs[i]);
1242 : : }
1243 : : }
1244 [ + + ]: 6478 : if (!flow->metadata) {
1245 : 6447 : WC_UNMASK_FIELD(wc, metadata);
1246 : : }
1247 : :
1248 : 6478 : match_format(&match, ds, OFP_DEFAULT_PRIORITY);
1249 : 6478 : }
1250 : :
1251 : : void
1252 : 1583 : flow_print(FILE *stream, const struct flow *flow)
1253 : : {
1254 : 1583 : char *s = flow_to_string(flow);
1255 : 1583 : fputs(s, stream);
1256 : 1583 : free(s);
1257 : 1583 : }
1258 : :
1259 : : /* flow_wildcards functions. */
1260 : :
1261 : : /* Initializes 'wc' as a set of wildcards that matches every packet. */
1262 : : void
1263 : 31090762 : flow_wildcards_init_catchall(struct flow_wildcards *wc)
1264 : : {
1265 : 31090762 : memset(&wc->masks, 0, sizeof wc->masks);
1266 : 31090762 : }
1267 : :
1268 : : /* Converts a flow into flow wildcards. It sets the wildcard masks based on
1269 : : * the packet headers extracted to 'flow'. It will not set the mask for fields
1270 : : * that do not make sense for the packet type. OpenFlow-only metadata is
1271 : : * wildcarded, but other metadata is unconditionally exact-matched. */
1272 : 12466 : void flow_wildcards_init_for_packet(struct flow_wildcards *wc,
1273 : : const struct flow *flow)
1274 : : {
1275 : 12466 : memset(&wc->masks, 0x0, sizeof wc->masks);
1276 : :
1277 : : /* Update this function whenever struct flow changes. */
1278 : : BUILD_ASSERT_DECL(FLOW_WC_SEQ == 36);
1279 : :
1280 [ + + ]: 12466 : if (flow_tnl_dst_is_set(&flow->tunnel)) {
1281 [ + + ]: 143 : if (flow->tunnel.flags & FLOW_TNL_F_KEY) {
1282 : 123 : WC_MASK_FIELD(wc, tunnel.tun_id);
1283 : : }
1284 : 143 : WC_MASK_FIELD(wc, tunnel.ip_src);
1285 : 143 : WC_MASK_FIELD(wc, tunnel.ip_dst);
1286 : 143 : WC_MASK_FIELD(wc, tunnel.ipv6_src);
1287 : 143 : WC_MASK_FIELD(wc, tunnel.ipv6_dst);
1288 : 143 : WC_MASK_FIELD(wc, tunnel.flags);
1289 : 143 : WC_MASK_FIELD(wc, tunnel.ip_tos);
1290 : 143 : WC_MASK_FIELD(wc, tunnel.ip_ttl);
1291 : 143 : WC_MASK_FIELD(wc, tunnel.tp_src);
1292 : 143 : WC_MASK_FIELD(wc, tunnel.tp_dst);
1293 : 143 : WC_MASK_FIELD(wc, tunnel.gbp_id);
1294 : 143 : WC_MASK_FIELD(wc, tunnel.gbp_flags);
1295 : :
1296 [ + - ]: 143 : if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) {
1297 [ + + ]: 143 : if (flow->tunnel.metadata.present.map) {
1298 : 99 : wc->masks.tunnel.metadata.present.map =
1299 : 99 : flow->tunnel.metadata.present.map;
1300 : 143 : WC_MASK_FIELD(wc, tunnel.metadata.opts.u8);
1301 : : }
1302 : : } else {
1303 : 0 : WC_MASK_FIELD(wc, tunnel.metadata.present.len);
1304 : 143 : memset(wc->masks.tunnel.metadata.opts.gnv, 0xff,
1305 : 0 : flow->tunnel.metadata.present.len);
1306 : : }
1307 [ + + ]: 12323 : } else if (flow->tunnel.tun_id) {
1308 : 4 : WC_MASK_FIELD(wc, tunnel.tun_id);
1309 : : }
1310 : :
1311 : : /* metadata, regs, and conj_id wildcarded. */
1312 : :
1313 : 12466 : WC_MASK_FIELD(wc, skb_priority);
1314 : 12466 : WC_MASK_FIELD(wc, pkt_mark);
1315 : 12466 : WC_MASK_FIELD(wc, ct_state);
1316 : 12466 : WC_MASK_FIELD(wc, ct_zone);
1317 : 12466 : WC_MASK_FIELD(wc, ct_mark);
1318 : 12466 : WC_MASK_FIELD(wc, ct_label);
1319 : 12466 : WC_MASK_FIELD(wc, recirc_id);
1320 : 12466 : WC_MASK_FIELD(wc, dp_hash);
1321 : 12466 : WC_MASK_FIELD(wc, in_port);
1322 : :
1323 : : /* actset_output wildcarded. */
1324 : :
1325 : 12466 : WC_MASK_FIELD(wc, dl_dst);
1326 : 12466 : WC_MASK_FIELD(wc, dl_src);
1327 : 12466 : WC_MASK_FIELD(wc, dl_type);
1328 : 12466 : WC_MASK_FIELD(wc, vlan_tci);
1329 : :
1330 [ + + ]: 12466 : if (flow->dl_type == htons(ETH_TYPE_IP)) {
1331 : 5074 : WC_MASK_FIELD(wc, nw_src);
1332 : 5074 : WC_MASK_FIELD(wc, nw_dst);
1333 [ + + ]: 7392 : } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
1334 : 55 : WC_MASK_FIELD(wc, ipv6_src);
1335 : 55 : WC_MASK_FIELD(wc, ipv6_dst);
1336 : 55 : WC_MASK_FIELD(wc, ipv6_label);
1337 [ + + + + ]: 12912 : } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
1338 : 5575 : flow->dl_type == htons(ETH_TYPE_RARP)) {
1339 : 1774 : WC_MASK_FIELD(wc, nw_src);
1340 : 1774 : WC_MASK_FIELD(wc, nw_dst);
1341 : 1774 : WC_MASK_FIELD(wc, nw_proto);
1342 : 1774 : WC_MASK_FIELD(wc, arp_sha);
1343 : 1774 : WC_MASK_FIELD(wc, arp_tha);
1344 : 1774 : return;
1345 [ + + ]: 5563 : } else if (eth_type_mpls(flow->dl_type)) {
1346 [ + - ]: 3564 : for (int i = 0; i < FLOW_MAX_MPLS_LABELS; i++) {
1347 : 3564 : WC_MASK_FIELD(wc, mpls_lse[i]);
1348 [ + + ]: 3564 : if (flow->mpls_lse[i] & htonl(MPLS_BOS_MASK)) {
1349 : 1881 : break;
1350 : : }
1351 : : }
1352 : 1881 : return;
1353 : : } else {
1354 : 3682 : return; /* Unknown ethertype. */
1355 : : }
1356 : :
1357 : : /* IPv4 or IPv6. */
1358 : 5129 : WC_MASK_FIELD(wc, nw_frag);
1359 : 5129 : WC_MASK_FIELD(wc, nw_tos);
1360 : 5129 : WC_MASK_FIELD(wc, nw_ttl);
1361 : 5129 : WC_MASK_FIELD(wc, nw_proto);
1362 : :
1363 : : /* No transport layer header in later fragments. */
1364 [ + + ][ + + ]: 5129 : if (!(flow->nw_frag & FLOW_NW_FRAG_LATER) &&
1365 [ + + ]: 2326 : (flow->nw_proto == IPPROTO_ICMP ||
1366 [ + + ]: 2298 : flow->nw_proto == IPPROTO_ICMPV6 ||
1367 [ + + ]: 707 : flow->nw_proto == IPPROTO_TCP ||
1368 [ + + ]: 201 : flow->nw_proto == IPPROTO_UDP ||
1369 [ - + ]: 183 : flow->nw_proto == IPPROTO_SCTP ||
1370 : 183 : flow->nw_proto == IPPROTO_IGMP)) {
1371 : 4817 : WC_MASK_FIELD(wc, tp_src);
1372 : 4817 : WC_MASK_FIELD(wc, tp_dst);
1373 : :
1374 [ + + ]: 4817 : if (flow->nw_proto == IPPROTO_TCP) {
1375 : 1591 : WC_MASK_FIELD(wc, tcp_flags);
1376 [ + + ]: 3226 : } else if (flow->nw_proto == IPPROTO_ICMPV6) {
1377 : 28 : WC_MASK_FIELD(wc, arp_sha);
1378 : 28 : WC_MASK_FIELD(wc, arp_tha);
1379 : 28 : WC_MASK_FIELD(wc, nd_target);
1380 [ - + ]: 3198 : } else if (flow->nw_proto == IPPROTO_IGMP) {
1381 : 0 : WC_MASK_FIELD(wc, igmp_group_ip4);
1382 : : }
1383 : : }
1384 : : }
1385 : :
1386 : : /* Return a map of possible fields for a packet of the same type as 'flow'.
1387 : : * Including extra bits in the returned mask is not wrong, it is just less
1388 : : * optimal.
1389 : : *
1390 : : * This is a less precise version of flow_wildcards_init_for_packet() above. */
1391 : : void
1392 : 10331 : flow_wc_map(const struct flow *flow, struct flowmap *map)
1393 : : {
1394 : : /* Update this function whenever struct flow changes. */
1395 : : BUILD_ASSERT_DECL(FLOW_WC_SEQ == 36);
1396 : :
1397 : 10331 : flowmap_init(map);
1398 : :
1399 [ + + ]: 10331 : if (flow_tnl_dst_is_set(&flow->tunnel)) {
1400 : 832 : FLOWMAP_SET__(map, tunnel, offsetof(struct flow_tnl, metadata));
1401 [ + + ]: 832 : if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) {
1402 [ - + ]: 34 : if (flow->tunnel.metadata.present.map) {
1403 : 34 : FLOWMAP_SET(map, tunnel.metadata);
1404 : : }
1405 : : } else {
1406 : 798 : FLOWMAP_SET(map, tunnel.metadata.present.len);
1407 : 798 : FLOWMAP_SET__(map, tunnel.metadata.opts.gnv,
1408 : : flow->tunnel.metadata.present.len);
1409 : : }
1410 : : }
1411 : :
1412 : : /* Metadata fields that can appear on packet input. */
1413 : 10331 : FLOWMAP_SET(map, skb_priority);
1414 : 10331 : FLOWMAP_SET(map, pkt_mark);
1415 : 10331 : FLOWMAP_SET(map, recirc_id);
1416 : 10331 : FLOWMAP_SET(map, dp_hash);
1417 : 10331 : FLOWMAP_SET(map, in_port);
1418 : 10331 : FLOWMAP_SET(map, dl_dst);
1419 : 10331 : FLOWMAP_SET(map, dl_src);
1420 : 10331 : FLOWMAP_SET(map, dl_type);
1421 : 10331 : FLOWMAP_SET(map, vlan_tci);
1422 : 10331 : FLOWMAP_SET(map, ct_state);
1423 : 10331 : FLOWMAP_SET(map, ct_zone);
1424 : 10331 : FLOWMAP_SET(map, ct_mark);
1425 : 10331 : FLOWMAP_SET(map, ct_label);
1426 : :
1427 : : /* Ethertype-dependent fields. */
1428 [ + + ]: 10331 : if (OVS_LIKELY(flow->dl_type == htons(ETH_TYPE_IP))) {
1429 : 3347 : FLOWMAP_SET(map, nw_src);
1430 : 3347 : FLOWMAP_SET(map, nw_dst);
1431 : 3347 : FLOWMAP_SET(map, nw_proto);
1432 : 3347 : FLOWMAP_SET(map, nw_frag);
1433 : 3347 : FLOWMAP_SET(map, nw_tos);
1434 : 3347 : FLOWMAP_SET(map, nw_ttl);
1435 : 3347 : FLOWMAP_SET(map, tp_src);
1436 : 3347 : FLOWMAP_SET(map, tp_dst);
1437 : :
1438 [ - + ]: 3347 : if (OVS_UNLIKELY(flow->nw_proto == IPPROTO_IGMP)) {
1439 : 0 : FLOWMAP_SET(map, igmp_group_ip4);
1440 : : } else {
1441 : 3347 : FLOWMAP_SET(map, tcp_flags);
1442 : : }
1443 [ + + ]: 6984 : } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
1444 : 313 : FLOWMAP_SET(map, ipv6_src);
1445 : 313 : FLOWMAP_SET(map, ipv6_dst);
1446 : 313 : FLOWMAP_SET(map, ipv6_label);
1447 : 313 : FLOWMAP_SET(map, nw_proto);
1448 : 313 : FLOWMAP_SET(map, nw_frag);
1449 : 313 : FLOWMAP_SET(map, nw_tos);
1450 : 313 : FLOWMAP_SET(map, nw_ttl);
1451 : 313 : FLOWMAP_SET(map, tp_src);
1452 : 313 : FLOWMAP_SET(map, tp_dst);
1453 : :
1454 [ + + ]: 313 : if (OVS_UNLIKELY(flow->nw_proto == IPPROTO_ICMPV6)) {
1455 : 290 : FLOWMAP_SET(map, nd_target);
1456 : 290 : FLOWMAP_SET(map, arp_sha);
1457 : 290 : FLOWMAP_SET(map, arp_tha);
1458 : : } else {
1459 : 313 : FLOWMAP_SET(map, tcp_flags);
1460 : : }
1461 [ + + ]: 6671 : } else if (eth_type_mpls(flow->dl_type)) {
1462 : 1694 : FLOWMAP_SET(map, mpls_lse);
1463 [ + + + + ]: 9267 : } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
1464 : 4290 : flow->dl_type == htons(ETH_TYPE_RARP)) {
1465 : 691 : FLOWMAP_SET(map, nw_src);
1466 : 691 : FLOWMAP_SET(map, nw_dst);
1467 : 691 : FLOWMAP_SET(map, nw_proto);
1468 : 691 : FLOWMAP_SET(map, arp_sha);
1469 : 691 : FLOWMAP_SET(map, arp_tha);
1470 : : }
1471 : 10331 : }
1472 : :
1473 : : /* Clear the metadata and register wildcard masks. They are not packet
1474 : : * header fields. */
1475 : : void
1476 : 84625 : flow_wildcards_clear_non_packet_fields(struct flow_wildcards *wc)
1477 : : {
1478 : : /* Update this function whenever struct flow changes. */
1479 : : BUILD_ASSERT_DECL(FLOW_WC_SEQ == 36);
1480 : :
1481 : 84625 : memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
1482 : 84625 : memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
1483 : 84625 : wc->masks.actset_output = 0;
1484 : 84625 : wc->masks.conj_id = 0;
1485 : 84625 : }
1486 : :
1487 : : /* Returns true if 'wc' matches every packet, false if 'wc' fixes any bits or
1488 : : * fields. */
1489 : : bool
1490 : 26612 : flow_wildcards_is_catchall(const struct flow_wildcards *wc)
1491 : : {
1492 : 26612 : const uint64_t *wc_u64 = (const uint64_t *) &wc->masks;
1493 : : size_t i;
1494 : :
1495 [ + - ]: 26612 : for (i = 0; i < FLOW_U64S; i++) {
1496 [ + - ]: 26612 : if (wc_u64[i]) {
1497 : 26612 : return false;
1498 : : }
1499 : : }
1500 : 0 : return true;
1501 : : }
1502 : :
1503 : : /* Sets 'dst' as the bitwise AND of wildcards in 'src1' and 'src2'.
1504 : : * That is, a bit or a field is wildcarded in 'dst' if it is wildcarded
1505 : : * in 'src1' or 'src2' or both. */
1506 : : void
1507 : 13306 : flow_wildcards_and(struct flow_wildcards *dst,
1508 : : const struct flow_wildcards *src1,
1509 : : const struct flow_wildcards *src2)
1510 : : {
1511 : 13306 : uint64_t *dst_u64 = (uint64_t *) &dst->masks;
1512 : 13306 : const uint64_t *src1_u64 = (const uint64_t *) &src1->masks;
1513 : 13306 : const uint64_t *src2_u64 = (const uint64_t *) &src2->masks;
1514 : : size_t i;
1515 : :
1516 [ + + ]: 984644 : for (i = 0; i < FLOW_U64S; i++) {
1517 : 971338 : dst_u64[i] = src1_u64[i] & src2_u64[i];
1518 : : }
1519 : 13306 : }
1520 : :
1521 : : /* Sets 'dst' as the bitwise OR of wildcards in 'src1' and 'src2'. That
1522 : : * is, a bit or a field is wildcarded in 'dst' if it is neither
1523 : : * wildcarded in 'src1' nor 'src2'. */
1524 : : void
1525 : 0 : flow_wildcards_or(struct flow_wildcards *dst,
1526 : : const struct flow_wildcards *src1,
1527 : : const struct flow_wildcards *src2)
1528 : : {
1529 : 0 : uint64_t *dst_u64 = (uint64_t *) &dst->masks;
1530 : 0 : const uint64_t *src1_u64 = (const uint64_t *) &src1->masks;
1531 : 0 : const uint64_t *src2_u64 = (const uint64_t *) &src2->masks;
1532 : : size_t i;
1533 : :
1534 [ # # ]: 0 : for (i = 0; i < FLOW_U64S; i++) {
1535 : 0 : dst_u64[i] = src1_u64[i] | src2_u64[i];
1536 : : }
1537 : 0 : }
1538 : :
1539 : : /* Returns a hash of the wildcards in 'wc'. */
1540 : : uint32_t
1541 : 2185334 : flow_wildcards_hash(const struct flow_wildcards *wc, uint32_t basis)
1542 : : {
1543 : 2185334 : return flow_hash(&wc->masks, basis);
1544 : : }
1545 : :
1546 : : /* Returns true if 'a' and 'b' represent the same wildcards, false if they are
1547 : : * different. */
1548 : : bool
1549 : 1055560 : flow_wildcards_equal(const struct flow_wildcards *a,
1550 : : const struct flow_wildcards *b)
1551 : : {
1552 : 1055560 : return flow_equal(&a->masks, &b->masks);
1553 : : }
1554 : :
1555 : : /* Returns true if at least one bit or field is wildcarded in 'a' but not in
1556 : : * 'b', false otherwise. */
1557 : : bool
1558 : 67741 : flow_wildcards_has_extra(const struct flow_wildcards *a,
1559 : : const struct flow_wildcards *b)
1560 : : {
1561 : 67741 : const uint64_t *a_u64 = (const uint64_t *) &a->masks;
1562 : 67741 : const uint64_t *b_u64 = (const uint64_t *) &b->masks;
1563 : : size_t i;
1564 : :
1565 [ + + ]: 4984435 : for (i = 0; i < FLOW_U64S; i++) {
1566 [ + + ]: 4917284 : if ((a_u64[i] & b_u64[i]) != b_u64[i]) {
1567 : 590 : return true;
1568 : : }
1569 : : }
1570 : 67151 : return false;
1571 : : }
1572 : :
1573 : : /* Returns true if 'a' and 'b' are equal, except that 0-bits (wildcarded bits)
1574 : : * in 'wc' do not need to be equal in 'a' and 'b'. */
1575 : : bool
1576 : 0 : flow_equal_except(const struct flow *a, const struct flow *b,
1577 : : const struct flow_wildcards *wc)
1578 : : {
1579 : 0 : const uint64_t *a_u64 = (const uint64_t *) a;
1580 : 0 : const uint64_t *b_u64 = (const uint64_t *) b;
1581 : 0 : const uint64_t *wc_u64 = (const uint64_t *) &wc->masks;
1582 : : size_t i;
1583 : :
1584 [ # # ]: 0 : for (i = 0; i < FLOW_U64S; i++) {
1585 [ # # ]: 0 : if ((a_u64[i] ^ b_u64[i]) & wc_u64[i]) {
1586 : 0 : return false;
1587 : : }
1588 : : }
1589 : 0 : return true;
1590 : : }
1591 : :
1592 : : /* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'.
1593 : : * (A 0-bit indicates a wildcard bit.) */
1594 : : void
1595 : 1332918 : flow_wildcards_set_reg_mask(struct flow_wildcards *wc, int idx, uint32_t mask)
1596 : : {
1597 : 1332918 : wc->masks.regs[idx] = mask;
1598 : 1332918 : }
1599 : :
1600 : : /* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'.
1601 : : * (A 0-bit indicates a wildcard bit.) */
1602 : : void
1603 : 66 : flow_wildcards_set_xreg_mask(struct flow_wildcards *wc, int idx, uint64_t mask)
1604 : : {
1605 : 66 : flow_set_xreg(&wc->masks, idx, mask);
1606 : 66 : }
1607 : :
1608 : : /* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'.
1609 : : * (A 0-bit indicates a wildcard bit.) */
1610 : : void
1611 : 146375 : flow_wildcards_set_xxreg_mask(struct flow_wildcards *wc, int idx,
1612 : : ovs_u128 mask)
1613 : : {
1614 : 146375 : flow_set_xxreg(&wc->masks, idx, mask);
1615 : 146375 : }
1616 : :
1617 : : /* Calculates the 5-tuple hash from the given miniflow.
1618 : : * This returns the same value as flow_hash_5tuple for the corresponding
1619 : : * flow. */
1620 : : uint32_t
1621 : 10033 : miniflow_hash_5tuple(const struct miniflow *flow, uint32_t basis)
1622 : : {
1623 : : BUILD_ASSERT_DECL(FLOW_WC_SEQ == 36);
1624 : 10033 : uint32_t hash = basis;
1625 : :
1626 [ + - ]: 10033 : if (flow) {
1627 [ + - ]: 10033 : ovs_be16 dl_type = MINIFLOW_GET_BE16(flow, dl_type);
1628 : : uint8_t nw_proto;
1629 : :
1630 [ + + ]: 10033 : if (dl_type == htons(ETH_TYPE_IPV6)) {
1631 : 712 : struct flowmap map = FLOWMAP_EMPTY_INITIALIZER;
1632 : : uint64_t value;
1633 : :
1634 : 712 : FLOWMAP_SET(&map, ipv6_src);
1635 : 712 : FLOWMAP_SET(&map, ipv6_dst);
1636 : :
1637 [ + + ]: 3560 : MINIFLOW_FOR_EACH_IN_FLOWMAP(value, flow, map) {
1638 : 2848 : hash = hash_add64(hash, value);
1639 : : }
1640 [ + + ]: 9321 : } else if (dl_type == htons(ETH_TYPE_IP)
1641 [ + + ]: 1635 : || dl_type == htons(ETH_TYPE_ARP)) {
1642 [ + + ]: 8314 : hash = hash_add(hash, MINIFLOW_GET_U32(flow, nw_src));
1643 [ + + ]: 8314 : hash = hash_add(hash, MINIFLOW_GET_U32(flow, nw_dst));
1644 : : } else {
1645 : : goto out;
1646 : : }
1647 : :
1648 [ + + ]: 9026 : nw_proto = MINIFLOW_GET_U8(flow, nw_proto);
1649 : 9026 : hash = hash_add(hash, nw_proto);
1650 [ + + ][ + + ]: 9026 : if (nw_proto != IPPROTO_TCP && nw_proto != IPPROTO_UDP
1651 [ + + ][ + + ]: 2247 : && nw_proto != IPPROTO_SCTP && nw_proto != IPPROTO_ICMP
1652 [ + + ]: 1068 : && nw_proto != IPPROTO_ICMPV6) {
1653 : 435 : goto out;
1654 : : }
1655 : :
1656 : : /* Add both ports at once. */
1657 [ + + ]: 8591 : hash = hash_add(hash, MINIFLOW_GET_U32(flow, tp_src));
1658 : : }
1659 : : out:
1660 : 10033 : return hash_finish(hash, 42);
1661 : : }
1662 : :
1663 : : ASSERT_SEQUENTIAL_SAME_WORD(tp_src, tp_dst);
1664 : : ASSERT_SEQUENTIAL(ipv6_src, ipv6_dst);
1665 : :
1666 : : /* Calculates the 5-tuple hash from the given flow. */
1667 : : uint32_t
1668 : 30540 : flow_hash_5tuple(const struct flow *flow, uint32_t basis)
1669 : : {
1670 : : BUILD_ASSERT_DECL(FLOW_WC_SEQ == 36);
1671 : 30540 : uint32_t hash = basis;
1672 : :
1673 [ + - ]: 30540 : if (flow) {
1674 : :
1675 [ + + ]: 30540 : if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
1676 : 185 : const uint64_t *flow_u64 = (const uint64_t *)flow;
1677 : 185 : int ofs = offsetof(struct flow, ipv6_src) / 8;
1678 : 185 : int end = ofs + 2 * sizeof flow->ipv6_src / 8;
1679 : :
1680 [ + + ]: 925 : for (;ofs < end; ofs++) {
1681 : 740 : hash = hash_add64(hash, flow_u64[ofs]);
1682 : : }
1683 [ + + ]: 30355 : } else if (flow->dl_type == htons(ETH_TYPE_IP)
1684 [ + + ]: 27472 : || flow->dl_type == htons(ETH_TYPE_ARP)) {
1685 : 28199 : hash = hash_add(hash, (OVS_FORCE uint32_t) flow->nw_src);
1686 : 28199 : hash = hash_add(hash, (OVS_FORCE uint32_t) flow->nw_dst);
1687 : : } else {
1688 : : goto out;
1689 : : }
1690 : :
1691 : 28384 : hash = hash_add(hash, flow->nw_proto);
1692 [ + + ][ + + ]: 28384 : if (flow->nw_proto != IPPROTO_TCP && flow->nw_proto != IPPROTO_UDP
1693 [ + + ][ + + ]: 25831 : && flow->nw_proto != IPPROTO_SCTP && flow->nw_proto != IPPROTO_ICMP
1694 [ + + ]: 23651 : && flow->nw_proto != IPPROTO_ICMPV6) {
1695 : 23480 : goto out;
1696 : : }
1697 : :
1698 : : /* Add both ports at once. */
1699 : 4904 : hash = hash_add(hash,
1700 : 4904 : ((const uint32_t *)flow)[offsetof(struct flow, tp_src)
1701 : : / sizeof(uint32_t)]);
1702 : : }
1703 : : out:
1704 : 30540 : return hash_finish(hash, 42); /* Arbitrary number. */
1705 : : }
1706 : :
1707 : : /* Hashes 'flow' based on its L2 through L4 protocol information. */
1708 : : uint32_t
1709 : 1900559 : flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
1710 : : {
1711 : : struct {
1712 : : union {
1713 : : ovs_be32 ipv4_addr;
1714 : : struct in6_addr ipv6_addr;
1715 : : };
1716 : : ovs_be16 eth_type;
1717 : : ovs_be16 vlan_tci;
1718 : : ovs_be16 tp_port;
1719 : : struct eth_addr eth_addr;
1720 : : uint8_t ip_proto;
1721 : : } fields;
1722 : :
1723 : : int i;
1724 : :
1725 : 1900559 : memset(&fields, 0, sizeof fields);
1726 [ + + ]: 7602236 : for (i = 0; i < ARRAY_SIZE(fields.eth_addr.be16); i++) {
1727 : 5701677 : fields.eth_addr.be16[i] = flow->dl_src.be16[i] ^ flow->dl_dst.be16[i];
1728 : : }
1729 : 1900559 : fields.vlan_tci = flow->vlan_tci & htons(VLAN_VID_MASK);
1730 : 1900559 : fields.eth_type = flow->dl_type;
1731 : :
1732 : : /* UDP source and destination port are not taken into account because they
1733 : : * will not necessarily be symmetric in a bidirectional flow. */
1734 [ + + ]: 1900559 : if (fields.eth_type == htons(ETH_TYPE_IP)) {
1735 : 951009 : fields.ipv4_addr = flow->nw_src ^ flow->nw_dst;
1736 : 951009 : fields.ip_proto = flow->nw_proto;
1737 [ + + ][ + + ]: 951009 : if (fields.ip_proto == IPPROTO_TCP || fields.ip_proto == IPPROTO_SCTP) {
1738 : 951009 : fields.tp_port = flow->tp_src ^ flow->tp_dst;
1739 : : }
1740 [ + + ]: 949550 : } else if (fields.eth_type == htons(ETH_TYPE_IPV6)) {
1741 : 475168 : const uint8_t *a = &flow->ipv6_src.s6_addr[0];
1742 : 475168 : const uint8_t *b = &flow->ipv6_dst.s6_addr[0];
1743 : 475168 : uint8_t *ipv6_addr = &fields.ipv6_addr.s6_addr[0];
1744 : :
1745 [ + + ]: 8077856 : for (i=0; i<16; i++) {
1746 : 7602688 : ipv6_addr[i] = a[i] ^ b[i];
1747 : : }
1748 : 475168 : fields.ip_proto = flow->nw_proto;
1749 [ + + ][ + + ]: 475168 : if (fields.ip_proto == IPPROTO_TCP || fields.ip_proto == IPPROTO_SCTP) {
1750 : 267882 : fields.tp_port = flow->tp_src ^ flow->tp_dst;
1751 : : }
1752 : : }
1753 : 1900559 : return jhash_bytes(&fields, sizeof fields, basis);
1754 : : }
1755 : :
1756 : : /* Hashes 'flow' based on its L3 through L4 protocol information */
1757 : : uint32_t
1758 : 0 : flow_hash_symmetric_l3l4(const struct flow *flow, uint32_t basis,
1759 : : bool inc_udp_ports)
1760 : : {
1761 : 0 : uint32_t hash = basis;
1762 : :
1763 : : /* UDP source and destination port are also taken into account. */
1764 [ # # ]: 0 : if (flow->dl_type == htons(ETH_TYPE_IP)) {
1765 : 0 : hash = hash_add(hash,
1766 : 0 : (OVS_FORCE uint32_t) (flow->nw_src ^ flow->nw_dst));
1767 [ # # ]: 0 : } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
1768 : : /* IPv6 addresses are 64-bit aligned inside struct flow. */
1769 : 0 : const uint64_t *a = ALIGNED_CAST(uint64_t *, flow->ipv6_src.s6_addr);
1770 : 0 : const uint64_t *b = ALIGNED_CAST(uint64_t *, flow->ipv6_dst.s6_addr);
1771 : :
1772 [ # # ]: 0 : for (int i = 0; i < 4; i++) {
1773 : 0 : hash = hash_add64(hash, a[i] ^ b[i]);
1774 : : }
1775 : : } else {
1776 : : /* Cannot hash non-IP flows */
1777 : 0 : return 0;
1778 : : }
1779 : :
1780 : 0 : hash = hash_add(hash, flow->nw_proto);
1781 [ # # ][ # # ]: 0 : if (flow->nw_proto == IPPROTO_TCP || flow->nw_proto == IPPROTO_SCTP ||
[ # # ]
1782 [ # # ]: 0 : (inc_udp_ports && flow->nw_proto == IPPROTO_UDP)) {
1783 : 0 : hash = hash_add(hash,
1784 : 0 : (OVS_FORCE uint16_t) (flow->tp_src ^ flow->tp_dst));
1785 : : }
1786 : :
1787 : 0 : return hash_finish(hash, basis);
1788 : : }
1789 : :
1790 : : /* Initialize a flow with random fields that matter for nx_hash_fields. */
1791 : : void
1792 : 16715072 : flow_random_hash_fields(struct flow *flow)
1793 : : {
1794 : 16715072 : uint16_t rnd = random_uint16();
1795 : :
1796 : : /* Initialize to all zeros. */
1797 : 16715072 : memset(flow, 0, sizeof *flow);
1798 : :
1799 : 16715072 : eth_addr_random(&flow->dl_src);
1800 : 16715072 : eth_addr_random(&flow->dl_dst);
1801 : :
1802 : 16715072 : flow->vlan_tci = (OVS_FORCE ovs_be16) (random_uint16() & VLAN_VID_MASK);
1803 : :
1804 : : /* Make most of the random flows IPv4, some IPv6, and rest random. */
1805 [ + + ][ + + ]: 16715072 : flow->dl_type = rnd < 0x8000 ? htons(ETH_TYPE_IP) :
1806 : : rnd < 0xc000 ? htons(ETH_TYPE_IPV6) : (OVS_FORCE ovs_be16)rnd;
1807 : :
1808 [ + + ]: 16715072 : if (dl_type_is_ip_any(flow->dl_type)) {
1809 [ + + ]: 12534609 : if (flow->dl_type == htons(ETH_TYPE_IP)) {
1810 : 8356776 : flow->nw_src = (OVS_FORCE ovs_be32)random_uint32();
1811 : 8356776 : flow->nw_dst = (OVS_FORCE ovs_be32)random_uint32();
1812 : : } else {
1813 : 4177833 : random_bytes(&flow->ipv6_src, sizeof flow->ipv6_src);
1814 : 4177833 : random_bytes(&flow->ipv6_dst, sizeof flow->ipv6_dst);
1815 : : }
1816 : : /* Make most of IP flows TCP, some UDP or SCTP, and rest random. */
1817 : 12534609 : rnd = random_uint16();
1818 [ + + ][ + + ]: 12534609 : flow->nw_proto = rnd < 0x8000 ? IPPROTO_TCP :
[ + + ]
1819 : : rnd < 0xc000 ? IPPROTO_UDP :
1820 : : rnd < 0xd000 ? IPPROTO_SCTP : (uint8_t)rnd;
1821 [ + + ][ + + ]: 12534609 : if (flow->nw_proto == IPPROTO_TCP ||
1822 [ + + ]: 3116255 : flow->nw_proto == IPPROTO_UDP ||
1823 : 3116255 : flow->nw_proto == IPPROTO_SCTP) {
1824 : 10210137 : flow->tp_src = (OVS_FORCE ovs_be16)random_uint16();
1825 : 10210137 : flow->tp_dst = (OVS_FORCE ovs_be16)random_uint16();
1826 : : }
1827 : : }
1828 : 16715072 : }
1829 : :
1830 : : /* Masks the fields in 'wc' that are used by the flow hash 'fields'. */
1831 : : void
1832 : 34686489 : flow_mask_hash_fields(const struct flow *flow, struct flow_wildcards *wc,
1833 : : enum nx_hash_fields fields)
1834 : : {
1835 [ + + - - : 34686489 : switch (fields) {
- ]
1836 : : case NX_HASH_FIELDS_ETH_SRC:
1837 : 33036239 : memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
1838 : 33036239 : break;
1839 : :
1840 : : case NX_HASH_FIELDS_SYMMETRIC_L4:
1841 : 1650250 : memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
1842 : 1650250 : memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
1843 [ + + ]: 1650250 : if (flow->dl_type == htons(ETH_TYPE_IP)) {
1844 : 825646 : memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
1845 : 825646 : memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
1846 [ + + ]: 824604 : } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
1847 : 412269 : memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
1848 : 412269 : memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
1849 : : }
1850 [ + + ]: 1650250 : if (is_ip_any(flow)) {
1851 : 1237915 : memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
1852 : 1237915 : flow_unwildcard_tp_ports(flow, wc);
1853 : : }
1854 : 1650250 : wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
1855 : 1650250 : break;
1856 : :
1857 : : case NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP:
1858 [ # # ][ # # ]: 0 : if (is_ip_any(flow) && flow->nw_proto == IPPROTO_UDP) {
1859 : 0 : memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
1860 : 0 : memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
1861 : : }
1862 : : /* no break */
1863 : : case NX_HASH_FIELDS_SYMMETRIC_L3L4:
1864 [ # # ]: 0 : if (flow->dl_type == htons(ETH_TYPE_IP)) {
1865 : 0 : memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
1866 : 0 : memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
1867 [ # # ]: 0 : } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
1868 : 0 : memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
1869 : 0 : memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
1870 : : } else {
1871 : 0 : break; /* non-IP flow */
1872 : : }
1873 : :
1874 : 0 : memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
1875 [ # # ][ # # ]: 0 : if (flow->nw_proto == IPPROTO_TCP || flow->nw_proto == IPPROTO_SCTP) {
1876 : 0 : memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
1877 : 0 : memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
1878 : : }
1879 : 0 : break;
1880 : :
1881 : : default:
1882 : 0 : OVS_NOT_REACHED();
1883 : : }
1884 : 34686489 : }
1885 : :
1886 : : /* Hashes the portions of 'flow' designated by 'fields'. */
1887 : : uint32_t
1888 : 34930152 : flow_hash_fields(const struct flow *flow, enum nx_hash_fields fields,
1889 : : uint16_t basis)
1890 : : {
1891 [ + + - - : 34930152 : switch (fields) {
- ]
1892 : :
1893 : : case NX_HASH_FIELDS_ETH_SRC:
1894 : 33030152 : return jhash_bytes(&flow->dl_src, sizeof flow->dl_src, basis);
1895 : :
1896 : : case NX_HASH_FIELDS_SYMMETRIC_L4:
1897 : 1900000 : return flow_hash_symmetric_l4(flow, basis);
1898 : :
1899 : : case NX_HASH_FIELDS_SYMMETRIC_L3L4:
1900 : 0 : return flow_hash_symmetric_l3l4(flow, basis, false);
1901 : :
1902 : : case NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP:
1903 : 0 : return flow_hash_symmetric_l3l4(flow, basis, true);
1904 : :
1905 : : }
1906 : :
1907 : 0 : OVS_NOT_REACHED();
1908 : : }
1909 : :
1910 : : /* Returns a string representation of 'fields'. */
1911 : : const char *
1912 : 26 : flow_hash_fields_to_str(enum nx_hash_fields fields)
1913 : : {
1914 [ + + - - : 26 : switch (fields) {
- ]
1915 : 17 : case NX_HASH_FIELDS_ETH_SRC: return "eth_src";
1916 : 9 : case NX_HASH_FIELDS_SYMMETRIC_L4: return "symmetric_l4";
1917 : 0 : case NX_HASH_FIELDS_SYMMETRIC_L3L4: return "symmetric_l3l4";
1918 : 0 : case NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP: return "symmetric_l3l4+udp";
1919 : 0 : default: return "<unknown>";
1920 : : }
1921 : : }
1922 : :
1923 : : /* Returns true if the value of 'fields' is supported. Otherwise false. */
1924 : : bool
1925 : 29 : flow_hash_fields_valid(enum nx_hash_fields fields)
1926 : : {
1927 : 29 : return fields == NX_HASH_FIELDS_ETH_SRC
1928 [ - + ]: 10 : || fields == NX_HASH_FIELDS_SYMMETRIC_L4
1929 [ # # ]: 0 : || fields == NX_HASH_FIELDS_SYMMETRIC_L3L4
1930 [ + + ][ # # ]: 39 : || fields == NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP;
1931 : : }
1932 : :
1933 : : /* Returns a hash value for the bits of 'flow' that are active based on
1934 : : * 'wc', given 'basis'. */
1935 : : uint32_t
1936 : 0 : flow_hash_in_wildcards(const struct flow *flow,
1937 : : const struct flow_wildcards *wc, uint32_t basis)
1938 : : {
1939 : 0 : const uint64_t *wc_u64 = (const uint64_t *) &wc->masks;
1940 : 0 : const uint64_t *flow_u64 = (const uint64_t *) flow;
1941 : : uint32_t hash;
1942 : : size_t i;
1943 : :
1944 : 0 : hash = basis;
1945 [ # # ]: 0 : for (i = 0; i < FLOW_U64S; i++) {
1946 : 0 : hash = hash_add64(hash, flow_u64[i] & wc_u64[i]);
1947 : : }
1948 : 0 : return hash_finish(hash, 8 * FLOW_U64S);
1949 : : }
1950 : :
1951 : : /* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
1952 : : * OpenFlow 1.0 "dl_vlan" value:
1953 : : *
1954 : : * - If it is in the range 0...4095, 'flow->vlan_tci' is set to match
1955 : : * that VLAN. Any existing PCP match is unchanged (it becomes 0 if
1956 : : * 'flow' previously matched packets without a VLAN header).
1957 : : *
1958 : : * - If it is OFP_VLAN_NONE, 'flow->vlan_tci' is set to match a packet
1959 : : * without a VLAN tag.
1960 : : *
1961 : : * - Other values of 'vid' should not be used. */
1962 : : void
1963 : 5008 : flow_set_dl_vlan(struct flow *flow, ovs_be16 vid)
1964 : : {
1965 [ + + ]: 5008 : if (vid == htons(OFP10_VLAN_NONE)) {
1966 : 3 : flow->vlan_tci = htons(0);
1967 : : } else {
1968 : 5005 : vid &= htons(VLAN_VID_MASK);
1969 : 5005 : flow->vlan_tci &= ~htons(VLAN_VID_MASK);
1970 : 5005 : flow->vlan_tci |= htons(VLAN_CFI) | vid;
1971 : : }
1972 : 5008 : }
1973 : :
1974 : : /* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
1975 : : * OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
1976 : : * plus CFI). */
1977 : : void
1978 : 1007 : flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
1979 : : {
1980 : 1007 : ovs_be16 mask = htons(VLAN_VID_MASK | VLAN_CFI);
1981 : 1007 : flow->vlan_tci &= ~mask;
1982 : 1007 : flow->vlan_tci |= vid & mask;
1983 : 1007 : }
1984 : :
1985 : : /* Sets the VLAN PCP that 'flow' matches to 'pcp', which should be in the
1986 : : * range 0...7.
1987 : : *
1988 : : * This function has no effect on the VLAN ID that 'flow' matches.
1989 : : *
1990 : : * After calling this function, 'flow' will not match packets without a VLAN
1991 : : * header. */
1992 : : void
1993 : 109 : flow_set_vlan_pcp(struct flow *flow, uint8_t pcp)
1994 : : {
1995 : 109 : pcp &= 0x07;
1996 : 109 : flow->vlan_tci &= ~htons(VLAN_PCP_MASK);
1997 : 109 : flow->vlan_tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI);
1998 : 109 : }
1999 : :
2000 : : /* Returns the number of MPLS LSEs present in 'flow'
2001 : : *
2002 : : * Returns 0 if the 'dl_type' of 'flow' is not an MPLS ethernet type.
2003 : : * Otherwise traverses 'flow''s MPLS label stack stopping at the
2004 : : * first entry that has the BoS bit set. If no such entry exists then
2005 : : * the maximum number of LSEs that can be stored in 'flow' is returned.
2006 : : */
2007 : : int
2008 : 239081 : flow_count_mpls_labels(const struct flow *flow, struct flow_wildcards *wc)
2009 : : {
2010 : : /* dl_type is always masked. */
2011 [ + + ]: 239081 : if (eth_type_mpls(flow->dl_type)) {
2012 : : int i;
2013 : : int cnt;
2014 : :
2015 : 5635 : cnt = 0;
2016 [ + + ]: 10888 : for (i = 0; i < FLOW_MAX_MPLS_LABELS; i++) {
2017 [ + + ]: 10874 : if (wc) {
2018 : 221 : wc->masks.mpls_lse[i] |= htonl(MPLS_BOS_MASK);
2019 : : }
2020 [ + + ]: 10874 : if (flow->mpls_lse[i] & htonl(MPLS_BOS_MASK)) {
2021 : 5621 : return i + 1;
2022 : : }
2023 [ + + ]: 5253 : if (flow->mpls_lse[i]) {
2024 : 203 : cnt++;
2025 : : }
2026 : : }
2027 : 14 : return cnt;
2028 : : } else {
2029 : 233446 : return 0;
2030 : : }
2031 : : }
2032 : :
2033 : : /* Returns the number consecutive of MPLS LSEs, starting at the
2034 : : * innermost LSE, that are common in 'a' and 'b'.
2035 : : *
2036 : : * 'an' must be flow_count_mpls_labels(a).
2037 : : * 'bn' must be flow_count_mpls_labels(b).
2038 : : */
2039 : : int
2040 : 116809 : flow_count_common_mpls_labels(const struct flow *a, int an,
2041 : : const struct flow *b, int bn,
2042 : : struct flow_wildcards *wc)
2043 : : {
2044 : 116809 : int min_n = MIN(an, bn);
2045 [ + + ]: 116809 : if (min_n == 0) {
2046 : 116747 : return 0;
2047 : : } else {
2048 : 62 : int common_n = 0;
2049 : 62 : int a_last = an - 1;
2050 : 62 : int b_last = bn - 1;
2051 : : int i;
2052 : :
2053 [ + + ]: 98 : for (i = 0; i < min_n; i++) {
2054 [ - + ]: 64 : if (wc) {
2055 : 0 : wc->masks.mpls_lse[a_last - i] = OVS_BE32_MAX;
2056 : 0 : wc->masks.mpls_lse[b_last - i] = OVS_BE32_MAX;
2057 : : }
2058 [ + + ]: 64 : if (a->mpls_lse[a_last - i] != b->mpls_lse[b_last - i]) {
2059 : 28 : break;
2060 : : } else {
2061 : 36 : common_n++;
2062 : : }
2063 : : }
2064 : :
2065 : 62 : return common_n;
2066 : : }
2067 : : }
2068 : :
2069 : : /* Adds a new outermost MPLS label to 'flow' and changes 'flow''s Ethernet type
2070 : : * to 'mpls_eth_type', which must be an MPLS Ethertype.
2071 : : *
2072 : : * If the new label is the first MPLS label in 'flow', it is generated as;
2073 : : *
2074 : : * - label: 2, if 'flow' is IPv6, otherwise 0.
2075 : : *
2076 : : * - TTL: IPv4 or IPv6 TTL, if present and nonzero, otherwise 64.
2077 : : *
2078 : : * - TC: IPv4 or IPv6 TOS, if present, otherwise 0.
2079 : : *
2080 : : * - BoS: 1.
2081 : : *
2082 : : * If the new label is the second or later label MPLS label in 'flow', it is
2083 : : * generated as;
2084 : : *
2085 : : * - label: Copied from outer label.
2086 : : *
2087 : : * - TTL: Copied from outer label.
2088 : : *
2089 : : * - TC: Copied from outer label.
2090 : : *
2091 : : * - BoS: 0.
2092 : : *
2093 : : * 'n' must be flow_count_mpls_labels(flow). 'n' must be less than
2094 : : * FLOW_MAX_MPLS_LABELS (because otherwise flow->mpls_lse[] would overflow).
2095 : : */
2096 : : void
2097 : 232 : flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
2098 : : struct flow_wildcards *wc)
2099 : : {
2100 [ - + ]: 232 : ovs_assert(eth_type_mpls(mpls_eth_type));
2101 [ - + ]: 232 : ovs_assert(n < FLOW_MAX_MPLS_LABELS);
2102 : :
2103 [ + + ]: 232 : if (n) {
2104 : : int i;
2105 : :
2106 [ + + ]: 54 : if (wc) {
2107 : 33 : memset(&wc->masks.mpls_lse, 0xff, sizeof *wc->masks.mpls_lse * n);
2108 : : }
2109 [ + + ]: 112 : for (i = n; i >= 1; i--) {
2110 : 58 : flow->mpls_lse[i] = flow->mpls_lse[i - 1];
2111 : : }
2112 : 54 : flow->mpls_lse[0] = (flow->mpls_lse[1] & htonl(~MPLS_BOS_MASK));
2113 : : } else {
2114 : 178 : int label = 0; /* IPv4 Explicit Null. */
2115 : 178 : int tc = 0;
2116 : 178 : int ttl = 64;
2117 : :
2118 [ + + ]: 178 : if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
2119 : 8 : label = 2;
2120 : : }
2121 : :
2122 [ + - ]: 178 : if (is_ip_any(flow)) {
2123 : 178 : tc = (flow->nw_tos & IP_DSCP_MASK) >> 2;
2124 [ + + ]: 178 : if (wc) {
2125 : 91 : wc->masks.nw_tos |= IP_DSCP_MASK;
2126 : 91 : wc->masks.nw_ttl = 0xff;
2127 : : }
2128 : :
2129 [ + + ]: 178 : if (flow->nw_ttl) {
2130 : 176 : ttl = flow->nw_ttl;
2131 : : }
2132 : : }
2133 : :
2134 : 178 : flow->mpls_lse[0] = set_mpls_lse_values(ttl, tc, 1, htonl(label));
2135 : :
2136 : : /* Clear all L3 and L4 fields and dp_hash. */
2137 : : BUILD_ASSERT(FLOW_WC_SEQ == 36);
2138 : 178 : memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0,
2139 : : sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT);
2140 : 178 : flow->dp_hash = 0;
2141 : : }
2142 : 232 : flow->dl_type = mpls_eth_type;
2143 : 232 : }
2144 : :
2145 : : /* Tries to remove the outermost MPLS label from 'flow'. Returns true if
2146 : : * successful, false otherwise. On success, sets 'flow''s Ethernet type to
2147 : : * 'eth_type'.
2148 : : *
2149 : : * 'n' must be flow_count_mpls_labels(flow). */
2150 : : bool
2151 : 214 : flow_pop_mpls(struct flow *flow, int n, ovs_be16 eth_type,
2152 : : struct flow_wildcards *wc)
2153 : : {
2154 : : int i;
2155 : :
2156 [ - + ]: 214 : if (n == 0) {
2157 : : /* Nothing to pop. */
2158 : 0 : return false;
2159 [ + + ]: 214 : } else if (n == FLOW_MAX_MPLS_LABELS) {
2160 [ + + ]: 24 : if (wc) {
2161 : 12 : wc->masks.mpls_lse[n - 1] |= htonl(MPLS_BOS_MASK);
2162 : : }
2163 [ - + ]: 24 : if (!(flow->mpls_lse[n - 1] & htonl(MPLS_BOS_MASK))) {
2164 : : /* Can't pop because don't know what to fill in mpls_lse[n - 1]. */
2165 : 0 : return false;
2166 : : }
2167 : : }
2168 : :
2169 [ + + ]: 214 : if (wc) {
2170 : 115 : memset(&wc->masks.mpls_lse[1], 0xff,
2171 : 115 : sizeof *wc->masks.mpls_lse * (n - 1));
2172 : : }
2173 [ + + ]: 344 : for (i = 1; i < n; i++) {
2174 : 130 : flow->mpls_lse[i - 1] = flow->mpls_lse[i];
2175 : : }
2176 : 214 : flow->mpls_lse[n - 1] = 0;
2177 : 214 : flow->dl_type = eth_type;
2178 : 214 : return true;
2179 : : }
2180 : :
2181 : : /* Sets the MPLS Label that 'flow' matches to 'label', which is interpreted
2182 : : * as an OpenFlow 1.1 "mpls_label" value. */
2183 : : void
2184 : 201 : flow_set_mpls_label(struct flow *flow, int idx, ovs_be32 label)
2185 : : {
2186 : 201 : set_mpls_lse_label(&flow->mpls_lse[idx], label);
2187 : 201 : }
2188 : :
2189 : : /* Sets the MPLS TTL that 'flow' matches to 'ttl', which should be in the
2190 : : * range 0...255. */
2191 : : void
2192 : 0 : flow_set_mpls_ttl(struct flow *flow, int idx, uint8_t ttl)
2193 : : {
2194 : 0 : set_mpls_lse_ttl(&flow->mpls_lse[idx], ttl);
2195 : 0 : }
2196 : :
2197 : : /* Sets the MPLS TC that 'flow' matches to 'tc', which should be in the
2198 : : * range 0...7. */
2199 : : void
2200 : 83 : flow_set_mpls_tc(struct flow *flow, int idx, uint8_t tc)
2201 : : {
2202 : 83 : set_mpls_lse_tc(&flow->mpls_lse[idx], tc);
2203 : 83 : }
2204 : :
2205 : : /* Sets the MPLS BOS bit that 'flow' matches to which should be 0 or 1. */
2206 : : void
2207 : 1781 : flow_set_mpls_bos(struct flow *flow, int idx, uint8_t bos)
2208 : : {
2209 : 1781 : set_mpls_lse_bos(&flow->mpls_lse[idx], bos);
2210 : 1781 : }
2211 : :
2212 : : /* Sets the entire MPLS LSE. */
2213 : : void
2214 : 136 : flow_set_mpls_lse(struct flow *flow, int idx, ovs_be32 lse)
2215 : : {
2216 : 136 : flow->mpls_lse[idx] = lse;
2217 : 136 : }
2218 : :
2219 : : static size_t
2220 : 1487 : flow_compose_l4(struct dp_packet *p, const struct flow *flow)
2221 : : {
2222 : 1487 : size_t l4_len = 0;
2223 : :
2224 [ + + ]: 1487 : if (!(flow->nw_frag & FLOW_NW_FRAG_ANY)
2225 [ + + ]: 6 : || !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
2226 [ + + ]: 1484 : if (flow->nw_proto == IPPROTO_TCP) {
2227 : : struct tcp_header *tcp;
2228 : :
2229 : 682 : l4_len = sizeof *tcp;
2230 : 682 : tcp = dp_packet_put_zeros(p, l4_len);
2231 : 682 : tcp->tcp_src = flow->tp_src;
2232 : 682 : tcp->tcp_dst = flow->tp_dst;
2233 : 682 : tcp->tcp_ctl = TCP_CTL(ntohs(flow->tcp_flags), 5);
2234 [ + + ]: 802 : } else if (flow->nw_proto == IPPROTO_UDP) {
2235 : : struct udp_header *udp;
2236 : :
2237 : 235 : l4_len = sizeof *udp;
2238 : 235 : udp = dp_packet_put_zeros(p, l4_len);
2239 : 235 : udp->udp_src = flow->tp_src;
2240 : 235 : udp->udp_dst = flow->tp_dst;
2241 : 235 : udp->udp_len = htons(l4_len);
2242 [ - + ]: 567 : } else if (flow->nw_proto == IPPROTO_SCTP) {
2243 : : struct sctp_header *sctp;
2244 : :
2245 : 0 : l4_len = sizeof *sctp;
2246 : 0 : sctp = dp_packet_put_zeros(p, l4_len);
2247 : 0 : sctp->sctp_src = flow->tp_src;
2248 : 0 : sctp->sctp_dst = flow->tp_dst;
2249 [ + + ]: 567 : } else if (flow->nw_proto == IPPROTO_ICMP) {
2250 : : struct icmp_header *icmp;
2251 : :
2252 : 415 : l4_len = sizeof *icmp;
2253 : 415 : icmp = dp_packet_put_zeros(p, l4_len);
2254 : 415 : icmp->icmp_type = ntohs(flow->tp_src);
2255 : 415 : icmp->icmp_code = ntohs(flow->tp_dst);
2256 [ - + ]: 152 : } else if (flow->nw_proto == IPPROTO_IGMP) {
2257 : : struct igmp_header *igmp;
2258 : :
2259 : 0 : l4_len = sizeof *igmp;
2260 : 0 : igmp = dp_packet_put_zeros(p, l4_len);
2261 : 0 : igmp->igmp_type = ntohs(flow->tp_src);
2262 : 0 : igmp->igmp_code = ntohs(flow->tp_dst);
2263 : 0 : put_16aligned_be32(&igmp->group, flow->igmp_group_ip4);
2264 [ + + ]: 152 : } else if (flow->nw_proto == IPPROTO_ICMPV6) {
2265 : : struct icmp6_hdr *icmp;
2266 : :
2267 : 55 : l4_len = sizeof *icmp;
2268 : 55 : icmp = dp_packet_put_zeros(p, l4_len);
2269 : 55 : icmp->icmp6_type = ntohs(flow->tp_src);
2270 : 55 : icmp->icmp6_code = ntohs(flow->tp_dst);
2271 : :
2272 [ + - ][ + + ]: 55 : if (icmp->icmp6_code == 0 &&
2273 [ + + ]: 44 : (icmp->icmp6_type == ND_NEIGHBOR_SOLICIT ||
2274 : 44 : icmp->icmp6_type == ND_NEIGHBOR_ADVERT)) {
2275 : : struct in6_addr *nd_target;
2276 : : struct ovs_nd_opt *nd_opt;
2277 : :
2278 : 13 : l4_len += sizeof *nd_target;
2279 : 13 : nd_target = dp_packet_put_zeros(p, sizeof *nd_target);
2280 : 13 : *nd_target = flow->nd_target;
2281 : :
2282 [ - + ]: 13 : if (!eth_addr_is_zero(flow->arp_sha)) {
2283 : 0 : l4_len += 8;
2284 : 0 : nd_opt = dp_packet_put_zeros(p, 8);
2285 : 0 : nd_opt->nd_opt_len = 1;
2286 : 0 : nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
2287 : 0 : nd_opt->nd_opt_mac = flow->arp_sha;
2288 : : }
2289 [ + + ]: 13 : if (!eth_addr_is_zero(flow->arp_tha)) {
2290 : 2 : l4_len += 8;
2291 : 2 : nd_opt = dp_packet_put_zeros(p, 8);
2292 : 2 : nd_opt->nd_opt_len = 1;
2293 : 2 : nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
2294 : 2 : nd_opt->nd_opt_mac = flow->arp_tha;
2295 : : }
2296 : : }
2297 : : }
2298 : : }
2299 : 1487 : return l4_len;
2300 : : }
2301 : :
2302 : : static void
2303 : 1487 : flow_compose_l4_csum(struct dp_packet *p, const struct flow *flow,
2304 : : uint32_t pseudo_hdr_csum)
2305 : : {
2306 : 1487 : size_t l4_len = (char *) dp_packet_tail(p) - (char *) dp_packet_l4(p);
2307 : :
2308 [ + + ]: 1487 : if (!(flow->nw_frag & FLOW_NW_FRAG_ANY)
2309 [ + + ]: 6 : || !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
2310 [ + + ]: 1484 : if (flow->nw_proto == IPPROTO_TCP) {
2311 : 682 : struct tcp_header *tcp = dp_packet_l4(p);
2312 : :
2313 : : /* Checksum has already been zeroed by put_zeros call in
2314 : : * flow_compose_l4(). */
2315 : 682 : tcp->tcp_csum = csum_finish(csum_continue(pseudo_hdr_csum,
2316 : : tcp, l4_len));
2317 [ + + ]: 802 : } else if (flow->nw_proto == IPPROTO_UDP) {
2318 : 235 : struct udp_header *udp = dp_packet_l4(p);
2319 : :
2320 : : /* Checksum has already been zeroed by put_zeros call in
2321 : : * flow_compose_l4(). */
2322 : 235 : udp->udp_csum = csum_finish(csum_continue(pseudo_hdr_csum,
2323 : : udp, l4_len));
2324 [ + + ]: 567 : } else if (flow->nw_proto == IPPROTO_ICMP) {
2325 : 415 : struct icmp_header *icmp = dp_packet_l4(p);
2326 : :
2327 : : /* Checksum has already been zeroed by put_zeros call in
2328 : : * flow_compose_l4(). */
2329 : 415 : icmp->icmp_csum = csum(icmp, l4_len);
2330 [ - + ]: 152 : } else if (flow->nw_proto == IPPROTO_IGMP) {
2331 : 0 : struct igmp_header *igmp = dp_packet_l4(p);
2332 : :
2333 : : /* Checksum has already been zeroed by put_zeros call in
2334 : : * flow_compose_l4(). */
2335 : 0 : igmp->igmp_csum = csum(igmp, l4_len);
2336 [ + + ]: 152 : } else if (flow->nw_proto == IPPROTO_ICMPV6) {
2337 : 55 : struct icmp6_hdr *icmp = dp_packet_l4(p);
2338 : :
2339 : : /* Checksum has already been zeroed by put_zeros call in
2340 : : * flow_compose_l4(). */
2341 : 55 : icmp->icmp6_cksum = (OVS_FORCE uint16_t)
2342 : 55 : csum_finish(csum_continue(pseudo_hdr_csum, icmp, l4_len));
2343 : : }
2344 : : }
2345 : 1487 : }
2346 : :
2347 : : /* Puts into 'b' a packet that flow_extract() would parse as having the given
2348 : : * 'flow'.
2349 : : *
2350 : : * (This is useful only for testing, obviously, and the packet isn't really
2351 : : * valid. Lots of fields are just zeroed.) */
2352 : : void
2353 : 6585 : flow_compose(struct dp_packet *p, const struct flow *flow)
2354 : : {
2355 : : uint32_t pseudo_hdr_csum;
2356 : : size_t l4_len;
2357 : :
2358 : : /* eth_compose() sets l3 pointer and makes sure it is 32-bit aligned. */
2359 : 6585 : eth_compose(p, flow->dl_dst, flow->dl_src, ntohs(flow->dl_type), 0);
2360 [ + + ]: 6585 : if (flow->dl_type == htons(FLOW_DL_TYPE_NONE)) {
2361 : 2768 : struct eth_header *eth = dp_packet_l2(p);
2362 : 2768 : eth->eth_type = htons(dp_packet_size(p));
2363 : 2768 : return;
2364 : : }
2365 : :
2366 [ + + ]: 3817 : if (flow->vlan_tci & htons(VLAN_CFI)) {
2367 : 28 : eth_push_vlan(p, htons(ETH_TYPE_VLAN), flow->vlan_tci);
2368 : : }
2369 : :
2370 [ + + ]: 3817 : if (flow->dl_type == htons(ETH_TYPE_IP)) {
2371 : : struct ip_header *ip;
2372 : :
2373 : 1421 : ip = dp_packet_put_zeros(p, sizeof *ip);
2374 : 1421 : ip->ip_ihl_ver = IP_IHL_VER(5, 4);
2375 : 1421 : ip->ip_tos = flow->nw_tos;
2376 : 1421 : ip->ip_ttl = flow->nw_ttl;
2377 : 1421 : ip->ip_proto = flow->nw_proto;
2378 : 1421 : put_16aligned_be32(&ip->ip_src, flow->nw_src);
2379 : 1421 : put_16aligned_be32(&ip->ip_dst, flow->nw_dst);
2380 : :
2381 [ + + ]: 1421 : if (flow->nw_frag & FLOW_NW_FRAG_ANY) {
2382 : 6 : ip->ip_frag_off |= htons(IP_MORE_FRAGMENTS);
2383 [ + + ]: 6 : if (flow->nw_frag & FLOW_NW_FRAG_LATER) {
2384 : 3 : ip->ip_frag_off |= htons(100);
2385 : : }
2386 : : }
2387 : :
2388 : 1421 : dp_packet_set_l4(p, dp_packet_tail(p));
2389 : :
2390 : 1421 : l4_len = flow_compose_l4(p, flow);
2391 : :
2392 : 1421 : ip = dp_packet_l3(p);
2393 : 1421 : ip->ip_tot_len = htons(p->l4_ofs - p->l3_ofs + l4_len);
2394 : : /* Checksum has already been zeroed by put_zeros call. */
2395 : 1421 : ip->ip_csum = csum(ip, sizeof *ip);
2396 : :
2397 : 1421 : pseudo_hdr_csum = packet_csum_pseudoheader(ip);
2398 : 1421 : flow_compose_l4_csum(p, flow, pseudo_hdr_csum);
2399 [ + + ]: 2396 : } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
2400 : : struct ovs_16aligned_ip6_hdr *nh;
2401 : :
2402 : 66 : nh = dp_packet_put_zeros(p, sizeof *nh);
2403 : 132 : put_16aligned_be32(&nh->ip6_flow, htonl(6 << 28) |
2404 : 66 : htonl(flow->nw_tos << 20) | flow->ipv6_label);
2405 : 66 : nh->ip6_hlim = flow->nw_ttl;
2406 : 66 : nh->ip6_nxt = flow->nw_proto;
2407 : :
2408 : 66 : memcpy(&nh->ip6_src, &flow->ipv6_src, sizeof(nh->ip6_src));
2409 : 66 : memcpy(&nh->ip6_dst, &flow->ipv6_dst, sizeof(nh->ip6_dst));
2410 : :
2411 : 66 : dp_packet_set_l4(p, dp_packet_tail(p));
2412 : :
2413 : 66 : l4_len = flow_compose_l4(p, flow);
2414 : :
2415 : 66 : nh = dp_packet_l3(p);
2416 : 66 : nh->ip6_plen = htons(l4_len);
2417 : :
2418 : 66 : pseudo_hdr_csum = packet_csum_pseudoheader6(nh);
2419 : 66 : flow_compose_l4_csum(p, flow, pseudo_hdr_csum);
2420 [ + + - + ]: 4592 : } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
2421 : 2262 : flow->dl_type == htons(ETH_TYPE_RARP)) {
2422 : : struct arp_eth_header *arp;
2423 : :
2424 : 68 : arp = dp_packet_put_zeros(p, sizeof *arp);
2425 : 68 : dp_packet_set_l3(p, arp);
2426 : 68 : arp->ar_hrd = htons(1);
2427 : 68 : arp->ar_pro = htons(ETH_TYPE_IP);
2428 : 68 : arp->ar_hln = ETH_ADDR_LEN;
2429 : 68 : arp->ar_pln = 4;
2430 : 68 : arp->ar_op = htons(flow->nw_proto);
2431 : :
2432 [ + + ][ + - ]: 68 : if (flow->nw_proto == ARP_OP_REQUEST ||
2433 : 7 : flow->nw_proto == ARP_OP_REPLY) {
2434 : 68 : put_16aligned_be32(&arp->ar_spa, flow->nw_src);
2435 : 68 : put_16aligned_be32(&arp->ar_tpa, flow->nw_dst);
2436 : 68 : arp->ar_sha = flow->arp_sha;
2437 : 68 : arp->ar_tha = flow->arp_tha;
2438 : : }
2439 : : }
2440 : :
2441 [ + + ]: 3817 : if (eth_type_mpls(flow->dl_type)) {
2442 : : int n;
2443 : :
2444 : 1671 : p->l2_5_ofs = p->l3_ofs;
2445 [ + + ]: 3324 : for (n = 1; n < FLOW_MAX_MPLS_LABELS; n++) {
2446 [ + + ]: 2773 : if (flow->mpls_lse[n - 1] & htonl(MPLS_BOS_MASK)) {
2447 : 1120 : break;
2448 : : }
2449 : : }
2450 [ + + ]: 4995 : while (n > 0) {
2451 : 3324 : push_mpls(p, flow->dl_type, flow->mpls_lse[--n]);
2452 : : }
2453 : : }
2454 : : }
2455 : :
2456 : : /* Compressed flow. */
2457 : :
2458 : : /* Completes an initialization of 'dst' as a miniflow copy of 'src' begun by
2459 : : * the caller. The caller must have already computed 'dst->map' properly to
2460 : : * indicate the significant uint64_t elements of 'src'.
2461 : : *
2462 : : * Normally the significant elements are the ones that are non-zero. However,
2463 : : * when a miniflow is initialized from a (mini)mask, the values can be zeroes,
2464 : : * so that the flow and mask always have the same maps. */
2465 : : void
2466 : 1092017 : miniflow_init(struct miniflow *dst, const struct flow *src)
2467 : : {
2468 : 1092017 : uint64_t *dst_u64 = miniflow_values(dst);
2469 : : size_t idx;
2470 : :
2471 [ + + ]: 3540231 : FLOWMAP_FOR_EACH_INDEX(idx, dst->map) {
2472 : 2448214 : *dst_u64++ = flow_u64_value(src, idx);
2473 : : }
2474 : 1092017 : }
2475 : :
2476 : : /* Initialize the maps of 'flow' from 'src'. */
2477 : : void
2478 : 592580 : miniflow_map_init(struct miniflow *flow, const struct flow *src)
2479 : : {
2480 : : /* Initialize map, counting the number of nonzero elements. */
2481 : 592580 : flowmap_init(&flow->map);
2482 [ + + ]: 43850920 : for (size_t i = 0; i < FLOW_U64S; i++) {
2483 [ + + ]: 43258340 : if (flow_u64_value(src, i)) {
2484 : 1631185 : flowmap_set(&flow->map, i, 1);
2485 : : }
2486 : : }
2487 : 592580 : }
2488 : :
2489 : : /* Allocates 'n' count of miniflows, consecutive in memory, initializing the
2490 : : * map of each from 'src'.
2491 : : * Returns the size of the miniflow data. */
2492 : : size_t
2493 : 646981 : miniflow_alloc(struct miniflow *dsts[], size_t n, const struct miniflow *src)
2494 : : {
2495 : 646981 : size_t n_values = miniflow_n_values(src);
2496 : 646981 : size_t data_size = MINIFLOW_VALUES_SIZE(n_values);
2497 : 646981 : struct miniflow *dst = xmalloc(n * (sizeof *src + data_size));
2498 : : size_t i;
2499 : :
2500 : 646981 : COVERAGE_INC(miniflow_malloc);
2501 : :
2502 [ + + ]: 1834494 : for (i = 0; i < n; i++) {
2503 : 1187513 : *dst = *src; /* Copy maps. */
2504 : 1187513 : dsts[i] = dst;
2505 : 1187513 : dst += 1; /* Just past the maps. */
2506 : 1187513 : dst = (struct miniflow *)((uint64_t *)dst + n_values); /* Skip data. */
2507 : : }
2508 : 646981 : return data_size;
2509 : : }
2510 : :
2511 : : /* Returns a miniflow copy of 'src'. The caller must eventually free() the
2512 : : * returned miniflow. */
2513 : : struct miniflow *
2514 : 93143 : miniflow_create(const struct flow *src)
2515 : : {
2516 : : struct miniflow tmp;
2517 : : struct miniflow *dst;
2518 : :
2519 : 93143 : miniflow_map_init(&tmp, src);
2520 : :
2521 : 93143 : miniflow_alloc(&dst, 1, &tmp);
2522 : 93143 : miniflow_init(dst, src);
2523 : 93143 : return dst;
2524 : : }
2525 : :
2526 : : /* Initializes 'dst' as a copy of 'src'. The caller must have allocated
2527 : : * 'dst' to have inline space for 'n_values' data in 'src'. */
2528 : : void
2529 : 901260 : miniflow_clone(struct miniflow *dst, const struct miniflow *src,
2530 : : size_t n_values)
2531 : : {
2532 : 901260 : *dst = *src; /* Copy maps. */
2533 : 901260 : memcpy(miniflow_values(dst), miniflow_get_values(src),
2534 : : MINIFLOW_VALUES_SIZE(n_values));
2535 : 901260 : }
2536 : :
2537 : : /* Initializes 'dst' as a copy of 'src'. */
2538 : : void
2539 : 443373806 : miniflow_expand(const struct miniflow *src, struct flow *dst)
2540 : : {
2541 : 443373806 : memset(dst, 0, sizeof *dst);
2542 : 443373806 : flow_union_with_miniflow(dst, src);
2543 : 443373806 : }
2544 : :
2545 : : /* Returns true if 'a' and 'b' are equal miniflows, false otherwise. */
2546 : : bool
2547 : 1236553 : miniflow_equal(const struct miniflow *a, const struct miniflow *b)
2548 : : {
2549 : 1236553 : const uint64_t *ap = miniflow_get_values(a);
2550 : 1236553 : const uint64_t *bp = miniflow_get_values(b);
2551 : :
2552 : : /* This is mostly called after a matching hash, so it is highly likely that
2553 : : * the maps are equal as well. */
2554 [ + - ]: 1236553 : if (OVS_LIKELY(flowmap_equal(a->map, b->map))) {
2555 : 1236553 : return !memcmp(ap, bp, miniflow_n_values(a) * sizeof *ap);
2556 : : } else {
2557 : : size_t idx;
2558 : :
2559 [ # # ]: 0 : FLOWMAP_FOR_EACH_INDEX (idx, flowmap_or(a->map, b->map)) {
2560 [ # # ][ # # ]: 0 : if ((flowmap_is_set(&a->map, idx) ? *ap++ : 0)
2561 [ # # ]: 0 : != (flowmap_is_set(&b->map, idx) ? *bp++ : 0)) {
2562 : 0 : return false;
2563 : : }
2564 : : }
2565 : : }
2566 : :
2567 : 0 : return true;
2568 : : }
2569 : :
2570 : : /* Returns false if 'a' and 'b' differ at the places where there are 1-bits
2571 : : * in 'mask', true otherwise. */
2572 : : bool
2573 : 584937 : miniflow_equal_in_minimask(const struct miniflow *a, const struct miniflow *b,
2574 : : const struct minimask *mask)
2575 : : {
2576 : 584937 : const uint64_t *p = miniflow_get_values(&mask->masks);
2577 : : size_t idx;
2578 : :
2579 [ + + ]: 781140 : FLOWMAP_FOR_EACH_INDEX(idx, mask->masks.map) {
2580 [ + + ]: 748780 : if ((miniflow_get(a, idx) ^ miniflow_get(b, idx)) & *p++) {
2581 : 552577 : return false;
2582 : : }
2583 : : }
2584 : :
2585 : 584937 : return true;
2586 : : }
2587 : :
2588 : : /* Returns true if 'a' and 'b' are equal at the places where there are 1-bits
2589 : : * in 'mask', false if they differ. */
2590 : : bool
2591 : 26612 : miniflow_equal_flow_in_minimask(const struct miniflow *a, const struct flow *b,
2592 : : const struct minimask *mask)
2593 : : {
2594 : 26612 : const uint64_t *p = miniflow_get_values(&mask->masks);
2595 : : size_t idx;
2596 : :
2597 [ + + ]: 39918 : FLOWMAP_FOR_EACH_INDEX(idx, mask->masks.map) {
2598 [ + + ]: 26612 : if ((miniflow_get(a, idx) ^ flow_u64_value(b, idx)) & *p++) {
2599 : 13306 : return false;
2600 : : }
2601 : : }
2602 : :
2603 : 26612 : return true;
2604 : : }
2605 : :
2606 : :
2607 : : void
2608 : 499437 : minimask_init(struct minimask *mask, const struct flow_wildcards *wc)
2609 : : {
2610 : 499437 : miniflow_init(&mask->masks, &wc->masks);
2611 : 499437 : }
2612 : :
2613 : : /* Returns a minimask copy of 'wc'. The caller must eventually free the
2614 : : * returned minimask with free(). */
2615 : : struct minimask *
2616 : 66531 : minimask_create(const struct flow_wildcards *wc)
2617 : : {
2618 : 66531 : return (struct minimask *)miniflow_create(&wc->masks);
2619 : : }
2620 : :
2621 : : /* Initializes 'dst_' as the bit-wise "and" of 'a_' and 'b_'.
2622 : : *
2623 : : * The caller must provide room for FLOW_U64S "uint64_t"s in 'storage', which
2624 : : * must follow '*dst_' in memory, for use by 'dst_'. The caller must *not*
2625 : : * free 'dst_' free(). */
2626 : : void
2627 : 26612 : minimask_combine(struct minimask *dst_,
2628 : : const struct minimask *a_, const struct minimask *b_,
2629 : : uint64_t storage[FLOW_U64S])
2630 : : {
2631 : 26612 : struct miniflow *dst = &dst_->masks;
2632 : 26612 : uint64_t *dst_values = storage;
2633 : 26612 : const struct miniflow *a = &a_->masks;
2634 : 26612 : const struct miniflow *b = &b_->masks;
2635 : : size_t idx;
2636 : :
2637 : 26612 : flowmap_init(&dst->map);
2638 : :
2639 [ + + ]: 46273 : FLOWMAP_FOR_EACH_INDEX(idx, flowmap_and(a->map, b->map)) {
2640 : : /* Both 'a' and 'b' have non-zero data at 'idx'. */
2641 : 19661 : uint64_t mask = *miniflow_get__(a, idx) & *miniflow_get__(b, idx);
2642 : :
2643 [ + + ]: 19661 : if (mask) {
2644 : 13489 : flowmap_set(&dst->map, idx, 1);
2645 : 13489 : *dst_values++ = mask;
2646 : : }
2647 : : }
2648 : 26612 : }
2649 : :
2650 : : /* Initializes 'wc' as a copy of 'mask'. */
2651 : : void
2652 : 221588412 : minimask_expand(const struct minimask *mask, struct flow_wildcards *wc)
2653 : : {
2654 : 221588412 : miniflow_expand(&mask->masks, &wc->masks);
2655 : 221588412 : }
2656 : :
2657 : : /* Returns true if 'a' and 'b' are the same flow mask, false otherwise.
2658 : : * Minimasks may not have zero data values, so for the minimasks to be the
2659 : : * same, they need to have the same map and the same data values. */
2660 : : bool
2661 : 1302796 : minimask_equal(const struct minimask *a, const struct minimask *b)
2662 : : {
2663 : 1302796 : return !memcmp(a, b, sizeof *a
2664 : 1302796 : + MINIFLOW_VALUES_SIZE(miniflow_n_values(&a->masks)));
2665 : : }
2666 : :
2667 : : /* Returns true if at least one bit matched by 'b' is wildcarded by 'a',
2668 : : * false otherwise. */
2669 : : bool
2670 : 224417 : minimask_has_extra(const struct minimask *a, const struct minimask *b)
2671 : : {
2672 : 224417 : const uint64_t *bp = miniflow_get_values(&b->masks);
2673 : : size_t idx;
2674 : :
2675 [ + + ]: 1736506 : FLOWMAP_FOR_EACH_INDEX(idx, b->masks.map) {
2676 : 1538716 : uint64_t b_u64 = *bp++;
2677 : :
2678 : : /* 'b_u64' is non-zero, check if the data in 'a' is either zero
2679 : : * or misses some of the bits in 'b_u64'. */
2680 [ + + ]: 1538716 : if (!MINIFLOW_IN_MAP(&a->masks, idx)
2681 [ + + ]: 1522336 : || ((*miniflow_get__(&a->masks, idx) & b_u64) != b_u64)) {
2682 : 26627 : return true; /* 'a' wildcards some bits 'b' doesn't. */
2683 : : }
2684 : : }
2685 : :
2686 : 224417 : return false;
2687 : : }
|