Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 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 : :
17 : : #include <config.h>
18 : :
19 : : #include "openvswitch/meta-flow.h"
20 : :
21 : : #include <errno.h>
22 : : #include <limits.h>
23 : : #include <netinet/icmp6.h>
24 : : #include <netinet/ip6.h>
25 : :
26 : : #include "classifier.h"
27 : : #include "openvswitch/dynamic-string.h"
28 : : #include "nx-match.h"
29 : : #include "openvswitch/ofp-util.h"
30 : : #include "ovs-thread.h"
31 : : #include "packets.h"
32 : : #include "random.h"
33 : : #include "openvswitch/shash.h"
34 : : #include "socket-util.h"
35 : : #include "tun-metadata.h"
36 : : #include "unaligned.h"
37 : : #include "util.h"
38 : : #include "openvswitch/ofp-errors.h"
39 : : #include "openvswitch/vlog.h"
40 : :
41 : 20190 : VLOG_DEFINE_THIS_MODULE(meta_flow);
42 : :
43 : : #define FLOW_U32OFS(FIELD) \
44 : : offsetof(struct flow, FIELD) % 4 ? -1 : offsetof(struct flow, FIELD) / 4
45 : :
46 : : #define MF_FIELD_SIZES(MEMBER) \
47 : : sizeof ((union mf_value *)0)->MEMBER, \
48 : : 8 * sizeof ((union mf_value *)0)->MEMBER
49 : :
50 : : extern const struct mf_field mf_fields[MFF_N_IDS]; /* Silence a warning. */
51 : :
52 : : const struct mf_field mf_fields[MFF_N_IDS] = {
53 : : #include "meta-flow.inc"
54 : : };
55 : :
56 : : /* Maps from an mf_field's 'name' or 'extra_name' to the mf_field. */
57 : : static struct shash mf_by_name;
58 : :
59 : : /* Rate limit for parse errors. These always indicate a bug in an OpenFlow
60 : : * controller and so there's not much point in showing a lot of them. */
61 : : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
62 : :
63 : : #define MF_VALUE_EXACT_8 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
64 : : #define MF_VALUE_EXACT_16 MF_VALUE_EXACT_8, MF_VALUE_EXACT_8
65 : : #define MF_VALUE_EXACT_32 MF_VALUE_EXACT_16, MF_VALUE_EXACT_16
66 : : #define MF_VALUE_EXACT_64 MF_VALUE_EXACT_32, MF_VALUE_EXACT_32
67 : : #define MF_VALUE_EXACT_128 MF_VALUE_EXACT_64, MF_VALUE_EXACT_64
68 : : #define MF_VALUE_EXACT_INITIALIZER { .tun_metadata = { MF_VALUE_EXACT_128 } }
69 : :
70 : : const union mf_value exact_match_mask = MF_VALUE_EXACT_INITIALIZER;
71 : :
72 : : static void nxm_init(void);
73 : :
74 : : /* Returns the field with the given 'name', or a null pointer if no field has
75 : : * that name. */
76 : : const struct mf_field *
77 : 65271 : mf_from_name(const char *name)
78 : : {
79 : 65271 : nxm_init();
80 : 65271 : return shash_find_data(&mf_by_name, name);
81 : : }
82 : :
83 : : static void
84 : 1038 : nxm_do_init(void)
85 : : {
86 : : int i;
87 : :
88 : 1038 : shash_init(&mf_by_name);
89 [ + + ]: 164004 : for (i = 0; i < MFF_N_IDS; i++) {
90 : 162966 : const struct mf_field *mf = &mf_fields[i];
91 : :
92 [ - + ]: 162966 : ovs_assert(mf->id == i); /* Fields must be in the enum order. */
93 : :
94 : 162966 : shash_add_once(&mf_by_name, mf->name, mf);
95 [ + + ]: 162966 : if (mf->extra_name) {
96 : 10380 : shash_add_once(&mf_by_name, mf->extra_name, mf);
97 : : }
98 : : }
99 : 1038 : }
100 : :
101 : : static void
102 : 65271 : nxm_init(void)
103 : : {
104 : : static pthread_once_t once = PTHREAD_ONCE_INIT;
105 : 65271 : pthread_once(&once, nxm_do_init);
106 : 65271 : }
107 : :
108 : : /* Consider the two value/mask pairs 'a_value/a_mask' and 'b_value/b_mask' as
109 : : * restrictions on a field's value. Then, this function initializes
110 : : * 'dst_value/dst_mask' such that it combines the restrictions of both pairs.
111 : : * This is not always possible, i.e. if one pair insists on a value of 0 in
112 : : * some bit and the other pair insists on a value of 1 in that bit. This
113 : : * function returns false in a case where the combined restriction is
114 : : * impossible (in which case 'dst_value/dst_mask' is not fully initialized),
115 : : * true otherwise.
116 : : *
117 : : * (As usually true for value/mask pairs in OVS, any 1-bit in a value must have
118 : : * a corresponding 1-bit in its mask.) */
119 : : bool
120 : 5883221 : mf_subvalue_intersect(const union mf_subvalue *a_value,
121 : : const union mf_subvalue *a_mask,
122 : : const union mf_subvalue *b_value,
123 : : const union mf_subvalue *b_mask,
124 : : union mf_subvalue *dst_value,
125 : : union mf_subvalue *dst_mask)
126 : : {
127 [ + + ]: 98656923 : for (int i = 0; i < ARRAY_SIZE(a_value->be64); i++) {
128 : 94131536 : ovs_be64 av = a_value->be64[i];
129 : 94131536 : ovs_be64 am = a_mask->be64[i];
130 : 94131536 : ovs_be64 bv = b_value->be64[i];
131 : 94131536 : ovs_be64 bm = b_mask->be64[i];
132 : 94131536 : ovs_be64 *dv = &dst_value->be64[i];
133 : 94131536 : ovs_be64 *dm = &dst_mask->be64[i];
134 : :
135 [ + + ]: 94131536 : if ((av ^ bv) & (am & bm)) {
136 : 1357834 : return false;
137 : : }
138 : 92773702 : *dv = av | bv;
139 : 92773702 : *dm = am | bm;
140 : : }
141 : 4525387 : return true;
142 : : }
143 : :
144 : : /* Returns the "number of bits" in 'v', e.g. 1 if only the lowest-order bit is
145 : : * set, 2 if the second-lowest-order bit is set, and so on. */
146 : : int
147 : 7332119 : mf_subvalue_width(const union mf_subvalue *v)
148 : : {
149 : 7332119 : return 1 + bitwise_rscan(v, sizeof *v, true, sizeof *v * 8 - 1, -1);
150 : : }
151 : :
152 : : /* For positive 'n', shifts the bits in 'value' 'n' bits to the left, and for
153 : : * negative 'n', shifts the bits '-n' bits to the right. */
154 : : void
155 : 229448 : mf_subvalue_shift(union mf_subvalue *value, int n)
156 : : {
157 [ + + ]: 229448 : if (n) {
158 : : union mf_subvalue tmp;
159 : 229080 : memset(&tmp, 0, sizeof tmp);
160 : :
161 [ + - ][ + - ]: 229080 : if (n > 0 && n < 8 * sizeof tmp) {
162 : 229080 : bitwise_copy(value, sizeof *value, 0,
163 : : &tmp, sizeof tmp, n,
164 : : 8 * sizeof tmp - n);
165 [ # # ][ # # ]: 0 : } else if (n < 0 && n > -8 * sizeof tmp) {
166 : 0 : bitwise_copy(value, sizeof *value, -n,
167 : : &tmp, sizeof tmp, 0,
168 : : 8 * sizeof tmp + n);
169 : : }
170 : 229080 : *value = tmp;
171 : : }
172 : 229448 : }
173 : :
174 : : /* Appends a formatted representation of 'sv' to 's'. */
175 : : void
176 : 0 : mf_subvalue_format(const union mf_subvalue *sv, struct ds *s)
177 : : {
178 : 0 : ds_put_hex(s, sv, sizeof *sv);
179 : 0 : }
180 : :
181 : : /* Returns true if 'wc' wildcards all the bits in field 'mf', false if 'wc'
182 : : * specifies at least one bit in the field.
183 : : *
184 : : * The caller is responsible for ensuring that 'wc' corresponds to a flow that
185 : : * meets 'mf''s prerequisites. */
186 : : bool
187 : 231183 : mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
188 : : {
189 [ + - + + : 231183 : switch (mf->id) {
+ + + + -
- + + + +
+ + - + +
+ + + + +
- + + + +
+ + + - +
+ + + + -
+ + + + +
+ + + + +
+ + + + +
+ + - ]
190 : : case MFF_DP_HASH:
191 : 11 : return !wc->masks.dp_hash;
192 : : case MFF_RECIRC_ID:
193 : 0 : return !wc->masks.recirc_id;
194 : : case MFF_CONJ_ID:
195 : 12 : return !wc->masks.conj_id;
196 : : case MFF_TUN_SRC:
197 : 6 : return !wc->masks.tunnel.ip_src;
198 : : case MFF_TUN_DST:
199 : 6 : return !wc->masks.tunnel.ip_dst;
200 : : case MFF_TUN_IPV6_SRC:
201 : 2 : return ipv6_mask_is_any(&wc->masks.tunnel.ipv6_src);
202 : : case MFF_TUN_IPV6_DST:
203 : 2 : return ipv6_mask_is_any(&wc->masks.tunnel.ipv6_dst);
204 : : case MFF_TUN_ID:
205 : 64 : return !wc->masks.tunnel.tun_id;
206 : : case MFF_TUN_TOS:
207 : 0 : return !wc->masks.tunnel.ip_tos;
208 : : case MFF_TUN_TTL:
209 : 0 : return !wc->masks.tunnel.ip_ttl;
210 : : case MFF_TUN_FLAGS:
211 : 2 : return !(wc->masks.tunnel.flags & FLOW_TNL_PUB_F_MASK);
212 : : case MFF_TUN_GBP_ID:
213 : 2 : return !wc->masks.tunnel.gbp_id;
214 : : case MFF_TUN_GBP_FLAGS:
215 : 2 : return !wc->masks.tunnel.gbp_flags;
216 : : CASE_MFF_TUN_METADATA:
217 : 75 : return !ULLONG_GET(wc->masks.tunnel.metadata.present.map,
218 : : mf->id - MFF_TUN_METADATA0);
219 : : case MFF_METADATA:
220 : 56770 : return !wc->masks.metadata;
221 : : case MFF_IN_PORT:
222 : : case MFF_IN_PORT_OXM:
223 : 7364 : return !wc->masks.in_port.ofp_port;
224 : : case MFF_SKB_PRIORITY:
225 : 0 : return !wc->masks.skb_priority;
226 : : case MFF_PKT_MARK:
227 : 7 : return !wc->masks.pkt_mark;
228 : : case MFF_CT_STATE:
229 : 692 : return !wc->masks.ct_state;
230 : : case MFF_CT_ZONE:
231 : 71 : return !wc->masks.ct_zone;
232 : : case MFF_CT_MARK:
233 : 41 : return !wc->masks.ct_mark;
234 : : case MFF_CT_LABEL:
235 : 84 : return ovs_u128_is_zero(wc->masks.ct_label);
236 : : CASE_MFF_REGS:
237 : 99092 : return !wc->masks.regs[mf->id - MFF_REG0];
238 : : CASE_MFF_XREGS:
239 : 36 : return !flow_get_xreg(&wc->masks, mf->id - MFF_XREG0);
240 : : CASE_MFF_XXREGS: {
241 : 0 : ovs_u128 value = flow_get_xxreg(&wc->masks, mf->id - MFF_XXREG0);
242 : 0 : return ovs_u128_is_zero(value);
243 : : }
244 : : case MFF_ACTSET_OUTPUT:
245 : 12 : return !wc->masks.actset_output;
246 : :
247 : : case MFF_ETH_SRC:
248 : 3874 : return eth_addr_is_zero(wc->masks.dl_src);
249 : : case MFF_ETH_DST:
250 : 5656 : return eth_addr_is_zero(wc->masks.dl_dst);
251 : : case MFF_ETH_TYPE:
252 : 21250 : return !wc->masks.dl_type;
253 : :
254 : : case MFF_ARP_SHA:
255 : : case MFF_ND_SLL:
256 : 826 : return eth_addr_is_zero(wc->masks.arp_sha);
257 : :
258 : : case MFF_ARP_THA:
259 : : case MFF_ND_TLL:
260 : 637 : return eth_addr_is_zero(wc->masks.arp_tha);
261 : :
262 : : case MFF_VLAN_TCI:
263 : 6483 : return !wc->masks.vlan_tci;
264 : : case MFF_DL_VLAN:
265 : 0 : return !(wc->masks.vlan_tci & htons(VLAN_VID_MASK));
266 : : case MFF_VLAN_VID:
267 : 873 : return !(wc->masks.vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI));
268 : : case MFF_DL_VLAN_PCP:
269 : : case MFF_VLAN_PCP:
270 : 7 : return !(wc->masks.vlan_tci & htons(VLAN_PCP_MASK));
271 : :
272 : : case MFF_MPLS_LABEL:
273 : 17 : return !(wc->masks.mpls_lse[0] & htonl(MPLS_LABEL_MASK));
274 : : case MFF_MPLS_TC:
275 : 1 : return !(wc->masks.mpls_lse[0] & htonl(MPLS_TC_MASK));
276 : : case MFF_MPLS_BOS:
277 : 1 : return !(wc->masks.mpls_lse[0] & htonl(MPLS_BOS_MASK));
278 : : case MFF_MPLS_TTL:
279 : 0 : return !(wc->masks.mpls_lse[0] & htonl(MPLS_TTL_MASK));
280 : :
281 : : case MFF_IPV4_SRC:
282 : 1457 : return !wc->masks.nw_src;
283 : : case MFF_IPV4_DST:
284 : 2216 : return !wc->masks.nw_dst;
285 : :
286 : : case MFF_IPV6_SRC:
287 : 688 : return ipv6_mask_is_any(&wc->masks.ipv6_src);
288 : : case MFF_IPV6_DST:
289 : 2361 : return ipv6_mask_is_any(&wc->masks.ipv6_dst);
290 : :
291 : : case MFF_IPV6_LABEL:
292 : 12 : return !wc->masks.ipv6_label;
293 : :
294 : : case MFF_IP_PROTO:
295 : 5041 : return !wc->masks.nw_proto;
296 : : case MFF_IP_DSCP:
297 : : case MFF_IP_DSCP_SHIFTED:
298 : 25 : return !(wc->masks.nw_tos & IP_DSCP_MASK);
299 : : case MFF_IP_ECN:
300 : 4 : return !(wc->masks.nw_tos & IP_ECN_MASK);
301 : : case MFF_IP_TTL:
302 : 3236 : return !wc->masks.nw_ttl;
303 : :
304 : : case MFF_ND_TARGET:
305 : 1172 : return ipv6_mask_is_any(&wc->masks.nd_target);
306 : :
307 : : case MFF_IP_FRAG:
308 : 52 : return !(wc->masks.nw_frag & FLOW_NW_FRAG_MASK);
309 : :
310 : : case MFF_ARP_OP:
311 : 1488 : return !wc->masks.nw_proto;
312 : : case MFF_ARP_SPA:
313 : 131 : return !wc->masks.nw_src;
314 : : case MFF_ARP_TPA:
315 : 1285 : return !wc->masks.nw_dst;
316 : :
317 : : case MFF_TCP_SRC:
318 : : case MFF_UDP_SRC:
319 : : case MFF_SCTP_SRC:
320 : : case MFF_ICMPV4_TYPE:
321 : : case MFF_ICMPV6_TYPE:
322 : 4138 : return !wc->masks.tp_src;
323 : : case MFF_TCP_DST:
324 : : case MFF_UDP_DST:
325 : : case MFF_SCTP_DST:
326 : : case MFF_ICMPV4_CODE:
327 : : case MFF_ICMPV6_CODE:
328 : 3881 : return !wc->masks.tp_dst;
329 : : case MFF_TCP_FLAGS:
330 : 18 : return !wc->masks.tcp_flags;
331 : :
332 : : case MFF_N_IDS:
333 : : default:
334 : 0 : OVS_NOT_REACHED();
335 : : }
336 : : }
337 : :
338 : : /* Initializes 'mask' with the wildcard bit pattern for field 'mf' within 'wc'.
339 : : * Each bit in 'mask' will be set to 1 if the bit is significant for matching
340 : : * purposes, or to 0 if it is wildcarded.
341 : : *
342 : : * The caller is responsible for ensuring that 'wc' corresponds to a flow that
343 : : * meets 'mf''s prerequisites. */
344 : : void
345 : 1990207 : mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
346 : : union mf_value *mask)
347 : : {
348 : 1990207 : mf_get_value(mf, &wc->masks, mask);
349 : 1990207 : }
350 : :
351 : : /* Tests whether 'mask' is a valid wildcard bit pattern for 'mf'. Returns true
352 : : * if the mask is valid, false otherwise. */
353 : : bool
354 : 253492 : mf_is_mask_valid(const struct mf_field *mf, const union mf_value *mask)
355 : : {
356 [ + + - ]: 253492 : switch (mf->maskable) {
357 : : case MFM_NONE:
358 [ + - + + ]: 107390 : return (is_all_zeros(mask, mf->n_bytes) ||
359 : 53695 : is_all_ones(mask, mf->n_bytes));
360 : :
361 : : case MFM_FULLY:
362 : 199797 : return true;
363 : : }
364 : :
365 : 0 : OVS_NOT_REACHED();
366 : : }
367 : :
368 : : /* Returns true if 'flow' meets the prerequisites for 'mf', false otherwise.
369 : : * Sets inspected bits in 'wc', if non-NULL. */
370 : : bool
371 : 5652912 : mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow,
372 : : struct flow_wildcards *wc)
373 : : {
374 [ + + + + : 5652912 : switch (mf->prereqs) {
+ + + + +
+ + + + +
+ - ]
375 : : case MFP_NONE:
376 : 1121921 : return true;
377 : : case MFP_ARP:
378 [ + + + + ]: 21346 : return (flow->dl_type == htons(ETH_TYPE_ARP) ||
379 : 41 : flow->dl_type == htons(ETH_TYPE_RARP));
380 : : case MFP_IPV4:
381 : 4482999 : return flow->dl_type == htons(ETH_TYPE_IP);
382 : : case MFP_IPV6:
383 : 4563 : return flow->dl_type == htons(ETH_TYPE_IPV6);
384 : : case MFP_VLAN_VID:
385 : 70 : return is_vlan(flow, wc);
386 : : case MFP_MPLS:
387 : 251 : return eth_type_mpls(flow->dl_type);
388 : : case MFP_IP_ANY:
389 : 9279 : return is_ip_any(flow);
390 : : case MFP_TCP:
391 [ + + ][ + + ]: 1201 : return is_tcp(flow, wc) && !(flow->nw_frag & FLOW_NW_FRAG_LATER);
392 : : case MFP_UDP:
393 [ + + ][ + + ]: 325 : return is_udp(flow, wc) && !(flow->nw_frag & FLOW_NW_FRAG_LATER);
394 : : case MFP_SCTP:
395 [ + + ][ + + ]: 20 : return is_sctp(flow, wc) && !(flow->nw_frag & FLOW_NW_FRAG_LATER);
396 : : case MFP_ICMPV4:
397 : 950 : return is_icmpv4(flow, wc);
398 : : case MFP_ICMPV6:
399 : 7046 : return is_icmpv6(flow, wc);
400 : : case MFP_ND:
401 : 1275 : return is_nd(flow, wc);
402 : : case MFP_ND_SOLICIT:
403 [ + - ][ + + ]: 992 : return is_nd(flow, wc) && flow->tp_src == htons(ND_NEIGHBOR_SOLICIT);
404 : : case MFP_ND_ADVERT:
405 [ + - ][ + + ]: 715 : return is_nd(flow, wc) && flow->tp_src == htons(ND_NEIGHBOR_ADVERT);
406 : : }
407 : :
408 : 0 : OVS_NOT_REACHED();
409 : : }
410 : :
411 : : /* Returns true if 'value' may be a valid value *as part of a masked match*,
412 : : * false otherwise.
413 : : *
414 : : * A value is not rejected just because it is not valid for the field in
415 : : * question, but only if it doesn't make sense to test the bits in question at
416 : : * all. For example, the MFF_VLAN_TCI field will never have a nonzero value
417 : : * without the VLAN_CFI bit being set, but we can't reject those values because
418 : : * it is still legitimate to test just for those bits (see the documentation
419 : : * for NXM_OF_VLAN_TCI in nicira-ext.h). On the other hand, there is never a
420 : : * reason to set the low bit of MFF_IP_DSCP to 1, so we reject that. */
421 : : bool
422 : 249711 : mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
423 : : {
424 [ + + + + : 249711 : switch (mf->id) {
+ + + + -
+ + + + +
+ + + - ]
425 : : case MFF_DP_HASH:
426 : : case MFF_RECIRC_ID:
427 : : case MFF_CONJ_ID:
428 : : case MFF_TUN_ID:
429 : : case MFF_TUN_SRC:
430 : : case MFF_TUN_DST:
431 : : case MFF_TUN_IPV6_SRC:
432 : : case MFF_TUN_IPV6_DST:
433 : : case MFF_TUN_TOS:
434 : : case MFF_TUN_TTL:
435 : : case MFF_TUN_GBP_ID:
436 : : case MFF_TUN_GBP_FLAGS:
437 : : CASE_MFF_TUN_METADATA:
438 : : case MFF_METADATA:
439 : : case MFF_IN_PORT:
440 : : case MFF_SKB_PRIORITY:
441 : : case MFF_PKT_MARK:
442 : : case MFF_CT_ZONE:
443 : : case MFF_CT_MARK:
444 : : case MFF_CT_LABEL:
445 : : CASE_MFF_REGS:
446 : : CASE_MFF_XREGS:
447 : : CASE_MFF_XXREGS:
448 : : case MFF_ETH_SRC:
449 : : case MFF_ETH_DST:
450 : : case MFF_ETH_TYPE:
451 : : case MFF_VLAN_TCI:
452 : : case MFF_MPLS_TTL:
453 : : case MFF_IPV4_SRC:
454 : : case MFF_IPV4_DST:
455 : : case MFF_IPV6_SRC:
456 : : case MFF_IPV6_DST:
457 : : case MFF_IP_PROTO:
458 : : case MFF_IP_TTL:
459 : : case MFF_ARP_SPA:
460 : : case MFF_ARP_TPA:
461 : : case MFF_ARP_SHA:
462 : : case MFF_ARP_THA:
463 : : case MFF_TCP_SRC:
464 : : case MFF_TCP_DST:
465 : : case MFF_UDP_SRC:
466 : : case MFF_UDP_DST:
467 : : case MFF_SCTP_SRC:
468 : : case MFF_SCTP_DST:
469 : : case MFF_ICMPV4_TYPE:
470 : : case MFF_ICMPV4_CODE:
471 : : case MFF_ICMPV6_TYPE:
472 : : case MFF_ICMPV6_CODE:
473 : : case MFF_ND_TARGET:
474 : : case MFF_ND_SLL:
475 : : case MFF_ND_TLL:
476 : 239341 : return true;
477 : :
478 : : case MFF_IN_PORT_OXM:
479 : : case MFF_ACTSET_OUTPUT: {
480 : : ofp_port_t port;
481 : 5600 : return !ofputil_port_from_ofp11(value->be32, &port);
482 : : }
483 : :
484 : : case MFF_IP_DSCP:
485 : 19 : return !(value->u8 & ~IP_DSCP_MASK);
486 : : case MFF_IP_DSCP_SHIFTED:
487 : 12 : return !(value->u8 & (~IP_DSCP_MASK >> 2));
488 : : case MFF_IP_ECN:
489 : 14 : return !(value->u8 & ~IP_ECN_MASK);
490 : : case MFF_IP_FRAG:
491 : 54 : return !(value->u8 & ~FLOW_NW_FRAG_MASK);
492 : : case MFF_TCP_FLAGS:
493 : 19 : return !(value->be16 & ~htons(0x0fff));
494 : :
495 : : case MFF_ARP_OP:
496 : 2961 : return !(value->be16 & htons(0xff00));
497 : :
498 : : case MFF_DL_VLAN:
499 : 0 : return !(value->be16 & htons(VLAN_CFI | VLAN_PCP_MASK));
500 : : case MFF_VLAN_VID:
501 : 899 : return !(value->be16 & htons(VLAN_PCP_MASK));
502 : :
503 : : case MFF_DL_VLAN_PCP:
504 : : case MFF_VLAN_PCP:
505 : 50 : return !(value->u8 & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT));
506 : :
507 : : case MFF_IPV6_LABEL:
508 : 16 : return !(value->be32 & ~htonl(IPV6_LABEL_MASK));
509 : :
510 : : case MFF_MPLS_LABEL:
511 : 29 : return !(value->be32 & ~htonl(MPLS_LABEL_MASK >> MPLS_LABEL_SHIFT));
512 : :
513 : : case MFF_MPLS_TC:
514 : 1 : return !(value->u8 & ~(MPLS_TC_MASK >> MPLS_TC_SHIFT));
515 : :
516 : : case MFF_MPLS_BOS:
517 : 1 : return !(value->u8 & ~(MPLS_BOS_MASK >> MPLS_BOS_SHIFT));
518 : :
519 : : case MFF_TUN_FLAGS:
520 : 2 : return !(value->be16 & ~htons(FLOW_TNL_PUB_F_MASK));
521 : :
522 : : case MFF_CT_STATE:
523 : 693 : return !(value->be32 & ~htonl(CS_SUPPORTED_MASK));
524 : :
525 : : case MFF_N_IDS:
526 : : default:
527 : 0 : OVS_NOT_REACHED();
528 : : }
529 : : }
530 : :
531 : : /* Copies the value of field 'mf' from 'flow' into 'value'. The caller is
532 : : * responsible for ensuring that 'flow' meets 'mf''s prerequisites. */
533 : : void
534 : 363770505 : mf_get_value(const struct mf_field *mf, const struct flow *flow,
535 : : union mf_value *value)
536 : : {
537 [ - - - + : 363770505 : switch (mf->id) {
+ + - + -
- - - - +
+ + + - +
+ + - + +
+ + + + +
+ + + + +
+ + - - +
+ + + - +
+ - - + -
+ + + + +
+ + - + +
+ - ]
538 : : case MFF_DP_HASH:
539 : 0 : value->be32 = htonl(flow->dp_hash);
540 : 0 : break;
541 : : case MFF_RECIRC_ID:
542 : 0 : value->be32 = htonl(flow->recirc_id);
543 : 0 : break;
544 : : case MFF_CONJ_ID:
545 : 0 : value->be32 = htonl(flow->conj_id);
546 : 0 : break;
547 : : case MFF_TUN_ID:
548 : 21292 : value->be64 = flow->tunnel.tun_id;
549 : 21292 : break;
550 : : case MFF_TUN_SRC:
551 : 4 : value->be32 = flow->tunnel.ip_src;
552 : 4 : break;
553 : : case MFF_TUN_DST:
554 : 18 : value->be32 = flow->tunnel.ip_dst;
555 : 18 : break;
556 : : case MFF_TUN_IPV6_SRC:
557 : 0 : value->ipv6 = flow->tunnel.ipv6_src;
558 : 0 : break;
559 : : case MFF_TUN_IPV6_DST:
560 : 20 : value->ipv6 = flow->tunnel.ipv6_dst;
561 : 20 : break;
562 : : case MFF_TUN_FLAGS:
563 : 0 : value->be16 = htons(flow->tunnel.flags & FLOW_TNL_PUB_F_MASK);
564 : 0 : break;
565 : : case MFF_TUN_GBP_ID:
566 : 0 : value->be16 = flow->tunnel.gbp_id;
567 : 0 : break;
568 : : case MFF_TUN_GBP_FLAGS:
569 : 0 : value->u8 = flow->tunnel.gbp_flags;
570 : 0 : break;
571 : : case MFF_TUN_TTL:
572 : 0 : value->u8 = flow->tunnel.ip_ttl;
573 : 0 : break;
574 : : case MFF_TUN_TOS:
575 : 0 : value->u8 = flow->tunnel.ip_tos;
576 : 0 : break;
577 : : CASE_MFF_TUN_METADATA:
578 : 42374 : tun_metadata_read(&flow->tunnel, mf, value);
579 : 42374 : break;
580 : :
581 : : case MFF_METADATA:
582 : 142526 : value->be64 = flow->metadata;
583 : 142526 : break;
584 : :
585 : : case MFF_IN_PORT:
586 : 22265 : value->be16 = htons(ofp_to_u16(flow->in_port.ofp_port));
587 : 22265 : break;
588 : : case MFF_IN_PORT_OXM:
589 : 8 : value->be32 = ofputil_port_to_ofp11(flow->in_port.ofp_port);
590 : 8 : break;
591 : : case MFF_ACTSET_OUTPUT:
592 : 0 : value->be32 = ofputil_port_to_ofp11(flow->actset_output);
593 : 0 : break;
594 : :
595 : : case MFF_SKB_PRIORITY:
596 : 1 : value->be32 = htonl(flow->skb_priority);
597 : 1 : break;
598 : :
599 : : case MFF_PKT_MARK:
600 : 13 : value->be32 = htonl(flow->pkt_mark);
601 : 13 : break;
602 : :
603 : : case MFF_CT_STATE:
604 : 580 : value->be32 = htonl(flow->ct_state);
605 : 580 : break;
606 : :
607 : : case MFF_CT_ZONE:
608 : 0 : value->be16 = htons(flow->ct_zone);
609 : 0 : break;
610 : :
611 : : case MFF_CT_MARK:
612 : 126 : value->be32 = htonl(flow->ct_mark);
613 : 126 : break;
614 : :
615 : : case MFF_CT_LABEL:
616 : 378 : value->be128 = hton128(flow->ct_label);
617 : 378 : break;
618 : :
619 : : CASE_MFF_REGS:
620 : 360829858 : value->be32 = htonl(flow->regs[mf->id - MFF_REG0]);
621 : 360829857 : break;
622 : :
623 : : CASE_MFF_XREGS:
624 : 210 : value->be64 = htonll(flow_get_xreg(flow, mf->id - MFF_XREG0));
625 : 210 : break;
626 : :
627 : : CASE_MFF_XXREGS:
628 : 315090 : value->be128 = hton128(flow_get_xxreg(flow, mf->id - MFF_XXREG0));
629 : 315090 : break;
630 : :
631 : : case MFF_ETH_SRC:
632 : 220219 : value->mac = flow->dl_src;
633 : 220219 : break;
634 : :
635 : : case MFF_ETH_DST:
636 : 209513 : value->mac = flow->dl_dst;
637 : 209513 : break;
638 : :
639 : : case MFF_ETH_TYPE:
640 : 652056 : value->be16 = flow->dl_type;
641 : 652056 : break;
642 : :
643 : : case MFF_VLAN_TCI:
644 : 16741 : value->be16 = flow->vlan_tci;
645 : 16741 : break;
646 : :
647 : : case MFF_DL_VLAN:
648 : 4 : value->be16 = flow->vlan_tci & htons(VLAN_VID_MASK);
649 : 4 : break;
650 : : case MFF_VLAN_VID:
651 : 134 : value->be16 = flow->vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI);
652 : 134 : break;
653 : :
654 : : case MFF_DL_VLAN_PCP:
655 : : case MFF_VLAN_PCP:
656 : 80 : value->u8 = vlan_tci_to_pcp(flow->vlan_tci);
657 : 80 : break;
658 : :
659 : : case MFF_MPLS_LABEL:
660 : 174 : value->be32 = htonl(mpls_lse_to_label(flow->mpls_lse[0]));
661 : 174 : break;
662 : :
663 : : case MFF_MPLS_TC:
664 : 80 : value->u8 = mpls_lse_to_tc(flow->mpls_lse[0]);
665 : 80 : break;
666 : :
667 : : case MFF_MPLS_BOS:
668 : 0 : value->u8 = mpls_lse_to_bos(flow->mpls_lse[0]);
669 : 0 : break;
670 : :
671 : : case MFF_MPLS_TTL:
672 : 0 : value->u8 = mpls_lse_to_ttl(flow->mpls_lse[0]);
673 : 0 : break;
674 : :
675 : : case MFF_IPV4_SRC:
676 : 67911 : value->be32 = flow->nw_src;
677 : 67911 : break;
678 : :
679 : : case MFF_IPV4_DST:
680 : 104081 : value->be32 = flow->nw_dst;
681 : 104081 : break;
682 : :
683 : : case MFF_IPV6_SRC:
684 : 29253 : value->ipv6 = flow->ipv6_src;
685 : 29253 : break;
686 : :
687 : : case MFF_IPV6_DST:
688 : 133787 : value->ipv6 = flow->ipv6_dst;
689 : 133787 : break;
690 : :
691 : : case MFF_IPV6_LABEL:
692 : 0 : value->be32 = flow->ipv6_label;
693 : 0 : break;
694 : :
695 : : case MFF_IP_PROTO:
696 : 154706 : value->u8 = flow->nw_proto;
697 : 154706 : break;
698 : :
699 : : case MFF_IP_DSCP:
700 : 19 : value->u8 = flow->nw_tos & IP_DSCP_MASK;
701 : 19 : break;
702 : :
703 : : case MFF_IP_DSCP_SHIFTED:
704 : 0 : value->u8 = flow->nw_tos >> 2;
705 : 0 : break;
706 : :
707 : : case MFF_IP_ECN:
708 : 0 : value->u8 = flow->nw_tos & IP_ECN_MASK;
709 : 0 : break;
710 : :
711 : : case MFF_IP_TTL:
712 : 109389 : value->u8 = flow->nw_ttl;
713 : 109389 : break;
714 : :
715 : : case MFF_IP_FRAG:
716 : 0 : value->u8 = flow->nw_frag;
717 : 0 : break;
718 : :
719 : : case MFF_ARP_OP:
720 : 98040 : value->be16 = htons(flow->nw_proto);
721 : 98040 : break;
722 : :
723 : : case MFF_ARP_SPA:
724 : 55172 : value->be32 = flow->nw_src;
725 : 55172 : break;
726 : :
727 : : case MFF_ARP_TPA:
728 : 93368 : value->be32 = flow->nw_dst;
729 : 93368 : break;
730 : :
731 : : case MFF_ARP_SHA:
732 : : case MFF_ND_SLL:
733 : 70991 : value->mac = flow->arp_sha;
734 : 70991 : break;
735 : :
736 : : case MFF_ARP_THA:
737 : : case MFF_ND_TLL:
738 : 16154 : value->mac = flow->arp_tha;
739 : 16154 : break;
740 : :
741 : : case MFF_TCP_SRC:
742 : : case MFF_UDP_SRC:
743 : : case MFF_SCTP_SRC:
744 : 2447 : value->be16 = flow->tp_src;
745 : 2447 : break;
746 : :
747 : : case MFF_TCP_DST:
748 : : case MFF_UDP_DST:
749 : : case MFF_SCTP_DST:
750 : 2423 : value->be16 = flow->tp_dst;
751 : 2423 : break;
752 : :
753 : : case MFF_TCP_FLAGS:
754 : 0 : value->be16 = flow->tcp_flags;
755 : 0 : break;
756 : :
757 : : case MFF_ICMPV4_TYPE:
758 : : case MFF_ICMPV6_TYPE:
759 : 152161 : value->u8 = ntohs(flow->tp_src);
760 : 152161 : break;
761 : :
762 : : case MFF_ICMPV4_CODE:
763 : : case MFF_ICMPV6_CODE:
764 : 149752 : value->u8 = ntohs(flow->tp_dst);
765 : 149752 : break;
766 : :
767 : : case MFF_ND_TARGET:
768 : 57087 : value->ipv6 = flow->nd_target;
769 : 57087 : break;
770 : :
771 : : case MFF_N_IDS:
772 : : default:
773 : 0 : OVS_NOT_REACHED();
774 : : }
775 : 363770504 : }
776 : :
777 : : /* Makes 'match' match field 'mf' exactly, with the value matched taken from
778 : : * 'value'. The caller is responsible for ensuring that 'match' meets 'mf''s
779 : : * prerequisites.
780 : : *
781 : : * If non-NULL, 'err_str' returns a malloc'ed string describing any errors
782 : : * with the request or NULL if there is no error. The caller is reponsible
783 : : * for freeing the string. */
784 : : void
785 : 1567305 : mf_set_value(const struct mf_field *mf,
786 : : const union mf_value *value, struct match *match, char **err_str)
787 : : {
788 [ + + ]: 1567305 : if (err_str) {
789 : 225002 : *err_str = NULL;
790 : : }
791 : :
792 [ + - + + : 1567305 : switch (mf->id) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ - ]
793 : : case MFF_DP_HASH:
794 : 6 : match_set_dp_hash(match, ntohl(value->be32));
795 : 6 : break;
796 : : case MFF_RECIRC_ID:
797 : 0 : match_set_recirc_id(match, ntohl(value->be32));
798 : 0 : break;
799 : : case MFF_CONJ_ID:
800 : 18 : match_set_conj_id(match, ntohl(value->be32));
801 : 18 : break;
802 : : case MFF_TUN_ID:
803 : 68 : match_set_tun_id(match, value->be64);
804 : 68 : break;
805 : : case MFF_TUN_SRC:
806 : 6 : match_set_tun_src(match, value->be32);
807 : 6 : break;
808 : : case MFF_TUN_DST:
809 : 6 : match_set_tun_dst(match, value->be32);
810 : 6 : break;
811 : : case MFF_TUN_IPV6_SRC:
812 : 2 : match_set_tun_ipv6_src(match, &value->ipv6);
813 : 2 : break;
814 : : case MFF_TUN_IPV6_DST:
815 : 2 : match_set_tun_ipv6_dst(match, &value->ipv6);
816 : 2 : break;
817 : : case MFF_TUN_FLAGS:
818 : 1 : match_set_tun_flags(match, ntohs(value->be16));
819 : 1 : break;
820 : : case MFF_TUN_GBP_ID:
821 : 2 : match_set_tun_gbp_id(match, value->be16);
822 : 2 : break;
823 : : case MFF_TUN_GBP_FLAGS:
824 : 2 : match_set_tun_gbp_flags(match, value->u8);
825 : 2 : break;
826 : : case MFF_TUN_TOS:
827 : 1 : match_set_tun_tos(match, value->u8);
828 : 1 : break;
829 : : case MFF_TUN_TTL:
830 : 1 : match_set_tun_ttl(match, value->u8);
831 : 1 : break;
832 : : CASE_MFF_TUN_METADATA:
833 : 74 : tun_metadata_set_match(mf, value, NULL, match, err_str);
834 : 74 : break;
835 : :
836 : : case MFF_METADATA:
837 : 56608 : match_set_metadata(match, value->be64);
838 : 56608 : break;
839 : :
840 : : case MFF_IN_PORT:
841 : 2811 : match_set_in_port(match, u16_to_ofp(ntohs(value->be16)));
842 : 2811 : break;
843 : :
844 : : case MFF_IN_PORT_OXM: {
845 : : ofp_port_t port;
846 : 5588 : ofputil_port_from_ofp11(value->be32, &port);
847 : 5588 : match_set_in_port(match, port);
848 : 5588 : break;
849 : : }
850 : : case MFF_ACTSET_OUTPUT: {
851 : : ofp_port_t port;
852 : 17 : ofputil_port_from_ofp11(value->be32, &port);
853 : 17 : match_set_actset_output(match, port);
854 : 17 : break;
855 : : }
856 : :
857 : : case MFF_SKB_PRIORITY:
858 : 2 : match_set_skb_priority(match, ntohl(value->be32));
859 : 2 : break;
860 : :
861 : : case MFF_PKT_MARK:
862 : 8 : match_set_pkt_mark(match, ntohl(value->be32));
863 : 8 : break;
864 : :
865 : : case MFF_CT_STATE:
866 : 1 : match_set_ct_state(match, ntohl(value->be32));
867 : 1 : break;
868 : :
869 : : case MFF_CT_ZONE:
870 : 106 : match_set_ct_zone(match, ntohs(value->be16));
871 : 106 : break;
872 : :
873 : : case MFF_CT_MARK:
874 : 53 : match_set_ct_mark(match, ntohl(value->be32));
875 : 53 : break;
876 : :
877 : : case MFF_CT_LABEL:
878 : 29 : match_set_ct_label(match, ntoh128(value->be128));
879 : 29 : break;
880 : :
881 : : CASE_MFF_REGS:
882 : 451646 : match_set_reg(match, mf->id - MFF_REG0, ntohl(value->be32));
883 : 451646 : break;
884 : :
885 : : CASE_MFF_XREGS:
886 : 31 : match_set_xreg(match, mf->id - MFF_XREG0, ntohll(value->be64));
887 : 31 : break;
888 : :
889 : : CASE_MFF_XXREGS:
890 : 21395 : match_set_xxreg(match, mf->id - MFF_XXREG0, ntoh128(value->be128));
891 : 21395 : break;
892 : :
893 : : case MFF_ETH_SRC:
894 : 28136 : match_set_dl_src(match, value->mac);
895 : 28136 : break;
896 : :
897 : : case MFF_ETH_DST:
898 : 77577 : match_set_dl_dst(match, value->mac);
899 : 77577 : break;
900 : :
901 : : case MFF_ETH_TYPE:
902 : 347035 : match_set_dl_type(match, value->be16);
903 : 347035 : break;
904 : :
905 : : case MFF_VLAN_TCI:
906 : 70 : match_set_dl_tci(match, value->be16);
907 : 70 : break;
908 : :
909 : : case MFF_DL_VLAN:
910 : 4681 : match_set_dl_vlan(match, value->be16);
911 : 4681 : break;
912 : : case MFF_VLAN_VID:
913 : 170 : match_set_vlan_vid(match, value->be16);
914 : 170 : break;
915 : :
916 : : case MFF_DL_VLAN_PCP:
917 : : case MFF_VLAN_PCP:
918 : 29 : match_set_dl_vlan_pcp(match, value->u8);
919 : 29 : break;
920 : :
921 : : case MFF_MPLS_LABEL:
922 : 26 : match_set_mpls_label(match, 0, value->be32);
923 : 26 : break;
924 : :
925 : : case MFF_MPLS_TC:
926 : 2 : match_set_mpls_tc(match, 0, value->u8);
927 : 2 : break;
928 : :
929 : : case MFF_MPLS_BOS:
930 : 2 : match_set_mpls_bos(match, 0, value->u8);
931 : 2 : break;
932 : :
933 : : case MFF_MPLS_TTL:
934 : 0 : match_set_mpls_ttl(match, 0, value->u8);
935 : 0 : break;
936 : :
937 : : case MFF_IPV4_SRC:
938 : 30014 : match_set_nw_src(match, value->be32);
939 : 30014 : break;
940 : :
941 : : case MFF_IPV4_DST:
942 : 28251 : match_set_nw_dst(match, value->be32);
943 : 28251 : break;
944 : :
945 : : case MFF_IPV6_SRC:
946 : 15239 : match_set_ipv6_src(match, &value->ipv6);
947 : 15239 : break;
948 : :
949 : : case MFF_IPV6_DST:
950 : 54579 : match_set_ipv6_dst(match, &value->ipv6);
951 : 54579 : break;
952 : :
953 : : case MFF_IPV6_LABEL:
954 : 11 : match_set_ipv6_label(match, value->be32);
955 : 11 : break;
956 : :
957 : : case MFF_IP_PROTO:
958 : 82183 : match_set_nw_proto(match, value->u8);
959 : 82183 : break;
960 : :
961 : : case MFF_IP_DSCP:
962 : 19 : match_set_nw_dscp(match, value->u8);
963 : 19 : break;
964 : :
965 : : case MFF_IP_DSCP_SHIFTED:
966 : 11 : match_set_nw_dscp(match, value->u8 << 2);
967 : 11 : break;
968 : :
969 : : case MFF_IP_ECN:
970 : 6 : match_set_nw_ecn(match, value->u8);
971 : 6 : break;
972 : :
973 : : case MFF_IP_TTL:
974 : 57918 : match_set_nw_ttl(match, value->u8);
975 : 57918 : break;
976 : :
977 : : case MFF_IP_FRAG:
978 : 63 : match_set_nw_frag(match, value->u8);
979 : 63 : break;
980 : :
981 : : case MFF_ARP_OP:
982 : 48676 : match_set_nw_proto(match, ntohs(value->be16));
983 : 48676 : break;
984 : :
985 : : case MFF_ARP_SPA:
986 : 751 : match_set_nw_src(match, value->be32);
987 : 751 : break;
988 : :
989 : : case MFF_ARP_TPA:
990 : 46059 : match_set_nw_dst(match, value->be32);
991 : 46059 : break;
992 : :
993 : : case MFF_ARP_SHA:
994 : : case MFF_ND_SLL:
995 : 9547 : match_set_arp_sha(match, value->mac);
996 : 9547 : break;
997 : :
998 : : case MFF_ARP_THA:
999 : : case MFF_ND_TLL:
1000 : 7076 : match_set_arp_tha(match, value->mac);
1001 : 7076 : break;
1002 : :
1003 : : case MFF_TCP_SRC:
1004 : : case MFF_UDP_SRC:
1005 : : case MFF_SCTP_SRC:
1006 : 1192 : match_set_tp_src(match, value->be16);
1007 : 1192 : break;
1008 : :
1009 : : case MFF_TCP_DST:
1010 : : case MFF_UDP_DST:
1011 : : case MFF_SCTP_DST:
1012 : 1236 : match_set_tp_dst(match, value->be16);
1013 : 1236 : break;
1014 : :
1015 : : case MFF_TCP_FLAGS:
1016 : 7 : match_set_tcp_flags(match, value->be16);
1017 : 7 : break;
1018 : :
1019 : : case MFF_ICMPV4_TYPE:
1020 : : case MFF_ICMPV6_TYPE:
1021 : 80012 : match_set_icmp_type(match, value->u8);
1022 : 80012 : break;
1023 : :
1024 : : case MFF_ICMPV4_CODE:
1025 : : case MFF_ICMPV6_CODE:
1026 : 78531 : match_set_icmp_code(match, value->u8);
1027 : 78531 : break;
1028 : :
1029 : : case MFF_ND_TARGET:
1030 : 29712 : match_set_nd_target(match, &value->ipv6);
1031 : 29712 : break;
1032 : :
1033 : : case MFF_N_IDS:
1034 : : default:
1035 : 0 : OVS_NOT_REACHED();
1036 : : }
1037 : 1567305 : }
1038 : :
1039 : : /* Unwildcard the bits in 'mask' of the 'wc' member field described by 'mf'.
1040 : : * The caller is responsible for ensuring that 'wc' meets 'mf''s
1041 : : * prerequisites. */
1042 : : void
1043 : 903466 : mf_mask_field_masked(const struct mf_field *mf, const union mf_value *mask,
1044 : : struct flow_wildcards *wc)
1045 : : {
1046 : : union mf_value temp_mask;
1047 : : /* For MFF_DL_VLAN, we cannot send a all 1's to flow_set_dl_vlan() as that
1048 : : * will be considered as OFP10_VLAN_NONE. So make sure the mask only has
1049 : : * valid bits in this case. */
1050 [ + + ]: 903466 : if (mf->id == MFF_DL_VLAN) {
1051 : 2 : temp_mask.be16 = htons(VLAN_VID_MASK) & mask->be16;
1052 : 2 : mask = &temp_mask;
1053 : : }
1054 : :
1055 : : union mf_value mask_value;
1056 : :
1057 : 903466 : mf_get_value(mf, &wc->masks, &mask_value);
1058 [ + + ]: 7510395 : for (size_t i = 0; i < mf->n_bytes; i++) {
1059 : 6606930 : mask_value.b[i] |= mask->b[i];
1060 : : }
1061 : 903465 : mf_set_flow_value(mf, &mask_value, &wc->masks);
1062 : 903466 : }
1063 : :
1064 : : /* Unwildcard 'wc' member field described by 'mf'. The caller is
1065 : : * responsible for ensuring that 'mask' meets 'mf''s prerequisites. */
1066 : : void
1067 : 12 : mf_mask_field(const struct mf_field *mf, struct flow_wildcards *wc)
1068 : : {
1069 : 12 : mf_mask_field_masked(mf, &exact_match_mask, wc);
1070 : 12 : }
1071 : :
1072 : : static int
1073 : 70306 : field_len(const struct mf_field *mf, const union mf_value *value_)
1074 : : {
1075 : 70306 : const uint8_t *value = &value_->u8;
1076 : : int i;
1077 : :
1078 [ + + ]: 70306 : if (!mf->variable_len) {
1079 : 69516 : return mf->n_bytes;
1080 : : }
1081 : :
1082 [ - + ]: 790 : if (!value) {
1083 : 0 : return 0;
1084 : : }
1085 : :
1086 [ + + ]: 96512 : for (i = 0; i < mf->n_bytes; i++) {
1087 [ + + ]: 96470 : if (value[i] != 0) {
1088 : 748 : break;
1089 : : }
1090 : : }
1091 : :
1092 : 790 : return mf->n_bytes - i;
1093 : : }
1094 : :
1095 : : /* Returns the effective length of the field. For fixed length fields,
1096 : : * this is just the defined length. For variable length fields, it is
1097 : : * the minimum size encoding that retains the same meaning (i.e.
1098 : : * discarding leading zeros).
1099 : : *
1100 : : * 'is_masked' returns (if non-NULL) whether the original contained
1101 : : * a mask. Otherwise, a mask that is the same length as the value
1102 : : * might be misinterpreted as an exact match. */
1103 : : int
1104 : 69948 : mf_field_len(const struct mf_field *mf, const union mf_value *value,
1105 : : const union mf_value *mask, bool *is_masked_)
1106 : : {
1107 : : int len, mask_len;
1108 [ + + ][ + + ]: 69948 : bool is_masked = mask && !is_all_ones(mask, mf->n_bytes);
1109 : :
1110 : 69948 : len = field_len(mf, value);
1111 [ + + ]: 69948 : if (is_masked) {
1112 : 358 : mask_len = field_len(mf, mask);
1113 : 358 : len = MAX(len, mask_len);
1114 : : }
1115 : :
1116 [ + + ]: 69948 : if (is_masked_) {
1117 : 69933 : *is_masked_ = is_masked;
1118 : : }
1119 : :
1120 : 69948 : return len;
1121 : : }
1122 : :
1123 : : /* Sets 'flow' member field described by 'mf' to 'value'. The caller is
1124 : : * responsible for ensuring that 'flow' meets 'mf''s prerequisites.*/
1125 : : void
1126 : 68143635 : mf_set_flow_value(const struct mf_field *mf,
1127 : : const union mf_value *value, struct flow *flow)
1128 : : {
1129 [ - - - + : 68143635 : switch (mf->id) {
+ + - + -
- - - - +
+ + + - +
+ - - + +
+ + + + +
+ + + + +
+ + - - +
+ + + - +
+ - - + -
+ + + + +
+ + - + +
+ - ]
1130 : : case MFF_DP_HASH:
1131 : 0 : flow->dp_hash = ntohl(value->be32);
1132 : 0 : break;
1133 : : case MFF_RECIRC_ID:
1134 : 0 : flow->recirc_id = ntohl(value->be32);
1135 : 0 : break;
1136 : : case MFF_CONJ_ID:
1137 : 0 : flow->conj_id = ntohl(value->be32);
1138 : 0 : break;
1139 : : case MFF_TUN_ID:
1140 : 12355 : flow->tunnel.tun_id = value->be64;
1141 : 12355 : break;
1142 : : case MFF_TUN_SRC:
1143 : 4 : flow->tunnel.ip_src = value->be32;
1144 : 4 : break;
1145 : : case MFF_TUN_DST:
1146 : 18 : flow->tunnel.ip_dst = value->be32;
1147 : 18 : break;
1148 : : case MFF_TUN_IPV6_SRC:
1149 : 0 : flow->tunnel.ipv6_src = value->ipv6;
1150 : 0 : break;
1151 : : case MFF_TUN_IPV6_DST:
1152 : 20 : flow->tunnel.ipv6_dst = value->ipv6;
1153 : 20 : break;
1154 : : case MFF_TUN_FLAGS:
1155 : 0 : flow->tunnel.flags = (flow->tunnel.flags & ~FLOW_TNL_PUB_F_MASK) |
1156 : 0 : ntohs(value->be16);
1157 : 0 : break;
1158 : : case MFF_TUN_GBP_ID:
1159 : 0 : flow->tunnel.gbp_id = value->be16;
1160 : 0 : break;
1161 : : case MFF_TUN_GBP_FLAGS:
1162 : 0 : flow->tunnel.gbp_flags = value->u8;
1163 : 0 : break;
1164 : : case MFF_TUN_TOS:
1165 : 0 : flow->tunnel.ip_tos = value->u8;
1166 : 0 : break;
1167 : : case MFF_TUN_TTL:
1168 : 0 : flow->tunnel.ip_ttl = value->u8;
1169 : 0 : break;
1170 : : CASE_MFF_TUN_METADATA:
1171 : 24548 : tun_metadata_write(&flow->tunnel, mf, value);
1172 : 24548 : break;
1173 : : case MFF_METADATA:
1174 : 142308 : flow->metadata = value->be64;
1175 : 142308 : break;
1176 : :
1177 : : case MFF_IN_PORT:
1178 : 18510 : flow->in_port.ofp_port = u16_to_ofp(ntohs(value->be16));
1179 : 18510 : break;
1180 : :
1181 : : case MFF_IN_PORT_OXM:
1182 : 1 : ofputil_port_from_ofp11(value->be32, &flow->in_port.ofp_port);
1183 : 1 : break;
1184 : : case MFF_ACTSET_OUTPUT:
1185 : 0 : ofputil_port_from_ofp11(value->be32, &flow->actset_output);
1186 : 0 : break;
1187 : :
1188 : : case MFF_SKB_PRIORITY:
1189 : 1 : flow->skb_priority = ntohl(value->be32);
1190 : 1 : break;
1191 : :
1192 : : case MFF_PKT_MARK:
1193 : 13 : flow->pkt_mark = ntohl(value->be32);
1194 : 13 : break;
1195 : :
1196 : : case MFF_CT_STATE:
1197 : 0 : flow->ct_state = ntohl(value->be32);
1198 : 0 : break;
1199 : :
1200 : : case MFF_CT_ZONE:
1201 : 0 : flow->ct_zone = ntohs(value->be16);
1202 : 0 : break;
1203 : :
1204 : : case MFF_CT_MARK:
1205 : 126 : flow->ct_mark = ntohl(value->be32);
1206 : 126 : break;
1207 : :
1208 : : case MFF_CT_LABEL:
1209 : 114 : flow->ct_label = ntoh128(value->be128);
1210 : 114 : break;
1211 : :
1212 : : CASE_MFF_REGS:
1213 : 67707484 : flow->regs[mf->id - MFF_REG0] = ntohl(value->be32);
1214 : 67707485 : break;
1215 : :
1216 : : CASE_MFF_XREGS:
1217 : 164 : flow_set_xreg(flow, mf->id - MFF_XREG0, ntohll(value->be64));
1218 : 164 : break;
1219 : :
1220 : : CASE_MFF_XXREGS:
1221 : 19038 : flow_set_xxreg(flow, mf->id - MFF_XXREG0, ntoh128(value->be128));
1222 : 19038 : break;
1223 : :
1224 : : case MFF_ETH_SRC:
1225 : 130001 : flow->dl_src = value->mac;
1226 : 130001 : break;
1227 : :
1228 : : case MFF_ETH_DST:
1229 : 13531 : flow->dl_dst = value->mac;
1230 : 13531 : break;
1231 : :
1232 : : case MFF_ETH_TYPE:
1233 : 544 : flow->dl_type = value->be16;
1234 : 544 : break;
1235 : :
1236 : : case MFF_VLAN_TCI:
1237 : 15 : flow->vlan_tci = value->be16;
1238 : 15 : break;
1239 : :
1240 : : case MFF_DL_VLAN:
1241 : 4 : flow_set_dl_vlan(flow, value->be16);
1242 : 4 : break;
1243 : : case MFF_VLAN_VID:
1244 : 134 : flow_set_vlan_vid(flow, value->be16);
1245 : 134 : break;
1246 : :
1247 : : case MFF_DL_VLAN_PCP:
1248 : : case MFF_VLAN_PCP:
1249 : 80 : flow_set_vlan_pcp(flow, value->u8);
1250 : 80 : break;
1251 : :
1252 : : case MFF_MPLS_LABEL:
1253 : 174 : flow_set_mpls_label(flow, 0, value->be32);
1254 : 174 : break;
1255 : :
1256 : : case MFF_MPLS_TC:
1257 : 80 : flow_set_mpls_tc(flow, 0, value->u8);
1258 : 80 : break;
1259 : :
1260 : : case MFF_MPLS_BOS:
1261 : 0 : flow_set_mpls_bos(flow, 0, value->u8);
1262 : 0 : break;
1263 : :
1264 : : case MFF_MPLS_TTL:
1265 : 0 : flow_set_mpls_ttl(flow, 0, value->u8);
1266 : 0 : break;
1267 : :
1268 : : case MFF_IPV4_SRC:
1269 : 614 : flow->nw_src = value->be32;
1270 : 614 : break;
1271 : :
1272 : : case MFF_IPV4_DST:
1273 : 4239 : flow->nw_dst = value->be32;
1274 : 4239 : break;
1275 : :
1276 : : case MFF_IPV6_SRC:
1277 : 85 : flow->ipv6_src = value->ipv6;
1278 : 85 : break;
1279 : :
1280 : : case MFF_IPV6_DST:
1281 : 4 : flow->ipv6_dst = value->ipv6;
1282 : 4 : break;
1283 : :
1284 : : case MFF_IPV6_LABEL:
1285 : 0 : flow->ipv6_label = value->be32 & htonl(IPV6_LABEL_MASK);
1286 : 0 : break;
1287 : :
1288 : : case MFF_IP_PROTO:
1289 : 452 : flow->nw_proto = value->u8;
1290 : 452 : break;
1291 : :
1292 : : case MFF_IP_DSCP:
1293 : 19 : flow->nw_tos &= ~IP_DSCP_MASK;
1294 : 19 : flow->nw_tos |= value->u8 & IP_DSCP_MASK;
1295 : 19 : break;
1296 : :
1297 : : case MFF_IP_DSCP_SHIFTED:
1298 : 0 : flow->nw_tos &= ~IP_DSCP_MASK;
1299 : 0 : flow->nw_tos |= value->u8 << 2;
1300 : 0 : break;
1301 : :
1302 : : case MFF_IP_ECN:
1303 : 0 : flow->nw_tos &= ~IP_ECN_MASK;
1304 : 0 : flow->nw_tos |= value->u8 & IP_ECN_MASK;
1305 : 0 : break;
1306 : :
1307 : : case MFF_IP_TTL:
1308 : 33 : flow->nw_ttl = value->u8;
1309 : 33 : break;
1310 : :
1311 : : case MFF_IP_FRAG:
1312 : 0 : flow->nw_frag = value->u8 & FLOW_NW_FRAG_MASK;
1313 : 0 : break;
1314 : :
1315 : : case MFF_ARP_OP:
1316 : 3710 : flow->nw_proto = ntohs(value->be16);
1317 : 3710 : break;
1318 : :
1319 : : case MFF_ARP_SPA:
1320 : 28785 : flow->nw_src = value->be32;
1321 : 28785 : break;
1322 : :
1323 : : case MFF_ARP_TPA:
1324 : 3759 : flow->nw_dst = value->be32;
1325 : 3759 : break;
1326 : :
1327 : : case MFF_ARP_SHA:
1328 : : case MFF_ND_SLL:
1329 : 28411 : flow->arp_sha = value->mac;
1330 : 28411 : break;
1331 : :
1332 : : case MFF_ARP_THA:
1333 : : case MFF_ND_TLL:
1334 : 3278 : flow->arp_tha = value->mac;
1335 : 3278 : break;
1336 : :
1337 : : case MFF_TCP_SRC:
1338 : : case MFF_UDP_SRC:
1339 : : case MFF_SCTP_SRC:
1340 : 481 : flow->tp_src = value->be16;
1341 : 481 : break;
1342 : :
1343 : : case MFF_TCP_DST:
1344 : : case MFF_UDP_DST:
1345 : : case MFF_SCTP_DST:
1346 : 458 : flow->tp_dst = value->be16;
1347 : 458 : break;
1348 : :
1349 : : case MFF_TCP_FLAGS:
1350 : 0 : flow->tcp_flags = value->be16;
1351 : 0 : break;
1352 : :
1353 : : case MFF_ICMPV4_TYPE:
1354 : : case MFF_ICMPV6_TYPE:
1355 : 19 : flow->tp_src = htons(value->u8);
1356 : 19 : break;
1357 : :
1358 : : case MFF_ICMPV4_CODE:
1359 : : case MFF_ICMPV6_CODE:
1360 : 10 : flow->tp_dst = htons(value->u8);
1361 : 10 : break;
1362 : :
1363 : : case MFF_ND_TARGET:
1364 : 11 : flow->nd_target = value->ipv6;
1365 : 11 : break;
1366 : :
1367 : : case MFF_N_IDS:
1368 : : default:
1369 : 0 : OVS_NOT_REACHED();
1370 : : }
1371 : 68143636 : }
1372 : :
1373 : : /* Consider each of 'src', 'mask', and 'dst' as if they were arrays of 8*n
1374 : : * bits. Then, for each 0 <= i < 8 * n such that mask[i] == 1, sets dst[i] =
1375 : : * src[i]. */
1376 : : static void
1377 : 825361 : apply_mask(const uint8_t *src, const uint8_t *mask, uint8_t *dst, size_t n)
1378 : : {
1379 : : size_t i;
1380 : :
1381 [ + + ]: 4645900 : for (i = 0; i < n; i++) {
1382 : 3820539 : dst[i] = (src[i] & mask[i]) | (dst[i] & ~mask[i]);
1383 : : }
1384 : 825361 : }
1385 : :
1386 : : /* Sets 'flow' member field described by 'field' to 'value', except that bits
1387 : : * for which 'mask' has a 0-bit keep their existing values. The caller is
1388 : : * responsible for ensuring that 'flow' meets 'field''s prerequisites.*/
1389 : : void
1390 : 825360 : mf_set_flow_value_masked(const struct mf_field *field,
1391 : : const union mf_value *value,
1392 : : const union mf_value *mask,
1393 : : struct flow *flow)
1394 : : {
1395 : : union mf_value tmp;
1396 : :
1397 : 825360 : mf_get_value(field, flow, &tmp);
1398 : 825360 : apply_mask((const uint8_t *) value, (const uint8_t *) mask,
1399 : 825360 : (uint8_t *) &tmp, field->n_bytes);
1400 : 825361 : mf_set_flow_value(field, &tmp, flow);
1401 : 825361 : }
1402 : :
1403 : : bool
1404 : 3830 : mf_is_tun_metadata(const struct mf_field *mf)
1405 : : {
1406 [ + + ][ + + ]: 3830 : return mf->id >= MFF_TUN_METADATA0 &&
1407 : 3829 : mf->id < MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS;
1408 : : }
1409 : :
1410 : : /* Returns true if 'mf' has previously been set in 'flow', false if
1411 : : * it contains a non-default value.
1412 : : *
1413 : : * The caller is responsible for ensuring that 'flow' meets 'mf''s
1414 : : * prerequisites. */
1415 : : bool
1416 : 3681 : mf_is_set(const struct mf_field *mf, const struct flow *flow)
1417 : : {
1418 [ + - ]: 3681 : if (!mf_is_tun_metadata(mf)) {
1419 : : union mf_value value;
1420 : :
1421 : 3681 : mf_get_value(mf, flow, &value);
1422 : 3681 : return !is_all_zeros(&value, mf->n_bytes);
1423 : : } else {
1424 : 0 : return ULLONG_GET(flow->tunnel.metadata.present.map,
1425 : : mf->id - MFF_TUN_METADATA0);
1426 : : }
1427 : : }
1428 : :
1429 : : /* Makes 'match' wildcard field 'mf'.
1430 : : *
1431 : : * The caller is responsible for ensuring that 'match' meets 'mf''s
1432 : : * prerequisites.
1433 : : *
1434 : : * If non-NULL, 'err_str' returns a malloc'ed string describing any errors
1435 : : * with the request or NULL if there is no error. The caller is reponsible
1436 : : * for freeing the string. */
1437 : : void
1438 : 138 : mf_set_wild(const struct mf_field *mf, struct match *match, char **err_str)
1439 : : {
1440 [ + + ]: 138 : if (err_str) {
1441 : 21 : *err_str = NULL;
1442 : : }
1443 : :
1444 [ - - - + : 138 : switch (mf->id) {
- - - - -
- - - - -
- - - - -
- - - - +
- - - + -
- + - - -
- - + + +
+ + - - -
- - - + +
+ + - +
- ]
1445 : : case MFF_DP_HASH:
1446 : 0 : match->flow.dp_hash = 0;
1447 : 0 : match->wc.masks.dp_hash = 0;
1448 : 0 : break;
1449 : : case MFF_RECIRC_ID:
1450 : 0 : match->flow.recirc_id = 0;
1451 : 0 : match->wc.masks.recirc_id = 0;
1452 : 0 : break;
1453 : : case MFF_CONJ_ID:
1454 : 0 : match->flow.conj_id = 0;
1455 : 0 : match->wc.masks.conj_id = 0;
1456 : 0 : break;
1457 : : case MFF_TUN_ID:
1458 : 1 : match_set_tun_id_masked(match, htonll(0), htonll(0));
1459 : 1 : break;
1460 : : case MFF_TUN_SRC:
1461 : 0 : match_set_tun_src_masked(match, htonl(0), htonl(0));
1462 : 0 : break;
1463 : : case MFF_TUN_DST:
1464 : 0 : match_set_tun_dst_masked(match, htonl(0), htonl(0));
1465 : 0 : break;
1466 : : case MFF_TUN_IPV6_SRC:
1467 : 0 : memset(&match->wc.masks.tunnel.ipv6_src, 0,
1468 : : sizeof match->wc.masks.tunnel.ipv6_src);
1469 : 0 : memset(&match->flow.tunnel.ipv6_src, 0,
1470 : : sizeof match->flow.tunnel.ipv6_src);
1471 : 0 : break;
1472 : : case MFF_TUN_IPV6_DST:
1473 : 0 : memset(&match->wc.masks.tunnel.ipv6_dst, 0,
1474 : : sizeof match->wc.masks.tunnel.ipv6_dst);
1475 : 0 : memset(&match->flow.tunnel.ipv6_dst, 0,
1476 : : sizeof match->flow.tunnel.ipv6_dst);
1477 : 0 : break;
1478 : : case MFF_TUN_FLAGS:
1479 : 0 : match_set_tun_flags_masked(match, 0, 0);
1480 : 0 : break;
1481 : : case MFF_TUN_GBP_ID:
1482 : 0 : match_set_tun_gbp_id_masked(match, 0, 0);
1483 : 0 : break;
1484 : : case MFF_TUN_GBP_FLAGS:
1485 : 0 : match_set_tun_gbp_flags_masked(match, 0, 0);
1486 : 0 : break;
1487 : : case MFF_TUN_TOS:
1488 : 0 : match_set_tun_tos_masked(match, 0, 0);
1489 : 0 : break;
1490 : : case MFF_TUN_TTL:
1491 : 0 : match_set_tun_ttl_masked(match, 0, 0);
1492 : 0 : break;
1493 : : CASE_MFF_TUN_METADATA:
1494 : 0 : tun_metadata_set_match(mf, NULL, NULL, match, err_str);
1495 : 0 : break;
1496 : :
1497 : : case MFF_METADATA:
1498 : 0 : match_set_metadata_masked(match, htonll(0), htonll(0));
1499 : 0 : break;
1500 : :
1501 : : case MFF_IN_PORT:
1502 : : case MFF_IN_PORT_OXM:
1503 : 0 : match->flow.in_port.ofp_port = 0;
1504 : 0 : match->wc.masks.in_port.ofp_port = 0;
1505 : 0 : break;
1506 : : case MFF_ACTSET_OUTPUT:
1507 : 0 : match->flow.actset_output = 0;
1508 : 0 : match->wc.masks.actset_output = 0;
1509 : 0 : break;
1510 : :
1511 : : case MFF_SKB_PRIORITY:
1512 : 0 : match->flow.skb_priority = 0;
1513 : 0 : match->wc.masks.skb_priority = 0;
1514 : 0 : break;
1515 : :
1516 : : case MFF_PKT_MARK:
1517 : 0 : match->flow.pkt_mark = 0;
1518 : 0 : match->wc.masks.pkt_mark = 0;
1519 : 0 : break;
1520 : :
1521 : : case MFF_CT_STATE:
1522 : 0 : match->flow.ct_state = 0;
1523 : 0 : match->wc.masks.ct_state = 0;
1524 : 0 : break;
1525 : :
1526 : : case MFF_CT_ZONE:
1527 : 0 : match->flow.ct_zone = 0;
1528 : 0 : match->wc.masks.ct_zone = 0;
1529 : 0 : break;
1530 : :
1531 : : case MFF_CT_MARK:
1532 : 0 : match->flow.ct_mark = 0;
1533 : 0 : match->wc.masks.ct_mark = 0;
1534 : 0 : break;
1535 : :
1536 : : case MFF_CT_LABEL:
1537 : 0 : memset(&match->flow.ct_label, 0, sizeof(match->flow.ct_label));
1538 : 0 : memset(&match->wc.masks.ct_label, 0, sizeof(match->wc.masks.ct_label));
1539 : 0 : break;
1540 : :
1541 : : CASE_MFF_REGS:
1542 : 1 : match_set_reg_masked(match, mf->id - MFF_REG0, 0, 0);
1543 : 1 : break;
1544 : :
1545 : : CASE_MFF_XREGS:
1546 : 0 : match_set_xreg_masked(match, mf->id - MFF_XREG0, 0, 0);
1547 : 0 : break;
1548 : :
1549 : : CASE_MFF_XXREGS: {
1550 : 0 : match_set_xxreg_masked(match, mf->id - MFF_XXREG0, OVS_U128_ZERO,
1551 : : OVS_U128_ZERO);
1552 : 0 : break;
1553 : : }
1554 : :
1555 : : case MFF_ETH_SRC:
1556 : 0 : match->flow.dl_src = eth_addr_zero;
1557 : 0 : match->wc.masks.dl_src = eth_addr_zero;
1558 : 0 : break;
1559 : :
1560 : : case MFF_ETH_DST:
1561 : 1 : match->flow.dl_dst = eth_addr_zero;
1562 : 1 : match->wc.masks.dl_dst = eth_addr_zero;
1563 : 1 : break;
1564 : :
1565 : : case MFF_ETH_TYPE:
1566 : 0 : match->flow.dl_type = htons(0);
1567 : 0 : match->wc.masks.dl_type = htons(0);
1568 : 0 : break;
1569 : :
1570 : : case MFF_VLAN_TCI:
1571 : 0 : match_set_dl_tci_masked(match, htons(0), htons(0));
1572 : 0 : break;
1573 : :
1574 : : case MFF_DL_VLAN:
1575 : : case MFF_VLAN_VID:
1576 : 1 : match_set_any_vid(match);
1577 : 1 : break;
1578 : :
1579 : : case MFF_DL_VLAN_PCP:
1580 : : case MFF_VLAN_PCP:
1581 : 0 : match_set_any_pcp(match);
1582 : 0 : break;
1583 : :
1584 : : case MFF_MPLS_LABEL:
1585 : 0 : match_set_any_mpls_label(match, 0);
1586 : 0 : break;
1587 : :
1588 : : case MFF_MPLS_TC:
1589 : 0 : match_set_any_mpls_tc(match, 0);
1590 : 0 : break;
1591 : :
1592 : : case MFF_MPLS_BOS:
1593 : 0 : match_set_any_mpls_bos(match, 0);
1594 : 0 : break;
1595 : :
1596 : : case MFF_MPLS_TTL:
1597 : 0 : match_set_any_mpls_ttl(match, 0);
1598 : 0 : break;
1599 : :
1600 : : case MFF_IPV4_SRC:
1601 : : case MFF_ARP_SPA:
1602 : 2 : match_set_nw_src_masked(match, htonl(0), htonl(0));
1603 : 2 : break;
1604 : :
1605 : : case MFF_IPV4_DST:
1606 : : case MFF_ARP_TPA:
1607 : 119 : match_set_nw_dst_masked(match, htonl(0), htonl(0));
1608 : 119 : break;
1609 : :
1610 : : case MFF_IPV6_SRC:
1611 : 1 : memset(&match->wc.masks.ipv6_src, 0, sizeof match->wc.masks.ipv6_src);
1612 : 1 : memset(&match->flow.ipv6_src, 0, sizeof match->flow.ipv6_src);
1613 : 1 : break;
1614 : :
1615 : : case MFF_IPV6_DST:
1616 : 2 : memset(&match->wc.masks.ipv6_dst, 0, sizeof match->wc.masks.ipv6_dst);
1617 : 2 : memset(&match->flow.ipv6_dst, 0, sizeof match->flow.ipv6_dst);
1618 : 2 : break;
1619 : :
1620 : : case MFF_IPV6_LABEL:
1621 : 1 : match->wc.masks.ipv6_label = htonl(0);
1622 : 1 : match->flow.ipv6_label = htonl(0);
1623 : 1 : break;
1624 : :
1625 : : case MFF_IP_PROTO:
1626 : 0 : match->wc.masks.nw_proto = 0;
1627 : 0 : match->flow.nw_proto = 0;
1628 : 0 : break;
1629 : :
1630 : : case MFF_IP_DSCP:
1631 : : case MFF_IP_DSCP_SHIFTED:
1632 : 0 : match->wc.masks.nw_tos &= ~IP_DSCP_MASK;
1633 : 0 : match->flow.nw_tos &= ~IP_DSCP_MASK;
1634 : 0 : break;
1635 : :
1636 : : case MFF_IP_ECN:
1637 : 0 : match->wc.masks.nw_tos &= ~IP_ECN_MASK;
1638 : 0 : match->flow.nw_tos &= ~IP_ECN_MASK;
1639 : 0 : break;
1640 : :
1641 : : case MFF_IP_TTL:
1642 : 0 : match->wc.masks.nw_ttl = 0;
1643 : 0 : match->flow.nw_ttl = 0;
1644 : 0 : break;
1645 : :
1646 : : case MFF_IP_FRAG:
1647 : 0 : match->wc.masks.nw_frag &= ~FLOW_NW_FRAG_MASK;
1648 : 0 : match->flow.nw_frag &= ~FLOW_NW_FRAG_MASK;
1649 : 0 : break;
1650 : :
1651 : : case MFF_ARP_OP:
1652 : 0 : match->wc.masks.nw_proto = 0;
1653 : 0 : match->flow.nw_proto = 0;
1654 : 0 : break;
1655 : :
1656 : : case MFF_ARP_SHA:
1657 : : case MFF_ND_SLL:
1658 : 1 : match->flow.arp_sha = eth_addr_zero;
1659 : 1 : match->wc.masks.arp_sha = eth_addr_zero;
1660 : 1 : break;
1661 : :
1662 : : case MFF_ARP_THA:
1663 : : case MFF_ND_TLL:
1664 : 1 : match->flow.arp_tha = eth_addr_zero;
1665 : 1 : match->wc.masks.arp_tha = eth_addr_zero;
1666 : 1 : break;
1667 : :
1668 : : case MFF_TCP_SRC:
1669 : : case MFF_UDP_SRC:
1670 : : case MFF_SCTP_SRC:
1671 : : case MFF_ICMPV4_TYPE:
1672 : : case MFF_ICMPV6_TYPE:
1673 : 3 : match->wc.masks.tp_src = htons(0);
1674 : 3 : match->flow.tp_src = htons(0);
1675 : 3 : break;
1676 : :
1677 : : case MFF_TCP_DST:
1678 : : case MFF_UDP_DST:
1679 : : case MFF_SCTP_DST:
1680 : : case MFF_ICMPV4_CODE:
1681 : : case MFF_ICMPV6_CODE:
1682 : 3 : match->wc.masks.tp_dst = htons(0);
1683 : 3 : match->flow.tp_dst = htons(0);
1684 : 3 : break;
1685 : :
1686 : : case MFF_TCP_FLAGS:
1687 : 0 : match->wc.masks.tcp_flags = htons(0);
1688 : 0 : match->flow.tcp_flags = htons(0);
1689 : 0 : break;
1690 : :
1691 : : case MFF_ND_TARGET:
1692 : 1 : memset(&match->wc.masks.nd_target, 0,
1693 : : sizeof match->wc.masks.nd_target);
1694 : 1 : memset(&match->flow.nd_target, 0, sizeof match->flow.nd_target);
1695 : 1 : break;
1696 : :
1697 : : case MFF_N_IDS:
1698 : : default:
1699 : 0 : OVS_NOT_REACHED();
1700 : : }
1701 : 138 : }
1702 : :
1703 : : /* Makes 'match' match field 'mf' with the specified 'value' and 'mask'.
1704 : : * 'value' specifies a value to match and 'mask' specifies a wildcard pattern,
1705 : : * with a 1-bit indicating that the corresponding value bit must match and a
1706 : : * 0-bit indicating a don't-care.
1707 : : *
1708 : : * If 'mask' is NULL or points to all-1-bits, then this call is equivalent to
1709 : : * mf_set_value(mf, value, match). If 'mask' points to all-0-bits, then this
1710 : : * call is equivalent to mf_set_wild(mf, match).
1711 : : *
1712 : : * 'mask' must be a valid mask for 'mf' (see mf_is_mask_valid()). The caller
1713 : : * is responsible for ensuring that 'match' meets 'mf''s prerequisites.
1714 : : *
1715 : : * If non-NULL, 'err_str' returns a malloc'ed string describing any errors
1716 : : * with the request or NULL if there is no error. The caller is reponsible
1717 : : * for freeing the string.
1718 : : *
1719 : : * Return a set of enum ofputil_protocol bits (as an uint32_t to avoid circular
1720 : : * dependency on enum ofputil_protocol definition) indicating which OpenFlow
1721 : : * protocol versions can support this functionality. */
1722 : : uint32_t
1723 : 2239729 : mf_set(const struct mf_field *mf,
1724 : : const union mf_value *value, const union mf_value *mask,
1725 : : struct match *match, char **err_str)
1726 : : {
1727 [ + - ][ + + ]: 2239729 : if (!mask || is_all_ones(mask, mf->n_bytes)) {
1728 : 1567289 : mf_set_value(mf, value, match, err_str);
1729 : 1567289 : return mf->usable_protocols_exact;
1730 [ + + ][ + + ]: 672440 : } else if (is_all_zeros(mask, mf->n_bytes) && !mf_is_tun_metadata(mf)) {
1731 : : /* Tunnel metadata matches on the existence of the field itself, so
1732 : : * it still needs to be encoded even if the value is wildcarded. */
1733 : 138 : mf_set_wild(mf, match, err_str);
1734 : 138 : return OFPUTIL_P_ANY;
1735 : : }
1736 : :
1737 [ + + ]: 672302 : if (err_str) {
1738 : 24495 : *err_str = NULL;
1739 : : }
1740 : :
1741 [ - + + + : 672302 : switch (mf->id) {
+ - - + +
+ - - + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
- ]
1742 : : case MFF_CT_ZONE:
1743 : : case MFF_RECIRC_ID:
1744 : : case MFF_CONJ_ID:
1745 : : case MFF_IN_PORT:
1746 : : case MFF_IN_PORT_OXM:
1747 : : case MFF_ACTSET_OUTPUT:
1748 : : case MFF_SKB_PRIORITY:
1749 : : case MFF_ETH_TYPE:
1750 : : case MFF_DL_VLAN:
1751 : : case MFF_DL_VLAN_PCP:
1752 : : case MFF_VLAN_PCP:
1753 : : case MFF_MPLS_LABEL:
1754 : : case MFF_MPLS_TC:
1755 : : case MFF_MPLS_BOS:
1756 : : case MFF_MPLS_TTL:
1757 : : case MFF_IP_PROTO:
1758 : : case MFF_IP_TTL:
1759 : : case MFF_IP_DSCP:
1760 : : case MFF_IP_DSCP_SHIFTED:
1761 : : case MFF_IP_ECN:
1762 : : case MFF_ARP_OP:
1763 : : case MFF_ICMPV4_TYPE:
1764 : : case MFF_ICMPV4_CODE:
1765 : : case MFF_ICMPV6_TYPE:
1766 : : case MFF_ICMPV6_CODE:
1767 : 0 : return OFPUTIL_P_NONE;
1768 : :
1769 : : case MFF_DP_HASH:
1770 : 5 : match_set_dp_hash_masked(match, ntohl(value->be32), ntohl(mask->be32));
1771 : 5 : break;
1772 : : case MFF_TUN_ID:
1773 : 7 : match_set_tun_id_masked(match, value->be64, mask->be64);
1774 : 7 : break;
1775 : : case MFF_TUN_SRC:
1776 : 2 : match_set_tun_src_masked(match, value->be32, mask->be32);
1777 : 2 : break;
1778 : : case MFF_TUN_DST:
1779 : 2 : match_set_tun_dst_masked(match, value->be32, mask->be32);
1780 : 2 : break;
1781 : : case MFF_TUN_IPV6_SRC:
1782 : 0 : match_set_tun_ipv6_src_masked(match, &value->ipv6, &mask->ipv6);
1783 : 0 : break;
1784 : : case MFF_TUN_IPV6_DST:
1785 : 0 : match_set_tun_ipv6_dst_masked(match, &value->ipv6, &mask->ipv6);
1786 : 0 : break;
1787 : : case MFF_TUN_FLAGS:
1788 : 3 : match_set_tun_flags_masked(match, ntohs(value->be16), ntohs(mask->be16));
1789 : 3 : break;
1790 : : case MFF_TUN_GBP_ID:
1791 : 2 : match_set_tun_gbp_id_masked(match, value->be16, mask->be16);
1792 : 2 : break;
1793 : : case MFF_TUN_GBP_FLAGS:
1794 : 2 : match_set_tun_gbp_flags_masked(match, value->u8, mask->u8);
1795 : 2 : break;
1796 : : case MFF_TUN_TTL:
1797 : 0 : match_set_tun_ttl_masked(match, value->u8, mask->u8);
1798 : 0 : break;
1799 : : case MFF_TUN_TOS:
1800 : 0 : match_set_tun_tos_masked(match, value->u8, mask->u8);
1801 : 0 : break;
1802 : : CASE_MFF_TUN_METADATA:
1803 : 28 : tun_metadata_set_match(mf, value, mask, match, err_str);
1804 : 28 : break;
1805 : :
1806 : : case MFF_METADATA:
1807 : 5 : match_set_metadata_masked(match, value->be64, mask->be64);
1808 : 5 : break;
1809 : :
1810 : : CASE_MFF_REGS:
1811 : 453174 : match_set_reg_masked(match, mf->id - MFF_REG0,
1812 : : ntohl(value->be32), ntohl(mask->be32));
1813 : 453174 : break;
1814 : :
1815 : : CASE_MFF_XREGS:
1816 : 35 : match_set_xreg_masked(match, mf->id - MFF_XREG0,
1817 : : ntohll(value->be64), ntohll(mask->be64));
1818 : 35 : break;
1819 : :
1820 : : CASE_MFF_XXREGS: {
1821 : 124873 : match_set_xxreg_masked(match, mf->id - MFF_XXREG0,
1822 : : ntoh128(value->be128), ntoh128(mask->be128));
1823 : 124873 : break;
1824 : : }
1825 : :
1826 : : case MFF_PKT_MARK:
1827 : 2 : match_set_pkt_mark_masked(match, ntohl(value->be32),
1828 : : ntohl(mask->be32));
1829 : 2 : break;
1830 : :
1831 : : case MFF_CT_STATE:
1832 : 1247 : match_set_ct_state_masked(match, ntohl(value->be32), ntohl(mask->be32));
1833 : 1247 : break;
1834 : :
1835 : : case MFF_CT_MARK:
1836 : 3 : match_set_ct_mark_masked(match, ntohl(value->be32), ntohl(mask->be32));
1837 : 3 : break;
1838 : :
1839 : : case MFF_CT_LABEL:
1840 [ + - ]: 197 : match_set_ct_label_masked(match, ntoh128(value->be128),
1841 : : mask ? ntoh128(mask->be128) : OVS_U128_MAX);
1842 : 197 : break;
1843 : :
1844 : : case MFF_ETH_DST:
1845 : 26117 : match_set_dl_dst_masked(match, value->mac, mask->mac);
1846 : 26117 : break;
1847 : :
1848 : : case MFF_ETH_SRC:
1849 : 9173 : match_set_dl_src_masked(match, value->mac, mask->mac);
1850 : 9173 : break;
1851 : :
1852 : : case MFF_ARP_SHA:
1853 : : case MFF_ND_SLL:
1854 : 3 : match_set_arp_sha_masked(match, value->mac, mask->mac);
1855 : 3 : break;
1856 : :
1857 : : case MFF_ARP_THA:
1858 : : case MFF_ND_TLL:
1859 : 3 : match_set_arp_tha_masked(match, value->mac, mask->mac);
1860 : 3 : break;
1861 : :
1862 : : case MFF_VLAN_TCI:
1863 : 14783 : match_set_dl_tci_masked(match, value->be16, mask->be16);
1864 : 14783 : break;
1865 : :
1866 : : case MFF_VLAN_VID:
1867 : 703 : match_set_vlan_vid_masked(match, value->be16, mask->be16);
1868 : 703 : break;
1869 : :
1870 : : case MFF_IPV4_SRC:
1871 : 5130 : match_set_nw_src_masked(match, value->be32, mask->be32);
1872 : 5130 : break;
1873 : :
1874 : : case MFF_IPV4_DST:
1875 : 22004 : match_set_nw_dst_masked(match, value->be32, mask->be32);
1876 : 22004 : break;
1877 : :
1878 : : case MFF_IPV6_SRC:
1879 : 8 : match_set_ipv6_src_masked(match, &value->ipv6, &mask->ipv6);
1880 : 8 : break;
1881 : :
1882 : : case MFF_IPV6_DST:
1883 : 14678 : match_set_ipv6_dst_masked(match, &value->ipv6, &mask->ipv6);
1884 : 14678 : break;
1885 : :
1886 : : case MFF_IPV6_LABEL:
1887 [ + + ]: 6 : if ((mask->be32 & htonl(IPV6_LABEL_MASK)) == htonl(IPV6_LABEL_MASK)) {
1888 : 2 : mf_set_value(mf, value, match, err_str);
1889 : : } else {
1890 : 4 : match_set_ipv6_label_masked(match, value->be32, mask->be32);
1891 : : }
1892 : 6 : break;
1893 : :
1894 : : case MFF_ND_TARGET:
1895 : 4 : match_set_nd_target_masked(match, &value->ipv6, &mask->ipv6);
1896 : 4 : break;
1897 : :
1898 : : case MFF_IP_FRAG:
1899 : 12 : match_set_nw_frag_masked(match, value->u8, mask->u8);
1900 : 12 : break;
1901 : :
1902 : : case MFF_ARP_SPA:
1903 : 43 : match_set_nw_src_masked(match, value->be32, mask->be32);
1904 : 43 : break;
1905 : :
1906 : : case MFF_ARP_TPA:
1907 : 4 : match_set_nw_dst_masked(match, value->be32, mask->be32);
1908 : 4 : break;
1909 : :
1910 : : case MFF_TCP_SRC:
1911 : : case MFF_UDP_SRC:
1912 : : case MFF_SCTP_SRC:
1913 : 15 : match_set_tp_src_masked(match, value->be16, mask->be16);
1914 : 15 : break;
1915 : :
1916 : : case MFF_TCP_DST:
1917 : : case MFF_UDP_DST:
1918 : : case MFF_SCTP_DST:
1919 : 13 : match_set_tp_dst_masked(match, value->be16, mask->be16);
1920 : 13 : break;
1921 : :
1922 : : case MFF_TCP_FLAGS:
1923 : 16 : match_set_tcp_flags_masked(match, value->be16, mask->be16);
1924 : 16 : break;
1925 : :
1926 : : case MFF_N_IDS:
1927 : : default:
1928 : 0 : OVS_NOT_REACHED();
1929 : : }
1930 : :
1931 : 672302 : return ((mf->usable_protocols_bitwise == mf->usable_protocols_cidr
1932 [ + + ]: 27181 : || ip_is_cidr(mask->be32))
1933 : : ? mf->usable_protocols_cidr
1934 [ + + ]: 699483 : : mf->usable_protocols_bitwise);
1935 : : }
1936 : :
1937 : : static enum ofperr
1938 : 71079 : mf_check__(const struct mf_subfield *sf, const struct flow *flow,
1939 : : const char *type)
1940 : : {
1941 [ - + ]: 71079 : if (!sf->field) {
1942 [ # # ]: 0 : VLOG_WARN_RL(&rl, "unknown %s field", type);
1943 : 0 : return OFPERR_OFPBAC_BAD_SET_TYPE;
1944 [ - + ]: 71079 : } else if (!sf->n_bits) {
1945 [ # # ]: 0 : VLOG_WARN_RL(&rl, "zero bit %s field %s", type, sf->field->name);
1946 : 0 : return OFPERR_OFPBAC_BAD_SET_LEN;
1947 [ - + ]: 71079 : } else if (sf->ofs >= sf->field->n_bits) {
1948 [ # # ]: 0 : VLOG_WARN_RL(&rl, "bit offset %d exceeds %d-bit width of %s field %s",
1949 : : sf->ofs, sf->field->n_bits, type, sf->field->name);
1950 : 0 : return OFPERR_OFPBAC_BAD_SET_LEN;
1951 [ - + ]: 71079 : } else if (sf->ofs + sf->n_bits > sf->field->n_bits) {
1952 [ # # ]: 0 : VLOG_WARN_RL(&rl, "bit offset %d and width %d exceeds %d-bit width "
1953 : : "of %s field %s", sf->ofs, sf->n_bits,
1954 : : sf->field->n_bits, type, sf->field->name);
1955 : 0 : return OFPERR_OFPBAC_BAD_SET_LEN;
1956 [ + + ][ + + ]: 71079 : } else if (flow && !mf_are_prereqs_ok(sf->field, flow, NULL)) {
1957 [ + - ]: 6 : VLOG_WARN_RL(&rl, "%s field %s lacks correct prerequisites",
1958 : : type, sf->field->name);
1959 : 6 : return OFPERR_OFPBAC_MATCH_INCONSISTENT;
1960 : : } else {
1961 : 71073 : return 0;
1962 : : }
1963 : : }
1964 : :
1965 : : /* Sets all the bits in 'sf' to 1 within 'wc', if 'wc' is nonnull. */
1966 : : static void
1967 : 78094 : unwildcard_subfield(const struct mf_subfield *sf, struct flow_wildcards *wc)
1968 : : {
1969 [ + - ]: 78094 : if (wc) {
1970 : : union mf_value mask;
1971 : :
1972 : 78094 : memset(&mask, 0, sizeof mask);
1973 : 78094 : bitwise_one(&mask, sf->field->n_bytes, sf->ofs, sf->n_bits);
1974 : 78094 : mf_mask_field_masked(sf->field, &mask, wc);
1975 : : }
1976 : 78094 : }
1977 : :
1978 : : /* Copies 'src' into 'dst' within 'flow', and sets all the bits in 'src' and
1979 : : * 'dst' to 1s in 'wc', if 'wc' is nonnull.
1980 : : *
1981 : : * 'src' and 'dst' may overlap. */
1982 : : void
1983 : 39047 : mf_subfield_copy(const struct mf_subfield *src,
1984 : : const struct mf_subfield *dst,
1985 : : struct flow *flow, struct flow_wildcards *wc)
1986 : : {
1987 [ - + ]: 39047 : ovs_assert(src->n_bits == dst->n_bits);
1988 [ + - ]: 39047 : if (mf_are_prereqs_ok(dst->field, flow, wc)
1989 [ + - ]: 39047 : && mf_are_prereqs_ok(src->field, flow, wc)) {
1990 : 39047 : unwildcard_subfield(src, wc);
1991 : 39047 : unwildcard_subfield(dst, wc);
1992 : :
1993 : : union mf_value src_value;
1994 : : union mf_value dst_value;
1995 : 39047 : mf_get_value(dst->field, flow, &dst_value);
1996 : 39047 : mf_get_value(src->field, flow, &src_value);
1997 : 39047 : bitwise_copy(&src_value, src->field->n_bytes, src->ofs,
1998 : 39047 : &dst_value, dst->field->n_bytes, dst->ofs,
1999 : : src->n_bits);
2000 : 39047 : mf_set_flow_value(dst->field, &dst_value, flow);
2001 : : }
2002 : 39047 : }
2003 : :
2004 : : /* Swaps the bits in 'src' and 'dst' within 'flow', and sets all the bits in
2005 : : * 'src' and 'dst' to 1s in 'wc', if 'wc' is nonnull.
2006 : : *
2007 : : * 'src' and 'dst' may overlap. */
2008 : : void
2009 : 0 : mf_subfield_swap(const struct mf_subfield *a,
2010 : : const struct mf_subfield *b,
2011 : : struct flow *flow, struct flow_wildcards *wc)
2012 : : {
2013 [ # # ]: 0 : ovs_assert(a->n_bits == b->n_bits);
2014 [ # # ]: 0 : if (mf_are_prereqs_ok(a->field, flow, wc)
2015 [ # # ]: 0 : && mf_are_prereqs_ok(b->field, flow, wc)) {
2016 : 0 : unwildcard_subfield(a, wc);
2017 : 0 : unwildcard_subfield(b, wc);
2018 : :
2019 : : union mf_value a_value;
2020 : : union mf_value b_value;
2021 : 0 : mf_get_value(a->field, flow, &a_value);
2022 : 0 : mf_get_value(b->field, flow, &b_value);
2023 : 0 : union mf_value b2_value = b_value;
2024 : :
2025 : : /* Copy 'a' into 'b'. */
2026 : 0 : bitwise_copy(&a_value, a->field->n_bytes, a->ofs,
2027 : 0 : &b_value, b->field->n_bytes, b->ofs,
2028 : : a->n_bits);
2029 : 0 : mf_set_flow_value(b->field, &b_value, flow);
2030 : :
2031 : : /* Copy original 'b' into 'a'. */
2032 : 0 : bitwise_copy(&b2_value, b->field->n_bytes, b->ofs,
2033 : 0 : &a_value, a->field->n_bytes, a->ofs,
2034 : : b->n_bits);
2035 : 0 : mf_set_flow_value(a->field, &a_value, flow);
2036 : : }
2037 : 0 : }
2038 : :
2039 : : /* Checks whether 'sf' is valid for reading a subfield out of 'flow'. Returns
2040 : : * 0 if so, otherwise an OpenFlow error code (e.g. as returned by
2041 : : * ofp_mkerr()). */
2042 : : enum ofperr
2043 : 34783 : mf_check_src(const struct mf_subfield *sf, const struct flow *flow)
2044 : : {
2045 : 34783 : return mf_check__(sf, flow, "source");
2046 : : }
2047 : :
2048 : : /* Checks whether 'sf' is valid for writing a subfield into 'flow'. Returns 0
2049 : : * if so, otherwise an OpenFlow error code (e.g. as returned by
2050 : : * ofp_mkerr()). */
2051 : : enum ofperr
2052 : 36296 : mf_check_dst(const struct mf_subfield *sf, const struct flow *flow)
2053 : : {
2054 : 36296 : int error = mf_check__(sf, flow, "destination");
2055 [ + + ][ + + ]: 36296 : if (!error && !sf->field->writable) {
2056 [ + - ]: 1 : VLOG_WARN_RL(&rl, "destination field %s is not writable",
2057 : : sf->field->name);
2058 : 1 : return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
2059 : : }
2060 : 36295 : return error;
2061 : : }
2062 : :
2063 : : /* Copies the value and wildcard bit pattern for 'mf' from 'match' into the
2064 : : * 'value' and 'mask', respectively. */
2065 : : void
2066 : 1990207 : mf_get(const struct mf_field *mf, const struct match *match,
2067 : : union mf_value *value, union mf_value *mask)
2068 : : {
2069 : 1990207 : mf_get_value(mf, &match->flow, value);
2070 : 1990207 : mf_get_mask(mf, &match->wc, mask);
2071 : 1990207 : }
2072 : :
2073 : : static char *
2074 : 21668 : mf_from_integer_string(const struct mf_field *mf, const char *s,
2075 : : uint8_t *valuep, uint8_t *maskp)
2076 : : {
2077 : : char *tail;
2078 : 21668 : const char *err_str = "";
2079 : : int err;
2080 : :
2081 : 21668 : err = parse_int_string(s, valuep, mf->n_bytes, &tail);
2082 [ + - ][ + + ]: 21668 : if (err || (*tail != '\0' && *tail != '/')) {
[ - + ]
2083 : 0 : err_str = "value";
2084 : 0 : goto syntax_error;
2085 : : }
2086 : :
2087 [ + + ]: 21668 : if (*tail == '/') {
2088 : 125 : err = parse_int_string(tail + 1, maskp, mf->n_bytes, &tail);
2089 [ + - ][ - + ]: 125 : if (err || *tail != '\0') {
2090 : 0 : err_str = "mask";
2091 : 0 : goto syntax_error;
2092 : : }
2093 : : } else {
2094 : 21543 : memset(maskp, 0xff, mf->n_bytes);
2095 : : }
2096 : :
2097 : 21668 : return NULL;
2098 : :
2099 : : syntax_error:
2100 [ # # ]: 0 : if (err == ERANGE) {
2101 : 0 : return xasprintf("%s: %s too large for %u-byte field %s",
2102 : : s, err_str, mf->n_bytes, mf->name);
2103 : : } else {
2104 : 21668 : return xasprintf("%s: bad syntax for %s %s", s, mf->name, err_str);
2105 : : }
2106 : : }
2107 : :
2108 : : static char *
2109 : 1062 : mf_from_ethernet_string(const struct mf_field *mf, const char *s,
2110 : : struct eth_addr *mac, struct eth_addr *mask)
2111 : : {
2112 : : int n;
2113 : :
2114 [ - + ]: 1062 : ovs_assert(mf->n_bytes == ETH_ADDR_LEN);
2115 : :
2116 : 1062 : n = -1;
2117 [ + - ]: 1062 : if (ovs_scan(s, ETH_ADDR_SCAN_FMT"%n", ETH_ADDR_SCAN_ARGS(*mac), &n)
2118 [ + + ]: 1062 : && n == strlen(s)) {
2119 : 1051 : *mask = eth_addr_exact;
2120 : 1051 : return NULL;
2121 : : }
2122 : :
2123 : 11 : n = -1;
2124 [ + - ]: 11 : if (ovs_scan(s, ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT"%n",
2125 : : ETH_ADDR_SCAN_ARGS(*mac), ETH_ADDR_SCAN_ARGS(*mask), &n)
2126 [ + - ]: 11 : && n == strlen(s)) {
2127 : 11 : return NULL;
2128 : : }
2129 : :
2130 : 1062 : return xasprintf("%s: invalid Ethernet address", s);
2131 : : }
2132 : :
2133 : : static char *
2134 : 1235 : mf_from_ipv4_string(const struct mf_field *mf, const char *s,
2135 : : ovs_be32 *ip, ovs_be32 *mask)
2136 : : {
2137 [ - + ]: 1235 : ovs_assert(mf->n_bytes == sizeof *ip);
2138 : 1235 : return ip_parse_masked(s, ip, mask);
2139 : : }
2140 : :
2141 : : static char *
2142 : 43 : mf_from_ipv6_string(const struct mf_field *mf, const char *s,
2143 : : struct in6_addr *ipv6, struct in6_addr *mask)
2144 : : {
2145 [ - + ]: 43 : ovs_assert(mf->n_bytes == sizeof *ipv6);
2146 : 43 : return ipv6_parse_masked(s, ipv6, mask);
2147 : : }
2148 : :
2149 : : static char *
2150 : 1731 : mf_from_ofp_port_string(const struct mf_field *mf, const char *s,
2151 : : ovs_be16 *valuep, ovs_be16 *maskp)
2152 : : {
2153 : : ofp_port_t port;
2154 : :
2155 [ - + ]: 1731 : ovs_assert(mf->n_bytes == sizeof(ovs_be16));
2156 : :
2157 [ + + ]: 1731 : if (ofputil_port_from_string(s, &port)) {
2158 : 1726 : *valuep = htons(ofp_to_u16(port));
2159 : 1726 : *maskp = OVS_BE16_MAX;
2160 : 1726 : return NULL;
2161 : : }
2162 : 1731 : return xasprintf("%s: port value out of range for %s", s, mf->name);
2163 : : }
2164 : :
2165 : : static char *
2166 : 6 : mf_from_ofp_port_string32(const struct mf_field *mf, const char *s,
2167 : : ovs_be32 *valuep, ovs_be32 *maskp)
2168 : : {
2169 : : ofp_port_t port;
2170 : :
2171 [ - + ]: 6 : ovs_assert(mf->n_bytes == sizeof(ovs_be32));
2172 [ + + ]: 6 : if (ofputil_port_from_string(s, &port)) {
2173 : 5 : *valuep = ofputil_port_to_ofp11(port);
2174 : 5 : *maskp = OVS_BE32_MAX;
2175 : 5 : return NULL;
2176 : : }
2177 : 6 : return xasprintf("%s: port value out of range for %s", s, mf->name);
2178 : : }
2179 : :
2180 : : struct frag_handling {
2181 : : const char *name;
2182 : : uint8_t mask;
2183 : : uint8_t value;
2184 : : };
2185 : :
2186 : : static const struct frag_handling all_frags[] = {
2187 : : #define A FLOW_NW_FRAG_ANY
2188 : : #define L FLOW_NW_FRAG_LATER
2189 : : /* name mask value */
2190 : :
2191 : : { "no", A|L, 0 },
2192 : : { "first", A|L, A },
2193 : : { "later", A|L, A|L },
2194 : :
2195 : : { "no", A, 0 },
2196 : : { "yes", A, A },
2197 : :
2198 : : { "not_later", L, 0 },
2199 : : { "later", L, L },
2200 : : #undef A
2201 : : #undef L
2202 : : };
2203 : :
2204 : : static char *
2205 : 23 : mf_from_frag_string(const char *s, uint8_t *valuep, uint8_t *maskp)
2206 : : {
2207 : : const struct frag_handling *h;
2208 : :
2209 [ + - ]: 47 : for (h = all_frags; h < &all_frags[ARRAY_SIZE(all_frags)]; h++) {
2210 [ + + ]: 47 : if (!strcasecmp(s, h->name)) {
2211 : : /* We force the upper bits of the mask on to make mf_parse_value()
2212 : : * happy (otherwise it will never think it's an exact match.) */
2213 : 23 : *maskp = h->mask | ~FLOW_NW_FRAG_MASK;
2214 : 23 : *valuep = h->value;
2215 : 23 : return NULL;
2216 : : }
2217 : : }
2218 : :
2219 : 0 : return xasprintf("%s: unknown fragment type (valid types are \"no\", "
2220 : : "\"yes\", \"first\", \"later\", \"not_first\"", s);
2221 : : }
2222 : :
2223 : : static char *
2224 : 8 : parse_mf_flags(const char *s, const char *(*bit_to_string)(uint32_t),
2225 : : const char *field_name, ovs_be16 *flagsp, ovs_be16 allowed,
2226 : : ovs_be16 *maskp)
2227 : : {
2228 : : int err;
2229 : : char *err_str;
2230 : : uint32_t flags, mask;
2231 : :
2232 [ + - ]: 16 : err = parse_flags(s, bit_to_string, '\0', field_name, &err_str,
2233 : 8 : &flags, ntohs(allowed), maskp ? &mask : NULL);
2234 [ + + ]: 8 : if (err < 0) {
2235 : 1 : return err_str;
2236 : : }
2237 : :
2238 : 7 : *flagsp = htons(flags);
2239 [ + - ]: 7 : if (maskp) {
2240 : 7 : *maskp = htons(mask);
2241 : : }
2242 : :
2243 : 8 : return NULL;
2244 : : }
2245 : :
2246 : : static char *
2247 : 6 : mf_from_tcp_flags_string(const char *s, ovs_be16 *flagsp, ovs_be16 *maskp)
2248 : : {
2249 : 6 : return parse_mf_flags(s, packet_tcp_flag_to_string, "TCP", flagsp,
2250 : 6 : TCP_FLAGS_BE16(OVS_BE16_MAX), maskp);
2251 : : }
2252 : :
2253 : : static char *
2254 : 2 : mf_from_tun_flags_string(const char *s, ovs_be16 *flagsp, ovs_be16 *maskp)
2255 : : {
2256 : 2 : return parse_mf_flags(s, flow_tun_flag_to_string, "tunnel", flagsp,
2257 : 2 : htons(FLOW_TNL_PUB_F_MASK), maskp);
2258 : : }
2259 : :
2260 : : static char *
2261 : 266 : mf_from_ct_state_string(const char *s, ovs_be32 *flagsp, ovs_be32 *maskp)
2262 : : {
2263 : : int err;
2264 : : char *err_str;
2265 : : uint32_t flags, mask;
2266 : :
2267 [ + - ]: 266 : err = parse_flags(s, ct_state_to_string, '\0', "ct_state", &err_str,
2268 : : &flags, CS_SUPPORTED_MASK, maskp ? &mask : NULL);
2269 [ - + ]: 266 : if (err < 0) {
2270 : 0 : return err_str;
2271 : : }
2272 : :
2273 : 266 : *flagsp = htonl(flags);
2274 [ + - ]: 266 : if (maskp) {
2275 : 266 : *maskp = htonl(mask);
2276 : : }
2277 : :
2278 : 266 : return NULL;
2279 : : }
2280 : :
2281 : : /* Parses 's', a string value for field 'mf', into 'value' and 'mask'. Returns
2282 : : * NULL if successful, otherwise a malloc()'d string describing the error. */
2283 : : char *
2284 : 26042 : mf_parse(const struct mf_field *mf, const char *s,
2285 : : union mf_value *value, union mf_value *mask)
2286 : : {
2287 : : char *error;
2288 : :
2289 [ - + ]: 26042 : if (!strcmp(s, "*")) {
2290 : 0 : memset(value, 0, mf->n_bytes);
2291 : 0 : memset(mask, 0, mf->n_bytes);
2292 : 0 : return NULL;
2293 : : }
2294 : :
2295 [ + + + + : 26042 : switch (mf->string) {
+ + + + +
+ - ]
2296 : : case MFS_DECIMAL:
2297 : : case MFS_HEXADECIMAL:
2298 : 21668 : error = mf_from_integer_string(mf, s,
2299 : : (uint8_t *) value, (uint8_t *) mask);
2300 : 21668 : break;
2301 : :
2302 : : case MFS_CT_STATE:
2303 [ - + ]: 266 : ovs_assert(mf->n_bytes == sizeof(ovs_be32));
2304 : 266 : error = mf_from_ct_state_string(s, &value->be32, &mask->be32);
2305 : 266 : break;
2306 : :
2307 : : case MFS_ETHERNET:
2308 : 1062 : error = mf_from_ethernet_string(mf, s, &value->mac, &mask->mac);
2309 : 1062 : break;
2310 : :
2311 : : case MFS_IPV4:
2312 : 1235 : error = mf_from_ipv4_string(mf, s, &value->be32, &mask->be32);
2313 : 1235 : break;
2314 : :
2315 : : case MFS_IPV6:
2316 : 43 : error = mf_from_ipv6_string(mf, s, &value->ipv6, &mask->ipv6);
2317 : 43 : break;
2318 : :
2319 : : case MFS_OFP_PORT:
2320 : 1731 : error = mf_from_ofp_port_string(mf, s, &value->be16, &mask->be16);
2321 : 1731 : break;
2322 : :
2323 : : case MFS_OFP_PORT_OXM:
2324 : 6 : error = mf_from_ofp_port_string32(mf, s, &value->be32, &mask->be32);
2325 : 6 : break;
2326 : :
2327 : : case MFS_FRAG:
2328 : 23 : error = mf_from_frag_string(s, &value->u8, &mask->u8);
2329 : 23 : break;
2330 : :
2331 : : case MFS_TNL_FLAGS:
2332 [ - + ]: 2 : ovs_assert(mf->n_bytes == sizeof(ovs_be16));
2333 : 2 : error = mf_from_tun_flags_string(s, &value->be16, &mask->be16);
2334 : 2 : break;
2335 : :
2336 : : case MFS_TCP_FLAGS:
2337 [ - + ]: 6 : ovs_assert(mf->n_bytes == sizeof(ovs_be16));
2338 : 6 : error = mf_from_tcp_flags_string(s, &value->be16, &mask->be16);
2339 : 6 : break;
2340 : :
2341 : : default:
2342 : 0 : OVS_NOT_REACHED();
2343 : : }
2344 : :
2345 [ + + ][ + + ]: 26042 : if (!error && !mf_is_mask_valid(mf, mask)) {
2346 : 24 : error = xasprintf("%s: invalid mask for field %s", s, mf->name);
2347 : : }
2348 : 26042 : return error;
2349 : : }
2350 : :
2351 : : /* Parses 's', a string value for field 'mf', into 'value'. Returns NULL if
2352 : : * successful, otherwise a malloc()'d string describing the error. */
2353 : : char *
2354 : 3696 : mf_parse_value(const struct mf_field *mf, const char *s, union mf_value *value)
2355 : : {
2356 : : union mf_value mask;
2357 : : char *error;
2358 : :
2359 : 3696 : error = mf_parse(mf, s, value, &mask);
2360 [ + + ]: 3696 : if (error) {
2361 : 1 : return error;
2362 : : }
2363 : :
2364 [ - + ]: 3695 : if (!is_all_ones((const uint8_t *) &mask, mf->n_bytes)) {
2365 : 0 : return xasprintf("%s: wildcards not allowed here", s);
2366 : : }
2367 : 3696 : return NULL;
2368 : : }
2369 : :
2370 : : static void
2371 : 8662 : mf_format_integer_string(const struct mf_field *mf, const uint8_t *valuep,
2372 : : const uint8_t *maskp, struct ds *s)
2373 : : {
2374 [ + + ]: 8662 : if (mf->string == MFS_HEXADECIMAL) {
2375 : 7485 : ds_put_hex(s, valuep, mf->n_bytes);
2376 : : } else {
2377 : 1177 : unsigned long long int integer = 0;
2378 : : int i;
2379 : :
2380 [ - + ]: 1177 : ovs_assert(mf->n_bytes <= 8);
2381 [ + + ]: 3102 : for (i = 0; i < mf->n_bytes; i++) {
2382 : 1925 : integer = (integer << 8) | valuep[i];
2383 : : }
2384 : 1177 : ds_put_format(s, "%lld", integer);
2385 : : }
2386 : :
2387 [ + + ]: 8662 : if (maskp) {
2388 : : /* I guess we could write the mask in decimal for MFS_DECIMAL but I'm
2389 : : * not sure that that a bit-mask written in decimal is ever easier to
2390 : : * understand than the same bit-mask written in hexadecimal. */
2391 : 449 : ds_put_char(s, '/');
2392 : 449 : ds_put_hex(s, maskp, mf->n_bytes);
2393 : : }
2394 : 8662 : }
2395 : :
2396 : : static void
2397 : 0 : mf_format_frag_string(uint8_t value, uint8_t mask, struct ds *s)
2398 : : {
2399 : : const struct frag_handling *h;
2400 : :
2401 : 0 : mask &= FLOW_NW_FRAG_MASK;
2402 : 0 : value &= mask;
2403 : :
2404 [ # # ]: 0 : for (h = all_frags; h < &all_frags[ARRAY_SIZE(all_frags)]; h++) {
2405 [ # # ][ # # ]: 0 : if (value == h->value && mask == h->mask) {
2406 : 0 : ds_put_cstr(s, h->name);
2407 : 0 : return;
2408 : : }
2409 : : }
2410 : 0 : ds_put_cstr(s, "<error>");
2411 : : }
2412 : :
2413 : : static void
2414 : 0 : mf_format_tnl_flags_string(ovs_be16 value, ovs_be16 mask, struct ds *s)
2415 : : {
2416 : 0 : format_flags_masked(s, NULL, flow_tun_flag_to_string, ntohs(value),
2417 : 0 : ntohs(mask) & FLOW_TNL_PUB_F_MASK, FLOW_TNL_PUB_F_MASK);
2418 : 0 : }
2419 : :
2420 : : static void
2421 : 0 : mf_format_tcp_flags_string(ovs_be16 value, ovs_be16 mask, struct ds *s)
2422 : : {
2423 : 0 : format_flags_masked(s, NULL, packet_tcp_flag_to_string, ntohs(value),
2424 : 0 : TCP_FLAGS(mask), TCP_FLAGS(OVS_BE16_MAX));
2425 : 0 : }
2426 : :
2427 : : static void
2428 : 0 : mf_format_ct_state_string(ovs_be32 value, ovs_be32 mask, struct ds *s)
2429 : : {
2430 : 0 : format_flags_masked(s, NULL, ct_state_to_string, ntohl(value),
2431 : : ntohl(mask), UINT16_MAX);
2432 : 0 : }
2433 : :
2434 : : /* Appends to 's' a string representation of field 'mf' whose value is in
2435 : : * 'value' and 'mask'. 'mask' may be NULL to indicate an exact match. */
2436 : : void
2437 : 12379 : mf_format(const struct mf_field *mf,
2438 : : const union mf_value *value, const union mf_value *mask,
2439 : : struct ds *s)
2440 : : {
2441 [ + + ]: 12379 : if (mask) {
2442 [ - + ]: 12351 : if (is_all_zeros(mask, mf->n_bytes)) {
2443 : 0 : ds_put_cstr(s, "ANY");
2444 : 0 : return;
2445 [ + + ]: 12351 : } else if (is_all_ones(mask, mf->n_bytes)) {
2446 : 11900 : mask = NULL;
2447 : : }
2448 : : }
2449 : :
2450 [ - + + - : 12379 : switch (mf->string) {
+ + + - -
- - ]
2451 : : case MFS_OFP_PORT_OXM:
2452 [ # # ]: 0 : if (!mask) {
2453 : : ofp_port_t port;
2454 : 0 : ofputil_port_from_ofp11(value->be32, &port);
2455 : 0 : ofputil_format_port(port, s);
2456 : 0 : break;
2457 : : }
2458 : : /* fall through */
2459 : : case MFS_OFP_PORT:
2460 [ + - ]: 601 : if (!mask) {
2461 : 601 : ofputil_format_port(u16_to_ofp(ntohs(value->be16)), s);
2462 : 601 : break;
2463 : : }
2464 : : /* fall through */
2465 : : case MFS_DECIMAL:
2466 : : case MFS_HEXADECIMAL:
2467 : 8662 : mf_format_integer_string(mf, (uint8_t *) value, (uint8_t *) mask, s);
2468 : 8662 : break;
2469 : :
2470 : : case MFS_CT_STATE:
2471 [ # # ]: 0 : mf_format_ct_state_string(value->be32,
2472 : : mask ? mask->be32 : OVS_BE32_MAX, s);
2473 : 0 : break;
2474 : :
2475 : : case MFS_ETHERNET:
2476 [ + + ]: 2609 : eth_format_masked(value->mac, mask ? &mask->mac : NULL, s);
2477 : 2609 : break;
2478 : :
2479 : : case MFS_IPV4:
2480 [ - + ]: 487 : ip_format_masked(value->be32, mask ? mask->be32 : OVS_BE32_MAX, s);
2481 : 487 : break;
2482 : :
2483 : : case MFS_IPV6:
2484 [ - + ]: 20 : ipv6_format_masked(&value->ipv6, mask ? &mask->ipv6 : NULL, s);
2485 : 20 : break;
2486 : :
2487 : : case MFS_FRAG:
2488 [ # # ]: 0 : mf_format_frag_string(value->u8, mask ? mask->u8 : UINT8_MAX, s);
2489 : 0 : break;
2490 : :
2491 : : case MFS_TNL_FLAGS:
2492 [ # # ]: 0 : mf_format_tnl_flags_string(value->be16,
2493 : 0 : mask ? mask->be16 : OVS_BE16_MAX, s);
2494 : 0 : break;
2495 : :
2496 : : case MFS_TCP_FLAGS:
2497 [ # # ]: 0 : mf_format_tcp_flags_string(value->be16,
2498 : 0 : mask ? mask->be16 : OVS_BE16_MAX, s);
2499 : 0 : break;
2500 : :
2501 : : default:
2502 : 0 : OVS_NOT_REACHED();
2503 : : }
2504 : : }
2505 : :
2506 : : /* Makes subfield 'sf' within 'flow' exactly match the 'sf->n_bits'
2507 : : * least-significant bits in 'x'.
2508 : : */
2509 : : void
2510 : 66372080 : mf_write_subfield_flow(const struct mf_subfield *sf,
2511 : : const union mf_subvalue *x, struct flow *flow)
2512 : : {
2513 : 66372080 : const struct mf_field *field = sf->field;
2514 : : union mf_value value;
2515 : :
2516 : 66372080 : mf_get_value(field, flow, &value);
2517 : 66372080 : bitwise_copy(x, sizeof *x, 0, &value, field->n_bytes,
2518 : : sf->ofs, sf->n_bits);
2519 : 66372080 : mf_set_flow_value(field, &value, flow);
2520 : 66372080 : }
2521 : :
2522 : : /* Makes subfield 'sf' within 'match' exactly match the 'sf->n_bits'
2523 : : * least-significant bits in 'x'.
2524 : : */
2525 : : void
2526 : 353285 : mf_write_subfield(const struct mf_subfield *sf, const union mf_subvalue *x,
2527 : : struct match *match)
2528 : : {
2529 : 353285 : const struct mf_field *field = sf->field;
2530 : : union mf_value value, mask;
2531 : :
2532 : 353285 : mf_get(field, match, &value, &mask);
2533 : 353285 : bitwise_copy(x, sizeof *x, 0, &value, field->n_bytes, sf->ofs, sf->n_bits);
2534 : 353285 : bitwise_one ( &mask, field->n_bytes, sf->ofs, sf->n_bits);
2535 : 353285 : mf_set(field, &value, &mask, match, NULL);
2536 : 353285 : }
2537 : :
2538 : : void
2539 : 33 : mf_write_subfield_value(const struct mf_subfield *sf, const void *src,
2540 : : struct match *match)
2541 : : {
2542 : 33 : const struct mf_field *field = sf->field;
2543 : : union mf_value value, mask;
2544 : 33 : unsigned int size = DIV_ROUND_UP(sf->n_bits, 8);
2545 : :
2546 : 33 : mf_get(field, match, &value, &mask);
2547 : 33 : bitwise_copy(src, size, 0, &value, field->n_bytes, sf->ofs, sf->n_bits);
2548 : 33 : bitwise_one ( &mask, field->n_bytes, sf->ofs, sf->n_bits);
2549 : 33 : mf_set(field, &value, &mask, match, NULL);
2550 : 33 : }
2551 : :
2552 : : /* 'v' and 'm' correspond to values of 'field'. This function copies them into
2553 : : * 'match' in the correspond positions. */
2554 : : void
2555 : 1636889 : mf_mask_subfield(const struct mf_field *field,
2556 : : const union mf_subvalue *v,
2557 : : const union mf_subvalue *m,
2558 : : struct match *match)
2559 : : {
2560 : : union mf_value value, mask;
2561 : :
2562 : 1636889 : mf_get(field, match, &value, &mask);
2563 : 1636889 : bitwise_copy(v, sizeof *v, 0, &value, field->n_bytes, 0, field->n_bits);
2564 : 1636889 : bitwise_copy(m, sizeof *m, 0, &mask, field->n_bytes, 0, field->n_bits);
2565 : 1636889 : mf_set(field, &value, &mask, match, NULL);
2566 : 1636889 : }
2567 : :
2568 : : /* Initializes 'x' to the value of 'sf' within 'flow'. 'sf' must be valid for
2569 : : * reading 'flow', e.g. as checked by mf_check_src(). */
2570 : : void
2571 : 104336 : mf_read_subfield(const struct mf_subfield *sf, const struct flow *flow,
2572 : : union mf_subvalue *x)
2573 : : {
2574 : : union mf_value value;
2575 : :
2576 : 104336 : mf_get_value(sf->field, flow, &value);
2577 : :
2578 : 104336 : memset(x, 0, sizeof *x);
2579 : 104336 : bitwise_copy(&value, sf->field->n_bytes, sf->ofs,
2580 : : x, sizeof *x, 0,
2581 : : sf->n_bits);
2582 : 104336 : }
2583 : :
2584 : : /* Returns the value of 'sf' within 'flow'. 'sf' must be valid for reading
2585 : : * 'flow', e.g. as checked by mf_check_src() and sf->n_bits must be 64 or
2586 : : * less. */
2587 : : uint64_t
2588 : 15247641 : mf_get_subfield(const struct mf_subfield *sf, const struct flow *flow)
2589 : : {
2590 : : union mf_value value;
2591 : :
2592 : 15247641 : mf_get_value(sf->field, flow, &value);
2593 : 15247641 : return bitwise_get(&value, sf->field->n_bytes, sf->ofs, sf->n_bits);
2594 : : }
2595 : :
2596 : : void
2597 : 98667 : mf_format_subvalue(const union mf_subvalue *subvalue, struct ds *s)
2598 : : {
2599 : 98667 : ds_put_hex(s, subvalue->u8, sizeof subvalue->u8);
2600 : 98667 : }
2601 : :
2602 : : void
2603 : 36 : field_array_set(enum mf_field_id id, const union mf_value *value,
2604 : : struct field_array *fa)
2605 : : {
2606 : 36 : size_t i, offset = 0;
2607 : :
2608 [ - + ]: 36 : ovs_assert(id < MFF_N_IDS);
2609 : :
2610 : : /* Find the spot for 'id'. */
2611 [ + + ]: 71 : BITMAP_FOR_EACH_1 (i, id, fa->used.bm) {
2612 : 35 : offset += mf_from_id(i)->n_bytes;
2613 : : }
2614 : :
2615 : 36 : size_t value_size = mf_from_id(id)->n_bytes;
2616 : :
2617 : : /* make room if necessary. */
2618 [ + - ]: 36 : if (!bitmap_is_set(fa->used.bm, id)) {
2619 : 36 : fa->values = xrealloc(fa->values, fa->values_size + value_size);
2620 : : /* Move remainder forward, if any. */
2621 [ + + ]: 36 : if (offset < fa->values_size) {
2622 : 1 : memmove(fa->values + offset + value_size, fa->values + offset,
2623 : 1 : fa->values_size - offset);
2624 : : }
2625 : 36 : fa->values_size += value_size;
2626 : : }
2627 : 36 : bitmap_set1(fa->used.bm, id);
2628 : :
2629 : 36 : memcpy(fa->values + offset, value, value_size);
2630 : 36 : }
|