]> git.proxmox.com Git - mirror_ovs.git/blame - lib/odp-util.c
Support accepting and displaying table names in OVS tools.
[mirror_ovs.git] / lib / odp-util.c
CommitLineData
064af421 1/*
fd13c6b5 2 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
064af421 3 *
a14bc59f
BP
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
064af421 7 *
a14bc59f
BP
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
064af421
BP
15 */
16
17#include <config.h>
b2befd5b
BP
18#include <sys/types.h>
19#include <netinet/in.h>
bed69b3e 20#include <arpa/inet.h>
064af421 21#include "odp-util.h"
36956a7d 22#include <errno.h>
064af421 23#include <inttypes.h>
7202cbe5 24#include <math.h>
685a51a5 25#include <netinet/icmp6.h>
370e373b 26#include <netinet/ip6.h>
064af421
BP
27#include <stdlib.h>
28#include <string.h>
a36de779 29
cdee00fd 30#include "byte-order.h"
064af421 31#include "coverage.h"
758c456d 32#include "dpif.h"
3e8a2ad1 33#include "openvswitch/dynamic-string.h"
064af421 34#include "flow.h"
cdee00fd 35#include "netlink.h"
64c96779 36#include "openvswitch/ofpbuf.h"
064af421 37#include "packets.h"
44bac24b 38#include "simap.h"
064af421 39#include "timeval.h"
9558d2a5 40#include "tun-metadata.h"
a36de779 41#include "unaligned.h"
064af421 42#include "util.h"
10e92b4f 43#include "uuid.h"
e6211adc 44#include "openvswitch/vlog.h"
8b668ee3 45#include "openvswitch/match.h"
34118cae
BP
46
47VLOG_DEFINE_THIS_MODULE(odp_util);
064af421 48
df2c07f4
JP
49/* The interface between userspace and kernel uses an "OVS_*" prefix.
50 * Since this is fairly non-specific for the OVS userspace components,
51 * "ODP_*" (Open vSwitch Datapath) is used as the prefix for
52 * interactions with the datapath.
53 */
54
7202cbe5
BP
55/* The set of characters that may separate one action or one key attribute
56 * from another. */
57static const char *delimiters = ", \t\r\n";
d787ad39 58static const char *delimiters_end = ", \t\r\n)";
7202cbe5 59
e6cc0bab
AZ
60static int parse_odp_key_mask_attr(const char *, const struct simap *port_names,
61 struct ofpbuf *, struct ofpbuf *);
62static void format_odp_key_attr(const struct nlattr *a,
0a37839c
GS
63 const struct nlattr *ma,
64 const struct hmap *portno_names, struct ds *ds,
041e7168 65 bool verbose);
a052b51b 66
5bb08b0e
JG
67struct geneve_scan {
68 struct geneve_opt d[63];
69 int len;
70};
71
72static int scan_geneve(const char *s, struct geneve_scan *key,
73 struct geneve_scan *mask);
74static void format_geneve_opts(const struct geneve_opt *opt,
75 const struct geneve_opt *mask, int opts_len,
76 struct ds *, bool verbose);
77
65da723b
JG
78static struct nlattr *generate_all_wildcard_mask(const struct attr_len_tbl tbl[],
79 int max, struct ofpbuf *,
80 const struct nlattr *key);
89cf41ec
BP
81static void format_u128(struct ds *d, const ovs_32aligned_u128 *key,
82 const ovs_32aligned_u128 *mask, bool verbose);
9daf2348
JS
83static int scan_u128(const char *s, ovs_u128 *value, ovs_u128 *mask);
84
c37f7135
AZ
85static int parse_odp_action(const char *s, const struct simap *port_names,
86 struct ofpbuf *actions);
87
98403001
BP
88/* Returns one the following for the action with the given OVS_ACTION_ATTR_*
89 * 'type':
90 *
91 * - For an action whose argument has a fixed length, returned that
92 * nonnegative length in bytes.
93 *
6b8da9e9 94 * - For an action with a variable-length argument, returns ATTR_LEN_VARIABLE.
98403001 95 *
6b8da9e9 96 * - For an invalid 'type', returns ATTR_LEN_INVALID. */
4edb9ae9 97static int
cdee00fd
BP
98odp_action_len(uint16_t type)
99{
df2c07f4 100 if (type > OVS_ACTION_ATTR_MAX) {
cdee00fd
BP
101 return -1;
102 }
103
09ded0ad 104 switch ((enum ovs_action_attr) type) {
fea393b1 105 case OVS_ACTION_ATTR_OUTPUT: return sizeof(uint32_t);
aaca4fe0 106 case OVS_ACTION_ATTR_TRUNC: return sizeof(struct ovs_action_trunc);
6b8da9e9 107 case OVS_ACTION_ATTR_TUNNEL_PUSH: return ATTR_LEN_VARIABLE;
a36de779 108 case OVS_ACTION_ATTR_TUNNEL_POP: return sizeof(uint32_t);
5dddf960 109 case OVS_ACTION_ATTR_METER: return sizeof(uint32_t);
6b8da9e9 110 case OVS_ACTION_ATTR_USERSPACE: return ATTR_LEN_VARIABLE;
fea393b1
BP
111 case OVS_ACTION_ATTR_PUSH_VLAN: return sizeof(struct ovs_action_push_vlan);
112 case OVS_ACTION_ATTR_POP_VLAN: return 0;
b02475c5
SH
113 case OVS_ACTION_ATTR_PUSH_MPLS: return sizeof(struct ovs_action_push_mpls);
114 case OVS_ACTION_ATTR_POP_MPLS: return sizeof(ovs_be16);
347bf289
AZ
115 case OVS_ACTION_ATTR_RECIRC: return sizeof(uint32_t);
116 case OVS_ACTION_ATTR_HASH: return sizeof(struct ovs_action_hash);
6b8da9e9
JG
117 case OVS_ACTION_ATTR_SET: return ATTR_LEN_VARIABLE;
118 case OVS_ACTION_ATTR_SET_MASKED: return ATTR_LEN_VARIABLE;
119 case OVS_ACTION_ATTR_SAMPLE: return ATTR_LEN_VARIABLE;
07659514 120 case OVS_ACTION_ATTR_CT: return ATTR_LEN_VARIABLE;
1fe178d2 121 case OVS_ACTION_ATTR_CT_CLEAR: return 0;
6fcecb85
YY
122 case OVS_ACTION_ATTR_PUSH_ETH: return sizeof(struct ovs_action_push_eth);
123 case OVS_ACTION_ATTR_POP_ETH: return 0;
535e3acf 124 case OVS_ACTION_ATTR_CLONE: return ATTR_LEN_VARIABLE;
f59cb331
YY
125 case OVS_ACTION_ATTR_PUSH_NSH: return ATTR_LEN_VARIABLE;
126 case OVS_ACTION_ATTR_POP_NSH: return 0;
df2c07f4
JP
127
128 case OVS_ACTION_ATTR_UNSPEC:
129 case __OVS_ACTION_ATTR_MAX:
6b8da9e9 130 return ATTR_LEN_INVALID;
cdee00fd
BP
131 }
132
6b8da9e9 133 return ATTR_LEN_INVALID;
cdee00fd
BP
134}
135
e6603631
BP
136/* Returns a string form of 'attr'. The return value is either a statically
137 * allocated constant string or the 'bufsize'-byte buffer 'namebuf'. 'bufsize'
138 * should be at least OVS_KEY_ATTR_BUFSIZE. */
139enum { OVS_KEY_ATTR_BUFSIZE = 3 + INT_STRLEN(unsigned int) + 1 };
744791b5 140static const char *
e6603631 141ovs_key_attr_to_string(enum ovs_key_attr attr, char *namebuf, size_t bufsize)
744791b5 142{
744791b5
BP
143 switch (attr) {
144 case OVS_KEY_ATTR_UNSPEC: return "unspec";
fea393b1 145 case OVS_KEY_ATTR_ENCAP: return "encap";
1b567fb9 146 case OVS_KEY_ATTR_PRIORITY: return "skb_priority";
72e8bf28 147 case OVS_KEY_ATTR_SKB_MARK: return "skb_mark";
07659514
JS
148 case OVS_KEY_ATTR_CT_STATE: return "ct_state";
149 case OVS_KEY_ATTR_CT_ZONE: return "ct_zone";
8e53fe8c 150 case OVS_KEY_ATTR_CT_MARK: return "ct_mark";
9daf2348 151 case OVS_KEY_ATTR_CT_LABELS: return "ct_label";
c30b4cea
JR
152 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4: return "ct_tuple4";
153 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6: return "ct_tuple6";
9b405f1a 154 case OVS_KEY_ATTR_TUNNEL: return "tunnel";
744791b5
BP
155 case OVS_KEY_ATTR_IN_PORT: return "in_port";
156 case OVS_KEY_ATTR_ETHERNET: return "eth";
fea393b1 157 case OVS_KEY_ATTR_VLAN: return "vlan";
744791b5
BP
158 case OVS_KEY_ATTR_ETHERTYPE: return "eth_type";
159 case OVS_KEY_ATTR_IPV4: return "ipv4";
160 case OVS_KEY_ATTR_IPV6: return "ipv6";
161 case OVS_KEY_ATTR_TCP: return "tcp";
dc235f7f 162 case OVS_KEY_ATTR_TCP_FLAGS: return "tcp_flags";
744791b5 163 case OVS_KEY_ATTR_UDP: return "udp";
c6bcb685 164 case OVS_KEY_ATTR_SCTP: return "sctp";
744791b5
BP
165 case OVS_KEY_ATTR_ICMP: return "icmp";
166 case OVS_KEY_ATTR_ICMPV6: return "icmpv6";
167 case OVS_KEY_ATTR_ARP: return "arp";
168 case OVS_KEY_ATTR_ND: return "nd";
b02475c5 169 case OVS_KEY_ATTR_MPLS: return "mpls";
572f732a
AZ
170 case OVS_KEY_ATTR_DP_HASH: return "dp_hash";
171 case OVS_KEY_ATTR_RECIRC_ID: return "recirc_id";
beb75a40 172 case OVS_KEY_ATTR_PACKET_TYPE: return "packet_type";
3d2fbd70 173 case OVS_KEY_ATTR_NSH: return "nsh";
744791b5
BP
174
175 case __OVS_KEY_ATTR_MAX:
176 default:
e6603631
BP
177 snprintf(namebuf, bufsize, "key%u", (unsigned int) attr);
178 return namebuf;
744791b5
BP
179 }
180}
181
cdee00fd
BP
182static void
183format_generic_odp_action(struct ds *ds, const struct nlattr *a)
184{
8ba43fbd
BP
185 size_t len = nl_attr_get_size(a);
186
fd13c6b5 187 ds_put_format(ds, "action%d", nl_attr_type(a));
8ba43fbd 188 if (len) {
cdee00fd
BP
189 const uint8_t *unspec;
190 unsigned int i;
191
192 unspec = nl_attr_get(a);
8ba43fbd 193 for (i = 0; i < len; i++) {
cdee00fd
BP
194 ds_put_char(ds, i ? ' ': '(');
195 ds_put_format(ds, "%02x", unspec[i]);
196 }
197 ds_put_char(ds, ')');
198 }
199}
200
6ff686f2 201static void
0722f341
BP
202format_odp_sample_action(struct ds *ds, const struct nlattr *attr,
203 const struct hmap *portno_names)
6ff686f2
PS
204{
205 static const struct nl_policy ovs_sample_policy[] = {
3548d242
BP
206 [OVS_SAMPLE_ATTR_PROBABILITY] = { .type = NL_A_U32 },
207 [OVS_SAMPLE_ATTR_ACTIONS] = { .type = NL_A_NESTED }
6ff686f2
PS
208 };
209 struct nlattr *a[ARRAY_SIZE(ovs_sample_policy)];
6ff686f2
PS
210 double percentage;
211 const struct nlattr *nla_acts;
212 int len;
213
214 ds_put_cstr(ds, "sample");
215
5621afff 216 if (!nl_parse_nested(attr, ovs_sample_policy, a, ARRAY_SIZE(a))) {
6ff686f2
PS
217 ds_put_cstr(ds, "(error)");
218 return;
219 }
220
221 percentage = (100.0 * nl_attr_get_u32(a[OVS_SAMPLE_ATTR_PROBABILITY])) /
222 UINT32_MAX;
223
224 ds_put_format(ds, "(sample=%.1f%%,", percentage);
225
226 ds_put_cstr(ds, "actions(");
227 nla_acts = nl_attr_get(a[OVS_SAMPLE_ATTR_ACTIONS]);
228 len = nl_attr_get_size(a[OVS_SAMPLE_ATTR_ACTIONS]);
0722f341 229 format_odp_actions(ds, nla_acts, len, portno_names);
6ff686f2
PS
230 ds_put_format(ds, "))");
231}
232
535e3acf 233static void
0722f341
BP
234format_odp_clone_action(struct ds *ds, const struct nlattr *attr,
235 const struct hmap *portno_names)
535e3acf
AZ
236{
237 const struct nlattr *nla_acts = nl_attr_get(attr);
238 int len = nl_attr_get_size(attr);
239
240 ds_put_cstr(ds, "clone");
241 ds_put_format(ds, "(");
0722f341 242 format_odp_actions(ds, nla_acts, len, portno_names);
535e3acf
AZ
243 ds_put_format(ds, ")");
244}
245
3d2fbd70
JS
246static void
247format_nsh_key(struct ds *ds, const struct ovs_key_nsh *key)
248{
249 ds_put_format(ds, "flags=%d", key->flags);
17553f27 250 ds_put_format(ds, "ttl=%d", key->ttl);
3d2fbd70
JS
251 ds_put_format(ds, ",mdtype=%d", key->mdtype);
252 ds_put_format(ds, ",np=%d", key->np);
253 ds_put_format(ds, ",spi=0x%x",
17553f27 254 nsh_path_hdr_to_spi_uint32(key->path_hdr));
3d2fbd70 255 ds_put_format(ds, ",si=%d",
17553f27 256 nsh_path_hdr_to_si(key->path_hdr));
3d2fbd70
JS
257
258 switch (key->mdtype) {
259 case NSH_M_TYPE1:
260 for (int i = 0; i < 4; i++) {
f59cb331 261 ds_put_format(ds, ",c%d=0x%x", i + 1, ntohl(key->context[i]));
3d2fbd70
JS
262 }
263 break;
264 case NSH_M_TYPE2:
3d2fbd70 265 default:
1fc11c59
JS
266 /* No support for matching other metadata formats yet. */
267 break;
3d2fbd70
JS
268 }
269}
270
271static void
272format_uint8_masked(struct ds *s, bool *first, const char *name,
273 uint8_t value, uint8_t mask)
274{
275 if (mask != 0) {
276 if (!*first) {
277 ds_put_char(s, ',');
278 }
279 ds_put_format(s, "%s=", name);
280 if (mask == UINT8_MAX) {
281 ds_put_format(s, "%"PRIu8, value);
282 } else {
283 ds_put_format(s, "0x%02"PRIx8"/0x%02"PRIx8, value, mask);
284 }
285 *first = false;
286 }
287}
288
289static void
290format_be32_masked(struct ds *s, bool *first, const char *name,
291 ovs_be32 value, ovs_be32 mask)
292{
293 if (mask != htonl(0)) {
294 if (!*first) {
295 ds_put_char(s, ',');
296 }
297 ds_put_format(s, "%s=", name);
298 if (mask == OVS_BE32_MAX) {
299 ds_put_format(s, "0x%"PRIx32, ntohl(value));
300 } else {
301 ds_put_format(s, "0x%"PRIx32"/0x%08"PRIx32,
302 ntohl(value), ntohl(mask));
303 }
304 *first = false;
305 }
306}
307
308static void
309format_nsh_key_mask(struct ds *ds, const struct ovs_key_nsh *key,
310 const struct ovs_key_nsh *mask)
311{
312 if (!mask) {
313 format_nsh_key(ds, key);
314 } else {
315 bool first = true;
17553f27
YY
316 uint32_t spi = nsh_path_hdr_to_spi_uint32(key->path_hdr);
317 uint32_t spi_mask = nsh_path_hdr_to_spi_uint32(mask->path_hdr);
318 if (spi_mask == (NSH_SPI_MASK >> NSH_SPI_SHIFT)) {
3d2fbd70
JS
319 spi_mask = UINT32_MAX;
320 }
17553f27
YY
321 uint8_t si = nsh_path_hdr_to_si(key->path_hdr);
322 uint8_t si_mask = nsh_path_hdr_to_si(mask->path_hdr);
3d2fbd70
JS
323
324 format_uint8_masked(ds, &first, "flags", key->flags, mask->flags);
17553f27 325 format_uint8_masked(ds, &first, "ttl", key->ttl, mask->ttl);
3d2fbd70
JS
326 format_uint8_masked(ds, &first, "mdtype", key->mdtype, mask->mdtype);
327 format_uint8_masked(ds, &first, "np", key->np, mask->np);
328 format_be32_masked(ds, &first, "spi", htonl(spi), htonl(spi_mask));
329 format_uint8_masked(ds, &first, "si", si, si_mask);
f59cb331
YY
330 format_be32_masked(ds, &first, "c1", key->context[0],
331 mask->context[0]);
332 format_be32_masked(ds, &first, "c2", key->context[1],
333 mask->context[1]);
334 format_be32_masked(ds, &first, "c3", key->context[2],
335 mask->context[2]);
336 format_be32_masked(ds, &first, "c4", key->context[3],
337 mask->context[3]);
3d2fbd70
JS
338 }
339}
340
1fc11c59 341static void
f59cb331
YY
342format_odp_push_nsh_action(struct ds *ds,
343 const struct nsh_hdr *nsh_hdr)
1fc11c59 344 {
f59cb331 345 size_t mdlen = nsh_hdr_len(nsh_hdr) - NSH_BASE_HDR_LEN;
17553f27
YY
346 uint32_t spi = ntohl(nsh_get_spi(nsh_hdr));
347 uint8_t si = nsh_get_si(nsh_hdr);
f59cb331 348 uint8_t flags = nsh_get_flags(nsh_hdr);
17553f27 349 uint8_t ttl = nsh_get_ttl(nsh_hdr);
1fc11c59 350
f59cb331
YY
351 ds_put_cstr(ds, "push_nsh(");
352 ds_put_format(ds, "flags=%d", flags);
17553f27 353 ds_put_format(ds, ",ttl=%d", ttl);
f59cb331
YY
354 ds_put_format(ds, ",mdtype=%d", nsh_hdr->md_type);
355 ds_put_format(ds, ",np=%d", nsh_hdr->next_proto);
1fc11c59
JS
356 ds_put_format(ds, ",spi=0x%x", spi);
357 ds_put_format(ds, ",si=%d", si);
f59cb331 358 switch (nsh_hdr->md_type) {
1fc11c59 359 case NSH_M_TYPE1: {
f59cb331 360 const struct nsh_md1_ctx *md1_ctx = &nsh_hdr->md1;
1fc11c59
JS
361 for (int i = 0; i < 4; i++) {
362 ds_put_format(ds, ",c%d=0x%x", i + 1,
f59cb331 363 ntohl(get_16aligned_be32(&md1_ctx->context[i])));
1fc11c59
JS
364 }
365 break;
366 }
f59cb331
YY
367 case NSH_M_TYPE2: {
368 const struct nsh_md2_tlv *md2_ctx = &nsh_hdr->md2;
1fc11c59 369 ds_put_cstr(ds, ",md2=");
f59cb331 370 ds_put_hex(ds, md2_ctx, mdlen);
1fc11c59 371 break;
f59cb331 372 }
1fc11c59
JS
373 default:
374 OVS_NOT_REACHED();
375 }
376 ds_put_format(ds, ")");
377}
378
6a7e895f 379static const char *
04594cd5 380slow_path_reason_to_string(uint32_t reason)
6a7e895f 381{
04594cd5
BP
382 switch ((enum slow_path_reason) reason) {
383#define SPR(ENUM, STRING, EXPLANATION) case ENUM: return STRING;
384 SLOW_PATH_REASONS
385#undef SPR
6a7e895f 386 }
04594cd5
BP
387
388 return NULL;
6a7e895f
BP
389}
390
04594cd5
BP
391const char *
392slow_path_reason_to_explanation(enum slow_path_reason reason)
98f0520f 393{
04594cd5
BP
394 switch (reason) {
395#define SPR(ENUM, STRING, EXPLANATION) case ENUM: return EXPLANATION;
396 SLOW_PATH_REASONS
397#undef SPR
98f0520f
EJ
398 }
399
04594cd5 400 return "<unknown>";
98f0520f
EJ
401}
402
ec956fc7 403static int
8e4c1621
JG
404parse_odp_flags(const char *s, const char *(*bit_to_string)(uint32_t),
405 uint32_t *res_flags, uint32_t allowed, uint32_t *res_mask)
ec956fc7 406{
8e4c1621
JG
407 return parse_flags(s, bit_to_string, ')', NULL, NULL,
408 res_flags, allowed, res_mask);
6a7e895f
BP
409}
410
98403001 411static void
0722f341
BP
412format_odp_userspace_action(struct ds *ds, const struct nlattr *attr,
413 const struct hmap *portno_names)
98403001
BP
414{
415 static const struct nl_policy ovs_userspace_policy[] = {
3548d242
BP
416 [OVS_USERSPACE_ATTR_PID] = { .type = NL_A_U32 },
417 [OVS_USERSPACE_ATTR_USERDATA] = { .type = NL_A_UNSPEC,
418 .optional = true },
8b7ea2d4
WZ
419 [OVS_USERSPACE_ATTR_EGRESS_TUN_PORT] = { .type = NL_A_U32,
420 .optional = true },
7321bda3
NM
421 [OVS_USERSPACE_ATTR_ACTIONS] = { .type = NL_A_UNSPEC,
422 .optional = true },
98403001
BP
423 };
424 struct nlattr *a[ARRAY_SIZE(ovs_userspace_policy)];
e995e3df 425 const struct nlattr *userdata_attr;
8b7ea2d4 426 const struct nlattr *tunnel_out_port_attr;
98403001
BP
427
428 if (!nl_parse_nested(attr, ovs_userspace_policy, a, ARRAY_SIZE(a))) {
429 ds_put_cstr(ds, "userspace(error)");
430 return;
431 }
432
433 ds_put_format(ds, "userspace(pid=%"PRIu32,
434 nl_attr_get_u32(a[OVS_USERSPACE_ATTR_PID]));
435
e995e3df 436 userdata_attr = a[OVS_USERSPACE_ATTR_USERDATA];
29089a54
RL
437
438 if (userdata_attr) {
439 const uint8_t *userdata = nl_attr_get(userdata_attr);
440 size_t userdata_len = nl_attr_get_size(userdata_attr);
441 bool userdata_unspec = true;
8de6ff3e 442 struct user_action_cookie cookie;
98403001 443
8de6ff3e
JP
444 if (userdata_len == sizeof cookie) {
445 memcpy(&cookie, userdata, sizeof cookie);
29089a54
RL
446
447 userdata_unspec = false;
448
8de6ff3e 449 if (cookie.type == USER_ACTION_COOKIE_SFLOW) {
29089a54 450 ds_put_format(ds, ",sFlow("
fd13c6b5 451 "vid=%"PRIu16",pcp=%d,output=%"PRIu32")",
29089a54
RL
452 vlan_tci_to_vid(cookie.sflow.vlan_tci),
453 vlan_tci_to_pcp(cookie.sflow.vlan_tci),
454 cookie.sflow.output);
8de6ff3e 455 } else if (cookie.type == USER_ACTION_COOKIE_SLOW_PATH) {
04594cd5
BP
456 ds_put_cstr(ds, ",slow_path(");
457 format_flags(ds, slow_path_reason_to_string,
458 cookie.slow_path.reason, ',');
459 ds_put_format(ds, ")");
8de6ff3e 460 } else if (cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) {
29089a54
RL
461 ds_put_format(ds, ",flow_sample(probability=%"PRIu16
462 ",collector_set_id=%"PRIu32
463 ",obs_domain_id=%"PRIu32
f69f713b 464 ",obs_point_id=%"PRIu32
0722f341 465 ",output_port=",
29089a54
RL
466 cookie.flow_sample.probability,
467 cookie.flow_sample.collector_set_id,
468 cookie.flow_sample.obs_domain_id,
0722f341
BP
469 cookie.flow_sample.obs_point_id);
470 odp_portno_name_format(portno_names,
471 cookie.flow_sample.output_odp_port, ds);
4930ea56
BP
472 if (cookie.flow_sample.direction == NX_ACTION_SAMPLE_INGRESS) {
473 ds_put_cstr(ds, ",ingress");
474 } else if (cookie.flow_sample.direction == NX_ACTION_SAMPLE_EGRESS) {
475 ds_put_cstr(ds, ",egress");
476 }
477 ds_put_char(ds, ')');
8de6ff3e 478 } else if (cookie.type == USER_ACTION_COOKIE_IPFIX) {
0722f341
BP
479 ds_put_format(ds, ",ipfix(output_port=");
480 odp_portno_name_format(portno_names,
481 cookie.ipfix.output_odp_port, ds);
482 ds_put_char(ds, ')');
d39ec23d
JP
483 } else if (cookie.type == USER_ACTION_COOKIE_CONTROLLER) {
484 ds_put_format(ds, ",controller(reason=%"PRIu16
68c5c73b
AC
485 ",dont_send=%d"
486 ",continuation=%d"
d39ec23d
JP
487 ",recirc_id=%"PRIu32
488 ",rule_cookie=%#"PRIx64
489 ",controller_id=%"PRIu16
490 ",max_len=%"PRIu16,
491 cookie.controller.reason,
492 cookie.controller.dont_send ? 1 : 0,
74c4530d 493 cookie.controller.continuation ? 1 : 0,
d39ec23d
JP
494 cookie.controller.recirc_id,
495 ntohll(get_32aligned_be64(
496 &cookie.controller.rule_cookie)),
497 cookie.controller.controller_id,
498 cookie.controller.max_len);
499 ds_put_char(ds, ')');
29089a54
RL
500 } else {
501 userdata_unspec = true;
502 }
98403001 503 }
e995e3df 504
29089a54
RL
505 if (userdata_unspec) {
506 size_t i;
507 ds_put_format(ds, ",userdata(");
508 for (i = 0; i < userdata_len; i++) {
509 ds_put_format(ds, "%02x", userdata[i]);
510 }
511 ds_put_char(ds, ')');
e995e3df 512 }
98403001
BP
513 }
514
7321bda3
NM
515 if (a[OVS_USERSPACE_ATTR_ACTIONS]) {
516 ds_put_cstr(ds, ",actions");
517 }
518
8b7ea2d4
WZ
519 tunnel_out_port_attr = a[OVS_USERSPACE_ATTR_EGRESS_TUN_PORT];
520 if (tunnel_out_port_attr) {
0722f341
BP
521 ds_put_format(ds, ",tunnel_out_port=");
522 odp_portno_name_format(portno_names,
523 nl_attr_get_odp_port(tunnel_out_port_attr), ds);
8b7ea2d4
WZ
524 }
525
98403001
BP
526 ds_put_char(ds, ')');
527}
528
8ddc056d 529static void
2d18eae8 530format_vlan_tci(struct ds *ds, ovs_be16 tci, ovs_be16 mask, bool verbose)
8ddc056d 531{
2d18eae8
JR
532 if (verbose || vlan_tci_to_vid(tci) || vlan_tci_to_vid(mask)) {
533 ds_put_format(ds, "vid=%"PRIu16, vlan_tci_to_vid(tci));
534 if (vlan_tci_to_vid(mask) != VLAN_VID_MASK) { /* Partially masked. */
535 ds_put_format(ds, "/0x%"PRIx16, vlan_tci_to_vid(mask));
536 };
537 ds_put_char(ds, ',');
538 }
539 if (verbose || vlan_tci_to_pcp(tci) || vlan_tci_to_pcp(mask)) {
540 ds_put_format(ds, "pcp=%d", vlan_tci_to_pcp(tci));
541 if (vlan_tci_to_pcp(mask) != (VLAN_PCP_MASK >> VLAN_PCP_SHIFT)) {
542 ds_put_format(ds, "/0x%x", vlan_tci_to_pcp(mask));
543 }
544 ds_put_char(ds, ',');
545 }
546 if (!(tci & htons(VLAN_CFI))) {
547 ds_put_cstr(ds, "cfi=0");
548 ds_put_char(ds, ',');
8ddc056d 549 }
2d18eae8 550 ds_chomp(ds, ',');
8ddc056d
BP
551}
552
b02475c5
SH
553static void
554format_mpls_lse(struct ds *ds, ovs_be32 mpls_lse)
555{
556 ds_put_format(ds, "label=%"PRIu32",tc=%d,ttl=%d,bos=%d",
557 mpls_lse_to_label(mpls_lse),
558 mpls_lse_to_tc(mpls_lse),
559 mpls_lse_to_ttl(mpls_lse),
560 mpls_lse_to_bos(mpls_lse));
561}
562
e6cc0bab
AZ
563static void
564format_mpls(struct ds *ds, const struct ovs_key_mpls *mpls_key,
8bfd0fda 565 const struct ovs_key_mpls *mpls_mask, int n)
e6cc0bab 566{
8f79bb4d
JR
567 for (int i = 0; i < n; i++) {
568 ovs_be32 key = mpls_key[i].mpls_lse;
e6cc0bab 569
8bfd0fda
BP
570 if (mpls_mask == NULL) {
571 format_mpls_lse(ds, key);
572 } else {
8f79bb4d 573 ovs_be32 mask = mpls_mask[i].mpls_lse;
8bfd0fda
BP
574
575 ds_put_format(ds, "label=%"PRIu32"/0x%x,tc=%d/%x,ttl=%d/0x%x,bos=%d/%x",
576 mpls_lse_to_label(key), mpls_lse_to_label(mask),
577 mpls_lse_to_tc(key), mpls_lse_to_tc(mask),
578 mpls_lse_to_ttl(key), mpls_lse_to_ttl(mask),
579 mpls_lse_to_bos(key), mpls_lse_to_bos(mask));
580 }
8f79bb4d 581 ds_put_char(ds, ',');
e6cc0bab 582 }
8f79bb4d 583 ds_chomp(ds, ',');
e6cc0bab
AZ
584}
585
572f732a 586static void
347bf289 587format_odp_recirc_action(struct ds *ds, uint32_t recirc_id)
572f732a 588{
8f19f0a7 589 ds_put_format(ds, "recirc(%#"PRIx32")", recirc_id);
347bf289 590}
572f732a 591
347bf289
AZ
592static void
593format_odp_hash_action(struct ds *ds, const struct ovs_action_hash *hash_act)
594{
595 ds_put_format(ds, "hash(");
572f732a 596
347bf289 597 if (hash_act->hash_alg == OVS_HASH_ALG_L4) {
62ac1f20 598 ds_put_format(ds, "hash_l4(%"PRIu32")", hash_act->hash_basis);
347bf289
AZ
599 } else {
600 ds_put_format(ds, "Unknown hash algorithm(%"PRIu32")",
601 hash_act->hash_alg);
602 }
603 ds_put_format(ds, ")");
572f732a
AZ
604}
605
e066f78f 606static const void *
370e373b 607format_udp_tnl_push_header(struct ds *ds, const struct udp_header *udp)
e066f78f 608{
8e45fe7c
JG
609 ds_put_format(ds, "udp(src=%"PRIu16",dst=%"PRIu16",csum=0x%"PRIx16"),",
610 ntohs(udp->udp_src), ntohs(udp->udp_dst),
611 ntohs(udp->udp_csum));
e066f78f
JG
612
613 return udp + 1;
614}
615
a36de779
PS
616static void
617format_odp_tnl_push_header(struct ds *ds, struct ovs_action_push_tnl *data)
618{
619 const struct eth_header *eth;
a36de779 620 const void *l3;
370e373b
TLSC
621 const void *l4;
622 const struct udp_header *udp;
a36de779
PS
623
624 eth = (const struct eth_header *)data->header;
625
626 l3 = eth + 1;
a36de779
PS
627
628 /* Ethernet */
fd13c6b5 629 ds_put_format(ds, "header(size=%"PRIu32",type=%"PRIu32",eth(dst=",
a36de779
PS
630 data->header_len, data->tnl_type);
631 ds_put_format(ds, ETH_ADDR_FMT, ETH_ADDR_ARGS(eth->eth_dst));
632 ds_put_format(ds, ",src=");
633 ds_put_format(ds, ETH_ADDR_FMT, ETH_ADDR_ARGS(eth->eth_src));
634 ds_put_format(ds, ",dl_type=0x%04"PRIx16"),", ntohs(eth->eth_type));
635
370e373b
TLSC
636 if (eth->eth_type == htons(ETH_TYPE_IP)) {
637 /* IPv4 */
8568c7a5 638 const struct ip_header *ip = l3;
370e373b
TLSC
639 ds_put_format(ds, "ipv4(src="IP_FMT",dst="IP_FMT",proto=%"PRIu8
640 ",tos=%#"PRIx8",ttl=%"PRIu8",frag=0x%"PRIx16"),",
641 IP_ARGS(get_16aligned_be32(&ip->ip_src)),
642 IP_ARGS(get_16aligned_be32(&ip->ip_dst)),
643 ip->ip_proto, ip->ip_tos,
644 ip->ip_ttl,
fa47c114 645 ntohs(ip->ip_frag_off));
370e373b
TLSC
646 l4 = (ip + 1);
647 } else {
8568c7a5
BP
648 const struct ovs_16aligned_ip6_hdr *ip6 = l3;
649 struct in6_addr src, dst;
650 memcpy(&src, &ip6->ip6_src, sizeof src);
651 memcpy(&dst, &ip6->ip6_dst, sizeof dst);
652 uint32_t ipv6_flow = ntohl(get_16aligned_be32(&ip6->ip6_flow));
653
370e373b 654 ds_put_format(ds, "ipv6(src=");
8568c7a5 655 ipv6_format_addr(&src, ds);
370e373b 656 ds_put_format(ds, ",dst=");
8568c7a5 657 ipv6_format_addr(&dst, ds);
fd13c6b5 658 ds_put_format(ds, ",label=%i,proto=%"PRIu8",tclass=0x%"PRIx32
370e373b 659 ",hlimit=%"PRIu8"),",
8568c7a5
BP
660 ipv6_flow & IPV6_LABEL_MASK, ip6->ip6_nxt,
661 (ipv6_flow >> 20) & 0xff, ip6->ip6_hlim);
370e373b
TLSC
662 l4 = (ip6 + 1);
663 }
664
665 udp = (const struct udp_header *) l4;
a36de779
PS
666
667 if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) {
668 const struct vxlanhdr *vxh;
a36de779 669
370e373b 670 vxh = format_udp_tnl_push_header(ds, udp);
a36de779 671
a36de779
PS
672 ds_put_format(ds, "vxlan(flags=0x%"PRIx32",vni=0x%"PRIx32")",
673 ntohl(get_16aligned_be32(&vxh->vx_flags)),
a92a3aae 674 ntohl(get_16aligned_be32(&vxh->vx_vni)) >> 8);
e5a1caee
JG
675 } else if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) {
676 const struct genevehdr *gnh;
677
370e373b 678 gnh = format_udp_tnl_push_header(ds, udp);
e5a1caee 679
5bb08b0e 680 ds_put_format(ds, "geneve(%s%svni=0x%"PRIx32,
e5a1caee 681 gnh->oam ? "oam," : "",
5bb08b0e 682 gnh->critical ? "crit," : "",
e5a1caee 683 ntohl(get_16aligned_be32(&gnh->vni)) >> 8);
1fc11c59 684
5bb08b0e
JG
685 if (gnh->opt_len) {
686 ds_put_cstr(ds, ",options(");
687 format_geneve_opts(gnh->options, NULL, gnh->opt_len * 4,
688 ds, false);
689 ds_put_char(ds, ')');
690 }
691
692 ds_put_char(ds, ')');
a36de779
PS
693 } else if (data->tnl_type == OVS_VPORT_TYPE_GRE) {
694 const struct gre_base_hdr *greh;
695 ovs_16aligned_be32 *options;
a36de779 696
a36de779
PS
697 greh = (const struct gre_base_hdr *) l4;
698
699 ds_put_format(ds, "gre((flags=0x%"PRIx16",proto=0x%"PRIx16")",
e8fe6ad0 700 ntohs(greh->flags), ntohs(greh->protocol));
a36de779
PS
701 options = (ovs_16aligned_be32 *)(greh + 1);
702 if (greh->flags & htons(GRE_CSUM)) {
d804d31e 703 ds_put_format(ds, ",csum=0x%"PRIx16, ntohs(*((ovs_be16 *)options)));
a36de779
PS
704 options++;
705 }
706 if (greh->flags & htons(GRE_KEY)) {
707 ds_put_format(ds, ",key=0x%"PRIx32, ntohl(get_16aligned_be32(options)));
708 options++;
709 }
710 if (greh->flags & htons(GRE_SEQ)) {
711 ds_put_format(ds, ",seq=0x%"PRIx32, ntohl(get_16aligned_be32(options)));
712 options++;
713 }
714 ds_put_format(ds, ")");
715 }
716 ds_put_format(ds, ")");
717}
718
719static void
0722f341
BP
720format_odp_tnl_push_action(struct ds *ds, const struct nlattr *attr,
721 const struct hmap *portno_names)
a36de779
PS
722{
723 struct ovs_action_push_tnl *data;
724
725 data = (struct ovs_action_push_tnl *) nl_attr_get(attr);
726
0722f341
BP
727 ds_put_cstr(ds, "tnl_push(tnl_port(");
728 odp_portno_name_format(portno_names, data->tnl_port, ds);
729 ds_put_cstr(ds, "),");
a36de779 730 format_odp_tnl_push_header(ds, data);
0722f341
BP
731 ds_put_format(ds, ",out_port(");
732 odp_portno_name_format(portno_names, data->out_port, ds);
733 ds_put_cstr(ds, "))");
a36de779
PS
734}
735
9ac0aada
JR
736static const struct nl_policy ovs_nat_policy[] = {
737 [OVS_NAT_ATTR_SRC] = { .type = NL_A_FLAG, .optional = true, },
738 [OVS_NAT_ATTR_DST] = { .type = NL_A_FLAG, .optional = true, },
739 [OVS_NAT_ATTR_IP_MIN] = { .type = NL_A_UNSPEC, .optional = true,
740 .min_len = sizeof(struct in_addr),
741 .max_len = sizeof(struct in6_addr)},
742 [OVS_NAT_ATTR_IP_MAX] = { .type = NL_A_UNSPEC, .optional = true,
743 .min_len = sizeof(struct in_addr),
744 .max_len = sizeof(struct in6_addr)},
745 [OVS_NAT_ATTR_PROTO_MIN] = { .type = NL_A_U16, .optional = true, },
746 [OVS_NAT_ATTR_PROTO_MAX] = { .type = NL_A_U16, .optional = true, },
747 [OVS_NAT_ATTR_PERSISTENT] = { .type = NL_A_FLAG, .optional = true, },
748 [OVS_NAT_ATTR_PROTO_HASH] = { .type = NL_A_FLAG, .optional = true, },
749 [OVS_NAT_ATTR_PROTO_RANDOM] = { .type = NL_A_FLAG, .optional = true, },
750};
751
752static void
753format_odp_ct_nat(struct ds *ds, const struct nlattr *attr)
754{
755 struct nlattr *a[ARRAY_SIZE(ovs_nat_policy)];
756 size_t addr_len;
757 ovs_be32 ip_min, ip_max;
758 struct in6_addr ip6_min, ip6_max;
759 uint16_t proto_min, proto_max;
760
761 if (!nl_parse_nested(attr, ovs_nat_policy, a, ARRAY_SIZE(a))) {
762 ds_put_cstr(ds, "nat(error: nl_parse_nested() failed.)");
763 return;
764 }
765 /* If no type, then nothing else either. */
766 if (!(a[OVS_NAT_ATTR_SRC] || a[OVS_NAT_ATTR_DST])
767 && (a[OVS_NAT_ATTR_IP_MIN] || a[OVS_NAT_ATTR_IP_MAX]
768 || a[OVS_NAT_ATTR_PROTO_MIN] || a[OVS_NAT_ATTR_PROTO_MAX]
769 || a[OVS_NAT_ATTR_PERSISTENT] || a[OVS_NAT_ATTR_PROTO_HASH]
770 || a[OVS_NAT_ATTR_PROTO_RANDOM])) {
771 ds_put_cstr(ds, "nat(error: options allowed only with \"src\" or \"dst\")");
772 return;
773 }
774 /* Both SNAT & DNAT may not be specified. */
775 if (a[OVS_NAT_ATTR_SRC] && a[OVS_NAT_ATTR_DST]) {
776 ds_put_cstr(ds, "nat(error: Only one of \"src\" or \"dst\" may be present.)");
777 return;
778 }
779 /* proto may not appear without ip. */
780 if (!a[OVS_NAT_ATTR_IP_MIN] && a[OVS_NAT_ATTR_PROTO_MIN]) {
781 ds_put_cstr(ds, "nat(error: proto but no IP.)");
782 return;
783 }
784 /* MAX may not appear without MIN. */
785 if ((!a[OVS_NAT_ATTR_IP_MIN] && a[OVS_NAT_ATTR_IP_MAX])
786 || (!a[OVS_NAT_ATTR_PROTO_MIN] && a[OVS_NAT_ATTR_PROTO_MAX])) {
787 ds_put_cstr(ds, "nat(error: range max without min.)");
788 return;
789 }
790 /* Address sizes must match. */
791 if ((a[OVS_NAT_ATTR_IP_MIN]
792 && (nl_attr_get_size(a[OVS_NAT_ATTR_IP_MIN]) != sizeof(ovs_be32) &&
793 nl_attr_get_size(a[OVS_NAT_ATTR_IP_MIN]) != sizeof(struct in6_addr)))
794 || (a[OVS_NAT_ATTR_IP_MIN] && a[OVS_NAT_ATTR_IP_MAX]
795 && (nl_attr_get_size(a[OVS_NAT_ATTR_IP_MIN])
796 != nl_attr_get_size(a[OVS_NAT_ATTR_IP_MAX])))) {
797 ds_put_cstr(ds, "nat(error: IP address sizes do not match)");
798 return;
799 }
800
801 addr_len = a[OVS_NAT_ATTR_IP_MIN]
802 ? nl_attr_get_size(a[OVS_NAT_ATTR_IP_MIN]) : 0;
803 ip_min = addr_len == sizeof(ovs_be32) && a[OVS_NAT_ATTR_IP_MIN]
804 ? nl_attr_get_be32(a[OVS_NAT_ATTR_IP_MIN]) : 0;
805 ip_max = addr_len == sizeof(ovs_be32) && a[OVS_NAT_ATTR_IP_MAX]
806 ? nl_attr_get_be32(a[OVS_NAT_ATTR_IP_MAX]) : 0;
807 if (addr_len == sizeof ip6_min) {
808 ip6_min = a[OVS_NAT_ATTR_IP_MIN]
809 ? *(struct in6_addr *)nl_attr_get(a[OVS_NAT_ATTR_IP_MIN])
810 : in6addr_any;
811 ip6_max = a[OVS_NAT_ATTR_IP_MAX]
812 ? *(struct in6_addr *)nl_attr_get(a[OVS_NAT_ATTR_IP_MAX])
813 : in6addr_any;
814 }
815 proto_min = a[OVS_NAT_ATTR_PROTO_MIN]
816 ? nl_attr_get_u16(a[OVS_NAT_ATTR_PROTO_MIN]) : 0;
817 proto_max = a[OVS_NAT_ATTR_PROTO_MAX]
818 ? nl_attr_get_u16(a[OVS_NAT_ATTR_PROTO_MAX]) : 0;
819
820 if ((addr_len == sizeof(ovs_be32)
821 && ip_max && ntohl(ip_min) > ntohl(ip_max))
822 || (addr_len == sizeof(struct in6_addr)
823 && !ipv6_mask_is_any(&ip6_max)
824 && memcmp(&ip6_min, &ip6_max, sizeof ip6_min) > 0)
825 || (proto_max && proto_min > proto_max)) {
826 ds_put_cstr(ds, "nat(range error)");
827 return;
828 }
829
830 ds_put_cstr(ds, "nat");
831 if (a[OVS_NAT_ATTR_SRC] || a[OVS_NAT_ATTR_DST]) {
832 ds_put_char(ds, '(');
833 if (a[OVS_NAT_ATTR_SRC]) {
834 ds_put_cstr(ds, "src");
835 } else if (a[OVS_NAT_ATTR_DST]) {
836 ds_put_cstr(ds, "dst");
837 }
838
839 if (addr_len > 0) {
840 ds_put_cstr(ds, "=");
841
842 if (addr_len == sizeof ip_min) {
843 ds_put_format(ds, IP_FMT, IP_ARGS(ip_min));
844
845 if (ip_max && ip_max != ip_min) {
846 ds_put_format(ds, "-"IP_FMT, IP_ARGS(ip_max));
847 }
848 } else if (addr_len == sizeof ip6_min) {
849 ipv6_format_addr_bracket(&ip6_min, ds, proto_min);
850
851 if (!ipv6_mask_is_any(&ip6_max) &&
852 memcmp(&ip6_max, &ip6_min, sizeof ip6_max) != 0) {
853 ds_put_char(ds, '-');
854 ipv6_format_addr_bracket(&ip6_max, ds, proto_min);
855 }
856 }
857 if (proto_min) {
858 ds_put_format(ds, ":%"PRIu16, proto_min);
859
860 if (proto_max && proto_max != proto_min) {
861 ds_put_format(ds, "-%"PRIu16, proto_max);
862 }
863 }
864 }
865 ds_put_char(ds, ',');
866 if (a[OVS_NAT_ATTR_PERSISTENT]) {
867 ds_put_cstr(ds, "persistent,");
868 }
869 if (a[OVS_NAT_ATTR_PROTO_HASH]) {
870 ds_put_cstr(ds, "hash,");
871 }
872 if (a[OVS_NAT_ATTR_PROTO_RANDOM]) {
873 ds_put_cstr(ds, "random,");
874 }
875 ds_chomp(ds, ',');
876 ds_put_char(ds, ')');
877 }
878}
879
07659514
JS
880static const struct nl_policy ovs_conntrack_policy[] = {
881 [OVS_CT_ATTR_COMMIT] = { .type = NL_A_FLAG, .optional = true, },
a76a37ef 882 [OVS_CT_ATTR_FORCE_COMMIT] = { .type = NL_A_FLAG, .optional = true, },
07659514 883 [OVS_CT_ATTR_ZONE] = { .type = NL_A_U16, .optional = true, },
8e53fe8c
JS
884 [OVS_CT_ATTR_MARK] = { .type = NL_A_UNSPEC, .optional = true,
885 .min_len = sizeof(uint32_t) * 2 },
9daf2348
JS
886 [OVS_CT_ATTR_LABELS] = { .type = NL_A_UNSPEC, .optional = true,
887 .min_len = sizeof(struct ovs_key_ct_labels) * 2 },
d787ad39
JS
888 [OVS_CT_ATTR_HELPER] = { .type = NL_A_STRING, .optional = true,
889 .min_len = 1, .max_len = 16 },
9ac0aada 890 [OVS_CT_ATTR_NAT] = { .type = NL_A_UNSPEC, .optional = true },
07659514
JS
891};
892
893static void
894format_odp_conntrack_action(struct ds *ds, const struct nlattr *attr)
895{
896 struct nlattr *a[ARRAY_SIZE(ovs_conntrack_policy)];
89cf41ec
BP
897 const struct {
898 ovs_32aligned_u128 value;
899 ovs_32aligned_u128 mask;
900 } *label;
8e53fe8c 901 const uint32_t *mark;
d787ad39 902 const char *helper;
07659514 903 uint16_t zone;
a76a37ef 904 bool commit, force;
9ac0aada 905 const struct nlattr *nat;
07659514
JS
906
907 if (!nl_parse_nested(attr, ovs_conntrack_policy, a, ARRAY_SIZE(a))) {
908 ds_put_cstr(ds, "ct(error)");
909 return;
910 }
911
912 commit = a[OVS_CT_ATTR_COMMIT] ? true : false;
a76a37ef 913 force = a[OVS_CT_ATTR_FORCE_COMMIT] ? true : false;
07659514 914 zone = a[OVS_CT_ATTR_ZONE] ? nl_attr_get_u16(a[OVS_CT_ATTR_ZONE]) : 0;
8e53fe8c 915 mark = a[OVS_CT_ATTR_MARK] ? nl_attr_get(a[OVS_CT_ATTR_MARK]) : NULL;
9daf2348 916 label = a[OVS_CT_ATTR_LABELS] ? nl_attr_get(a[OVS_CT_ATTR_LABELS]): NULL;
d787ad39 917 helper = a[OVS_CT_ATTR_HELPER] ? nl_attr_get(a[OVS_CT_ATTR_HELPER]) : NULL;
9ac0aada 918 nat = a[OVS_CT_ATTR_NAT];
07659514
JS
919
920 ds_put_format(ds, "ct");
a76a37ef 921 if (commit || force || zone || mark || label || helper || nat) {
07659514
JS
922 ds_put_cstr(ds, "(");
923 if (commit) {
924 ds_put_format(ds, "commit,");
925 }
a76a37ef
JR
926 if (force) {
927 ds_put_format(ds, "force_commit,");
928 }
07659514
JS
929 if (zone) {
930 ds_put_format(ds, "zone=%"PRIu16",", zone);
931 }
8e53fe8c
JS
932 if (mark) {
933 ds_put_format(ds, "mark=%#"PRIx32"/%#"PRIx32",", *mark,
934 *(mark + 1));
935 }
9daf2348
JS
936 if (label) {
937 ds_put_format(ds, "label=");
89cf41ec 938 format_u128(ds, &label->value, &label->mask, true);
121cf327 939 ds_put_char(ds, ',');
9daf2348 940 }
d787ad39
JS
941 if (helper) {
942 ds_put_format(ds, "helper=%s,", helper);
943 }
9ac0aada
JR
944 if (nat) {
945 format_odp_ct_nat(ds, nat);
946 }
07659514
JS
947 ds_chomp(ds, ',');
948 ds_put_cstr(ds, ")");
949 }
950}
951
81fdabb9
YY
952static const struct attr_len_tbl
953ovs_nsh_key_attr_lens[OVS_NSH_KEY_ATTR_MAX + 1] = {
954 [OVS_NSH_KEY_ATTR_BASE] = { .len = 8 },
955 [OVS_NSH_KEY_ATTR_MD1] = { .len = 16 },
956 [OVS_NSH_KEY_ATTR_MD2] = { .len = ATTR_LEN_VARIABLE },
957};
958
959static void
960format_odp_set_nsh(struct ds *ds, const struct nlattr *attr)
961{
962 unsigned int left;
963 const struct nlattr *a;
964 struct ovs_key_nsh nsh;
965 struct ovs_key_nsh nsh_mask;
966
967 memset(&nsh, 0, sizeof nsh);
968 memset(&nsh_mask, 0xff, sizeof nsh_mask);
969
970 NL_NESTED_FOR_EACH (a, left, attr) {
971 enum ovs_nsh_key_attr type = nl_attr_type(a);
972 size_t len = nl_attr_get_size(a);
973
974 if (type >= OVS_NSH_KEY_ATTR_MAX) {
975 return;
976 }
977
978 int expected_len = ovs_nsh_key_attr_lens[type].len;
979 if ((expected_len != ATTR_LEN_VARIABLE) && (len != 2 * expected_len)) {
980 return;
981 }
982
983 switch (type) {
984 case OVS_NSH_KEY_ATTR_UNSPEC:
985 break;
986 case OVS_NSH_KEY_ATTR_BASE: {
987 const struct ovs_nsh_key_base *base = nl_attr_get(a);
988 const struct ovs_nsh_key_base *base_mask = base + 1;
989 memcpy(&nsh, base, sizeof(*base));
990 memcpy(&nsh_mask, base_mask, sizeof(*base_mask));
991 break;
992 }
993 case OVS_NSH_KEY_ATTR_MD1: {
994 const struct ovs_nsh_key_md1 *md1 = nl_attr_get(a);
995 const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
996 memcpy(&nsh.context, &md1->context, sizeof(*md1));
997 memcpy(&nsh_mask.context, &md1_mask->context, sizeof(*md1_mask));
998 break;
999 }
1000 case OVS_NSH_KEY_ATTR_MD2:
1001 case __OVS_NSH_KEY_ATTR_MAX:
1002 default:
1003 /* No support for matching other metadata formats yet. */
1004 break;
1005 }
1006 }
1007
1008 ds_put_cstr(ds, "set(nsh(");
1009 format_nsh_key_mask(ds, &nsh, &nsh_mask);
1010 ds_put_cstr(ds, "))");
1011}
1012
1013
4edb9ae9 1014static void
0722f341
BP
1015format_odp_action(struct ds *ds, const struct nlattr *a,
1016 const struct hmap *portno_names)
064af421 1017{
98403001 1018 int expected_len;
4edb9ae9 1019 enum ovs_action_attr type = nl_attr_type(a);
6d670e7f 1020 size_t size;
cdee00fd 1021
98403001 1022 expected_len = odp_action_len(nl_attr_type(a));
6b8da9e9
JG
1023 if (expected_len != ATTR_LEN_VARIABLE &&
1024 nl_attr_get_size(a) != expected_len) {
34582733 1025 ds_put_format(ds, "bad length %"PRIuSIZE", expected %d for: ",
98403001 1026 nl_attr_get_size(a), expected_len);
cdee00fd
BP
1027 format_generic_odp_action(ds, a);
1028 return;
1029 }
1030
4edb9ae9 1031 switch (type) {
5dddf960
JR
1032 case OVS_ACTION_ATTR_METER:
1033 ds_put_format(ds, "meter(%"PRIu32")", nl_attr_get_u32(a));
1034 break;
df2c07f4 1035 case OVS_ACTION_ATTR_OUTPUT:
0722f341 1036 odp_portno_name_format(portno_names, nl_attr_get_odp_port(a), ds);
064af421 1037 break;
aaca4fe0
WT
1038 case OVS_ACTION_ATTR_TRUNC: {
1039 const struct ovs_action_trunc *trunc =
1040 nl_attr_get_unspec(a, sizeof *trunc);
1041
1042 ds_put_format(ds, "trunc(%"PRIu32")", trunc->max_len);
1043 break;
1044 }
a36de779 1045 case OVS_ACTION_ATTR_TUNNEL_POP:
0722f341
BP
1046 ds_put_cstr(ds, "tnl_pop(");
1047 odp_portno_name_format(portno_names, nl_attr_get_odp_port(a), ds);
1048 ds_put_char(ds, ')');
a36de779
PS
1049 break;
1050 case OVS_ACTION_ATTR_TUNNEL_PUSH:
0722f341 1051 format_odp_tnl_push_action(ds, a, portno_names);
a36de779 1052 break;
df2c07f4 1053 case OVS_ACTION_ATTR_USERSPACE:
0722f341 1054 format_odp_userspace_action(ds, a, portno_names);
064af421 1055 break;
572f732a 1056 case OVS_ACTION_ATTR_RECIRC:
347bf289
AZ
1057 format_odp_recirc_action(ds, nl_attr_get_u32(a));
1058 break;
1059 case OVS_ACTION_ATTR_HASH:
1060 format_odp_hash_action(ds, nl_attr_get(a));
572f732a 1061 break;
6d670e7f
JR
1062 case OVS_ACTION_ATTR_SET_MASKED:
1063 a = nl_attr_get(a);
81fdabb9
YY
1064 /* OVS_KEY_ATTR_NSH is nested attribute, so it needs special process */
1065 if (nl_attr_type(a) == OVS_KEY_ATTR_NSH) {
1066 format_odp_set_nsh(ds, a);
1067 break;
1068 }
6d670e7f
JR
1069 size = nl_attr_get_size(a) / 2;
1070 ds_put_cstr(ds, "set(");
1071
1072 /* Masked set action not supported for tunnel key, which is bigger. */
1073 if (size <= sizeof(struct ovs_key_ipv6)) {
1074 struct nlattr attr[1 + DIV_ROUND_UP(sizeof(struct ovs_key_ipv6),
1075 sizeof(struct nlattr))];
1076 struct nlattr mask[1 + DIV_ROUND_UP(sizeof(struct ovs_key_ipv6),
1077 sizeof(struct nlattr))];
1078
1079 mask->nla_type = attr->nla_type = nl_attr_type(a);
1080 mask->nla_len = attr->nla_len = NLA_HDRLEN + size;
1081 memcpy(attr + 1, (char *)(a + 1), size);
1082 memcpy(mask + 1, (char *)(a + 1) + size, size);
2d18eae8 1083 format_odp_key_attr(attr, mask, NULL, ds, false);
6d670e7f 1084 } else {
2d18eae8 1085 format_odp_key_attr(a, NULL, NULL, ds, false);
6d670e7f
JR
1086 }
1087 ds_put_cstr(ds, ")");
1088 break;
4edb9ae9
PS
1089 case OVS_ACTION_ATTR_SET:
1090 ds_put_cstr(ds, "set(");
0a37839c 1091 format_odp_key_attr(nl_attr_get(a), NULL, NULL, ds, true);
4edb9ae9 1092 ds_put_cstr(ds, ")");
6fcecb85
YY
1093 break;
1094 case OVS_ACTION_ATTR_PUSH_ETH: {
1095 const struct ovs_action_push_eth *eth = nl_attr_get(a);
1096 ds_put_format(ds, "push_eth(src="ETH_ADDR_FMT",dst="ETH_ADDR_FMT")",
1097 ETH_ADDR_ARGS(eth->addresses.eth_src),
1098 ETH_ADDR_ARGS(eth->addresses.eth_dst));
1099 break;
1100 }
1101 case OVS_ACTION_ATTR_POP_ETH:
1102 ds_put_cstr(ds, "pop_eth");
064af421 1103 break;
66026437
SH
1104 case OVS_ACTION_ATTR_PUSH_VLAN: {
1105 const struct ovs_action_push_vlan *vlan = nl_attr_get(a);
fea393b1
BP
1106 ds_put_cstr(ds, "push_vlan(");
1107 if (vlan->vlan_tpid != htons(ETH_TYPE_VLAN)) {
1108 ds_put_format(ds, "tpid=0x%04"PRIx16",", ntohs(vlan->vlan_tpid));
1109 }
2d18eae8 1110 format_vlan_tci(ds, vlan->vlan_tci, OVS_BE16_MAX, false);
8ddc056d 1111 ds_put_char(ds, ')');
064af421 1112 break;
66026437 1113 }
fea393b1
BP
1114 case OVS_ACTION_ATTR_POP_VLAN:
1115 ds_put_cstr(ds, "pop_vlan");
064af421 1116 break;
b02475c5
SH
1117 case OVS_ACTION_ATTR_PUSH_MPLS: {
1118 const struct ovs_action_push_mpls *mpls = nl_attr_get(a);
1119 ds_put_cstr(ds, "push_mpls(");
1120 format_mpls_lse(ds, mpls->mpls_lse);
1121 ds_put_format(ds, ",eth_type=0x%"PRIx16")", ntohs(mpls->mpls_ethertype));
1122 break;
1123 }
1124 case OVS_ACTION_ATTR_POP_MPLS: {
1125 ovs_be16 ethertype = nl_attr_get_be16(a);
1126 ds_put_format(ds, "pop_mpls(eth_type=0x%"PRIx16")", ntohs(ethertype));
1127 break;
1128 }
6ff686f2 1129 case OVS_ACTION_ATTR_SAMPLE:
0722f341 1130 format_odp_sample_action(ds, a, portno_names);
6ff686f2 1131 break;
07659514
JS
1132 case OVS_ACTION_ATTR_CT:
1133 format_odp_conntrack_action(ds, a);
1134 break;
1fe178d2
EG
1135 case OVS_ACTION_ATTR_CT_CLEAR:
1136 ds_put_cstr(ds, "ct_clear");
1137 break;
535e3acf 1138 case OVS_ACTION_ATTR_CLONE:
0722f341 1139 format_odp_clone_action(ds, a, portno_names);
535e3acf 1140 break;
f59cb331
YY
1141 case OVS_ACTION_ATTR_PUSH_NSH: {
1142 uint32_t buffer[NSH_HDR_MAX_LEN / 4];
1143 struct nsh_hdr *nsh_hdr = ALIGNED_CAST(struct nsh_hdr *, buffer);
1144 nsh_reset_ver_flags_ttl_len(nsh_hdr);
1145 odp_nsh_hdr_from_attr(nl_attr_get(a), nsh_hdr, NSH_HDR_MAX_LEN);
1146 format_odp_push_nsh_action(ds, nsh_hdr);
1fc11c59 1147 break;
f59cb331
YY
1148 }
1149 case OVS_ACTION_ATTR_POP_NSH:
1150 ds_put_cstr(ds, "pop_nsh()");
1fc11c59 1151 break;
4edb9ae9
PS
1152 case OVS_ACTION_ATTR_UNSPEC:
1153 case __OVS_ACTION_ATTR_MAX:
064af421 1154 default:
cdee00fd 1155 format_generic_odp_action(ds, a);
064af421
BP
1156 break;
1157 }
1158}
1159
1160void
cdee00fd 1161format_odp_actions(struct ds *ds, const struct nlattr *actions,
0722f341 1162 size_t actions_len, const struct hmap *portno_names)
064af421 1163{
cdee00fd
BP
1164 if (actions_len) {
1165 const struct nlattr *a;
1166 unsigned int left;
1167
1168 NL_ATTR_FOR_EACH (a, left, actions, actions_len) {
1169 if (a != actions) {
1170 ds_put_char(ds, ',');
1171 }
0722f341 1172 format_odp_action(ds, a, portno_names);
064af421 1173 }
cdee00fd 1174 if (left) {
3a8cfc50
BP
1175 int i;
1176
3476fce3
BP
1177 if (left == actions_len) {
1178 ds_put_cstr(ds, "<empty>");
1179 }
3a8cfc50
BP
1180 ds_put_format(ds, ",***%u leftover bytes*** (", left);
1181 for (i = 0; i < left; i++) {
1182 ds_put_format(ds, "%02x", ((const uint8_t *) a)[i]);
1183 }
1184 ds_put_char(ds, ')');
cdee00fd
BP
1185 }
1186 } else {
064af421
BP
1187 ds_put_cstr(ds, "drop");
1188 }
1189}
7202cbe5 1190
8b7ea2d4 1191/* Separate out parse_odp_userspace_action() function. */
7202cbe5 1192static int
8b7ea2d4 1193parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
7202cbe5 1194{
8b7ea2d4 1195 uint32_t pid;
8de6ff3e 1196 struct user_action_cookie cookie;
8b7ea2d4
WZ
1197 struct ofpbuf buf;
1198 odp_port_t tunnel_out_port;
1199 int n = -1;
1200 void *user_data = NULL;
1201 size_t user_data_size = 0;
7321bda3 1202 bool include_actions = false;
9d4e54c6 1203 int res;
8b7ea2d4
WZ
1204
1205 if (!ovs_scan(s, "userspace(pid=%"SCNi32"%n", &pid, &n)) {
1206 return -EINVAL;
7202cbe5
BP
1207 }
1208
9d4e54c6 1209 ofpbuf_init(&buf, 16);
8de6ff3e 1210 memset(&cookie, 0, sizeof cookie);
9d4e54c6 1211
8de6ff3e
JP
1212 user_data = &cookie;
1213 user_data_size = sizeof cookie;
7202cbe5 1214 {
c2c28dfd
BP
1215 uint32_t output;
1216 uint32_t probability;
1217 uint32_t collector_set_id;
1218 uint32_t obs_domain_id;
1219 uint32_t obs_point_id;
d39ec23d
JP
1220
1221 /* USER_ACTION_COOKIE_CONTROLLER. */
1222 uint8_t dont_send;
74c4530d 1223 uint8_t continuation;
d39ec23d
JP
1224 uint16_t reason;
1225 uint32_t recirc_id;
ab53fe8d 1226 uint64_t rule_cookie;
d39ec23d
JP
1227 uint16_t controller_id;
1228 uint16_t max_len;
1229
7202cbe5 1230 int vid, pcp;
8b7ea2d4
WZ
1231 int n1 = -1;
1232 if (ovs_scan(&s[n], ",sFlow(vid=%i,"
1233 "pcp=%i,output=%"SCNi32")%n",
1234 &vid, &pcp, &output, &n1)) {
7202cbe5
BP
1235 uint16_t tci;
1236
8b7ea2d4 1237 n += n1;
7202cbe5
BP
1238 tci = vid | (pcp << VLAN_PCP_SHIFT);
1239 if (tci) {
1240 tci |= VLAN_CFI;
1241 }
1242
1243 cookie.type = USER_ACTION_COOKIE_SFLOW;
fcb9579b
JP
1244 cookie.ofp_in_port = OFPP_NONE;
1245 cookie.ofproto_uuid = UUID_ZERO;
1673e0e4
BP
1246 cookie.sflow.vlan_tci = htons(tci);
1247 cookie.sflow.output = output;
2d18eae8 1248 } else if (ovs_scan(&s[n], ",slow_path(%n",
8b7ea2d4 1249 &n1)) {
8b7ea2d4 1250 n += n1;
6a7e895f 1251 cookie.type = USER_ACTION_COOKIE_SLOW_PATH;
fcb9579b
JP
1252 cookie.ofp_in_port = OFPP_NONE;
1253 cookie.ofproto_uuid = UUID_ZERO;
04594cd5 1254 cookie.slow_path.reason = 0;
6a7e895f 1255
8e4c1621
JG
1256 res = parse_odp_flags(&s[n], slow_path_reason_to_string,
1257 &cookie.slow_path.reason,
1258 SLOW_PATH_REASON_MASK, NULL);
2d18eae8 1259 if (res < 0 || s[n + res] != ')') {
9d4e54c6 1260 goto out;
04594cd5 1261 }
2d18eae8 1262 n += res + 1;
8b7ea2d4 1263 } else if (ovs_scan(&s[n], ",flow_sample(probability=%"SCNi32","
c2c28dfd
BP
1264 "collector_set_id=%"SCNi32","
1265 "obs_domain_id=%"SCNi32","
f69f713b 1266 "obs_point_id=%"SCNi32","
4930ea56 1267 "output_port=%"SCNi32"%n",
8b7ea2d4 1268 &probability, &collector_set_id,
f69f713b
BY
1269 &obs_domain_id, &obs_point_id,
1270 &output, &n1)) {
8b7ea2d4 1271 n += n1;
29089a54
RL
1272
1273 cookie.type = USER_ACTION_COOKIE_FLOW_SAMPLE;
fcb9579b
JP
1274 cookie.ofp_in_port = OFPP_NONE;
1275 cookie.ofproto_uuid = UUID_ZERO;
29089a54
RL
1276 cookie.flow_sample.probability = probability;
1277 cookie.flow_sample.collector_set_id = collector_set_id;
1278 cookie.flow_sample.obs_domain_id = obs_domain_id;
1279 cookie.flow_sample.obs_point_id = obs_point_id;
f69f713b 1280 cookie.flow_sample.output_odp_port = u32_to_odp(output);
4930ea56
BP
1281
1282 if (ovs_scan(&s[n], ",ingress%n", &n1)) {
1283 cookie.flow_sample.direction = NX_ACTION_SAMPLE_INGRESS;
1284 n += n1;
1285 } else if (ovs_scan(&s[n], ",egress%n", &n1)) {
1286 cookie.flow_sample.direction = NX_ACTION_SAMPLE_EGRESS;
1287 n += n1;
1288 } else {
1289 cookie.flow_sample.direction = NX_ACTION_SAMPLE_DEFAULT;
1290 }
1291 if (s[n] != ')') {
1292 res = -EINVAL;
1293 goto out;
1294 }
1295 n++;
8b7ea2d4
WZ
1296 } else if (ovs_scan(&s[n], ",ipfix(output_port=%"SCNi32")%n",
1297 &output, &n1) ) {
1298 n += n1;
29089a54 1299 cookie.type = USER_ACTION_COOKIE_IPFIX;
fcb9579b
JP
1300 cookie.ofp_in_port = OFPP_NONE;
1301 cookie.ofproto_uuid = UUID_ZERO;
8b7ea2d4 1302 cookie.ipfix.output_odp_port = u32_to_odp(output);
d39ec23d
JP
1303 } else if (ovs_scan(&s[n], ",controller(reason=%"SCNu16
1304 ",dont_send=%"SCNu8
74c4530d 1305 ",continuation=%"SCNu8
d39ec23d
JP
1306 ",recirc_id=%"SCNu32
1307 ",rule_cookie=%"SCNx64
1308 ",controller_id=%"SCNu16
1309 ",max_len=%"SCNu16")%n",
74c4530d
JP
1310 &reason, &dont_send, &continuation, &recirc_id,
1311 &rule_cookie, &controller_id, &max_len, &n1)) {
d39ec23d
JP
1312 n += n1;
1313 cookie.type = USER_ACTION_COOKIE_CONTROLLER;
1314 cookie.ofp_in_port = OFPP_NONE;
1315 cookie.ofproto_uuid = UUID_ZERO;
1316 cookie.controller.dont_send = dont_send ? true : false;
74c4530d 1317 cookie.controller.continuation = continuation ? true : false;
d39ec23d
JP
1318 cookie.controller.reason = reason;
1319 cookie.controller.recirc_id = recirc_id;
1320 put_32aligned_be64(&cookie.controller.rule_cookie,
1321 htonll(rule_cookie));
1322 cookie.controller.controller_id = controller_id;
1323 cookie.controller.max_len = max_len;
1324 } else if (ovs_scan(&s[n], ",userdata(%n", &n1)) {
e995e3df
BP
1325 char *end;
1326
8b7ea2d4 1327 n += n1;
e995e3df 1328 end = ofpbuf_put_hex(&buf, &s[n], NULL);
8b7ea2d4 1329 if (end[0] != ')') {
9d4e54c6
WT
1330 res = -EINVAL;
1331 goto out;
e995e3df 1332 }
6fd6ed71
PS
1333 user_data = buf.data;
1334 user_data_size = buf.size;
8b7ea2d4
WZ
1335 n = (end + 1) - s;
1336 }
1337 }
1338
7321bda3
NM
1339 {
1340 int n1 = -1;
1341 if (ovs_scan(&s[n], ",actions%n", &n1)) {
1342 n += n1;
1343 include_actions = true;
1344 }
1345 }
1346
8b7ea2d4
WZ
1347 {
1348 int n1 = -1;
1349 if (ovs_scan(&s[n], ",tunnel_out_port=%"SCNi32")%n",
1350 &tunnel_out_port, &n1)) {
7321bda3
NM
1351 odp_put_userspace_action(pid, user_data, user_data_size,
1352 tunnel_out_port, include_actions, actions);
9d4e54c6 1353 res = n + n1;
88fc5281 1354 goto out;
8b7ea2d4 1355 } else if (s[n] == ')') {
7321bda3
NM
1356 odp_put_userspace_action(pid, user_data, user_data_size,
1357 ODPP_NONE, include_actions, actions);
9d4e54c6 1358 res = n + 1;
88fc5281
JS
1359 goto out;
1360 }
1361 }
1362
1363 {
1364 struct ovs_action_push_eth push;
1365 int eth_type = 0;
1366 int n1 = -1;
1367
1368 if (ovs_scan(&s[n], "push_eth(src="ETH_ADDR_SCAN_FMT","
1369 "dst="ETH_ADDR_SCAN_FMT",type=%i)%n",
1370 ETH_ADDR_SCAN_ARGS(push.addresses.eth_src),
1371 ETH_ADDR_SCAN_ARGS(push.addresses.eth_dst),
1372 &eth_type, &n1)) {
1373
1374 nl_msg_put_unspec(actions, OVS_ACTION_ATTR_PUSH_ETH,
1375 &push, sizeof push);
1376
1377 res = n + n1;
1378 goto out;
8b7ea2d4
WZ
1379 }
1380 }
88fc5281
JS
1381
1382 if (!strncmp(&s[n], "pop_eth", 7)) {
1383 nl_msg_put_flag(actions, OVS_ACTION_ATTR_POP_ETH);
1384 res = 7;
1385 goto out;
1386 }
1387
1388 res = -EINVAL;
9d4e54c6
WT
1389out:
1390 ofpbuf_uninit(&buf);
1391 return res;
8b7ea2d4
WZ
1392}
1393
a36de779
PS
1394static int
1395ovs_parse_tnl_push(const char *s, struct ovs_action_push_tnl *data)
1396{
1397 struct eth_header *eth;
1398 struct ip_header *ip;
370e373b 1399 struct ovs_16aligned_ip6_hdr *ip6;
a36de779
PS
1400 struct udp_header *udp;
1401 struct gre_base_hdr *greh;
e8fe6ad0 1402 uint16_t gre_proto, gre_flags, dl_type, udp_src, udp_dst, csum;
a36de779 1403 ovs_be32 sip, dip;
370e373b 1404 uint32_t tnl_type = 0, header_len = 0, ip_len = 0;
a36de779
PS
1405 void *l3, *l4;
1406 int n = 0;
1407
1408 if (!ovs_scan_len(s, &n, "tnl_push(tnl_port(%"SCNi32"),", &data->tnl_port)) {
1409 return -EINVAL;
1410 }
1411 eth = (struct eth_header *) data->header;
1620b7ea 1412 l3 = (struct ip_header *) (eth + 1);
a36de779 1413 ip = (struct ip_header *) l3;
370e373b 1414 ip6 = (struct ovs_16aligned_ip6_hdr *) l3;
a36de779 1415 if (!ovs_scan_len(s, &n, "header(size=%"SCNi32",type=%"SCNi32","
9ac0aada
JR
1416 "eth(dst="ETH_ADDR_SCAN_FMT",",
1417 &data->header_len,
1418 &data->tnl_type,
1419 ETH_ADDR_SCAN_ARGS(eth->eth_dst))) {
a36de779
PS
1420 return -EINVAL;
1421 }
1422
1423 if (!ovs_scan_len(s, &n, "src="ETH_ADDR_SCAN_FMT",",
9ac0aada 1424 ETH_ADDR_SCAN_ARGS(eth->eth_src))) {
a36de779
PS
1425 return -EINVAL;
1426 }
1427 if (!ovs_scan_len(s, &n, "dl_type=0x%"SCNx16"),", &dl_type)) {
1428 return -EINVAL;
1429 }
1430 eth->eth_type = htons(dl_type);
1431
370e373b
TLSC
1432 if (eth->eth_type == htons(ETH_TYPE_IP)) {
1433 /* IPv4 */
fa47c114 1434 uint16_t ip_frag_off;
370e373b
TLSC
1435 if (!ovs_scan_len(s, &n, "ipv4(src="IP_SCAN_FMT",dst="IP_SCAN_FMT",proto=%"SCNi8
1436 ",tos=%"SCNi8",ttl=%"SCNi8",frag=0x%"SCNx16"),",
1437 IP_SCAN_ARGS(&sip),
1438 IP_SCAN_ARGS(&dip),
1439 &ip->ip_proto, &ip->ip_tos,
fa47c114 1440 &ip->ip_ttl, &ip_frag_off)) {
370e373b
TLSC
1441 return -EINVAL;
1442 }
1443 put_16aligned_be32(&ip->ip_src, sip);
1444 put_16aligned_be32(&ip->ip_dst, dip);
fa47c114 1445 ip->ip_frag_off = htons(ip_frag_off);
370e373b
TLSC
1446 ip_len = sizeof *ip;
1447 } else {
1448 char sip6_s[IPV6_SCAN_LEN + 1];
1449 char dip6_s[IPV6_SCAN_LEN + 1];
1450 struct in6_addr sip6, dip6;
1451 uint8_t tclass;
1452 uint32_t label;
1453 if (!ovs_scan_len(s, &n, "ipv6(src="IPV6_SCAN_FMT",dst="IPV6_SCAN_FMT
1454 ",label=%i,proto=%"SCNi8",tclass=0x%"SCNx8
1455 ",hlimit=%"SCNi8"),",
1456 sip6_s, dip6_s, &label, &ip6->ip6_nxt,
1457 &tclass, &ip6->ip6_hlim)
1458 || (label & ~IPV6_LABEL_MASK) != 0
1459 || inet_pton(AF_INET6, sip6_s, &sip6) != 1
1460 || inet_pton(AF_INET6, dip6_s, &dip6) != 1) {
1461 return -EINVAL;
1462 }
1463 put_16aligned_be32(&ip6->ip6_flow, htonl(6 << 28) |
1464 htonl(tclass << 20) | htonl(label));
1465 memcpy(&ip6->ip6_src, &sip6, sizeof(ip6->ip6_src));
1466 memcpy(&ip6->ip6_dst, &dip6, sizeof(ip6->ip6_dst));
1467 ip_len = sizeof *ip6;
a36de779 1468 }
a36de779
PS
1469
1470 /* Tunnel header */
370e373b 1471 l4 = ((uint8_t *) l3 + ip_len);
a36de779
PS
1472 udp = (struct udp_header *) l4;
1473 greh = (struct gre_base_hdr *) l4;
8e45fe7c 1474 if (ovs_scan_len(s, &n, "udp(src=%"SCNi16",dst=%"SCNi16",csum=0x%"SCNx16"),",
9ac0aada 1475 &udp_src, &udp_dst, &csum)) {
e5a1caee 1476 uint32_t vx_flags, vni;
a36de779
PS
1477
1478 udp->udp_src = htons(udp_src);
1479 udp->udp_dst = htons(udp_dst);
1480 udp->udp_len = 0;
8e45fe7c 1481 udp->udp_csum = htons(csum);
a36de779 1482
e066f78f 1483 if (ovs_scan_len(s, &n, "vxlan(flags=0x%"SCNx32",vni=0x%"SCNx32"))",
9ac0aada 1484 &vx_flags, &vni)) {
e066f78f
JG
1485 struct vxlanhdr *vxh = (struct vxlanhdr *) (udp + 1);
1486
1487 put_16aligned_be32(&vxh->vx_flags, htonl(vx_flags));
e5a1caee 1488 put_16aligned_be32(&vxh->vx_vni, htonl(vni << 8));
e066f78f 1489 tnl_type = OVS_VPORT_TYPE_VXLAN;
370e373b 1490 header_len = sizeof *eth + ip_len +
e066f78f 1491 sizeof *udp + sizeof *vxh;
e5a1caee
JG
1492 } else if (ovs_scan_len(s, &n, "geneve(")) {
1493 struct genevehdr *gnh = (struct genevehdr *) (udp + 1);
1494
46e7137c 1495 memset(gnh, 0, sizeof *gnh);
370e373b 1496 header_len = sizeof *eth + ip_len +
5bb08b0e
JG
1497 sizeof *udp + sizeof *gnh;
1498
e5a1caee
JG
1499 if (ovs_scan_len(s, &n, "oam,")) {
1500 gnh->oam = 1;
1501 }
5bb08b0e
JG
1502 if (ovs_scan_len(s, &n, "crit,")) {
1503 gnh->critical = 1;
1504 }
1505 if (!ovs_scan_len(s, &n, "vni=%"SCNi32, &vni)) {
e5a1caee
JG
1506 return -EINVAL;
1507 }
5bb08b0e
JG
1508 if (ovs_scan_len(s, &n, ",options(")) {
1509 struct geneve_scan options;
1510 int len;
1511
1512 memset(&options, 0, sizeof options);
1513 len = scan_geneve(s + n, &options, NULL);
1514 if (!len) {
1515 return -EINVAL;
1516 }
1517
1518 memcpy(gnh->options, options.d, options.len);
1519 gnh->opt_len = options.len / 4;
1520 header_len += options.len;
1521
1522 n += len;
1523 }
1524 if (!ovs_scan_len(s, &n, "))")) {
1525 return -EINVAL;
1526 }
1527
e5a1caee
JG
1528 gnh->proto_type = htons(ETH_TYPE_TEB);
1529 put_16aligned_be32(&gnh->vni, htonl(vni << 8));
1530 tnl_type = OVS_VPORT_TYPE_GENEVE;
e066f78f 1531 } else {
a36de779
PS
1532 return -EINVAL;
1533 }
a36de779 1534 } else if (ovs_scan_len(s, &n, "gre((flags=0x%"SCNx16",proto=0x%"SCNx16")",
9ac0aada 1535 &gre_flags, &gre_proto)){
a36de779
PS
1536
1537 tnl_type = OVS_VPORT_TYPE_GRE;
e8fe6ad0 1538 greh->flags = htons(gre_flags);
a36de779
PS
1539 greh->protocol = htons(gre_proto);
1540 ovs_16aligned_be32 *options = (ovs_16aligned_be32 *) (greh + 1);
1541
1542 if (greh->flags & htons(GRE_CSUM)) {
d804d31e 1543 if (!ovs_scan_len(s, &n, ",csum=0x%"SCNx16, &csum)) {
a36de779
PS
1544 return -EINVAL;
1545 }
d804d31e
JG
1546
1547 memset(options, 0, sizeof *options);
1548 *((ovs_be16 *)options) = htons(csum);
a36de779
PS
1549 options++;
1550 }
1551 if (greh->flags & htons(GRE_KEY)) {
1552 uint32_t key;
1553
1554 if (!ovs_scan_len(s, &n, ",key=0x%"SCNx32, &key)) {
1555 return -EINVAL;
1556 }
1557
1558 put_16aligned_be32(options, htonl(key));
1559 options++;
1560 }
1561 if (greh->flags & htons(GRE_SEQ)) {
1562 uint32_t seq;
1563
1564 if (!ovs_scan_len(s, &n, ",seq=0x%"SCNx32, &seq)) {
1565 return -EINVAL;
1566 }
1567 put_16aligned_be32(options, htonl(seq));
1568 options++;
1569 }
1570
1571 if (!ovs_scan_len(s, &n, "))")) {
1572 return -EINVAL;
1573 }
1574
370e373b 1575 header_len = sizeof *eth + ip_len +
a36de779
PS
1576 ((uint8_t *) options - (uint8_t *) greh);
1577 } else {
1578 return -EINVAL;
1579 }
1580
1581 /* check tunnel meta data. */
1582 if (data->tnl_type != tnl_type) {
1583 return -EINVAL;
1584 }
1585 if (data->header_len != header_len) {
1586 return -EINVAL;
1587 }
1588
1589 /* Out port */
1590 if (!ovs_scan_len(s, &n, ",out_port(%"SCNi32"))", &data->out_port)) {
1591 return -EINVAL;
1592 }
1593
1594 return n;
1595}
1596
9ac0aada
JR
1597struct ct_nat_params {
1598 bool snat;
1599 bool dnat;
1600 size_t addr_len;
1601 union {
1602 ovs_be32 ip;
1603 struct in6_addr ip6;
1604 } addr_min;
1605 union {
1606 ovs_be32 ip;
1607 struct in6_addr ip6;
1608 } addr_max;
1609 uint16_t proto_min;
1610 uint16_t proto_max;
1611 bool persistent;
1612 bool proto_hash;
1613 bool proto_random;
1614};
1615
1616static int
1617scan_ct_nat_range(const char *s, int *n, struct ct_nat_params *p)
1618{
1619 if (ovs_scan_len(s, n, "=")) {
1620 char ipv6_s[IPV6_SCAN_LEN + 1];
1621 struct in6_addr ipv6;
1622
1623 if (ovs_scan_len(s, n, IP_SCAN_FMT, IP_SCAN_ARGS(&p->addr_min.ip))) {
1624 p->addr_len = sizeof p->addr_min.ip;
1625 if (ovs_scan_len(s, n, "-")) {
1626 if (!ovs_scan_len(s, n, IP_SCAN_FMT,
1627 IP_SCAN_ARGS(&p->addr_max.ip))) {
1628 return -EINVAL;
1629 }
1630 }
1631 } else if ((ovs_scan_len(s, n, IPV6_SCAN_FMT, ipv6_s)
1632 || ovs_scan_len(s, n, "["IPV6_SCAN_FMT"]", ipv6_s))
1633 && inet_pton(AF_INET6, ipv6_s, &ipv6) == 1) {
1634 p->addr_len = sizeof p->addr_min.ip6;
1635 p->addr_min.ip6 = ipv6;
1636 if (ovs_scan_len(s, n, "-")) {
1637 if ((ovs_scan_len(s, n, IPV6_SCAN_FMT, ipv6_s)
1638 || ovs_scan_len(s, n, "["IPV6_SCAN_FMT"]", ipv6_s))
1639 && inet_pton(AF_INET6, ipv6_s, &ipv6) == 1) {
1640 p->addr_max.ip6 = ipv6;
1641 } else {
1642 return -EINVAL;
1643 }
1644 }
1645 } else {
1646 return -EINVAL;
1647 }
1648 if (ovs_scan_len(s, n, ":%"SCNu16, &p->proto_min)) {
1649 if (ovs_scan_len(s, n, "-")) {
1650 if (!ovs_scan_len(s, n, "%"SCNu16, &p->proto_max)) {
1651 return -EINVAL;
1652 }
1653 }
1654 }
1655 }
1656 return 0;
1657}
1658
1659static int
1660scan_ct_nat(const char *s, struct ct_nat_params *p)
1661{
1662 int n = 0;
1663
1664 if (ovs_scan_len(s, &n, "nat")) {
1665 memset(p, 0, sizeof *p);
1666
1667 if (ovs_scan_len(s, &n, "(")) {
1668 char *end;
1669 int end_n;
1670
1671 end = strchr(s + n, ')');
1672 if (!end) {
1673 return -EINVAL;
1674 }
1675 end_n = end - s;
1676
1677 while (n < end_n) {
1678 n += strspn(s + n, delimiters);
1679 if (ovs_scan_len(s, &n, "src")) {
1680 int err = scan_ct_nat_range(s, &n, p);
1681 if (err) {
1682 return err;
1683 }
1684 p->snat = true;
1685 continue;
1686 }
1687 if (ovs_scan_len(s, &n, "dst")) {
1688 int err = scan_ct_nat_range(s, &n, p);
1689 if (err) {
1690 return err;
1691 }
1692 p->dnat = true;
1693 continue;
1694 }
1695 if (ovs_scan_len(s, &n, "persistent")) {
1696 p->persistent = true;
1697 continue;
1698 }
1699 if (ovs_scan_len(s, &n, "hash")) {
1700 p->proto_hash = true;
1701 continue;
1702 }
1703 if (ovs_scan_len(s, &n, "random")) {
1704 p->proto_random = true;
1705 continue;
1706 }
1707 return -EINVAL;
1708 }
1709
1710 if (p->snat && p->dnat) {
1711 return -EINVAL;
1712 }
1713 if ((p->addr_len != 0 &&
1714 memcmp(&p->addr_max, &in6addr_any, p->addr_len) &&
1715 memcmp(&p->addr_max, &p->addr_min, p->addr_len) < 0) ||
1716 (p->proto_max && p->proto_max < p->proto_min)) {
1717 return -EINVAL;
1718 }
1719 if (p->proto_hash && p->proto_random) {
1720 return -EINVAL;
1721 }
1722 n++;
1723 }
1724 }
1725 return n;
1726}
1727
1728static void
1729nl_msg_put_ct_nat(struct ct_nat_params *p, struct ofpbuf *actions)
1730{
1731 size_t start = nl_msg_start_nested(actions, OVS_CT_ATTR_NAT);
1732
1733 if (p->snat) {
1734 nl_msg_put_flag(actions, OVS_NAT_ATTR_SRC);
1735 } else if (p->dnat) {
1736 nl_msg_put_flag(actions, OVS_NAT_ATTR_DST);
1737 } else {
1738 goto out;
1739 }
1740 if (p->addr_len != 0) {
1741 nl_msg_put_unspec(actions, OVS_NAT_ATTR_IP_MIN, &p->addr_min,
1742 p->addr_len);
1743 if (memcmp(&p->addr_max, &p->addr_min, p->addr_len) > 0) {
1744 nl_msg_put_unspec(actions, OVS_NAT_ATTR_IP_MAX, &p->addr_max,
1745 p->addr_len);
1746 }
1747 if (p->proto_min) {
1748 nl_msg_put_u16(actions, OVS_NAT_ATTR_PROTO_MIN, p->proto_min);
1749 if (p->proto_max && p->proto_max > p->proto_min) {
1750 nl_msg_put_u16(actions, OVS_NAT_ATTR_PROTO_MAX, p->proto_max);
1751 }
1752 }
1753 if (p->persistent) {
1754 nl_msg_put_flag(actions, OVS_NAT_ATTR_PERSISTENT);
1755 }
1756 if (p->proto_hash) {
1757 nl_msg_put_flag(actions, OVS_NAT_ATTR_PROTO_HASH);
1758 }
1759 if (p->proto_random) {
1760 nl_msg_put_flag(actions, OVS_NAT_ATTR_PROTO_RANDOM);
1761 }
1762 }
1763out:
1764 nl_msg_end_nested(actions, start);
1765}
1766
07659514
JS
1767static int
1768parse_conntrack_action(const char *s_, struct ofpbuf *actions)
1769{
1770 const char *s = s_;
1771
1772 if (ovs_scan(s, "ct")) {
d787ad39
JS
1773 const char *helper = NULL;
1774 size_t helper_len = 0;
07659514 1775 bool commit = false;
a76a37ef 1776 bool force_commit = false;
07659514 1777 uint16_t zone = 0;
8e53fe8c
JS
1778 struct {
1779 uint32_t value;
1780 uint32_t mask;
1781 } ct_mark = { 0, 0 };
9daf2348
JS
1782 struct {
1783 ovs_u128 value;
1784 ovs_u128 mask;
1785 } ct_label;
9ac0aada
JR
1786 struct ct_nat_params nat_params;
1787 bool have_nat = false;
07659514
JS
1788 size_t start;
1789 char *end;
1790
9daf2348
JS
1791 memset(&ct_label, 0, sizeof(ct_label));
1792
07659514
JS
1793 s += 2;
1794 if (ovs_scan(s, "(")) {
1795 s++;
9ac0aada 1796find_end:
07659514
JS
1797 end = strchr(s, ')');
1798 if (!end) {
1799 return -EINVAL;
1800 }
1801
1802 while (s != end) {
9ac0aada 1803 int n;
07659514
JS
1804
1805 s += strspn(s, delimiters);
1806 if (ovs_scan(s, "commit%n", &n)) {
1807 commit = true;
1808 s += n;
1809 continue;
1810 }
a76a37ef
JR
1811 if (ovs_scan(s, "force_commit%n", &n)) {
1812 force_commit = true;
1813 s += n;
1814 continue;
1815 }
07659514
JS
1816 if (ovs_scan(s, "zone=%"SCNu16"%n", &zone, &n)) {
1817 s += n;
1818 continue;
1819 }
8e53fe8c
JS
1820 if (ovs_scan(s, "mark=%"SCNx32"%n", &ct_mark.value, &n)) {
1821 s += n;
1822 n = -1;
1823 if (ovs_scan(s, "/%"SCNx32"%n", &ct_mark.mask, &n)) {
1824 s += n;
1825 } else {
1826 ct_mark.mask = UINT32_MAX;
1827 }
1828 continue;
1829 }
9daf2348
JS
1830 if (ovs_scan(s, "label=%n", &n)) {
1831 int retval;
1832
1833 s += n;
1834 retval = scan_u128(s, &ct_label.value, &ct_label.mask);
1835 if (retval < 0) {
1836 return retval;
1837 }
1838 s += retval;
1839 continue;
1840 }
d787ad39
JS
1841 if (ovs_scan(s, "helper=%n", &n)) {
1842 s += n;
1843 helper_len = strcspn(s, delimiters_end);
1844 if (!helper_len || helper_len > 15) {
1845 return -EINVAL;
1846 }
1847 helper = s;
1848 s += helper_len;
1849 continue;
1850 }
07659514 1851
9ac0aada
JR
1852 n = scan_ct_nat(s, &nat_params);
1853 if (n > 0) {
1854 s += n;
1855 have_nat = true;
1856
1857 /* end points to the end of the nested, nat action.
1858 * find the real end. */
1859 goto find_end;
1860 }
1861 /* Nothing matched. */
07659514
JS
1862 return -EINVAL;
1863 }
1864 s++;
1865 }
a76a37ef
JR
1866 if (commit && force_commit) {
1867 return -EINVAL;
1868 }
07659514
JS
1869
1870 start = nl_msg_start_nested(actions, OVS_ACTION_ATTR_CT);
1871 if (commit) {
1872 nl_msg_put_flag(actions, OVS_CT_ATTR_COMMIT);
a76a37ef
JR
1873 } else if (force_commit) {
1874 nl_msg_put_flag(actions, OVS_CT_ATTR_FORCE_COMMIT);
07659514
JS
1875 }
1876 if (zone) {
1877 nl_msg_put_u16(actions, OVS_CT_ATTR_ZONE, zone);
1878 }
8e53fe8c
JS
1879 if (ct_mark.mask) {
1880 nl_msg_put_unspec(actions, OVS_CT_ATTR_MARK, &ct_mark,
1881 sizeof(ct_mark));
1882 }
2ff8484b 1883 if (!ovs_u128_is_zero(ct_label.mask)) {
9daf2348
JS
1884 nl_msg_put_unspec(actions, OVS_CT_ATTR_LABELS, &ct_label,
1885 sizeof ct_label);
1886 }
d787ad39
JS
1887 if (helper) {
1888 nl_msg_put_string__(actions, OVS_CT_ATTR_HELPER, helper,
1889 helper_len);
1890 }
9ac0aada
JR
1891 if (have_nat) {
1892 nl_msg_put_ct_nat(&nat_params, actions);
1893 }
07659514
JS
1894 nl_msg_end_nested(actions, start);
1895 }
1896
1897 return s - s_;
1898}
1899
f59cb331 1900static void
17553f27 1901nsh_key_to_attr(struct ofpbuf *buf, const struct ovs_key_nsh *nsh,
f59cb331
YY
1902 uint8_t * metadata, size_t md_size,
1903 bool is_mask)
1904{
1905 size_t nsh_key_ofs;
1906 struct ovs_nsh_key_base base;
1907
1908 base.flags = nsh->flags;
17553f27 1909 base.ttl = nsh->ttl;
f59cb331
YY
1910 base.mdtype = nsh->mdtype;
1911 base.np = nsh->np;
17553f27 1912 base.path_hdr = nsh->path_hdr;
f59cb331
YY
1913
1914 nsh_key_ofs = nl_msg_start_nested(buf, OVS_KEY_ATTR_NSH);
1915 nl_msg_put_unspec(buf, OVS_NSH_KEY_ATTR_BASE, &base, sizeof base);
1916
1917 if (is_mask) {
1918 nl_msg_put_unspec(buf, OVS_NSH_KEY_ATTR_MD1, nsh->context,
1919 sizeof nsh->context);
1920 } else {
1921 switch (nsh->mdtype) {
1922 case NSH_M_TYPE1:
1923 nl_msg_put_unspec(buf, OVS_NSH_KEY_ATTR_MD1, nsh->context,
1924 sizeof nsh->context);
1925 break;
1926 case NSH_M_TYPE2:
1927 if (metadata && md_size > 0) {
1928 nl_msg_put_unspec(buf, OVS_NSH_KEY_ATTR_MD2, metadata,
1929 md_size);
1930 }
1931 break;
1932 default:
1933 /* No match support for other MD formats yet. */
1934 break;
1935 }
1936 }
1937 nl_msg_end_nested(buf, nsh_key_ofs);
1938}
1939
1940
1fc11c59 1941static int
f59cb331 1942parse_odp_push_nsh_action(const char *s, struct ofpbuf *actions)
1fc11c59
JS
1943{
1944 int n = 0;
1945 int ret = 0;
f59cb331 1946 uint32_t spi = 0;
17553f27 1947 uint8_t si = 255;
1fc11c59 1948 uint32_t cd;
17553f27 1949 struct ovs_key_nsh nsh;
f59cb331
YY
1950 uint8_t metadata[NSH_CTX_HDRS_MAX_LEN];
1951 uint8_t md_size = 0;
1fc11c59 1952
f59cb331 1953 if (!ovs_scan_len(s, &n, "push_nsh(")) {
1fc11c59
JS
1954 ret = -EINVAL;
1955 goto out;
1956 }
1957
1958 /* The default is NSH_M_TYPE1 */
f59cb331 1959 nsh.flags = 0;
17553f27 1960 nsh.ttl = 63;
f59cb331
YY
1961 nsh.mdtype = NSH_M_TYPE1;
1962 nsh.np = NSH_P_ETHERNET;
17553f27 1963 nsh.path_hdr = nsh_spi_si_to_path_hdr(0, 255);
f59cb331 1964 memset(nsh.context, 0, NSH_M_TYPE1_MDLEN);
1fc11c59
JS
1965
1966 for (;;) {
1967 n += strspn(s + n, delimiters);
1968 if (s[n] == ')') {
1969 break;
1970 }
1971
f59cb331 1972 if (ovs_scan_len(s, &n, "flags=%"SCNi8, &nsh.flags)) {
1fc11c59
JS
1973 continue;
1974 }
17553f27
YY
1975 if (ovs_scan_len(s, &n, "ttl=%"SCNi8, &nsh.ttl)) {
1976 continue;
1977 }
f59cb331
YY
1978 if (ovs_scan_len(s, &n, "mdtype=%"SCNi8, &nsh.mdtype)) {
1979 switch (nsh.mdtype) {
1fc11c59
JS
1980 case NSH_M_TYPE1:
1981 /* This is the default format. */;
1982 break;
1983 case NSH_M_TYPE2:
1984 /* Length will be updated later. */
f59cb331 1985 md_size = 0;
1fc11c59
JS
1986 break;
1987 default:
1988 ret = -EINVAL;
1989 goto out;
1990 }
1991 continue;
1992 }
f59cb331 1993 if (ovs_scan_len(s, &n, "np=%"SCNi8, &nsh.np)) {
1fc11c59
JS
1994 continue;
1995 }
1996 if (ovs_scan_len(s, &n, "spi=0x%"SCNx32, &spi)) {
1fc11c59
JS
1997 continue;
1998 }
17553f27 1999 if (ovs_scan_len(s, &n, "si=%"SCNi8, &si)) {
1fc11c59
JS
2000 continue;
2001 }
f59cb331 2002 if (nsh.mdtype == NSH_M_TYPE1) {
1fc11c59 2003 if (ovs_scan_len(s, &n, "c1=0x%"SCNx32, &cd)) {
f59cb331 2004 nsh.context[0] = htonl(cd);
1fc11c59
JS
2005 continue;
2006 }
2007 if (ovs_scan_len(s, &n, "c2=0x%"SCNx32, &cd)) {
f59cb331 2008 nsh.context[1] = htonl(cd);
1fc11c59
JS
2009 continue;
2010 }
2011 if (ovs_scan_len(s, &n, "c3=0x%"SCNx32, &cd)) {
f59cb331 2012 nsh.context[2] = htonl(cd);
1fc11c59
JS
2013 continue;
2014 }
2015 if (ovs_scan_len(s, &n, "c4=0x%"SCNx32, &cd)) {
f59cb331 2016 nsh.context[3] = htonl(cd);
1fc11c59
JS
2017 continue;
2018 }
2019 }
f59cb331 2020 else if (nsh.mdtype == NSH_M_TYPE2) {
1fc11c59
JS
2021 struct ofpbuf b;
2022 char buf[512];
7edef47b 2023 size_t mdlen, padding;
1fc11c59 2024 if (ovs_scan_len(s, &n, "md2=0x%511[0-9a-fA-F]", buf)) {
f59cb331
YY
2025 ofpbuf_use_stub(&b, metadata,
2026 NSH_CTX_HDRS_MAX_LEN);
1fc11c59 2027 ofpbuf_put_hex(&b, buf, &mdlen);
7edef47b
JS
2028 /* Pad metadata to 4 bytes. */
2029 padding = PAD_SIZE(mdlen, 4);
2030 if (padding > 0) {
2031 ofpbuf_push_zeros(&b, padding);
2032 }
f59cb331 2033 md_size = mdlen + padding;
1fc11c59 2034 ofpbuf_uninit(&b);
99cf9959 2035 continue;
1fc11c59 2036 }
1fc11c59 2037 }
0884990e
BP
2038
2039 ret = -EINVAL;
2040 goto out;
1fc11c59
JS
2041 }
2042out:
f59cb331 2043 if (ret >= 0) {
17553f27 2044 nsh.path_hdr = nsh_spi_si_to_path_hdr(spi, si);
f59cb331
YY
2045 size_t offset = nl_msg_start_nested(actions, OVS_ACTION_ATTR_PUSH_NSH);
2046 nsh_key_to_attr(actions, &nsh, metadata, md_size, false);
2047 nl_msg_end_nested(actions, offset);
2048 ret = n;
1fc11c59 2049 }
f59cb331 2050 return ret;
1fc11c59
JS
2051}
2052
c37f7135
AZ
2053static int
2054parse_action_list(const char *s, const struct simap *port_names,
2055 struct ofpbuf *actions)
2056{
2057 int n = 0;
2058
2059 for (;;) {
2060 int retval;
2061
2062 n += strspn(s + n, delimiters);
2063 if (s[n] == ')') {
2064 break;
2065 }
2066 retval = parse_odp_action(s + n, port_names, actions);
2067 if (retval < 0) {
2068 return retval;
2069 }
2070 n += retval;
2071 }
2072
2073 return n;
2074}
2075
8b7ea2d4
WZ
2076static int
2077parse_odp_action(const char *s, const struct simap *port_names,
2078 struct ofpbuf *actions)
2079{
2080 {
2081 uint32_t port;
2082 int n;
2083
2084 if (ovs_scan(s, "%"SCNi32"%n", &port, &n)) {
2085 nl_msg_put_u32(actions, OVS_ACTION_ATTR_OUTPUT, port);
2086 return n;
7202cbe5
BP
2087 }
2088 }
2089
aaca4fe0
WT
2090 {
2091 uint32_t max_len;
2092 int n;
2093
2094 if (ovs_scan(s, "trunc(%"SCNi32")%n", &max_len, &n)) {
2095 struct ovs_action_trunc *trunc;
2096
2097 trunc = nl_msg_put_unspec_uninit(actions,
2098 OVS_ACTION_ATTR_TRUNC, sizeof *trunc);
2099 trunc->max_len = max_len;
2100 return n;
2101 }
2102 }
2103
8b7ea2d4
WZ
2104 if (port_names) {
2105 int len = strcspn(s, delimiters);
2106 struct simap_node *node;
2107
2108 node = simap_find_len(port_names, s, len);
2109 if (node) {
2110 nl_msg_put_u32(actions, OVS_ACTION_ATTR_OUTPUT, node->data);
2111 return len;
2112 }
2113 }
2114
d73803ca
DDP
2115 {
2116 uint32_t recirc_id;
2117 int n = -1;
2118
2119 if (ovs_scan(s, "recirc(%"PRIu32")%n", &recirc_id, &n)) {
2120 nl_msg_put_u32(actions, OVS_ACTION_ATTR_RECIRC, recirc_id);
2121 return n;
2122 }
2123 }
2124
8b7ea2d4
WZ
2125 if (!strncmp(s, "userspace(", 10)) {
2126 return parse_odp_userspace_action(s, actions);
2127 }
2128
7202cbe5
BP
2129 if (!strncmp(s, "set(", 4)) {
2130 size_t start_ofs;
2131 int retval;
c34a5515
BP
2132 struct nlattr mask[1024 / sizeof(struct nlattr)];
2133 struct ofpbuf maskbuf = OFPBUF_STUB_INITIALIZER(mask);
6d670e7f
JR
2134 struct nlattr *nested, *key;
2135 size_t size;
2136
7202cbe5 2137 start_ofs = nl_msg_start_nested(actions, OVS_ACTION_ATTR_SET);
6d670e7f 2138 retval = parse_odp_key_mask_attr(s + 4, port_names, actions, &maskbuf);
7202cbe5 2139 if (retval < 0) {
c34a5515 2140 ofpbuf_uninit(&maskbuf);
7202cbe5
BP
2141 return retval;
2142 }
2143 if (s[retval + 4] != ')') {
c34a5515 2144 ofpbuf_uninit(&maskbuf);
7202cbe5
BP
2145 return -EINVAL;
2146 }
6d670e7f
JR
2147
2148 nested = ofpbuf_at_assert(actions, start_ofs, sizeof *nested);
2149 key = nested + 1;
2150
2151 size = nl_attr_get_size(mask);
2152 if (size == nl_attr_get_size(key)) {
2153 /* Change to masked set action if not fully masked. */
53cb9c3e 2154 if (!is_all_ones(mask + 1, size)) {
34ed68a6
PB
2155 /* Remove padding of eariler key payload */
2156 actions->size -= NLA_ALIGN(key->nla_len) - key->nla_len;
2157
2158 /* Put mask payload right after key payload */
6d670e7f
JR
2159 key->nla_len += size;
2160 ofpbuf_put(actions, mask + 1, size);
34ed68a6
PB
2161
2162 /* Add new padding as needed */
2163 ofpbuf_put_zeros(actions, NLA_ALIGN(key->nla_len) -
2164 key->nla_len);
2165
6d670e7f
JR
2166 /* 'actions' may have been reallocated by ofpbuf_put(). */
2167 nested = ofpbuf_at_assert(actions, start_ofs, sizeof *nested);
2168 nested->nla_type = OVS_ACTION_ATTR_SET_MASKED;
2169 }
2170 }
c34a5515 2171 ofpbuf_uninit(&maskbuf);
6d670e7f 2172
7202cbe5
BP
2173 nl_msg_end_nested(actions, start_ofs);
2174 return retval + 5;
2175 }
2176
becffb86
BP
2177 {
2178 struct ovs_action_push_vlan push;
2179 int tpid = ETH_TYPE_VLAN;
2180 int vid, pcp;
2181 int cfi = 1;
2182 int n = -1;
7202cbe5 2183
c2c28dfd
BP
2184 if (ovs_scan(s, "push_vlan(vid=%i,pcp=%i)%n", &vid, &pcp, &n)
2185 || ovs_scan(s, "push_vlan(vid=%i,pcp=%i,cfi=%i)%n",
2186 &vid, &pcp, &cfi, &n)
2187 || ovs_scan(s, "push_vlan(tpid=%i,vid=%i,pcp=%i)%n",
2188 &tpid, &vid, &pcp, &n)
2189 || ovs_scan(s, "push_vlan(tpid=%i,vid=%i,pcp=%i,cfi=%i)%n",
2190 &tpid, &vid, &pcp, &cfi, &n)) {
becffb86
BP
2191 push.vlan_tpid = htons(tpid);
2192 push.vlan_tci = htons((vid << VLAN_VID_SHIFT)
2193 | (pcp << VLAN_PCP_SHIFT)
2194 | (cfi ? VLAN_CFI : 0));
2195 nl_msg_put_unspec(actions, OVS_ACTION_ATTR_PUSH_VLAN,
2196 &push, sizeof push);
2197
2198 return n;
7202cbe5 2199 }
7202cbe5
BP
2200 }
2201
becffb86
BP
2202 if (!strncmp(s, "pop_vlan", 8)) {
2203 nl_msg_put_flag(actions, OVS_ACTION_ATTR_POP_VLAN);
2204 return 8;
7202cbe5
BP
2205 }
2206
5dddf960
JR
2207 {
2208 unsigned long long int meter_id;
2209 int n = -1;
2210
2211 if (sscanf(s, "meter(%lli)%n", &meter_id, &n) > 0 && n > 0) {
2212 nl_msg_put_u32(actions, OVS_ACTION_ATTR_METER, meter_id);
2213 return n;
2214 }
2215 }
2216
7202cbe5
BP
2217 {
2218 double percentage;
2219 int n = -1;
2220
c2c28dfd
BP
2221 if (ovs_scan(s, "sample(sample=%lf%%,actions(%n", &percentage, &n)
2222 && percentage >= 0. && percentage <= 100.0) {
7202cbe5
BP
2223 size_t sample_ofs, actions_ofs;
2224 double probability;
2225
2226 probability = floor(UINT32_MAX * (percentage / 100.0) + .5);
2227 sample_ofs = nl_msg_start_nested(actions, OVS_ACTION_ATTR_SAMPLE);
2228 nl_msg_put_u32(actions, OVS_SAMPLE_ATTR_PROBABILITY,
2229 (probability <= 0 ? 0
2230 : probability >= UINT32_MAX ? UINT32_MAX
2231 : probability));
2232
2233 actions_ofs = nl_msg_start_nested(actions,
2234 OVS_SAMPLE_ATTR_ACTIONS);
c37f7135
AZ
2235 int retval = parse_action_list(s + n, port_names, actions);
2236 if (retval < 0)
2237 return retval;
7202cbe5 2238
c37f7135 2239 n += retval;
7202cbe5
BP
2240 nl_msg_end_nested(actions, actions_ofs);
2241 nl_msg_end_nested(actions, sample_ofs);
2242
2243 return s[n + 1] == ')' ? n + 2 : -EINVAL;
2244 }
2245 }
2246
c37f7135
AZ
2247 {
2248 if (!strncmp(s, "clone(", 6)) {
2249 size_t actions_ofs;
2250 int n = 6;
2251
2252 actions_ofs = nl_msg_start_nested(actions, OVS_ACTION_ATTR_CLONE);
2253 int retval = parse_action_list(s + n, port_names, actions);
2254 if (retval < 0) {
2255 return retval;
2256 }
2257 n += retval;
2258 nl_msg_end_nested(actions, actions_ofs);
2259 return n + 1;
2260 }
2261 }
2262
1fc11c59 2263 {
f59cb331
YY
2264 if (!strncmp(s, "push_nsh(", 9)) {
2265 int retval = parse_odp_push_nsh_action(s, actions);
1fc11c59
JS
2266 if (retval < 0) {
2267 return retval;
2268 }
2269 return retval + 1;
2270 }
2271 }
2272
2273 {
2274 int n;
f59cb331
YY
2275 if (ovs_scan(s, "pop_nsh()%n", &n)) {
2276 nl_msg_put_flag(actions, OVS_ACTION_ATTR_POP_NSH);
1fc11c59
JS
2277 return n;
2278 }
2279 }
2280
a36de779
PS
2281 {
2282 uint32_t port;
2283 int n;
2284
2285 if (ovs_scan(s, "tnl_pop(%"SCNi32")%n", &port, &n)) {
2286 nl_msg_put_u32(actions, OVS_ACTION_ATTR_TUNNEL_POP, port);
2287 return n;
2288 }
2289 }
2290
1fe178d2
EG
2291 {
2292 if (!strncmp(s, "ct_clear", 8)) {
2293 nl_msg_put_flag(actions, OVS_ACTION_ATTR_CT_CLEAR);
2294 return 8;
2295 }
2296 }
2297
07659514
JS
2298 {
2299 int retval;
2300
2301 retval = parse_conntrack_action(s, actions);
2302 if (retval) {
2303 return retval;
2304 }
2305 }
2306
a36de779
PS
2307 {
2308 struct ovs_action_push_tnl data;
2309 int n;
2310
2311 n = ovs_parse_tnl_push(s, &data);
2312 if (n > 0) {
2313 odp_put_tnl_push_action(actions, &data);
2314 return n;
2315 } else if (n < 0) {
2316 return n;
2317 }
2318 }
7202cbe5
BP
2319 return -EINVAL;
2320}
2321
2322/* Parses the string representation of datapath actions, in the format output
2323 * by format_odp_action(). Returns 0 if successful, otherwise a positive errno
2324 * value. On success, the ODP actions are appended to 'actions' as a series of
2325 * Netlink attributes. On failure, no data is appended to 'actions'. Either
2326 * way, 'actions''s data might be reallocated. */
2327int
44bac24b 2328odp_actions_from_string(const char *s, const struct simap *port_names,
7202cbe5
BP
2329 struct ofpbuf *actions)
2330{
2331 size_t old_size;
2332
2333 if (!strcasecmp(s, "drop")) {
2334 return 0;
2335 }
2336
6fd6ed71 2337 old_size = actions->size;
7202cbe5
BP
2338 for (;;) {
2339 int retval;
2340
2341 s += strspn(s, delimiters);
2342 if (!*s) {
2343 return 0;
2344 }
2345
2346 retval = parse_odp_action(s, port_names, actions);
2347 if (retval < 0 || !strchr(delimiters, s[retval])) {
6fd6ed71 2348 actions->size = old_size;
7202cbe5
BP
2349 return -retval;
2350 }
2351 s += retval;
2352 }
2353
2354 return 0;
2355}
14608a15 2356\f
6b8da9e9
JG
2357static const struct attr_len_tbl ovs_vxlan_ext_attr_lens[OVS_VXLAN_EXT_MAX + 1] = {
2358 [OVS_VXLAN_EXT_GBP] = { .len = 4 },
2359};
2360
2361static const struct attr_len_tbl ovs_tun_key_attr_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
2362 [OVS_TUNNEL_KEY_ATTR_ID] = { .len = 8 },
2363 [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = { .len = 4 },
2364 [OVS_TUNNEL_KEY_ATTR_IPV4_DST] = { .len = 4 },
2365 [OVS_TUNNEL_KEY_ATTR_TOS] = { .len = 1 },
2366 [OVS_TUNNEL_KEY_ATTR_TTL] = { .len = 1 },
2367 [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = { .len = 0 },
2368 [OVS_TUNNEL_KEY_ATTR_CSUM] = { .len = 0 },
2369 [OVS_TUNNEL_KEY_ATTR_TP_SRC] = { .len = 2 },
2370 [OVS_TUNNEL_KEY_ATTR_TP_DST] = { .len = 2 },
2371 [OVS_TUNNEL_KEY_ATTR_OAM] = { .len = 0 },
2372 [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = { .len = ATTR_LEN_VARIABLE },
2373 [OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS] = { .len = ATTR_LEN_NESTED,
2374 .next = ovs_vxlan_ext_attr_lens ,
2375 .next_max = OVS_VXLAN_EXT_MAX},
ffe4c74f
JB
2376 [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = 16 },
2377 [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = 16 },
6b8da9e9
JG
2378};
2379
0aee3827 2380const struct attr_len_tbl ovs_flow_key_attr_lens[OVS_KEY_ATTR_MAX + 1] = {
6b8da9e9
JG
2381 [OVS_KEY_ATTR_ENCAP] = { .len = ATTR_LEN_NESTED },
2382 [OVS_KEY_ATTR_PRIORITY] = { .len = 4 },
2383 [OVS_KEY_ATTR_SKB_MARK] = { .len = 4 },
2384 [OVS_KEY_ATTR_DP_HASH] = { .len = 4 },
2385 [OVS_KEY_ATTR_RECIRC_ID] = { .len = 4 },
2386 [OVS_KEY_ATTR_TUNNEL] = { .len = ATTR_LEN_NESTED,
2387 .next = ovs_tun_key_attr_lens,
2388 .next_max = OVS_TUNNEL_KEY_ATTR_MAX },
2389 [OVS_KEY_ATTR_IN_PORT] = { .len = 4 },
2390 [OVS_KEY_ATTR_ETHERNET] = { .len = sizeof(struct ovs_key_ethernet) },
2391 [OVS_KEY_ATTR_VLAN] = { .len = 2 },
2392 [OVS_KEY_ATTR_ETHERTYPE] = { .len = 2 },
2393 [OVS_KEY_ATTR_MPLS] = { .len = ATTR_LEN_VARIABLE },
2394 [OVS_KEY_ATTR_IPV4] = { .len = sizeof(struct ovs_key_ipv4) },
2395 [OVS_KEY_ATTR_IPV6] = { .len = sizeof(struct ovs_key_ipv6) },
2396 [OVS_KEY_ATTR_TCP] = { .len = sizeof(struct ovs_key_tcp) },
2397 [OVS_KEY_ATTR_TCP_FLAGS] = { .len = 2 },
2398 [OVS_KEY_ATTR_UDP] = { .len = sizeof(struct ovs_key_udp) },
2399 [OVS_KEY_ATTR_SCTP] = { .len = sizeof(struct ovs_key_sctp) },
2400 [OVS_KEY_ATTR_ICMP] = { .len = sizeof(struct ovs_key_icmp) },
2401 [OVS_KEY_ATTR_ICMPV6] = { .len = sizeof(struct ovs_key_icmpv6) },
2402 [OVS_KEY_ATTR_ARP] = { .len = sizeof(struct ovs_key_arp) },
2403 [OVS_KEY_ATTR_ND] = { .len = sizeof(struct ovs_key_nd) },
07659514
JS
2404 [OVS_KEY_ATTR_CT_STATE] = { .len = 4 },
2405 [OVS_KEY_ATTR_CT_ZONE] = { .len = 2 },
8e53fe8c 2406 [OVS_KEY_ATTR_CT_MARK] = { .len = 4 },
9daf2348 2407 [OVS_KEY_ATTR_CT_LABELS] = { .len = sizeof(struct ovs_key_ct_labels) },
c30b4cea
JR
2408 [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4] = { .len = sizeof(struct ovs_key_ct_tuple_ipv4) },
2409 [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = { .len = sizeof(struct ovs_key_ct_tuple_ipv6) },
beb75a40 2410 [OVS_KEY_ATTR_PACKET_TYPE] = { .len = 4 },
f59cb331
YY
2411 [OVS_KEY_ATTR_NSH] = { .len = ATTR_LEN_NESTED,
2412 .next = ovs_nsh_key_attr_lens,
2413 .next_max = OVS_NSH_KEY_ATTR_MAX },
6b8da9e9
JG
2414};
2415
36956a7d 2416/* Returns the correct length of the payload for a flow key attribute of the
6b8da9e9
JG
2417 * specified 'type', ATTR_LEN_INVALID if 'type' is unknown, ATTR_LEN_VARIABLE
2418 * if the attribute's payload is variable length, or ATTR_LEN_NESTED if the
2419 * payload is a nested type. */
36956a7d 2420static int
ce9c9b8b 2421odp_key_attr_len(const struct attr_len_tbl tbl[], int max_type, uint16_t type)
36956a7d 2422{
ce9c9b8b 2423 if (type > max_type) {
6b8da9e9 2424 return ATTR_LEN_INVALID;
36956a7d
BP
2425 }
2426
6b8da9e9 2427 return tbl[type].len;
36956a7d
BP
2428}
2429
36956a7d
BP
2430static void
2431format_generic_odp_key(const struct nlattr *a, struct ds *ds)
2432{
2433 size_t len = nl_attr_get_size(a);
36956a7d
BP
2434 if (len) {
2435 const uint8_t *unspec;
2436 unsigned int i;
2437
2438 unspec = nl_attr_get(a);
2439 for (i = 0; i < len; i++) {
e6cc0bab
AZ
2440 if (i) {
2441 ds_put_char(ds, ' ');
2442 }
36956a7d
BP
2443 ds_put_format(ds, "%02x", unspec[i]);
2444 }
36956a7d
BP
2445 }
2446}
2447
7257b535
BP
2448static const char *
2449ovs_frag_type_to_string(enum ovs_frag_type type)
2450{
2451 switch (type) {
2452 case OVS_FRAG_TYPE_NONE:
2453 return "no";
2454 case OVS_FRAG_TYPE_FIRST:
2455 return "first";
2456 case OVS_FRAG_TYPE_LATER:
2457 return "later";
2458 case __OVS_FRAG_TYPE_MAX:
2459 default:
2460 return "<error>";
2461 }
2462}
2463
f59cb331
YY
2464enum odp_key_fitness
2465odp_nsh_hdr_from_attr(const struct nlattr *attr,
2466 struct nsh_hdr *nsh_hdr, size_t size)
2467{
2468 unsigned int left;
2469 const struct nlattr *a;
2470 bool unknown = false;
2471 uint8_t flags = 0;
17553f27 2472 uint8_t ttl = 63;
f59cb331
YY
2473 size_t mdlen = 0;
2474 bool has_md1 = false;
2475 bool has_md2 = false;
2476
2477 NL_NESTED_FOR_EACH (a, left, attr) {
2478 uint16_t type = nl_attr_type(a);
2479 size_t len = nl_attr_get_size(a);
2480 int expected_len = odp_key_attr_len(ovs_nsh_key_attr_lens,
2481 OVS_NSH_KEY_ATTR_MAX, type);
2482
2483 if (len != expected_len && expected_len >= 0) {
2484 return ODP_FIT_ERROR;
2485 }
2486
2487 switch (type) {
2488 case OVS_NSH_KEY_ATTR_BASE: {
2489 const struct ovs_nsh_key_base *base = nl_attr_get(a);
2490 nsh_hdr->next_proto = base->np;
2491 nsh_hdr->md_type = base->mdtype;
2492 put_16aligned_be32(&nsh_hdr->path_hdr, base->path_hdr);
2493 flags = base->flags;
17553f27 2494 ttl = base->ttl;
f59cb331
YY
2495 break;
2496 }
2497 case OVS_NSH_KEY_ATTR_MD1: {
2498 const struct ovs_nsh_key_md1 *md1 = nl_attr_get(a);
2499 struct nsh_md1_ctx *md1_dst = &nsh_hdr->md1;
2500 has_md1 = true;
2501 mdlen = nl_attr_get_size(a);
2502 if ((mdlen + NSH_BASE_HDR_LEN != NSH_M_TYPE1_LEN) ||
2503 (mdlen + NSH_BASE_HDR_LEN > size)) {
2504 return ODP_FIT_ERROR;
2505 }
2506 memcpy(md1_dst, md1, mdlen);
2507 break;
2508 }
2509 case OVS_NSH_KEY_ATTR_MD2: {
2510 struct nsh_md2_tlv *md2_dst = &nsh_hdr->md2;
2511 const uint8_t *md2 = nl_attr_get(a);
2512 has_md2 = true;
2513 mdlen = nl_attr_get_size(a);
2514 if (mdlen + NSH_BASE_HDR_LEN > size) {
2515 return ODP_FIT_ERROR;
2516 }
2517 memcpy(md2_dst, md2, mdlen);
2518 break;
2519 }
2520 default:
2521 /* Allow this to show up as unexpected, if there are unknown
2522 * tunnel attribute, eventually resulting in ODP_FIT_TOO_MUCH. */
2523 unknown = true;
2524 break;
2525 }
2526 }
2527
2528 if (unknown) {
2529 return ODP_FIT_TOO_MUCH;
2530 }
2531
2532 if ((has_md1 && nsh_hdr->md_type != NSH_M_TYPE1)
2533 || (has_md2 && nsh_hdr->md_type != NSH_M_TYPE2)) {
2534 return ODP_FIT_ERROR;
2535 }
2536
2537 /* nsh header length = NSH_BASE_HDR_LEN + mdlen */
17553f27 2538 nsh_set_flags_ttl_len(nsh_hdr, flags, ttl, NSH_BASE_HDR_LEN + mdlen);
f59cb331
YY
2539
2540 return ODP_FIT_PERFECT;
2541}
2542
2543enum odp_key_fitness
81fdabb9
YY
2544odp_nsh_key_from_attr(const struct nlattr *attr, struct ovs_key_nsh *nsh,
2545 struct ovs_key_nsh *nsh_mask)
f59cb331
YY
2546{
2547 unsigned int left;
2548 const struct nlattr *a;
2549 bool unknown = false;
2550 bool has_md1 = false;
2551
2552 NL_NESTED_FOR_EACH (a, left, attr) {
2553 uint16_t type = nl_attr_type(a);
2554 size_t len = nl_attr_get_size(a);
2555 int expected_len = odp_key_attr_len(ovs_nsh_key_attr_lens,
2556 OVS_NSH_KEY_ATTR_MAX, type);
2557
81fdabb9
YY
2558 /* the attribute can have mask, len is 2 * expected_len for that case.
2559 */
2560 if ((len != expected_len) && (len != 2 * expected_len) &&
2561 (expected_len >= 0)) {
2562 return ODP_FIT_ERROR;
2563 }
2564
2565 if ((nsh_mask && (expected_len >= 0) && (len != 2 * expected_len)) ||
2566 (!nsh_mask && (expected_len >= 0) && (len == 2 * expected_len))) {
f59cb331
YY
2567 return ODP_FIT_ERROR;
2568 }
2569
2570 switch (type) {
81fdabb9
YY
2571 case OVS_NSH_KEY_ATTR_UNSPEC:
2572 break;
f59cb331
YY
2573 case OVS_NSH_KEY_ATTR_BASE: {
2574 const struct ovs_nsh_key_base *base = nl_attr_get(a);
2575 nsh->flags = base->flags;
17553f27 2576 nsh->ttl = base->ttl;
f59cb331
YY
2577 nsh->mdtype = base->mdtype;
2578 nsh->np = base->np;
17553f27 2579 nsh->path_hdr = base->path_hdr;
81fdabb9
YY
2580 if (nsh_mask && (len == 2 * sizeof(*base))) {
2581 const struct ovs_nsh_key_base *base_mask = base + 1;
2582 nsh_mask->flags = base_mask->flags;
2583 nsh_mask->ttl = base_mask->ttl;
2584 nsh_mask->mdtype = base_mask->mdtype;
2585 nsh_mask->np = base_mask->np;
2586 nsh_mask->path_hdr = base_mask->path_hdr;
2587 }
f59cb331
YY
2588 break;
2589 }
2590 case OVS_NSH_KEY_ATTR_MD1: {
2591 const struct ovs_nsh_key_md1 *md1 = nl_attr_get(a);
2592 has_md1 = true;
2593 memcpy(nsh->context, md1->context, sizeof md1->context);
81fdabb9
YY
2594 if (len == 2 * sizeof(*md1)) {
2595 const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
2596 memcpy(nsh_mask->context, md1_mask->context,
2597 sizeof(*md1_mask));
2598 }
f59cb331
YY
2599 break;
2600 }
2601 case OVS_NSH_KEY_ATTR_MD2:
2602 default:
2603 /* Allow this to show up as unexpected, if there are unknown
2604 * tunnel attribute, eventually resulting in ODP_FIT_TOO_MUCH. */
2605 unknown = true;
2606 break;
2607 }
2608 }
2609
2610 if (unknown) {
2611 return ODP_FIT_TOO_MUCH;
2612 }
2613
2614 if (has_md1 && nsh->mdtype != NSH_M_TYPE1) {
2615 return ODP_FIT_ERROR;
2616 }
2617
2618 return ODP_FIT_PERFECT;
2619}
2620
ec1f6f32 2621static enum odp_key_fitness
8d8ab6c2
JG
2622odp_tun_key_from_attr__(const struct nlattr *attr, bool is_mask,
2623 struct flow_tnl *tun)
9b405f1a
PS
2624{
2625 unsigned int left;
2626 const struct nlattr *a;
2627 bool ttl = false;
2628 bool unknown = false;
2629
2630 NL_NESTED_FOR_EACH(a, left, attr) {
2631 uint16_t type = nl_attr_type(a);
2632 size_t len = nl_attr_get_size(a);
6b8da9e9
JG
2633 int expected_len = odp_key_attr_len(ovs_tun_key_attr_lens,
2634 OVS_TUNNEL_ATTR_MAX, type);
9b405f1a
PS
2635
2636 if (len != expected_len && expected_len >= 0) {
2637 return ODP_FIT_ERROR;
2638 }
2639
2640 switch (type) {
2641 case OVS_TUNNEL_KEY_ATTR_ID:
2642 tun->tun_id = nl_attr_get_be64(a);
2643 tun->flags |= FLOW_TNL_F_KEY;
2644 break;
2645 case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
2646 tun->ip_src = nl_attr_get_be32(a);
2647 break;
2648 case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
2649 tun->ip_dst = nl_attr_get_be32(a);
2650 break;
ffe4c74f
JB
2651 case OVS_TUNNEL_KEY_ATTR_IPV6_SRC:
2652 tun->ipv6_src = nl_attr_get_in6_addr(a);
2653 break;
2654 case OVS_TUNNEL_KEY_ATTR_IPV6_DST:
2655 tun->ipv6_dst = nl_attr_get_in6_addr(a);
2656 break;
9b405f1a
PS
2657 case OVS_TUNNEL_KEY_ATTR_TOS:
2658 tun->ip_tos = nl_attr_get_u8(a);
2659 break;
2660 case OVS_TUNNEL_KEY_ATTR_TTL:
2661 tun->ip_ttl = nl_attr_get_u8(a);
2662 ttl = true;
2663 break;
2664 case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
2665 tun->flags |= FLOW_TNL_F_DONT_FRAGMENT;
2666 break;
2667 case OVS_TUNNEL_KEY_ATTR_CSUM:
2668 tun->flags |= FLOW_TNL_F_CSUM;
2669 break;
8b7ea2d4
WZ
2670 case OVS_TUNNEL_KEY_ATTR_TP_SRC:
2671 tun->tp_src = nl_attr_get_be16(a);
2672 break;
2673 case OVS_TUNNEL_KEY_ATTR_TP_DST:
2674 tun->tp_dst = nl_attr_get_be16(a);
2675 break;
94872594
JG
2676 case OVS_TUNNEL_KEY_ATTR_OAM:
2677 tun->flags |= FLOW_TNL_F_OAM;
2678 break;
ac6073e3
MC
2679 case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: {
2680 static const struct nl_policy vxlan_opts_policy[] = {
2681 [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 },
2682 };
2683 struct nlattr *ext[ARRAY_SIZE(vxlan_opts_policy)];
2684
2685 if (!nl_parse_nested(a, vxlan_opts_policy, ext, ARRAY_SIZE(ext))) {
2686 return ODP_FIT_ERROR;
2687 }
2688
2689 if (ext[OVS_VXLAN_EXT_GBP]) {
2690 uint32_t gbp = nl_attr_get_u32(ext[OVS_VXLAN_EXT_GBP]);
2691
2692 tun->gbp_id = htons(gbp & 0xFFFF);
2693 tun->gbp_flags = (gbp >> 16) & 0xFF;
2694 }
2695
2696 break;
2697 }
9558d2a5 2698 case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS:
8d8ab6c2 2699 tun_metadata_from_geneve_nlattr(a, is_mask, tun);
c1fc1411 2700 break;
9558d2a5 2701
9b405f1a
PS
2702 default:
2703 /* Allow this to show up as unexpected, if there are unknown
2704 * tunnel attribute, eventually resulting in ODP_FIT_TOO_MUCH. */
2705 unknown = true;
2706 break;
2707 }
2708 }
2709
2710 if (!ttl) {
2711 return ODP_FIT_ERROR;
2712 }
2713 if (unknown) {
758c456d 2714 return ODP_FIT_TOO_MUCH;
9b405f1a
PS
2715 }
2716 return ODP_FIT_PERFECT;
2717}
2718
ec1f6f32 2719enum odp_key_fitness
8d8ab6c2 2720odp_tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
ec1f6f32 2721{
35303d71 2722 memset(tun, 0, sizeof *tun);
8d8ab6c2 2723 return odp_tun_key_from_attr__(attr, false, tun);
ec1f6f32
JG
2724}
2725
9b405f1a 2726static void
ec1f6f32 2727tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key,
9558d2a5
JG
2728 const struct flow_tnl *tun_flow_key,
2729 const struct ofpbuf *key_buf)
9b405f1a
PS
2730{
2731 size_t tun_key_ofs;
2732
2733 tun_key_ofs = nl_msg_start_nested(a, OVS_KEY_ATTR_TUNNEL);
2734
27a8cbbc
BP
2735 /* tun_id != 0 without FLOW_TNL_F_KEY is valid if tun_key is a mask. */
2736 if (tun_key->tun_id || tun_key->flags & FLOW_TNL_F_KEY) {
9b405f1a
PS
2737 nl_msg_put_be64(a, OVS_TUNNEL_KEY_ATTR_ID, tun_key->tun_id);
2738 }
2739 if (tun_key->ip_src) {
2740 nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, tun_key->ip_src);
2741 }
2742 if (tun_key->ip_dst) {
2743 nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_DST, tun_key->ip_dst);
2744 }
ffe4c74f
JB
2745 if (ipv6_addr_is_set(&tun_key->ipv6_src)) {
2746 nl_msg_put_in6_addr(a, OVS_TUNNEL_KEY_ATTR_IPV6_SRC, &tun_key->ipv6_src);
2747 }
2748 if (ipv6_addr_is_set(&tun_key->ipv6_dst)) {
2749 nl_msg_put_in6_addr(a, OVS_TUNNEL_KEY_ATTR_IPV6_DST, &tun_key->ipv6_dst);
2750 }
9b405f1a
PS
2751 if (tun_key->ip_tos) {
2752 nl_msg_put_u8(a, OVS_TUNNEL_KEY_ATTR_TOS, tun_key->ip_tos);
2753 }
2754 nl_msg_put_u8(a, OVS_TUNNEL_KEY_ATTR_TTL, tun_key->ip_ttl);
2755 if (tun_key->flags & FLOW_TNL_F_DONT_FRAGMENT) {
2756 nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT);
2757 }
2758 if (tun_key->flags & FLOW_TNL_F_CSUM) {
2759 nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_CSUM);
2760 }
8b7ea2d4
WZ
2761 if (tun_key->tp_src) {
2762 nl_msg_put_be16(a, OVS_TUNNEL_KEY_ATTR_TP_SRC, tun_key->tp_src);
2763 }
2764 if (tun_key->tp_dst) {
2765 nl_msg_put_be16(a, OVS_TUNNEL_KEY_ATTR_TP_DST, tun_key->tp_dst);
2766 }
94872594
JG
2767 if (tun_key->flags & FLOW_TNL_F_OAM) {
2768 nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_OAM);
2769 }
ac6073e3
MC
2770 if (tun_key->gbp_flags || tun_key->gbp_id) {
2771 size_t vxlan_opts_ofs;
2772
2773 vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
2774 nl_msg_put_u32(a, OVS_VXLAN_EXT_GBP,
2775 (tun_key->gbp_flags << 16) | ntohs(tun_key->gbp_id));
2776 nl_msg_end_nested(a, vxlan_opts_ofs);
2777 }
6728d578 2778 tun_metadata_to_geneve_nlattr(tun_key, tun_flow_key, key_buf, a);
9558d2a5 2779
9b405f1a 2780 nl_msg_end_nested(a, tun_key_ofs);
29c7a2b2
PS
2781}
2782
b17298ae
BP
2783static bool
2784odp_mask_is_constant__(enum ovs_key_attr attr, const void *mask, size_t size,
2785 int constant)
2786{
2787 /* Convert 'constant' to all the widths we need. C conversion rules ensure
2788 * that -1 becomes all-1-bits and 0 does not change. */
2789 ovs_be16 be16 = (OVS_FORCE ovs_be16) constant;
2790 uint32_t u32 = constant;
2791 uint8_t u8 = constant;
2792 const struct in6_addr *in6 = constant ? &in6addr_exact : &in6addr_any;
2793
2794 switch (attr) {
2795 case OVS_KEY_ATTR_UNSPEC:
2796 case OVS_KEY_ATTR_ENCAP:
2797 case __OVS_KEY_ATTR_MAX:
2798 default:
2799 return false;
2800
2801 case OVS_KEY_ATTR_PRIORITY:
2802 case OVS_KEY_ATTR_IN_PORT:
2803 case OVS_KEY_ATTR_ETHERNET:
2804 case OVS_KEY_ATTR_VLAN:
2805 case OVS_KEY_ATTR_ETHERTYPE:
2806 case OVS_KEY_ATTR_IPV4:
2807 case OVS_KEY_ATTR_TCP:
2808 case OVS_KEY_ATTR_UDP:
2809 case OVS_KEY_ATTR_ICMP:
2810 case OVS_KEY_ATTR_ICMPV6:
2811 case OVS_KEY_ATTR_ND:
2812 case OVS_KEY_ATTR_SKB_MARK:
2813 case OVS_KEY_ATTR_TUNNEL:
2814 case OVS_KEY_ATTR_SCTP:
2815 case OVS_KEY_ATTR_DP_HASH:
2816 case OVS_KEY_ATTR_RECIRC_ID:
2817 case OVS_KEY_ATTR_MPLS:
2818 case OVS_KEY_ATTR_CT_STATE:
2819 case OVS_KEY_ATTR_CT_ZONE:
2820 case OVS_KEY_ATTR_CT_MARK:
2821 case OVS_KEY_ATTR_CT_LABELS:
2822 case OVS_KEY_ATTR_PACKET_TYPE:
3d2fbd70 2823 case OVS_KEY_ATTR_NSH:
b17298ae
BP
2824 return is_all_byte(mask, size, u8);
2825
2826 case OVS_KEY_ATTR_TCP_FLAGS:
2827 return TCP_FLAGS(*(ovs_be16 *) mask) == TCP_FLAGS(be16);
2828
2829 case OVS_KEY_ATTR_IPV6: {
2830 const struct ovs_key_ipv6 *ipv6_mask = mask;
2831 return ((ipv6_mask->ipv6_label & htonl(IPV6_LABEL_MASK))
2832 == htonl(IPV6_LABEL_MASK & u32)
2833 && ipv6_mask->ipv6_proto == u8
2834 && ipv6_mask->ipv6_tclass == u8
2835 && ipv6_mask->ipv6_hlimit == u8
2836 && ipv6_mask->ipv6_frag == u8
2837 && ipv6_addr_equals(&ipv6_mask->ipv6_src, in6)
2838 && ipv6_addr_equals(&ipv6_mask->ipv6_dst, in6));
2839 }
2840
2841 case OVS_KEY_ATTR_ARP:
2842 return is_all_byte(mask, OFFSETOFEND(struct ovs_key_arp, arp_tha), u8);
2843
2844 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4:
2845 return is_all_byte(mask, OFFSETOFEND(struct ovs_key_ct_tuple_ipv4,
2846 ipv4_proto), u8);
2847
2848 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6:
2849 return is_all_byte(mask, OFFSETOFEND(struct ovs_key_ct_tuple_ipv6,
2850 ipv6_proto), u8);
2851 }
2852}
2853
2854/* The caller must already have verified that 'ma' has a correct length.
2855 *
2856 * The main purpose of this function is formatting, to allow code to figure out
2857 * whether the mask can be omitted. It doesn't try hard for attributes that
2858 * contain sub-attributes, etc., because normally those would be broken down
2859 * further for formatting. */
041e7168
AZ
2860static bool
2861odp_mask_attr_is_wildcard(const struct nlattr *ma)
2862{
b17298ae
BP
2863 return odp_mask_is_constant__(nl_attr_type(ma),
2864 nl_attr_get(ma), nl_attr_get_size(ma), 0);
041e7168
AZ
2865}
2866
2f73024d 2867/* The caller must already have verified that 'size' is a correct length for
b17298ae
BP
2868 * 'attr'.
2869 *
2870 * The main purpose of this function is formatting, to allow code to figure out
2871 * whether the mask can be omitted. It doesn't try hard for attributes that
2872 * contain sub-attributes, etc., because normally those would be broken down
2873 * further for formatting. */
e6cc0bab 2874static bool
d23df9a8 2875odp_mask_is_exact(enum ovs_key_attr attr, const void *mask, size_t size)
e6cc0bab 2876{
b17298ae 2877 return odp_mask_is_constant__(attr, mask, size, -1);
d23df9a8
JR
2878}
2879
2f73024d 2880/* The caller must already have verified that 'ma' has a correct length. */
d23df9a8
JR
2881static bool
2882odp_mask_attr_is_exact(const struct nlattr *ma)
2883{
d23df9a8 2884 enum ovs_key_attr attr = nl_attr_type(ma);
a4e8ed0c 2885 return odp_mask_is_exact(attr, nl_attr_get(ma), nl_attr_get_size(ma));
e6cc0bab
AZ
2886}
2887
0a37839c
GS
2888void
2889odp_portno_names_set(struct hmap *portno_names, odp_port_t port_no,
2890 char *port_name)
2891{
2892 struct odp_portno_names *odp_portno_names;
2893
2894 odp_portno_names = xmalloc(sizeof *odp_portno_names);
2895 odp_portno_names->port_no = port_no;
2896 odp_portno_names->name = xstrdup(port_name);
2897 hmap_insert(portno_names, &odp_portno_names->hmap_node,
2898 hash_odp_port(port_no));
2899}
2900
2901static char *
2902odp_portno_names_get(const struct hmap *portno_names, odp_port_t port_no)
2903{
0722f341
BP
2904 if (portno_names) {
2905 struct odp_portno_names *odp_portno_names;
0a37839c 2906
0722f341
BP
2907 HMAP_FOR_EACH_IN_BUCKET (odp_portno_names, hmap_node,
2908 hash_odp_port(port_no), portno_names) {
2909 if (odp_portno_names->port_no == port_no) {
2910 return odp_portno_names->name;
2911 }
0a37839c
GS
2912 }
2913 }
2914 return NULL;
2915}
2916
2917void
2918odp_portno_names_destroy(struct hmap *portno_names)
2919{
4ec3d7c7
DDP
2920 struct odp_portno_names *odp_portno_names;
2921
2922 HMAP_FOR_EACH_POP (odp_portno_names, hmap_node, portno_names) {
0a37839c
GS
2923 free(odp_portno_names->name);
2924 free(odp_portno_names);
2925 }
2926}
e6cc0bab 2927
0722f341
BP
2928void
2929odp_portno_name_format(const struct hmap *portno_names, odp_port_t port_no,
2930 struct ds *s)
2931{
2932 const char *name = odp_portno_names_get(portno_names, port_no);
2933 if (name) {
2934 ds_put_cstr(s, name);
2935 } else {
2936 ds_put_format(s, "%"PRIu32, port_no);
2937 }
2938}
2939
2d18eae8
JR
2940/* Format helpers. */
2941
2942static void
74ff3298
JR
2943format_eth(struct ds *ds, const char *name, const struct eth_addr key,
2944 const struct eth_addr *mask, bool verbose)
2d18eae8
JR
2945{
2946 bool mask_empty = mask && eth_addr_is_zero(*mask);
2947
2948 if (verbose || !mask_empty) {
2949 bool mask_full = !mask || eth_mask_is_exact(*mask);
2950
2951 if (mask_full) {
2952 ds_put_format(ds, "%s="ETH_ADDR_FMT",", name, ETH_ADDR_ARGS(key));
2953 } else {
2954 ds_put_format(ds, "%s=", name);
74ff3298 2955 eth_format_masked(key, mask, ds);
2d18eae8
JR
2956 ds_put_char(ds, ',');
2957 }
2958 }
2959}
2960
1fc11c59 2961
2d18eae8
JR
2962static void
2963format_be64(struct ds *ds, const char *name, ovs_be64 key,
2964 const ovs_be64 *mask, bool verbose)
2965{
2966 bool mask_empty = mask && !*mask;
2967
2968 if (verbose || !mask_empty) {
2969 bool mask_full = !mask || *mask == OVS_BE64_MAX;
2970
2971 ds_put_format(ds, "%s=0x%"PRIx64, name, ntohll(key));
2972 if (!mask_full) { /* Partially masked. */
2973 ds_put_format(ds, "/%#"PRIx64, ntohll(*mask));
2974 }
2975 ds_put_char(ds, ',');
2976 }
2977}
2978
2979static void
2980format_ipv4(struct ds *ds, const char *name, ovs_be32 key,
2981 const ovs_be32 *mask, bool verbose)
2982{
2983 bool mask_empty = mask && !*mask;
2984
2985 if (verbose || !mask_empty) {
2986 bool mask_full = !mask || *mask == OVS_BE32_MAX;
2987
2988 ds_put_format(ds, "%s="IP_FMT, name, IP_ARGS(key));
2989 if (!mask_full) { /* Partially masked. */
2990 ds_put_format(ds, "/"IP_FMT, IP_ARGS(*mask));
2991 }
2992 ds_put_char(ds, ',');
2993 }
2994}
2995
2996static void
d15aef48
JB
2997format_in6_addr(struct ds *ds, const char *name,
2998 const struct in6_addr *key,
2999 const struct in6_addr *mask,
3000 bool verbose)
2d18eae8
JR
3001{
3002 char buf[INET6_ADDRSTRLEN];
2d18eae8
JR
3003 bool mask_empty = mask && ipv6_mask_is_any(mask);
3004
3005 if (verbose || !mask_empty) {
3006 bool mask_full = !mask || ipv6_mask_is_exact(mask);
3007
3008 inet_ntop(AF_INET6, key, buf, sizeof buf);
3009 ds_put_format(ds, "%s=%s", name, buf);
3010 if (!mask_full) { /* Partially masked. */
3011 inet_ntop(AF_INET6, mask, buf, sizeof buf);
3012 ds_put_format(ds, "/%s", buf);
3013 }
3014 ds_put_char(ds, ',');
3015 }
3016}
3017
3018static void
3019format_ipv6_label(struct ds *ds, const char *name, ovs_be32 key,
3020 const ovs_be32 *mask, bool verbose)
3021{
3022 bool mask_empty = mask && !*mask;
3023
3024 if (verbose || !mask_empty) {
3025 bool mask_full = !mask
3026 || (*mask & htonl(IPV6_LABEL_MASK)) == htonl(IPV6_LABEL_MASK);
3027
3028 ds_put_format(ds, "%s=%#"PRIx32, name, ntohl(key));
3029 if (!mask_full) { /* Partially masked. */
3030 ds_put_format(ds, "/%#"PRIx32, ntohl(*mask));
3031 }
3032 ds_put_char(ds, ',');
3033 }
3034}
3035
3036static void
3037format_u8x(struct ds *ds, const char *name, uint8_t key,
3038 const uint8_t *mask, bool verbose)
3039{
3040 bool mask_empty = mask && !*mask;
3041
3042 if (verbose || !mask_empty) {
3043 bool mask_full = !mask || *mask == UINT8_MAX;
3044
3045 ds_put_format(ds, "%s=%#"PRIx8, name, key);
3046 if (!mask_full) { /* Partially masked. */
3047 ds_put_format(ds, "/%#"PRIx8, *mask);
3048 }
3049 ds_put_char(ds, ',');
3050 }
3051}
3052
3053static void
3054format_u8u(struct ds *ds, const char *name, uint8_t key,
3055 const uint8_t *mask, bool verbose)
3056{
3057 bool mask_empty = mask && !*mask;
3058
3059 if (verbose || !mask_empty) {
3060 bool mask_full = !mask || *mask == UINT8_MAX;
3061
3062 ds_put_format(ds, "%s=%"PRIu8, name, key);
3063 if (!mask_full) { /* Partially masked. */
3064 ds_put_format(ds, "/%#"PRIx8, *mask);
3065 }
3066 ds_put_char(ds, ',');
3067 }
3068}
3069
3070static void
3071format_be16(struct ds *ds, const char *name, ovs_be16 key,
3072 const ovs_be16 *mask, bool verbose)
3073{
3074 bool mask_empty = mask && !*mask;
3075
3076 if (verbose || !mask_empty) {
3077 bool mask_full = !mask || *mask == OVS_BE16_MAX;
3078
3079 ds_put_format(ds, "%s=%"PRIu16, name, ntohs(key));
3080 if (!mask_full) { /* Partially masked. */
3081 ds_put_format(ds, "/%#"PRIx16, ntohs(*mask));
3082 }
3083 ds_put_char(ds, ',');
3084 }
3085}
3086
622a0a8e
JG
3087static void
3088format_be16x(struct ds *ds, const char *name, ovs_be16 key,
3089 const ovs_be16 *mask, bool verbose)
3090{
3091 bool mask_empty = mask && !*mask;
3092
3093 if (verbose || !mask_empty) {
3094 bool mask_full = !mask || *mask == OVS_BE16_MAX;
3095
3096 ds_put_format(ds, "%s=%#"PRIx16, name, ntohs(key));
3097 if (!mask_full) { /* Partially masked. */
3098 ds_put_format(ds, "/%#"PRIx16, ntohs(*mask));
3099 }
3100 ds_put_char(ds, ',');
3101 }
3102}
3103
2d18eae8
JR
3104static void
3105format_tun_flags(struct ds *ds, const char *name, uint16_t key,
3106 const uint16_t *mask, bool verbose)
3107{
3108 bool mask_empty = mask && !*mask;
3109
3110 if (verbose || !mask_empty) {
2d18eae8
JR
3111 ds_put_cstr(ds, name);
3112 ds_put_char(ds, '(');
8e4c1621
JG
3113 if (mask) {
3114 format_flags_masked(ds, NULL, flow_tun_flag_to_string, key,
3115 *mask & FLOW_TNL_F_MASK, FLOW_TNL_F_MASK);
2d18eae8 3116 } else { /* Fully masked. */
8e4c1621 3117 format_flags(ds, flow_tun_flag_to_string, key, '|');
2d18eae8
JR
3118 }
3119 ds_put_cstr(ds, "),");
3120 }
3121}
3122
65da723b
JG
3123static bool
3124check_attr_len(struct ds *ds, const struct nlattr *a, const struct nlattr *ma,
ce9c9b8b 3125 const struct attr_len_tbl tbl[], int max_type, bool need_key)
65da723b
JG
3126{
3127 int expected_len;
3128
ce9c9b8b 3129 expected_len = odp_key_attr_len(tbl, max_type, nl_attr_type(a));
65da723b
JG
3130 if (expected_len != ATTR_LEN_VARIABLE &&
3131 expected_len != ATTR_LEN_NESTED) {
3132
3133 bool bad_key_len = nl_attr_get_size(a) != expected_len;
3134 bool bad_mask_len = ma && nl_attr_get_size(ma) != expected_len;
3135
3136 if (bad_key_len || bad_mask_len) {
3137 if (need_key) {
3138 ds_put_format(ds, "key%u", nl_attr_type(a));
3139 }
3140 if (bad_key_len) {
3141 ds_put_format(ds, "(bad key length %"PRIuSIZE", expected %d)(",
3142 nl_attr_get_size(a), expected_len);
3143 }
3144 format_generic_odp_key(a, ds);
3145 if (ma) {
3146 ds_put_char(ds, '/');
3147 if (bad_mask_len) {
3148 ds_put_format(ds, "(bad mask length %"PRIuSIZE", expected %d)(",
3149 nl_attr_get_size(ma), expected_len);
3150 }
3151 format_generic_odp_key(ma, ds);
3152 }
3153 ds_put_char(ds, ')');
3154 return false;
3155 }
3156 }
3157
3158 return true;
3159}
3160
3161static void
3162format_unknown_key(struct ds *ds, const struct nlattr *a,
3163 const struct nlattr *ma)
3164{
3165 ds_put_format(ds, "key%u(", nl_attr_type(a));
3166 format_generic_odp_key(a, ds);
3167 if (ma && !odp_mask_attr_is_exact(ma)) {
3168 ds_put_char(ds, '/');
3169 format_generic_odp_key(ma, ds);
3170 }
3171 ds_put_cstr(ds, "),");
3172}
3173
3174static void
3175format_odp_tun_vxlan_opt(const struct nlattr *attr,
3176 const struct nlattr *mask_attr, struct ds *ds,
3177 bool verbose)
3178{
3179 unsigned int left;
3180 const struct nlattr *a;
3181 struct ofpbuf ofp;
3182
3183 ofpbuf_init(&ofp, 100);
3184 NL_NESTED_FOR_EACH(a, left, attr) {
3185 uint16_t type = nl_attr_type(a);
3186 const struct nlattr *ma = NULL;
3187
3188 if (mask_attr) {
3189 ma = nl_attr_find__(nl_attr_get(mask_attr),
3190 nl_attr_get_size(mask_attr), type);
3191 if (!ma) {
3192 ma = generate_all_wildcard_mask(ovs_vxlan_ext_attr_lens,
3193 OVS_VXLAN_EXT_MAX,
3194 &ofp, a);
3195 }
3196 }
3197
3198 if (!check_attr_len(ds, a, ma, ovs_vxlan_ext_attr_lens,
3199 OVS_VXLAN_EXT_MAX, true)) {
3200 continue;
3201 }
3202
3203 switch (type) {
3204 case OVS_VXLAN_EXT_GBP: {
3205 uint32_t key = nl_attr_get_u32(a);
3206 ovs_be16 id, id_mask;
498535c3 3207 uint8_t flags, flags_mask = 0;
65da723b
JG
3208
3209 id = htons(key & 0xFFFF);
3210 flags = (key >> 16) & 0xFF;
3211 if (ma) {
3212 uint32_t mask = nl_attr_get_u32(ma);
3213 id_mask = htons(mask & 0xFFFF);
3214 flags_mask = (mask >> 16) & 0xFF;
3215 }
3216
3217 ds_put_cstr(ds, "gbp(");
3218 format_be16(ds, "id", id, ma ? &id_mask : NULL, verbose);
3219 format_u8x(ds, "flags", flags, ma ? &flags_mask : NULL, verbose);
3220 ds_chomp(ds, ',');
3221 ds_put_cstr(ds, "),");
3222 break;
3223 }
3224
3225 default:
3226 format_unknown_key(ds, a, ma);
3227 }
3228 ofpbuf_clear(&ofp);
3229 }
3230
3231 ds_chomp(ds, ',');
3232 ofpbuf_uninit(&ofp);
3233}
3234
622a0a8e
JG
3235#define MASK(PTR, FIELD) PTR ? &PTR->FIELD : NULL
3236
3237static void
5bb08b0e
JG
3238format_geneve_opts(const struct geneve_opt *opt,
3239 const struct geneve_opt *mask, int opts_len,
3240 struct ds *ds, bool verbose)
622a0a8e 3241{
622a0a8e
JG
3242 while (opts_len > 0) {
3243 unsigned int len;
3244 uint8_t data_len, data_len_mask;
3245
3246 if (opts_len < sizeof *opt) {
3247 ds_put_format(ds, "opt len %u less than minimum %"PRIuSIZE,
3248 opts_len, sizeof *opt);
3249 return;
3250 }
3251
3252 data_len = opt->length * 4;
3253 if (mask) {
3254 if (mask->length == 0x1f) {
3255 data_len_mask = UINT8_MAX;
3256 } else {
3257 data_len_mask = mask->length;
3258 }
3259 }
3260 len = sizeof *opt + data_len;
3261 if (len > opts_len) {
3262 ds_put_format(ds, "opt len %u greater than remaining %u",
3263 len, opts_len);
3264 return;
3265 }
3266
3267 ds_put_char(ds, '{');
3268 format_be16x(ds, "class", opt->opt_class, MASK(mask, opt_class),
3269 verbose);
3270 format_u8x(ds, "type", opt->type, MASK(mask, type), verbose);
3271 format_u8u(ds, "len", data_len, mask ? &data_len_mask : NULL, verbose);
1cb20095
JG
3272 if (data_len &&
3273 (verbose || !mask || !is_all_zeros(mask + 1, data_len))) {
622a0a8e
JG
3274 ds_put_hex(ds, opt + 1, data_len);
3275 if (mask && !is_all_ones(mask + 1, data_len)) {
3276 ds_put_char(ds, '/');
3277 ds_put_hex(ds, mask + 1, data_len);
3278 }
3279 } else {
3280 ds_chomp(ds, ',');
3281 }
3282 ds_put_char(ds, '}');
3283
3284 opt += len / sizeof(*opt);
3285 if (mask) {
3286 mask += len / sizeof(*opt);
3287 }
3288 opts_len -= len;
3289 };
3290}
3291
5bb08b0e
JG
3292static void
3293format_odp_tun_geneve(const struct nlattr *attr,
3294 const struct nlattr *mask_attr, struct ds *ds,
3295 bool verbose)
3296{
3297 int opts_len = nl_attr_get_size(attr);
3298 const struct geneve_opt *opt = nl_attr_get(attr);
3299 const struct geneve_opt *mask = mask_attr ?
3300 nl_attr_get(mask_attr) : NULL;
3301
3302 if (mask && nl_attr_get_size(attr) != nl_attr_get_size(mask_attr)) {
3303 ds_put_format(ds, "value len %"PRIuSIZE" different from mask len %"PRIuSIZE,
3304 nl_attr_get_size(attr), nl_attr_get_size(mask_attr));
3305 return;
3306 }
3307
3308 format_geneve_opts(opt, mask, opts_len, ds, verbose);
3309}
3310
f59cb331
YY
3311static void
3312format_odp_nsh_attr(const struct nlattr *attr, const struct nlattr *mask_attr,
3313 struct ds *ds)
3314{
3315 unsigned int left;
3316 const struct nlattr *a;
3317 struct ovs_key_nsh nsh;
3318 struct ovs_key_nsh nsh_mask;
3319
3320 memset(&nsh, 0, sizeof nsh);
3321 memset(&nsh_mask, 0xff, sizeof nsh_mask);
3322
3323 NL_NESTED_FOR_EACH (a, left, attr) {
3324 enum ovs_nsh_key_attr type = nl_attr_type(a);
3325 const struct nlattr *ma = NULL;
3326
3327 if (mask_attr) {
3328 ma = nl_attr_find__(nl_attr_get(mask_attr),
3329 nl_attr_get_size(mask_attr), type);
3330 }
3331
3332 if (!check_attr_len(ds, a, ma, ovs_nsh_key_attr_lens,
3333 OVS_NSH_KEY_ATTR_MAX, true)) {
3334 continue;
3335 }
3336
3337 switch (type) {
3338 case OVS_NSH_KEY_ATTR_UNSPEC:
3339 break;
3340 case OVS_NSH_KEY_ATTR_BASE: {
17553f27
YY
3341 const struct ovs_nsh_key_base *base = nl_attr_get(a);
3342 const struct ovs_nsh_key_base *base_mask
f59cb331
YY
3343 = ma ? nl_attr_get(ma) : NULL;
3344 nsh.flags = base->flags;
17553f27 3345 nsh.ttl = base->ttl;
f59cb331
YY
3346 nsh.mdtype = base->mdtype;
3347 nsh.np = base->np;
3348 nsh.path_hdr = base->path_hdr;
3349 if (base_mask) {
3350 nsh_mask.flags = base_mask->flags;
17553f27 3351 nsh_mask.ttl = base_mask->ttl;
f59cb331
YY
3352 nsh_mask.mdtype = base_mask->mdtype;
3353 nsh_mask.np = base_mask->np;
3354 nsh_mask.path_hdr = base_mask->path_hdr;
3355 }
3356 break;
3357 }
3358 case OVS_NSH_KEY_ATTR_MD1: {
17553f27
YY
3359 const struct ovs_nsh_key_md1 *md1 = nl_attr_get(a);
3360 const struct ovs_nsh_key_md1 *md1_mask
f59cb331
YY
3361 = ma ? nl_attr_get(ma) : NULL;
3362 memcpy(nsh.context, md1->context, sizeof md1->context);
3363 if (md1_mask) {
3364 memcpy(nsh_mask.context, md1_mask->context,
3365 sizeof md1_mask->context);
3366 }
3367 break;
3368 }
3369 case OVS_NSH_KEY_ATTR_MD2:
3370 case __OVS_NSH_KEY_ATTR_MAX:
3371 default:
3372 /* No support for matching other metadata formats yet. */
3373 break;
3374 }
3375 }
3376
3377 if (mask_attr) {
3378 format_nsh_key_mask(ds, &nsh, &nsh_mask);
3379 } else {
3380 format_nsh_key(ds, &nsh);
3381 }
3382}
3383
65da723b
JG
3384static void
3385format_odp_tun_attr(const struct nlattr *attr, const struct nlattr *mask_attr,
3386 struct ds *ds, bool verbose)
3387{
3388 unsigned int left;
3389 const struct nlattr *a;
3390 uint16_t flags = 0;
3391 uint16_t mask_flags = 0;
3392 struct ofpbuf ofp;
3393
3394 ofpbuf_init(&ofp, 100);
3395 NL_NESTED_FOR_EACH(a, left, attr) {
3396 enum ovs_tunnel_key_attr type = nl_attr_type(a);
3397 const struct nlattr *ma = NULL;
3398
3399 if (mask_attr) {
3400 ma = nl_attr_find__(nl_attr_get(mask_attr),
3401 nl_attr_get_size(mask_attr), type);
3402 if (!ma) {
3403 ma = generate_all_wildcard_mask(ovs_tun_key_attr_lens,
3404 OVS_TUNNEL_KEY_ATTR_MAX,
3405 &ofp, a);
3406 }
3407 }
3408
3409 if (!check_attr_len(ds, a, ma, ovs_tun_key_attr_lens,
3410 OVS_TUNNEL_KEY_ATTR_MAX, true)) {
3411 continue;
3412 }
3413
3414 switch (type) {
3415 case OVS_TUNNEL_KEY_ATTR_ID:
3416 format_be64(ds, "tun_id", nl_attr_get_be64(a),
3417 ma ? nl_attr_get(ma) : NULL, verbose);
d39ec23d 3418 flags |= FLOW_TNL_F_KEY;
65da723b
JG
3419 if (ma) {
3420 mask_flags |= FLOW_TNL_F_KEY;
3421 }
3422 break;
3423 case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
3424 format_ipv4(ds, "src", nl_attr_get_be32(a),
3425 ma ? nl_attr_get(ma) : NULL, verbose);
3426 break;
3427 case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
3428 format_ipv4(ds, "dst", nl_attr_get_be32(a),
3429 ma ? nl_attr_get(ma) : NULL, verbose);
3430 break;
ffe4c74f
JB
3431 case OVS_TUNNEL_KEY_ATTR_IPV6_SRC: {
3432 struct in6_addr ipv6_src;
3433 ipv6_src = nl_attr_get_in6_addr(a);
3434 format_in6_addr(ds, "ipv6_src", &ipv6_src,
3435 ma ? nl_attr_get(ma) : NULL, verbose);
3436 break;
3437 }
3438 case OVS_TUNNEL_KEY_ATTR_IPV6_DST: {
3439 struct in6_addr ipv6_dst;
3440 ipv6_dst = nl_attr_get_in6_addr(a);
3441 format_in6_addr(ds, "ipv6_dst", &ipv6_dst,
3442 ma ? nl_attr_get(ma) : NULL, verbose);
3443 break;
3444 }
65da723b
JG
3445 case OVS_TUNNEL_KEY_ATTR_TOS:
3446 format_u8x(ds, "tos", nl_attr_get_u8(a),
3447 ma ? nl_attr_get(ma) : NULL, verbose);
3448 break;
3449 case OVS_TUNNEL_KEY_ATTR_TTL:
3450 format_u8u(ds, "ttl", nl_attr_get_u8(a),
3451 ma ? nl_attr_get(ma) : NULL, verbose);
3452 break;
3453 case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
d39ec23d 3454 flags |= FLOW_TNL_F_DONT_FRAGMENT;
65da723b
JG
3455 break;
3456 case OVS_TUNNEL_KEY_ATTR_CSUM:
d39ec23d 3457 flags |= FLOW_TNL_F_CSUM;
65da723b
JG
3458 break;
3459 case OVS_TUNNEL_KEY_ATTR_TP_SRC:
3460 format_be16(ds, "tp_src", nl_attr_get_be16(a),
3461 ma ? nl_attr_get(ma) : NULL, verbose);
3462 break;
3463 case OVS_TUNNEL_KEY_ATTR_TP_DST:
3464 format_be16(ds, "tp_dst", nl_attr_get_be16(a),
3465 ma ? nl_attr_get(ma) : NULL, verbose);
3466 break;
3467 case OVS_TUNNEL_KEY_ATTR_OAM:
d39ec23d 3468 flags |= FLOW_TNL_F_OAM;
65da723b
JG
3469 break;
3470 case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
3471 ds_put_cstr(ds, "vxlan(");
3472 format_odp_tun_vxlan_opt(a, ma, ds, verbose);
3473 ds_put_cstr(ds, "),");
3474 break;
3475 case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS:
622a0a8e
JG
3476 ds_put_cstr(ds, "geneve(");
3477 format_odp_tun_geneve(a, ma, ds, verbose);
3478 ds_put_cstr(ds, "),");
3479 break;
f3464818
PS
3480 case OVS_TUNNEL_KEY_ATTR_PAD:
3481 break;
65da723b
JG
3482 case __OVS_TUNNEL_KEY_ATTR_MAX:
3483 default:
3484 format_unknown_key(ds, a, ma);
3485 }
3486 ofpbuf_clear(&ofp);
3487 }
3488
3489 /* Flags can have a valid mask even if the attribute is not set, so
3490 * we need to collect these separately. */
3491 if (mask_attr) {
3492 NL_NESTED_FOR_EACH(a, left, mask_attr) {
3493 switch (nl_attr_type(a)) {
3494 case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
3495 mask_flags |= FLOW_TNL_F_DONT_FRAGMENT;
3496 break;
3497 case OVS_TUNNEL_KEY_ATTR_CSUM:
3498 mask_flags |= FLOW_TNL_F_CSUM;
3499 break;
3500 case OVS_TUNNEL_KEY_ATTR_OAM:
3501 mask_flags |= FLOW_TNL_F_OAM;
3502 break;
3503 }
3504 }
3505 }
3506
3507 format_tun_flags(ds, "flags", flags, mask_attr ? &mask_flags : NULL,
3508 verbose);
3509 ds_chomp(ds, ',');
3510 ofpbuf_uninit(&ofp);
3511}
3512
07659514
JS
3513static const char *
3514odp_ct_state_to_string(uint32_t flag)
3515{
3516 switch (flag) {
3517 case OVS_CS_F_REPLY_DIR:
3518 return "rpl";
3519 case OVS_CS_F_TRACKED:
3520 return "trk";
3521 case OVS_CS_F_NEW:
3522 return "new";
3523 case OVS_CS_F_ESTABLISHED:
3524 return "est";
3525 case OVS_CS_F_RELATED:
3526 return "rel";
3527 case OVS_CS_F_INVALID:
3528 return "inv";
819571b5
DDP
3529 case OVS_CS_F_SRC_NAT:
3530 return "snat";
3531 case OVS_CS_F_DST_NAT:
3532 return "dnat";
07659514
JS
3533 default:
3534 return NULL;
3535 }
3536}
3537
2d18eae8
JR
3538static void
3539format_frag(struct ds *ds, const char *name, uint8_t key,
08fa0266 3540 const uint8_t *mask, bool verbose OVS_UNUSED)
2d18eae8
JR
3541{
3542 bool mask_empty = mask && !*mask;
08fa0266 3543 bool mask_full = !mask || *mask == UINT8_MAX;
2d18eae8
JR
3544
3545 /* ODP frag is an enumeration field; partial masks are not meaningful. */
08fa0266
PB
3546 if (!mask_empty && !mask_full) {
3547 ds_put_format(ds, "error: partial mask not supported for frag (%#"
3548 PRIx8"),", *mask);
3549 } else if (!mask_empty) {
3550 ds_put_format(ds, "%s=%s,", name, ovs_frag_type_to_string(key));
2d18eae8
JR
3551 }
3552}
3553
07659514
JS
3554static bool
3555mask_empty(const struct nlattr *ma)
3556{
3557 const void *mask;
3558 size_t n;
3559
3560 if (!ma) {
3561 return true;
3562 }
3563 mask = nl_attr_get(ma);
3564 n = nl_attr_get_size(ma);
3565
3566 return is_all_zeros(mask, n);
3567}
3568
2f73024d
BP
3569/* The caller must have already verified that 'a' and 'ma' have correct
3570 * lengths. */
36956a7d 3571static void
2f73024d
BP
3572format_odp_key_attr__(const struct nlattr *a, const struct nlattr *ma,
3573 const struct hmap *portno_names, struct ds *ds,
3574 bool verbose)
36956a7d 3575{
7a8e9ed2 3576 enum ovs_key_attr attr = nl_attr_type(a);
e6603631 3577 char namebuf[OVS_KEY_ATTR_BUFSIZE];
dc8c5408 3578 bool is_exact;
36956a7d 3579
dc8c5408 3580 is_exact = ma ? odp_mask_attr_is_exact(ma) : true;
e6cc0bab 3581
e6603631 3582 ds_put_cstr(ds, ovs_key_attr_to_string(attr, namebuf, sizeof namebuf));
e6cc0bab 3583
e6cc0bab 3584 ds_put_char(ds, '(');
7a8e9ed2 3585 switch (attr) {
fea393b1 3586 case OVS_KEY_ATTR_ENCAP:
e6cc0bab
AZ
3587 if (ma && nl_attr_get_size(ma) && nl_attr_get_size(a)) {
3588 odp_flow_format(nl_attr_get(a), nl_attr_get_size(a),
0a37839c 3589 nl_attr_get(ma), nl_attr_get_size(ma), NULL, ds,
041e7168 3590 verbose);
0a37839c
GS
3591 } else if (nl_attr_get_size(a)) {
3592 odp_flow_format(nl_attr_get(a), nl_attr_get_size(a), NULL, 0, NULL,
3593 ds, verbose);
fea393b1 3594 }
fea393b1
BP
3595 break;
3596
abff858b 3597 case OVS_KEY_ATTR_PRIORITY:
72e8bf28 3598 case OVS_KEY_ATTR_SKB_MARK:
572f732a
AZ
3599 case OVS_KEY_ATTR_DP_HASH:
3600 case OVS_KEY_ATTR_RECIRC_ID:
e6cc0bab 3601 ds_put_format(ds, "%#"PRIx32, nl_attr_get_u32(a));
dc8c5408 3602 if (!is_exact) {
e6cc0bab
AZ
3603 ds_put_format(ds, "/%#"PRIx32, nl_attr_get_u32(ma));
3604 }
72e8bf28
AA
3605 break;
3606
8e53fe8c
JS
3607 case OVS_KEY_ATTR_CT_MARK:
3608 if (verbose || !mask_empty(ma)) {
3609 ds_put_format(ds, "%#"PRIx32, nl_attr_get_u32(a));
3610 if (!is_exact) {
3611 ds_put_format(ds, "/%#"PRIx32, nl_attr_get_u32(ma));
3612 }
3613 }
3614 break;
3615
07659514
JS
3616 case OVS_KEY_ATTR_CT_STATE:
3617 if (verbose) {
3618 ds_put_format(ds, "%#"PRIx32, nl_attr_get_u32(a));
3619 if (!is_exact) {
3620 ds_put_format(ds, "/%#"PRIx32,
3621 mask_empty(ma) ? 0 : nl_attr_get_u32(ma));
3622 }
3623 } else if (!is_exact) {
3624 format_flags_masked(ds, NULL, odp_ct_state_to_string,
3625 nl_attr_get_u32(a),
3626 mask_empty(ma) ? 0 : nl_attr_get_u32(ma),
3627 UINT32_MAX);
3628 } else {
3629 format_flags(ds, odp_ct_state_to_string, nl_attr_get_u32(a), '|');
3630 }
3631 break;
3632
3633 case OVS_KEY_ATTR_CT_ZONE:
3634 if (verbose || !mask_empty(ma)) {
3635 ds_put_format(ds, "%#"PRIx16, nl_attr_get_u16(a));
3636 if (!is_exact) {
3637 ds_put_format(ds, "/%#"PRIx16, nl_attr_get_u16(ma));
3638 }
3639 }
3640 break;
3641
9daf2348 3642 case OVS_KEY_ATTR_CT_LABELS: {
ab79d262
BP
3643 const ovs_32aligned_u128 *value = nl_attr_get(a);
3644 const ovs_32aligned_u128 *mask = ma ? nl_attr_get(ma) : NULL;
9daf2348
JS
3645
3646 format_u128(ds, value, mask, verbose);
3647 break;
3648 }
07659514 3649
c30b4cea
JR
3650 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4: {
3651 const struct ovs_key_ct_tuple_ipv4 *key = nl_attr_get(a);
3652 const struct ovs_key_ct_tuple_ipv4 *mask = ma ? nl_attr_get(ma) : NULL;
3653
3654 format_ipv4(ds, "src", key->ipv4_src, MASK(mask, ipv4_src), verbose);
3655 format_ipv4(ds, "dst", key->ipv4_dst, MASK(mask, ipv4_dst), verbose);
3656 format_u8u(ds, "proto", key->ipv4_proto, MASK(mask, ipv4_proto),
3657 verbose);
3658 format_be16(ds, "tp_src", key->src_port, MASK(mask, src_port),
3659 verbose);
3660 format_be16(ds, "tp_dst", key->dst_port, MASK(mask, dst_port),
3661 verbose);
3662 ds_chomp(ds, ',');
3663 break;
3664 }
3665
3666 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6: {
3667 const struct ovs_key_ct_tuple_ipv6 *key = nl_attr_get(a);
3668 const struct ovs_key_ct_tuple_ipv6 *mask = ma ? nl_attr_get(ma) : NULL;
3669
3670 format_in6_addr(ds, "src", &key->ipv6_src, MASK(mask, ipv6_src),
3671 verbose);
3672 format_in6_addr(ds, "dst", &key->ipv6_dst, MASK(mask, ipv6_dst),
3673 verbose);
3674 format_u8u(ds, "proto", key->ipv6_proto, MASK(mask, ipv6_proto),
3675 verbose);
3676 format_be16(ds, "src_port", key->src_port, MASK(mask, src_port),
3677 verbose);
3678 format_be16(ds, "dst_port", key->dst_port, MASK(mask, dst_port),
3679 verbose);
3680 ds_chomp(ds, ',');
3681 break;
3682 }
3683
65da723b
JG
3684 case OVS_KEY_ATTR_TUNNEL:
3685 format_odp_tun_attr(a, ma, ds, verbose);
356af50b 3686 break;
65da723b 3687
df2c07f4 3688 case OVS_KEY_ATTR_IN_PORT:
0722f341
BP
3689 if (is_exact) {
3690 odp_portno_name_format(portno_names, nl_attr_get_odp_port(a), ds);
0a37839c
GS
3691 } else {
3692 ds_put_format(ds, "%"PRIu32, nl_attr_get_u32(a));
3693 if (!is_exact) {
3694 ds_put_format(ds, "/%#"PRIx32, nl_attr_get_u32(ma));
3695 }
e6cc0bab 3696 }
36956a7d
BP
3697 break;
3698
beb75a40 3699 case OVS_KEY_ATTR_PACKET_TYPE: {
3d4b2e6e
JS
3700 ovs_be32 value = nl_attr_get_be32(a);
3701 ovs_be32 mask = ma ? nl_attr_get_be32(ma) : OVS_BE32_MAX;
beb75a40 3702
3d4b2e6e
JS
3703 ovs_be16 ns = htons(pt_ns(value));
3704 ovs_be16 ns_mask = htons(pt_ns(mask));
3705 format_be16(ds, "ns", ns, &ns_mask, verbose);
beb75a40 3706
3d4b2e6e
JS
3707 ovs_be16 ns_type = pt_ns_type_be(value);
3708 ovs_be16 ns_type_mask = pt_ns_type_be(mask);
3709 format_be16x(ds, "id", ns_type, &ns_type_mask, verbose);
3710
3711 ds_chomp(ds, ',');
beb75a40
JS
3712 break;
3713 }
3714
2d18eae8
JR
3715 case OVS_KEY_ATTR_ETHERNET: {
3716 const struct ovs_key_ethernet *mask = ma ? nl_attr_get(ma) : NULL;
3717 const struct ovs_key_ethernet *key = nl_attr_get(a);
e6cc0bab 3718
2d18eae8
JR
3719 format_eth(ds, "src", key->eth_src, MASK(mask, eth_src), verbose);
3720 format_eth(ds, "dst", key->eth_dst, MASK(mask, eth_dst), verbose);
3721 ds_chomp(ds, ',');
36956a7d 3722 break;
2d18eae8 3723 }
fea393b1 3724 case OVS_KEY_ATTR_VLAN:
2d18eae8
JR
3725 format_vlan_tci(ds, nl_attr_get_be16(a),
3726 ma ? nl_attr_get_be16(ma) : OVS_BE16_MAX, verbose);
36956a7d
BP
3727 break;
3728
b02475c5
SH
3729 case OVS_KEY_ATTR_MPLS: {
3730 const struct ovs_key_mpls *mpls_key = nl_attr_get(a);
e6cc0bab 3731 const struct ovs_key_mpls *mpls_mask = NULL;
8bfd0fda
BP
3732 size_t size = nl_attr_get_size(a);
3733
3734 if (!size || size % sizeof *mpls_key) {
6d670e7f 3735 ds_put_format(ds, "(bad key length %"PRIuSIZE")", size);
8bfd0fda
BP
3736 return;
3737 }
dc8c5408 3738 if (!is_exact) {
e6cc0bab 3739 mpls_mask = nl_attr_get(ma);
6d670e7f 3740 if (size != nl_attr_get_size(ma)) {
8bfd0fda
BP
3741 ds_put_format(ds, "(key length %"PRIuSIZE" != "
3742 "mask length %"PRIuSIZE")",
6d670e7f 3743 size, nl_attr_get_size(ma));
8bfd0fda
BP
3744 return;
3745 }
e6cc0bab 3746 }
8bfd0fda 3747 format_mpls(ds, mpls_key, mpls_mask, size / sizeof *mpls_key);
b02475c5
SH
3748 break;
3749 }
df2c07f4 3750 case OVS_KEY_ATTR_ETHERTYPE:
e6cc0bab 3751 ds_put_format(ds, "0x%04"PRIx16, ntohs(nl_attr_get_be16(a)));
dc8c5408 3752 if (!is_exact) {
e6cc0bab
AZ
3753 ds_put_format(ds, "/0x%04"PRIx16, ntohs(nl_attr_get_be16(ma)));
3754 }
36956a7d
BP
3755 break;
3756
2d18eae8
JR
3757 case OVS_KEY_ATTR_IPV4: {
3758 const struct ovs_key_ipv4 *key = nl_attr_get(a);
3759 const struct ovs_key_ipv4 *mask = ma ? nl_attr_get(ma) : NULL;
3760
3761 format_ipv4(ds, "src", key->ipv4_src, MASK(mask, ipv4_src), verbose);
3762 format_ipv4(ds, "dst", key->ipv4_dst, MASK(mask, ipv4_dst), verbose);
3763 format_u8u(ds, "proto", key->ipv4_proto, MASK(mask, ipv4_proto),
3764 verbose);
3765 format_u8x(ds, "tos", key->ipv4_tos, MASK(mask, ipv4_tos), verbose);
3766 format_u8u(ds, "ttl", key->ipv4_ttl, MASK(mask, ipv4_ttl), verbose);
3767 format_frag(ds, "frag", key->ipv4_frag, MASK(mask, ipv4_frag),
3768 verbose);
3769 ds_chomp(ds, ',');
36956a7d 3770 break;
2d18eae8
JR
3771 }
3772 case OVS_KEY_ATTR_IPV6: {
3773 const struct ovs_key_ipv6 *key = nl_attr_get(a);
3774 const struct ovs_key_ipv6 *mask = ma ? nl_attr_get(ma) : NULL;
3775
932c96b7
JR
3776 format_in6_addr(ds, "src", &key->ipv6_src, MASK(mask, ipv6_src),
3777 verbose);
3778 format_in6_addr(ds, "dst", &key->ipv6_dst, MASK(mask, ipv6_dst),
3779 verbose);
2d18eae8
JR
3780 format_ipv6_label(ds, "label", key->ipv6_label, MASK(mask, ipv6_label),
3781 verbose);
3782 format_u8u(ds, "proto", key->ipv6_proto, MASK(mask, ipv6_proto),
932c96b7 3783 verbose);
2d18eae8 3784 format_u8x(ds, "tclass", key->ipv6_tclass, MASK(mask, ipv6_tclass),
932c96b7 3785 verbose);
2d18eae8 3786 format_u8u(ds, "hlimit", key->ipv6_hlimit, MASK(mask, ipv6_hlimit),
932c96b7 3787 verbose);
2d18eae8
JR
3788 format_frag(ds, "frag", key->ipv6_frag, MASK(mask, ipv6_frag),
3789 verbose);
3790 ds_chomp(ds, ',');
d31f1109 3791 break;
2d18eae8
JR
3792 }
3793 /* These have the same structure and format. */
df2c07f4 3794 case OVS_KEY_ATTR_TCP:
2d18eae8
JR
3795 case OVS_KEY_ATTR_UDP:
3796 case OVS_KEY_ATTR_SCTP: {
3797 const struct ovs_key_tcp *key = nl_attr_get(a);
3798 const struct ovs_key_tcp *mask = ma ? nl_attr_get(ma) : NULL;
e6cc0bab 3799
2d18eae8
JR
3800 format_be16(ds, "src", key->tcp_src, MASK(mask, tcp_src), verbose);
3801 format_be16(ds, "dst", key->tcp_dst, MASK(mask, tcp_dst), verbose);
3802 ds_chomp(ds, ',');
36956a7d 3803 break;
2d18eae8 3804 }
dc235f7f 3805 case OVS_KEY_ATTR_TCP_FLAGS:
dc235f7f 3806 if (!is_exact) {
ea2735d3
JR
3807 format_flags_masked(ds, NULL, packet_tcp_flag_to_string,
3808 ntohs(nl_attr_get_be16(a)),
8e4c1621
JG
3809 TCP_FLAGS(nl_attr_get_be16(ma)),
3810 TCP_FLAGS(OVS_BE16_MAX));
ea2735d3
JR
3811 } else {
3812 format_flags(ds, packet_tcp_flag_to_string,
8e4c1621 3813 ntohs(nl_attr_get_be16(a)), '|');
dc235f7f
JR
3814 }
3815 break;
3816
2d18eae8
JR
3817 case OVS_KEY_ATTR_ICMP: {
3818 const struct ovs_key_icmp *key = nl_attr_get(a);
3819 const struct ovs_key_icmp *mask = ma ? nl_attr_get(ma) : NULL;
e6cc0bab 3820
2d18eae8
JR
3821 format_u8u(ds, "type", key->icmp_type, MASK(mask, icmp_type), verbose);
3822 format_u8u(ds, "code", key->icmp_code, MASK(mask, icmp_code), verbose);
3823 ds_chomp(ds, ',');
36956a7d 3824 break;
2d18eae8
JR
3825 }
3826 case OVS_KEY_ATTR_ICMPV6: {
3827 const struct ovs_key_icmpv6 *key = nl_attr_get(a);
3828 const struct ovs_key_icmpv6 *mask = ma ? nl_attr_get(ma) : NULL;
36956a7d 3829
2d18eae8
JR
3830 format_u8u(ds, "type", key->icmpv6_type, MASK(mask, icmpv6_type),
3831 verbose);
3832 format_u8u(ds, "code", key->icmpv6_code, MASK(mask, icmpv6_code),
3833 verbose);
3834 ds_chomp(ds, ',');
d31f1109 3835 break;
2d18eae8
JR
3836 }
3837 case OVS_KEY_ATTR_ARP: {
3838 const struct ovs_key_arp *mask = ma ? nl_attr_get(ma) : NULL;
3839 const struct ovs_key_arp *key = nl_attr_get(a);
d31f1109 3840
2d18eae8
JR
3841 format_ipv4(ds, "sip", key->arp_sip, MASK(mask, arp_sip), verbose);
3842 format_ipv4(ds, "tip", key->arp_tip, MASK(mask, arp_tip), verbose);
3843 format_be16(ds, "op", key->arp_op, MASK(mask, arp_op), verbose);
3844 format_eth(ds, "sha", key->arp_sha, MASK(mask, arp_sha), verbose);
3845 format_eth(ds, "tha", key->arp_tha, MASK(mask, arp_tha), verbose);
3846 ds_chomp(ds, ',');
36956a7d 3847 break;
2d18eae8 3848 }
df2c07f4 3849 case OVS_KEY_ATTR_ND: {
2d18eae8
JR
3850 const struct ovs_key_nd *mask = ma ? nl_attr_get(ma) : NULL;
3851 const struct ovs_key_nd *key = nl_attr_get(a);
e6cc0bab 3852
932c96b7
JR
3853 format_in6_addr(ds, "target", &key->nd_target, MASK(mask, nd_target),
3854 verbose);
2d18eae8
JR
3855 format_eth(ds, "sll", key->nd_sll, MASK(mask, nd_sll), verbose);
3856 format_eth(ds, "tll", key->nd_tll, MASK(mask, nd_tll), verbose);
685a51a5 3857
2d18eae8 3858 ds_chomp(ds, ',');
685a51a5
JP
3859 break;
3860 }
3d2fbd70 3861 case OVS_KEY_ATTR_NSH: {
f59cb331 3862 format_odp_nsh_attr(a, ma, ds);
3d2fbd70
JS
3863 break;
3864 }
7a8e9ed2
BP
3865 case OVS_KEY_ATTR_UNSPEC:
3866 case __OVS_KEY_ATTR_MAX:
36956a7d
BP
3867 default:
3868 format_generic_odp_key(a, ds);
dc8c5408 3869 if (!is_exact) {
e6cc0bab
AZ
3870 ds_put_char(ds, '/');
3871 format_generic_odp_key(ma, ds);
3872 }
36956a7d
BP
3873 break;
3874 }
e6cc0bab 3875 ds_put_char(ds, ')');
36956a7d
BP
3876}
3877
2f73024d
BP
3878static void
3879format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
3880 const struct hmap *portno_names, struct ds *ds,
3881 bool verbose)
3882{
3883 if (check_attr_len(ds, a, ma, ovs_flow_key_attr_lens,
3884 OVS_KEY_ATTR_MAX, false)) {
3885 format_odp_key_attr__(a, ma, portno_names, ds, verbose);
3886 }
3887}
3888
dc8c5408 3889static struct nlattr *
6b8da9e9
JG
3890generate_all_wildcard_mask(const struct attr_len_tbl tbl[], int max,
3891 struct ofpbuf *ofp, const struct nlattr *key)
dc8c5408
AZ
3892{
3893 const struct nlattr *a;
3894 unsigned int left;
3895 int type = nl_attr_type(key);
3896 int size = nl_attr_get_size(key);
3897
6b8da9e9 3898 if (odp_key_attr_len(tbl, max, type) != ATTR_LEN_NESTED) {
9ddf12cc 3899 nl_msg_put_unspec_zero(ofp, type, size);
dc8c5408
AZ
3900 } else {
3901 size_t nested_mask;
3902
6b8da9e9 3903 if (tbl[type].next) {
464cc3ee
BP
3904 const struct attr_len_tbl *entry = &tbl[type];
3905 tbl = entry->next;
3906 max = entry->next_max;
6b8da9e9
JG
3907 }
3908
dc8c5408
AZ
3909 nested_mask = nl_msg_start_nested(ofp, type);
3910 NL_ATTR_FOR_EACH(a, left, key, nl_attr_get_size(key)) {
6b8da9e9 3911 generate_all_wildcard_mask(tbl, max, ofp, nl_attr_get(a));
dc8c5408
AZ
3912 }
3913 nl_msg_end_nested(ofp, nested_mask);
3914 }
3915
6fd6ed71 3916 return ofp->base;
dc8c5408
AZ
3917}
3918
9daf2348 3919static void
ab79d262
BP
3920format_u128(struct ds *ds, const ovs_32aligned_u128 *key,
3921 const ovs_32aligned_u128 *mask, bool verbose)
9daf2348 3922{
ab79d262
BP
3923 if (verbose || (mask && !ovs_u128_is_zero(get_32aligned_u128(mask)))) {
3924 ovs_be128 value = hton128(get_32aligned_u128(key));
9daf2348 3925 ds_put_hex(ds, &value, sizeof value);
ab79d262
BP
3926 if (mask && !(ovs_u128_is_ones(get_32aligned_u128(mask)))) {
3927 value = hton128(get_32aligned_u128(mask));
9daf2348
JS
3928 ds_put_char(ds, '/');
3929 ds_put_hex(ds, &value, sizeof value);
3930 }
3931 }
3932}
3933
b23ada8e
JP
3934/* Read the string from 's_' as a 128-bit value. If the string contains
3935 * a "/", the rest of the string will be treated as a 128-bit mask.
3936 *
3937 * If either the value or mask is larger than 64 bits, the string must
3938 * be in hexadecimal.
3939 */
9daf2348
JS
3940static int
3941scan_u128(const char *s_, ovs_u128 *value, ovs_u128 *mask)
3942{
3943 char *s = CONST_CAST(char *, s_);
3944 ovs_be128 be_value;
3945 ovs_be128 be_mask;
3946
3947 if (!parse_int_string(s, (uint8_t *)&be_value, sizeof be_value, &s)) {
32ea15f6 3948 *value = ntoh128(be_value);
9daf2348
JS
3949
3950 if (mask) {
3951 int n;
3952
3953 if (ovs_scan(s, "/%n", &n)) {
3954 int error;
3955
3956 s += n;
3957 error = parse_int_string(s, (uint8_t *)&be_mask,
3958 sizeof be_mask, &s);
3959 if (error) {
2c539492 3960 return 0;
9daf2348 3961 }
32ea15f6 3962 *mask = ntoh128(be_mask);
9daf2348
JS
3963 } else {
3964 *mask = OVS_U128_MAX;
3965 }
3966 }
3967 return s - s_;
3968 }
3969
3970 return 0;
3971}
3972
534a19b9
JS
3973int
3974odp_ufid_from_string(const char *s_, ovs_u128 *ufid)
3975{
3976 const char *s = s_;
3977
3978 if (ovs_scan(s, "ufid:")) {
534a19b9 3979 s += 5;
534a19b9 3980
10e92b4f 3981 if (!uuid_from_string_prefix((struct uuid *)ufid, s)) {
534a19b9
JS
3982 return -EINVAL;
3983 }
10e92b4f 3984 s += UUID_LEN;
534a19b9
JS
3985
3986 return s - s_;
3987 }
3988
3989 return 0;
3990}
3991
70e5ed6f
JS
3992void
3993odp_format_ufid(const ovs_u128 *ufid, struct ds *ds)
3994{
10e92b4f 3995 ds_put_format(ds, "ufid:"UUID_FMT, UUID_ARGS((struct uuid *)ufid));
70e5ed6f
JS
3996}
3997
36956a7d 3998/* Appends to 'ds' a string representation of the 'key_len' bytes of
e6cc0bab 3999 * OVS_KEY_ATTR_* attributes in 'key'. If non-null, additionally formats the
73580638 4000 * 'mask_len' bytes of 'mask' which apply to 'key'. If 'portno_names' is
d1fd1ea9 4001 * non-null, translates odp port number to its name. */
14608a15 4002void
e6cc0bab
AZ
4003odp_flow_format(const struct nlattr *key, size_t key_len,
4004 const struct nlattr *mask, size_t mask_len,
0a37839c 4005 const struct hmap *portno_names, struct ds *ds, bool verbose)
14608a15 4006{
36956a7d
BP
4007 if (key_len) {
4008 const struct nlattr *a;
4009 unsigned int left;
e6cc0bab 4010 bool has_ethtype_key = false;
dc8c5408 4011 struct ofpbuf ofp;
041e7168 4012 bool first_field = true;
36956a7d 4013
dc8c5408 4014 ofpbuf_init(&ofp, 100);
36956a7d 4015 NL_ATTR_FOR_EACH (a, left, key, key_len) {
2f73024d
BP
4016 int attr_type = nl_attr_type(a);
4017 const struct nlattr *ma = (mask && mask_len
4018 ? nl_attr_find__(mask, mask_len,
4019 attr_type)
4020 : NULL);
4021 if (!check_attr_len(ds, a, ma, ovs_flow_key_attr_lens,
4022 OVS_KEY_ATTR_MAX, false)) {
4023 continue;
4024 }
4025
041e7168
AZ
4026 bool is_nested_attr;
4027 bool is_wildcard = false;
041e7168
AZ
4028
4029 if (attr_type == OVS_KEY_ATTR_ETHERTYPE) {
e6cc0bab
AZ
4030 has_ethtype_key = true;
4031 }
041e7168 4032
6b8da9e9
JG
4033 is_nested_attr = odp_key_attr_len(ovs_flow_key_attr_lens,
4034 OVS_KEY_ATTR_MAX, attr_type) ==
4035 ATTR_LEN_NESTED;
041e7168 4036
e6cc0bab
AZ
4037 if (mask && mask_len) {
4038 ma = nl_attr_find__(mask, mask_len, nl_attr_type(a));
041e7168
AZ
4039 is_wildcard = ma ? odp_mask_attr_is_wildcard(ma) : true;
4040 }
4041
4042 if (verbose || !is_wildcard || is_nested_attr) {
4043 if (is_wildcard && !ma) {
6b8da9e9
JG
4044 ma = generate_all_wildcard_mask(ovs_flow_key_attr_lens,
4045 OVS_KEY_ATTR_MAX,
4046 &ofp, a);
dc8c5408 4047 }
041e7168
AZ
4048 if (!first_field) {
4049 ds_put_char(ds, ',');
4050 }
2f73024d 4051 format_odp_key_attr__(a, ma, portno_names, ds, verbose);
041e7168 4052 first_field = false;
e6cc0bab 4053 }
dc8c5408 4054 ofpbuf_clear(&ofp);
36956a7d 4055 }
dc8c5408
AZ
4056 ofpbuf_uninit(&ofp);
4057
36956a7d 4058 if (left) {
3a8cfc50 4059 int i;
1394054e 4060
36956a7d
BP
4061 if (left == key_len) {
4062 ds_put_cstr(ds, "<empty>");
4063 }
3a8cfc50
BP
4064 ds_put_format(ds, ",***%u leftover bytes*** (", left);
4065 for (i = 0; i < left; i++) {
4066 ds_put_format(ds, "%02x", ((const uint8_t *) a)[i]);
4067 }
4068 ds_put_char(ds, ')');
36956a7d 4069 }
e6cc0bab 4070 if (!has_ethtype_key) {
2f73024d
BP
4071 const struct nlattr *ma = nl_attr_find__(mask, mask_len,
4072 OVS_KEY_ATTR_ETHERTYPE);
e6cc0bab
AZ
4073 if (ma) {
4074 ds_put_format(ds, ",eth_type(0/0x%04"PRIx16")",
4075 ntohs(nl_attr_get_be16(ma)));
4076 }
4077 }
36956a7d
BP
4078 } else {
4079 ds_put_cstr(ds, "<empty>");
4080 }
14608a15 4081}
064af421 4082
e6cc0bab
AZ
4083/* Appends to 'ds' a string representation of the 'key_len' bytes of
4084 * OVS_KEY_ATTR_* attributes in 'key'. */
4085void
4086odp_flow_key_format(const struct nlattr *key,
4087 size_t key_len, struct ds *ds)
4088{
0a37839c 4089 odp_flow_format(key, key_len, NULL, 0, NULL, ds, true);
e6cc0bab
AZ
4090}
4091
7257b535
BP
4092static bool
4093ovs_frag_type_from_string(const char *s, enum ovs_frag_type *type)
4094{
4095 if (!strcasecmp(s, "no")) {
4096 *type = OVS_FRAG_TYPE_NONE;
4097 } else if (!strcasecmp(s, "first")) {
4098 *type = OVS_FRAG_TYPE_FIRST;
4099 } else if (!strcasecmp(s, "later")) {
4100 *type = OVS_FRAG_TYPE_LATER;
4101 } else {
4102 return false;
4103 }
4104 return true;
4105}
4106
2d18eae8 4107/* Parsing. */
b02475c5 4108
3bffc610 4109static int
74ff3298 4110scan_eth(const char *s, struct eth_addr *key, struct eth_addr *mask)
3bffc610 4111{
2d18eae8 4112 int n;
abff858b 4113
74ff3298
JR
4114 if (ovs_scan(s, ETH_ADDR_SCAN_FMT"%n",
4115 ETH_ADDR_SCAN_ARGS(*key), &n)) {
2d18eae8
JR
4116 int len = n;
4117
4118 if (mask) {
4119 if (ovs_scan(s + len, "/"ETH_ADDR_SCAN_FMT"%n",
4120 ETH_ADDR_SCAN_ARGS(*mask), &n)) {
4121 len += n;
4122 } else {
4123 memset(mask, 0xff, sizeof *mask);
e6cc0bab 4124 }
abff858b 4125 }
2d18eae8 4126 return len;
abff858b 4127 }
2d18eae8
JR
4128 return 0;
4129}
abff858b 4130
2d18eae8
JR
4131static int
4132scan_ipv4(const char *s, ovs_be32 *key, ovs_be32 *mask)
4133{
4134 int n;
72e8bf28 4135
2d18eae8
JR
4136 if (ovs_scan(s, IP_SCAN_FMT"%n", IP_SCAN_ARGS(key), &n)) {
4137 int len = n;
4138
4139 if (mask) {
4140 if (ovs_scan(s + len, "/"IP_SCAN_FMT"%n",
4141 IP_SCAN_ARGS(mask), &n)) {
4142 len += n;
4143 } else {
4144 *mask = OVS_BE32_MAX;
e6cc0bab 4145 }
72e8bf28 4146 }
2d18eae8 4147 return len;
72e8bf28 4148 }
2d18eae8
JR
4149 return 0;
4150}
72e8bf28 4151
2d18eae8 4152static int
d15aef48 4153scan_in6_addr(const char *s, struct in6_addr *key, struct in6_addr *mask)
2d18eae8
JR
4154{
4155 int n;
4156 char ipv6_s[IPV6_SCAN_LEN + 1];
572f732a 4157
2d18eae8
JR
4158 if (ovs_scan(s, IPV6_SCAN_FMT"%n", ipv6_s, &n)
4159 && inet_pton(AF_INET6, ipv6_s, key) == 1) {
4160 int len = n;
4161
4162 if (mask) {
4163 if (ovs_scan(s + len, "/"IPV6_SCAN_FMT"%n", ipv6_s, &n)
4164 && inet_pton(AF_INET6, ipv6_s, mask) == 1) {
4165 len += n;
4166 } else {
4167 memset(mask, 0xff, sizeof *mask);
78669073 4168 }
572f732a 4169 }
2d18eae8 4170 return len;
572f732a 4171 }
2d18eae8
JR
4172 return 0;
4173}
572f732a 4174
2d18eae8
JR
4175static int
4176scan_ipv6_label(const char *s, ovs_be32 *key, ovs_be32 *mask)
4177{
4178 int key_, mask_;
4179 int n;
572f732a 4180
2d18eae8
JR
4181 if (ovs_scan(s, "%i%n", &key_, &n)
4182 && (key_ & ~IPV6_LABEL_MASK) == 0) {
4183 int len = n;
29c7a2b2 4184
2d18eae8
JR
4185 *key = htonl(key_);
4186 if (mask) {
4187 if (ovs_scan(s + len, "/%i%n", &mask_, &n)
4188 && (mask_ & ~IPV6_LABEL_MASK) == 0) {
4189 len += n;
4190 *mask = htonl(mask_);
4191 } else {
4192 *mask = htonl(IPV6_LABEL_MASK);
e6cc0bab 4193 }
35651d6a 4194 }
2d18eae8 4195 return len;
35651d6a 4196 }
2d18eae8
JR
4197 return 0;
4198}
35651d6a 4199
2d18eae8
JR
4200static int
4201scan_u8(const char *s, uint8_t *key, uint8_t *mask)
4202{
4203 int n;
3bffc610 4204
2d18eae8
JR
4205 if (ovs_scan(s, "%"SCNi8"%n", key, &n)) {
4206 int len = n;
4207
4208 if (mask) {
4209 if (ovs_scan(s + len, "/%"SCNi8"%n", mask, &n)) {
4210 len += n;
4211 } else {
4212 *mask = UINT8_MAX;
e6cc0bab 4213 }
3bffc610 4214 }
2d18eae8 4215 return len;
3bffc610 4216 }
2d18eae8
JR
4217 return 0;
4218}
3bffc610 4219
07659514
JS
4220static int
4221scan_u16(const char *s, uint16_t *key, uint16_t *mask)
4222{
4223 int n;
4224
4225 if (ovs_scan(s, "%"SCNi16"%n", key, &n)) {
4226 int len = n;
4227
4228 if (mask) {
4229 if (ovs_scan(s + len, "/%"SCNi16"%n", mask, &n)) {
4230 len += n;
4231 } else {
4232 *mask = UINT16_MAX;
4233 }
4234 }
4235 return len;
4236 }
4237 return 0;
4238}
4239
2d18eae8
JR
4240static int
4241scan_u32(const char *s, uint32_t *key, uint32_t *mask)
4242{
4243 int n;
e6cc0bab 4244
2d18eae8
JR
4245 if (ovs_scan(s, "%"SCNi32"%n", key, &n)) {
4246 int len = n;
e6cc0bab 4247
2d18eae8
JR
4248 if (mask) {
4249 if (ovs_scan(s + len, "/%"SCNi32"%n", mask, &n)) {
4250 len += n;
4251 } else {
4252 *mask = UINT32_MAX;
e6cc0bab 4253 }
b2a60db8 4254 }
2d18eae8 4255 return len;
b2a60db8 4256 }
2d18eae8
JR
4257 return 0;
4258}
b2a60db8 4259
2d18eae8
JR
4260static int
4261scan_be16(const char *s, ovs_be16 *key, ovs_be16 *mask)
4262{
4263 uint16_t key_, mask_;
4264 int n;
3bffc610 4265
2d18eae8
JR
4266 if (ovs_scan(s, "%"SCNi16"%n", &key_, &n)) {
4267 int len = n;
e6cc0bab 4268
2d18eae8
JR
4269 *key = htons(key_);
4270 if (mask) {
4271 if (ovs_scan(s + len, "/%"SCNi16"%n", &mask_, &n)) {
4272 len += n;
4273 *mask = htons(mask_);
4274 } else {
4275 *mask = OVS_BE16_MAX;
e6cc0bab 4276 }
3bffc610 4277 }
2d18eae8 4278 return len;
3bffc610 4279 }
2d18eae8
JR
4280 return 0;
4281}
3bffc610 4282
3d2fbd70
JS
4283static int
4284scan_be32(const char *s, ovs_be32 *key, ovs_be32 *mask)
4285{
4286 uint32_t key_, mask_;
4287 int n;
4288
4289 if (ovs_scan(s, "%"SCNi32"%n", &key_, &n)) {
4290 int len = n;
4291
4292 *key = htonl(key_);
4293 if (mask) {
4294 if (ovs_scan(s + len, "/%"SCNi32"%n", &mask_, &n)) {
4295 len += n;
4296 *mask = htonl(mask_);
4297 } else {
4298 *mask = OVS_BE32_MAX;
4299 }
4300 }
4301 return len;
4302 }
4303 return 0;
4304}
4305
2d18eae8
JR
4306static int
4307scan_be64(const char *s, ovs_be64 *key, ovs_be64 *mask)
4308{
4309 uint64_t key_, mask_;
4310 int n;
3bffc610 4311
2d18eae8
JR
4312 if (ovs_scan(s, "%"SCNi64"%n", &key_, &n)) {
4313 int len = n;
4314
4315 *key = htonll(key_);
4316 if (mask) {
4317 if (ovs_scan(s + len, "/%"SCNi64"%n", &mask_, &n)) {
4318 len += n;
4319 *mask = htonll(mask_);
4320 } else {
4321 *mask = OVS_BE64_MAX;
e6cc0bab 4322 }
3bffc610 4323 }
2d18eae8 4324 return len;
3bffc610 4325 }
2d18eae8
JR
4326 return 0;
4327}
3bffc610 4328
2d18eae8
JR
4329static int
4330scan_tun_flags(const char *s, uint16_t *key, uint16_t *mask)
4331{
4332 uint32_t flags, fmask;
4333 int n;
3bffc610 4334
8e4c1621
JG
4335 n = parse_odp_flags(s, flow_tun_flag_to_string, &flags,
4336 FLOW_TNL_F_MASK, mask ? &fmask : NULL);
2d18eae8
JR
4337 if (n >= 0 && s[n] == ')') {
4338 *key = flags;
4339 if (mask) {
4340 *mask = fmask;
3bffc610 4341 }
2d18eae8 4342 return n + 1;
3bffc610 4343 }
2d18eae8
JR
4344 return 0;
4345}
3bffc610 4346
2d18eae8
JR
4347static int
4348scan_tcp_flags(const char *s, ovs_be16 *key, ovs_be16 *mask)
4349{
4350 uint32_t flags, fmask;
4351 int n;
b02475c5 4352
8e4c1621
JG
4353 n = parse_odp_flags(s, packet_tcp_flag_to_string, &flags,
4354 TCP_FLAGS(OVS_BE16_MAX), mask ? &fmask : NULL);
2d18eae8
JR
4355 if (n >= 0) {
4356 *key = htons(flags);
4357 if (mask) {
4358 *mask = htons(fmask);
b02475c5 4359 }
2d18eae8 4360 return n;
b02475c5 4361 }
2d18eae8
JR
4362 return 0;
4363}
b02475c5 4364
07659514
JS
4365static uint32_t
4366ovs_to_odp_ct_state(uint8_t state)
4367{
4368 uint32_t odp = 0;
4369
fd6cd1bf
BP
4370#define CS_STATE(ENUM, INDEX, NAME) \
4371 if (state & CS_##ENUM) { \
4372 odp |= OVS_CS_F_##ENUM; \
819571b5 4373 }
fd6cd1bf
BP
4374 CS_STATES
4375#undef CS_STATE
07659514
JS
4376
4377 return odp;
4378}
4379
4380static uint8_t
4381odp_to_ovs_ct_state(uint32_t flags)
4382{
4383 uint32_t state = 0;
4384
fd6cd1bf
BP
4385#define CS_STATE(ENUM, INDEX, NAME) \
4386 if (flags & OVS_CS_F_##ENUM) { \
4387 state |= CS_##ENUM; \
819571b5 4388 }
fd6cd1bf
BP
4389 CS_STATES
4390#undef CS_STATE
07659514
JS
4391
4392 return state;
4393}
4394
4395static int
4396scan_ct_state(const char *s, uint32_t *key, uint32_t *mask)
4397{
4398 uint32_t flags, fmask;
4399 int n;
4400
4401 n = parse_flags(s, odp_ct_state_to_string, ')', NULL, NULL, &flags,
4402 ovs_to_odp_ct_state(CS_SUPPORTED_MASK),
4403 mask ? &fmask : NULL);
4404
4405 if (n >= 0) {
4406 *key = flags;
4407 if (mask) {
4408 *mask = fmask;
4409 }
4410 return n;
4411 }
4412 return 0;
4413}
4414
2d18eae8
JR
4415static int
4416scan_frag(const char *s, uint8_t *key, uint8_t *mask)
4417{
4418 int n;
4419 char frag[8];
4420 enum ovs_frag_type frag_type;
e6cc0bab 4421
2d18eae8
JR
4422 if (ovs_scan(s, "%7[a-z]%n", frag, &n)
4423 && ovs_frag_type_from_string(frag, &frag_type)) {
4424 int len = n;
e6cc0bab 4425
2d18eae8
JR
4426 *key = frag_type;
4427 if (mask) {
4428 *mask = UINT8_MAX;
3bffc610 4429 }
2d18eae8 4430 return len;
3bffc610 4431 }
2d18eae8
JR
4432 return 0;
4433}
3bffc610 4434
2d18eae8
JR
4435static int
4436scan_port(const char *s, uint32_t *key, uint32_t *mask,
4437 const struct simap *port_names)
4438{
4439 int n;
3bffc610 4440
2d18eae8
JR
4441 if (ovs_scan(s, "%"SCNi32"%n", key, &n)) {
4442 int len = n;
e6cc0bab 4443
2d18eae8
JR
4444 if (mask) {
4445 if (ovs_scan(s + len, "/%"SCNi32"%n", mask, &n)) {
4446 len += n;
4447 } else {
4448 *mask = UINT32_MAX;
e6cc0bab 4449 }
3bffc610 4450 }
2d18eae8
JR
4451 return len;
4452 } else if (port_names) {
4453 const struct simap_node *node;
4454 int len;
e6cc0bab 4455
2d18eae8
JR
4456 len = strcspn(s, ")");
4457 node = simap_find_len(port_names, s, len);
4458 if (node) {
4459 *key = node->data;
e6cc0bab
AZ
4460
4461 if (mask) {
2d18eae8 4462 *mask = UINT32_MAX;
e6cc0bab 4463 }
2d18eae8 4464 return len;
3bffc610
BP
4465 }
4466 }
2d18eae8
JR
4467 return 0;
4468}
3bffc610 4469
2d18eae8
JR
4470/* Helper for vlan parsing. */
4471struct ovs_key_vlan__ {
4472 ovs_be16 tci;
4473};
dc235f7f 4474
2d18eae8
JR
4475static bool
4476set_be16_bf(ovs_be16 *bf, uint8_t bits, uint8_t offset, uint16_t value)
4477{
4478 const uint16_t mask = ((1U << bits) - 1) << offset;
ea2735d3 4479
2d18eae8
JR
4480 if (value >> bits) {
4481 return false;
dc235f7f
JR
4482 }
4483
2d18eae8
JR
4484 *bf = htons((ntohs(*bf) & ~mask) | (value << offset));
4485 return true;
4486}
e6cc0bab 4487
2d18eae8
JR
4488static int
4489scan_be16_bf(const char *s, ovs_be16 *key, ovs_be16 *mask, uint8_t bits,
4490 uint8_t offset)
4491{
4492 uint16_t key_, mask_;
4493 int n;
3bffc610 4494
2d18eae8
JR
4495 if (ovs_scan(s, "%"SCNi16"%n", &key_, &n)) {
4496 int len = n;
e6cc0bab 4497
2d18eae8 4498 if (set_be16_bf(key, bits, offset, key_)) {
e6cc0bab 4499 if (mask) {
2d18eae8
JR
4500 if (ovs_scan(s + len, "/%"SCNi16"%n", &mask_, &n)) {
4501 len += n;
4502
4503 if (!set_be16_bf(mask, bits, offset, mask_)) {
4504 return 0;
4505 }
4506 } else {
4507 *mask |= htons(((1U << bits) - 1) << offset);
4508 }
e6cc0bab 4509 }
2d18eae8 4510 return len;
3bffc610
BP
4511 }
4512 }
2d18eae8
JR
4513 return 0;
4514}
3bffc610 4515
2d18eae8
JR
4516static int
4517scan_vid(const char *s, ovs_be16 *key, ovs_be16 *mask)
4518{
4519 return scan_be16_bf(s, key, mask, 12, VLAN_VID_SHIFT);
4520}
c6bcb685 4521
2d18eae8
JR
4522static int
4523scan_pcp(const char *s, ovs_be16 *key, ovs_be16 *mask)
4524{
4525 return scan_be16_bf(s, key, mask, 3, VLAN_PCP_SHIFT);
4526}
c6bcb685 4527
2d18eae8
JR
4528static int
4529scan_cfi(const char *s, ovs_be16 *key, ovs_be16 *mask)
4530{
4531 return scan_be16_bf(s, key, mask, 1, VLAN_CFI_SHIFT);
4532}
c6bcb685 4533
2d18eae8
JR
4534/* For MPLS. */
4535static bool
4536set_be32_bf(ovs_be32 *bf, uint8_t bits, uint8_t offset, uint32_t value)
4537{
4538 const uint32_t mask = ((1U << bits) - 1) << offset;
c6bcb685 4539
2d18eae8
JR
4540 if (value >> bits) {
4541 return false;
c6bcb685
JS
4542 }
4543
2d18eae8
JR
4544 *bf = htonl((ntohl(*bf) & ~mask) | (value << offset));
4545 return true;
4546}
3bffc610 4547
2d18eae8
JR
4548static int
4549scan_be32_bf(const char *s, ovs_be32 *key, ovs_be32 *mask, uint8_t bits,
4550 uint8_t offset)
4551{
4552 uint32_t key_, mask_;
4553 int n;
3bffc610 4554
2d18eae8
JR
4555 if (ovs_scan(s, "%"SCNi32"%n", &key_, &n)) {
4556 int len = n;
e6cc0bab 4557
2d18eae8 4558 if (set_be32_bf(key, bits, offset, key_)) {
e6cc0bab 4559 if (mask) {
2d18eae8
JR
4560 if (ovs_scan(s + len, "/%"SCNi32"%n", &mask_, &n)) {
4561 len += n;
3bffc610 4562
2d18eae8
JR
4563 if (!set_be32_bf(mask, bits, offset, mask_)) {
4564 return 0;
4565 }
4566 } else {
4567 *mask |= htonl(((1U << bits) - 1) << offset);
4568 }
e6cc0bab 4569 }
2d18eae8 4570 return len;
3bffc610
BP
4571 }
4572 }
2d18eae8
JR
4573 return 0;
4574}
3bffc610 4575
2d18eae8
JR
4576static int
4577scan_mpls_label(const char *s, ovs_be32 *key, ovs_be32 *mask)
4578{
4579 return scan_be32_bf(s, key, mask, 20, MPLS_LABEL_SHIFT);
4580}
3bffc610 4581
2d18eae8
JR
4582static int
4583scan_mpls_tc(const char *s, ovs_be32 *key, ovs_be32 *mask)
4584{
4585 return scan_be32_bf(s, key, mask, 3, MPLS_TC_SHIFT);
4586}
e6cc0bab 4587
2d18eae8
JR
4588static int
4589scan_mpls_ttl(const char *s, ovs_be32 *key, ovs_be32 *mask)
4590{
4591 return scan_be32_bf(s, key, mask, 8, MPLS_TTL_SHIFT);
4592}
e6cc0bab 4593
2d18eae8
JR
4594static int
4595scan_mpls_bos(const char *s, ovs_be32 *key, ovs_be32 *mask)
4596{
4597 return scan_be32_bf(s, key, mask, 1, MPLS_BOS_SHIFT);
4598}
4599
65da723b
JG
4600static int
4601scan_vxlan_gbp(const char *s, uint32_t *key, uint32_t *mask)
4602{
4603 const char *s_base = s;
3139b8e9
JR
4604 ovs_be16 id = 0, id_mask = 0;
4605 uint8_t flags = 0, flags_mask = 0;
65da723b
JG
4606
4607 if (!strncmp(s, "id=", 3)) {
4608 s += 3;
4609 s += scan_be16(s, &id, mask ? &id_mask : NULL);
65da723b
JG
4610 }
4611
4612 if (s[0] == ',') {
4613 s++;
4614 }
4615 if (!strncmp(s, "flags=", 6)) {
4616 s += 6;
4617 s += scan_u8(s, &flags, mask ? &flags_mask : NULL);
65da723b
JG
4618 }
4619
4620 if (!strncmp(s, "))", 2)) {
4621 s += 2;
4622
4623 *key = (flags << 16) | ntohs(id);
4624 if (mask) {
4625 *mask = (flags_mask << 16) | ntohs(id_mask);
4626 }
4627
4628 return s - s_base;
4629 }
4630
4631 return 0;
4632}
4633
622a0a8e
JG
4634static int
4635scan_geneve(const char *s, struct geneve_scan *key, struct geneve_scan *mask)
4636{
4637 const char *s_base = s;
c05c01cd
JG
4638 struct geneve_opt *opt = key->d;
4639 struct geneve_opt *opt_mask = mask ? mask->d : NULL;
622a0a8e
JG
4640 int len_remain = sizeof key->d;
4641
4642 while (s[0] == '{' && len_remain >= sizeof *opt) {
4643 int data_len = 0;
4644
4645 s++;
4646 len_remain -= sizeof *opt;
4647
4648 if (!strncmp(s, "class=", 6)) {
4649 s += 6;
4650 s += scan_be16(s, &opt->opt_class,
4651 mask ? &opt_mask->opt_class : NULL);
4652 } else if (mask) {
4653 memset(&opt_mask->opt_class, 0, sizeof opt_mask->opt_class);
4654 }
4655
4656 if (s[0] == ',') {
4657 s++;
4658 }
4659 if (!strncmp(s, "type=", 5)) {
4660 s += 5;
4661 s += scan_u8(s, &opt->type, mask ? &opt_mask->type : NULL);
4662 } else if (mask) {
4663 memset(&opt_mask->type, 0, sizeof opt_mask->type);
4664 }
4665
4666 if (s[0] == ',') {
4667 s++;
4668 }
4669 if (!strncmp(s, "len=", 4)) {
4670 uint8_t opt_len, opt_len_mask;
4671 s += 4;
4672 s += scan_u8(s, &opt_len, mask ? &opt_len_mask : NULL);
4673
4674 if (opt_len > 124 || opt_len % 4 || opt_len > len_remain) {
4675 return 0;
4676 }
4677 opt->length = opt_len / 4;
4678 if (mask) {
4679 opt_mask->length = opt_len_mask;
4680 }
4681 data_len = opt_len;
4682 } else if (mask) {
4683 memset(&opt_mask->type, 0, sizeof opt_mask->type);
4684 }
4685
4686 if (s[0] == ',') {
4687 s++;
4688 }
4689 if (parse_int_string(s, (uint8_t *)(opt + 1), data_len, (char **)&s)) {
4690 return 0;
4691 }
4692
4693 if (mask) {
4694 if (s[0] == '/') {
4695 s++;
4696 if (parse_int_string(s, (uint8_t *)(opt_mask + 1),
4697 data_len, (char **)&s)) {
4698 return 0;
4699 }
4700 }
4701 opt_mask->r1 = 0;
4702 opt_mask->r2 = 0;
4703 opt_mask->r3 = 0;
4704 }
4705
4706 if (s[0] == '}') {
4707 s++;
4708 opt += 1 + data_len / 4;
4709 if (mask) {
4710 opt_mask += 1 + data_len / 4;
4711 }
4712 len_remain -= data_len;
4713 }
4714 }
4715
4716 if (s[0] == ')') {
4717 int len = sizeof key->d - len_remain;
4718
4719 s++;
4720 key->len = len;
4721 if (mask) {
4722 mask->len = len;
4723 }
4724 return s - s_base;
4725 }
4726
4727 return 0;
4728}
4729
65da723b
JG
4730static void
4731tun_flags_to_attr(struct ofpbuf *a, const void *data_)
4732{
4733 const uint16_t *flags = data_;
4734
4735 if (*flags & FLOW_TNL_F_DONT_FRAGMENT) {
4736 nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT);
4737 }
4738 if (*flags & FLOW_TNL_F_CSUM) {
4739 nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_CSUM);
4740 }
4741 if (*flags & FLOW_TNL_F_OAM) {
4742 nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_OAM);
4743 }
4744}
4745
4746static void
4747vxlan_gbp_to_attr(struct ofpbuf *a, const void *data_)
4748{
4749 const uint32_t *gbp = data_;
4750
4751 if (*gbp) {
4752 size_t vxlan_opts_ofs;
4753
4754 vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
4755 nl_msg_put_u32(a, OVS_VXLAN_EXT_GBP, *gbp);
4756 nl_msg_end_nested(a, vxlan_opts_ofs);
4757 }
4758}
4759
622a0a8e
JG
4760static void
4761geneve_to_attr(struct ofpbuf *a, const void *data_)
4762{
4763 const struct geneve_scan *geneve = data_;
4764
4765 nl_msg_put_unspec(a, OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS, geneve->d,
4766 geneve->len);
4767}
4768
65da723b
JG
4769#define SCAN_PUT_ATTR(BUF, ATTR, DATA, FUNC) \
4770 { \
4771 unsigned long call_fn = (unsigned long)FUNC; \
4772 if (call_fn) { \
4773 typedef void (*fn)(struct ofpbuf *, const void *); \
4774 fn func = FUNC; \
4775 func(BUF, &(DATA)); \
4776 } else { \
4777 nl_msg_put_unspec(BUF, ATTR, &(DATA), sizeof (DATA)); \
4778 } \
2d18eae8
JR
4779 }
4780
4781#define SCAN_IF(NAME) \
4782 if (strncmp(s, NAME, strlen(NAME)) == 0) { \
4783 const char *start = s; \
4784 int len; \
4785 \
4786 s += strlen(NAME)
4787
4788/* Usually no special initialization is needed. */
4789#define SCAN_BEGIN(NAME, TYPE) \
4790 SCAN_IF(NAME); \
4791 TYPE skey, smask; \
4792 memset(&skey, 0, sizeof skey); \
4793 memset(&smask, 0, sizeof smask); \
4794 do { \
4795 len = 0;
4796
657ac953
JR
4797/* Init as fully-masked as mask will not be scanned. */
4798#define SCAN_BEGIN_FULLY_MASKED(NAME, TYPE) \
4799 SCAN_IF(NAME); \
4800 TYPE skey, smask; \
4801 memset(&skey, 0, sizeof skey); \
4802 memset(&smask, 0xff, sizeof smask); \
4803 do { \
4804 len = 0;
4805
2d18eae8
JR
4806/* VLAN needs special initialization. */
4807#define SCAN_BEGIN_INIT(NAME, TYPE, KEY_INIT, MASK_INIT) \
4808 SCAN_IF(NAME); \
4809 TYPE skey = KEY_INIT; \
4810 TYPE smask = MASK_INIT; \
4811 do { \
4812 len = 0;
4813
4814/* Scan unnamed entry as 'TYPE' */
4815#define SCAN_TYPE(TYPE, KEY, MASK) \
4816 len = scan_##TYPE(s, KEY, MASK); \
4817 if (len == 0) { \
4818 return -EINVAL; \
4819 } \
4820 s += len
4821
4822/* Scan named ('NAME') entry 'FIELD' as 'TYPE'. */
4823#define SCAN_FIELD(NAME, TYPE, FIELD) \
4824 if (strncmp(s, NAME, strlen(NAME)) == 0) { \
4825 s += strlen(NAME); \
4826 SCAN_TYPE(TYPE, &skey.FIELD, mask ? &smask.FIELD : NULL); \
4827 continue; \
4828 }
4829
4830#define SCAN_FINISH() \
4831 } while (*s++ == ',' && len != 0); \
4832 if (s[-1] != ')') { \
4833 return -EINVAL; \
4834 }
4835
4836#define SCAN_FINISH_SINGLE() \
4837 } while (false); \
4838 if (*s++ != ')') { \
4839 return -EINVAL; \
4840 }
4841
65da723b
JG
4842/* Beginning of nested attribute. */
4843#define SCAN_BEGIN_NESTED(NAME, ATTR) \
4844 SCAN_IF(NAME); \
4845 size_t key_offset, mask_offset; \
4846 key_offset = nl_msg_start_nested(key, ATTR); \
4847 if (mask) { \
4848 mask_offset = nl_msg_start_nested(mask, ATTR); \
4849 } \
4850 do { \
4851 len = 0;
4852
4853#define SCAN_END_NESTED() \
4854 SCAN_FINISH(); \
4855 nl_msg_end_nested(key, key_offset); \
4856 if (mask) { \
4857 nl_msg_end_nested(mask, mask_offset); \
4858 } \
4859 return s - start; \
4860 }
4861
4862#define SCAN_FIELD_NESTED__(NAME, TYPE, SCAN_AS, ATTR, FUNC) \
4863 if (strncmp(s, NAME, strlen(NAME)) == 0) { \
4864 TYPE skey, smask; \
4865 memset(&skey, 0, sizeof skey); \
4866 memset(&smask, 0xff, sizeof smask); \
4867 s += strlen(NAME); \
4868 SCAN_TYPE(SCAN_AS, &skey, &smask); \
4869 SCAN_PUT(ATTR, FUNC); \
4870 continue; \
4871 }
4872
4873#define SCAN_FIELD_NESTED(NAME, TYPE, SCAN_AS, ATTR) \
4874 SCAN_FIELD_NESTED__(NAME, TYPE, SCAN_AS, ATTR, NULL)
4875
4876#define SCAN_FIELD_NESTED_FUNC(NAME, TYPE, SCAN_AS, FUNC) \
4877 SCAN_FIELD_NESTED__(NAME, TYPE, SCAN_AS, 0, FUNC)
4878
4879#define SCAN_PUT(ATTR, FUNC) \
00ec4017
HE
4880 SCAN_PUT_ATTR(key, ATTR, skey, FUNC); \
4881 if (mask) \
4882 SCAN_PUT_ATTR(mask, ATTR, smask, FUNC); \
2d18eae8
JR
4883
4884#define SCAN_END(ATTR) \
4885 SCAN_FINISH(); \
65da723b 4886 SCAN_PUT(ATTR, NULL); \
2d18eae8
JR
4887 return s - start; \
4888 }
4889
8f79bb4d
JR
4890#define SCAN_BEGIN_ARRAY(NAME, TYPE, CNT) \
4891 SCAN_IF(NAME); \
4892 TYPE skey[CNT], smask[CNT]; \
4893 memset(&skey, 0, sizeof skey); \
4894 memset(&smask, 0, sizeof smask); \
4895 int idx = 0, cnt = CNT; \
4896 uint64_t fields = 0; \
4897 do { \
4898 int field = 0; \
4899 len = 0;
4900
4901/* Scan named ('NAME') entry 'FIELD' as 'TYPE'. */
4902#define SCAN_FIELD_ARRAY(NAME, TYPE, FIELD) \
4903 if (strncmp(s, NAME, strlen(NAME)) == 0) { \
4904 if (fields & (1UL << field)) { \
4905 fields = 0; \
4906 if (++idx == cnt) { \
4907 break; \
4908 } \
4909 } \
4910 s += strlen(NAME); \
4911 SCAN_TYPE(TYPE, &skey[idx].FIELD, mask ? &smask[idx].FIELD : NULL); \
4912 fields |= 1UL << field; \
4913 continue; \
4914 } \
4915 field++;
4916
4917#define SCAN_PUT_ATTR_ARRAY(BUF, ATTR, DATA, CNT) \
4918 nl_msg_put_unspec(BUF, ATTR, &(DATA), sizeof (DATA)[0] * (CNT)); \
4919
4920#define SCAN_PUT_ARRAY(ATTR, CNT) \
4921 SCAN_PUT_ATTR_ARRAY(key, ATTR, skey, CNT); \
4922 if (mask) { \
4923 SCAN_PUT_ATTR_ARRAY(mask, ATTR, smask, CNT); \
4924 }
4925
4926#define SCAN_END_ARRAY(ATTR) \
4927 SCAN_FINISH(); \
4928 if (idx == cnt) { \
4929 return -EINVAL; \
4930 } \
4931 SCAN_PUT_ARRAY(ATTR, idx + 1); \
4932 return s - start; \
4933 }
4934
2d18eae8
JR
4935#define SCAN_END_SINGLE(ATTR) \
4936 SCAN_FINISH_SINGLE(); \
65da723b 4937 SCAN_PUT(ATTR, NULL); \
2d18eae8
JR
4938 return s - start; \
4939 }
4940
4941#define SCAN_SINGLE(NAME, TYPE, SCAN_AS, ATTR) \
4942 SCAN_BEGIN(NAME, TYPE) { \
4943 SCAN_TYPE(SCAN_AS, &skey, &smask); \
4944 } SCAN_END_SINGLE(ATTR)
4945
657ac953
JR
4946#define SCAN_SINGLE_FULLY_MASKED(NAME, TYPE, SCAN_AS, ATTR) \
4947 SCAN_BEGIN_FULLY_MASKED(NAME, TYPE) { \
4948 SCAN_TYPE(SCAN_AS, &skey, NULL); \
2d18eae8
JR
4949 } SCAN_END_SINGLE(ATTR)
4950
4951/* scan_port needs one extra argument. */
4952#define SCAN_SINGLE_PORT(NAME, TYPE, ATTR) \
4953 SCAN_BEGIN(NAME, TYPE) { \
4954 len = scan_port(s, &skey, &smask, port_names); \
4955 if (len == 0) { \
4956 return -EINVAL; \
4957 } \
4958 s += len; \
4959 } SCAN_END_SINGLE(ATTR)
3bffc610 4960
f59cb331
YY
4961static int
4962parse_odp_nsh_key_mask_attr(const char *s, struct ofpbuf *key,
4963 struct ofpbuf *mask)
4964{
4965 if (strncmp(s, "nsh(", 4) == 0) {
4966 const char *start = s;
4967 int len;
17553f27
YY
4968 struct ovs_key_nsh skey, smask;
4969 uint32_t spi = 0, spi_mask = 0;
4970 uint8_t si = 0, si_mask = 0;
f59cb331
YY
4971
4972 s += 4;
4973
4974 memset(&skey, 0, sizeof skey);
4975 memset(&smask, 0, sizeof smask);
4976 do {
4977 len = 0;
4978
4979 if (strncmp(s, "flags=", 6) == 0) {
4980 s += 6;
4981 len = scan_u8(s, &skey.flags, mask ? &smask.flags : NULL);
4982 if (len == 0) {
4983 return -EINVAL;
4984 }
4985 s += len;
4986 continue;
4987 }
4988
4989 if (strncmp(s, "mdtype=", 7) == 0) {
4990 s += 7;
4991 len = scan_u8(s, &skey.mdtype, mask ? &smask.mdtype : NULL);
4992 if (len == 0) {
4993 return -EINVAL;
4994 }
4995 s += len;
4996 continue;
4997 }
4998
4999 if (strncmp(s, "np=", 3) == 0) {
5000 s += 3;
5001 len = scan_u8(s, &skey.np, mask ? &smask.np : NULL);
5002 if (len == 0) {
5003 return -EINVAL;
5004 }
5005 s += len;
5006 continue;
5007 }
5008
5009 if (strncmp(s, "spi=", 4) == 0) {
5010 s += 4;
17553f27 5011 len = scan_u32(s, &spi, mask ? &spi_mask : NULL);
f59cb331
YY
5012 if (len == 0) {
5013 return -EINVAL;
5014 }
5015 s += len;
5016 continue;
5017 }
5018
5019 if (strncmp(s, "si=", 3) == 0) {
5020 s += 3;
17553f27 5021 len = scan_u8(s, &si, mask ? &si_mask : NULL);
f59cb331
YY
5022 if (len == 0) {
5023 return -EINVAL;
5024 }
5025 s += len;
5026 continue;
5027 }
5028
5029 if (strncmp(s, "c1=", 3) == 0) {
5030 s += 3;
5031 len = scan_be32(s, &skey.context[0],
5032 mask ? &smask.context[0] : NULL);
5033 if (len == 0) {
5034 return -EINVAL;
5035 }
5036 s += len;
5037 continue;
5038 }
5039
5040 if (strncmp(s, "c2=", 3) == 0) {
5041 s += 3;
5042 len = scan_be32(s, &skey.context[1],
5043 mask ? &smask.context[1] : NULL);
5044 if (len == 0) {
5045 return -EINVAL;
5046 }
5047 s += len;
5048 continue;
5049 }
5050
5051 if (strncmp(s, "c3=", 3) == 0) {
5052 s += 3;
5053 len = scan_be32(s, &skey.context[2],
5054 mask ? &smask.context[2] : NULL);
5055 if (len == 0) {
5056 return -EINVAL;
5057 }
5058 s += len;
5059 continue;
5060 }
5061
5062 if (strncmp(s, "c4=", 3) == 0) {
5063 s += 3;
5064 len = scan_be32(s, &skey.context[3],
5065 mask ? &smask.context[3] : NULL);
5066 if (len == 0) {
5067 return -EINVAL;
5068 }
5069 s += len;
5070 continue;
5071 }
5072 } while (*s++ == ',' && len != 0);
5073 if (s[-1] != ')') {
5074 return -EINVAL;
5075 }
5076
17553f27
YY
5077 skey.path_hdr = nsh_spi_si_to_path_hdr(spi, si);
5078 smask.path_hdr = nsh_spi_si_to_path_hdr(spi_mask, si_mask);
5079
f59cb331
YY
5080 nsh_key_to_attr(key, &skey, NULL, 0, false);
5081 if (mask) {
5082 nsh_key_to_attr(mask, &smask, NULL, 0, true);
5083 }
5084 return s - start;
5085 }
5086 return 0;
5087}
5088
2d18eae8
JR
5089static int
5090parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
5091 struct ofpbuf *key, struct ofpbuf *mask)
5092{
10e92b4f 5093 /* Skip UFID. */
71f21279
BP
5094 ovs_u128 ufid;
5095 int ufid_len = odp_ufid_from_string(s, &ufid);
5096 if (ufid_len) {
5097 return ufid_len;
eb731b76
JS
5098 }
5099
2d18eae8
JR
5100 SCAN_SINGLE("skb_priority(", uint32_t, u32, OVS_KEY_ATTR_PRIORITY);
5101 SCAN_SINGLE("skb_mark(", uint32_t, u32, OVS_KEY_ATTR_SKB_MARK);
657ac953
JR
5102 SCAN_SINGLE_FULLY_MASKED("recirc_id(", uint32_t, u32,
5103 OVS_KEY_ATTR_RECIRC_ID);
2d18eae8
JR
5104 SCAN_SINGLE("dp_hash(", uint32_t, u32, OVS_KEY_ATTR_DP_HASH);
5105
07659514
JS
5106 SCAN_SINGLE("ct_state(", uint32_t, ct_state, OVS_KEY_ATTR_CT_STATE);
5107 SCAN_SINGLE("ct_zone(", uint16_t, u16, OVS_KEY_ATTR_CT_ZONE);
8e53fe8c 5108 SCAN_SINGLE("ct_mark(", uint32_t, u32, OVS_KEY_ATTR_CT_MARK);
9daf2348 5109 SCAN_SINGLE("ct_label(", ovs_u128, u128, OVS_KEY_ATTR_CT_LABELS);
07659514 5110
daf4d3c1
JR
5111 SCAN_BEGIN("ct_tuple4(", struct ovs_key_ct_tuple_ipv4) {
5112 SCAN_FIELD("src=", ipv4, ipv4_src);
5113 SCAN_FIELD("dst=", ipv4, ipv4_dst);
5114 SCAN_FIELD("proto=", u8, ipv4_proto);
5115 SCAN_FIELD("tp_src=", be16, src_port);
5116 SCAN_FIELD("tp_dst=", be16, dst_port);
5117 } SCAN_END(OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4);
5118
5119 SCAN_BEGIN("ct_tuple6(", struct ovs_key_ct_tuple_ipv6) {
5120 SCAN_FIELD("src=", in6_addr, ipv6_src);
5121 SCAN_FIELD("dst=", in6_addr, ipv6_dst);
5122 SCAN_FIELD("proto=", u8, ipv6_proto);
5123 SCAN_FIELD("tp_src=", be16, src_port);
5124 SCAN_FIELD("tp_dst=", be16, dst_port);
5125 } SCAN_END(OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6);
5126
65da723b
JG
5127 SCAN_BEGIN_NESTED("tunnel(", OVS_KEY_ATTR_TUNNEL) {
5128 SCAN_FIELD_NESTED("tun_id=", ovs_be64, be64, OVS_TUNNEL_KEY_ATTR_ID);
5129 SCAN_FIELD_NESTED("src=", ovs_be32, ipv4, OVS_TUNNEL_KEY_ATTR_IPV4_SRC);
5130 SCAN_FIELD_NESTED("dst=", ovs_be32, ipv4, OVS_TUNNEL_KEY_ATTR_IPV4_DST);
ffe4c74f
JB
5131 SCAN_FIELD_NESTED("ipv6_src=", struct in6_addr, in6_addr, OVS_TUNNEL_KEY_ATTR_IPV6_SRC);
5132 SCAN_FIELD_NESTED("ipv6_dst=", struct in6_addr, in6_addr, OVS_TUNNEL_KEY_ATTR_IPV6_DST);
65da723b
JG
5133 SCAN_FIELD_NESTED("tos=", uint8_t, u8, OVS_TUNNEL_KEY_ATTR_TOS);
5134 SCAN_FIELD_NESTED("ttl=", uint8_t, u8, OVS_TUNNEL_KEY_ATTR_TTL);
5135 SCAN_FIELD_NESTED("tp_src=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_SRC);
5136 SCAN_FIELD_NESTED("tp_dst=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_DST);
5137 SCAN_FIELD_NESTED_FUNC("vxlan(gbp(", uint32_t, vxlan_gbp, vxlan_gbp_to_attr);
622a0a8e
JG
5138 SCAN_FIELD_NESTED_FUNC("geneve(", struct geneve_scan, geneve,
5139 geneve_to_attr);
65da723b
JG
5140 SCAN_FIELD_NESTED_FUNC("flags(", uint16_t, tun_flags, tun_flags_to_attr);
5141 } SCAN_END_NESTED();
2d18eae8
JR
5142
5143 SCAN_SINGLE_PORT("in_port(", uint32_t, OVS_KEY_ATTR_IN_PORT);
5144
5145 SCAN_BEGIN("eth(", struct ovs_key_ethernet) {
5146 SCAN_FIELD("src=", eth, eth_src);
5147 SCAN_FIELD("dst=", eth, eth_dst);
5148 } SCAN_END(OVS_KEY_ATTR_ETHERNET);
5149
5150 SCAN_BEGIN_INIT("vlan(", struct ovs_key_vlan__,
5151 { htons(VLAN_CFI) }, { htons(VLAN_CFI) }) {
5152 SCAN_FIELD("vid=", vid, tci);
5153 SCAN_FIELD("pcp=", pcp, tci);
5154 SCAN_FIELD("cfi=", cfi, tci);
5155 } SCAN_END(OVS_KEY_ATTR_VLAN);
5156
5157 SCAN_SINGLE("eth_type(", ovs_be16, be16, OVS_KEY_ATTR_ETHERTYPE);
5158
ab83c8c5 5159 SCAN_BEGIN_ARRAY("mpls(", struct ovs_key_mpls, FLOW_MAX_MPLS_LABELS) {
8f79bb4d
JR
5160 SCAN_FIELD_ARRAY("label=", mpls_label, mpls_lse);
5161 SCAN_FIELD_ARRAY("tc=", mpls_tc, mpls_lse);
5162 SCAN_FIELD_ARRAY("ttl=", mpls_ttl, mpls_lse);
5163 SCAN_FIELD_ARRAY("bos=", mpls_bos, mpls_lse);
5164 } SCAN_END_ARRAY(OVS_KEY_ATTR_MPLS);
2d18eae8
JR
5165
5166 SCAN_BEGIN("ipv4(", struct ovs_key_ipv4) {
5167 SCAN_FIELD("src=", ipv4, ipv4_src);
5168 SCAN_FIELD("dst=", ipv4, ipv4_dst);
5169 SCAN_FIELD("proto=", u8, ipv4_proto);
5170 SCAN_FIELD("tos=", u8, ipv4_tos);
5171 SCAN_FIELD("ttl=", u8, ipv4_ttl);
5172 SCAN_FIELD("frag=", frag, ipv4_frag);
5173 } SCAN_END(OVS_KEY_ATTR_IPV4);
5174
5175 SCAN_BEGIN("ipv6(", struct ovs_key_ipv6) {
932c96b7
JR
5176 SCAN_FIELD("src=", in6_addr, ipv6_src);
5177 SCAN_FIELD("dst=", in6_addr, ipv6_dst);
2d18eae8
JR
5178 SCAN_FIELD("label=", ipv6_label, ipv6_label);
5179 SCAN_FIELD("proto=", u8, ipv6_proto);
5180 SCAN_FIELD("tclass=", u8, ipv6_tclass);
5181 SCAN_FIELD("hlimit=", u8, ipv6_hlimit);
5182 SCAN_FIELD("frag=", frag, ipv6_frag);
5183 } SCAN_END(OVS_KEY_ATTR_IPV6);
5184
5185 SCAN_BEGIN("tcp(", struct ovs_key_tcp) {
5186 SCAN_FIELD("src=", be16, tcp_src);
5187 SCAN_FIELD("dst=", be16, tcp_dst);
5188 } SCAN_END(OVS_KEY_ATTR_TCP);
5189
5190 SCAN_SINGLE("tcp_flags(", ovs_be16, tcp_flags, OVS_KEY_ATTR_TCP_FLAGS);
5191
5192 SCAN_BEGIN("udp(", struct ovs_key_udp) {
5193 SCAN_FIELD("src=", be16, udp_src);
5194 SCAN_FIELD("dst=", be16, udp_dst);
5195 } SCAN_END(OVS_KEY_ATTR_UDP);
5196
5197 SCAN_BEGIN("sctp(", struct ovs_key_sctp) {
5198 SCAN_FIELD("src=", be16, sctp_src);
5199 SCAN_FIELD("dst=", be16, sctp_dst);
5200 } SCAN_END(OVS_KEY_ATTR_SCTP);
5201
5202 SCAN_BEGIN("icmp(", struct ovs_key_icmp) {
5203 SCAN_FIELD("type=", u8, icmp_type);
5204 SCAN_FIELD("code=", u8, icmp_code);
5205 } SCAN_END(OVS_KEY_ATTR_ICMP);
5206
5207 SCAN_BEGIN("icmpv6(", struct ovs_key_icmpv6) {
5208 SCAN_FIELD("type=", u8, icmpv6_type);
5209 SCAN_FIELD("code=", u8, icmpv6_code);
5210 } SCAN_END(OVS_KEY_ATTR_ICMPV6);
5211
5212 SCAN_BEGIN("arp(", struct ovs_key_arp) {
5213 SCAN_FIELD("sip=", ipv4, arp_sip);
5214 SCAN_FIELD("tip=", ipv4, arp_tip);
5215 SCAN_FIELD("op=", be16, arp_op);
5216 SCAN_FIELD("sha=", eth, arp_sha);
5217 SCAN_FIELD("tha=", eth, arp_tha);
5218 } SCAN_END(OVS_KEY_ATTR_ARP);
5219
5220 SCAN_BEGIN("nd(", struct ovs_key_nd) {
932c96b7 5221 SCAN_FIELD("target=", in6_addr, nd_target);
2d18eae8
JR
5222 SCAN_FIELD("sll=", eth, nd_sll);
5223 SCAN_FIELD("tll=", eth, nd_tll);
5224 } SCAN_END(OVS_KEY_ATTR_ND);
5225
3d4b2e6e
JS
5226 struct packet_type {
5227 ovs_be16 ns;
5228 ovs_be16 id;
5229 };
5230 SCAN_BEGIN("packet_type(", struct packet_type) {
5231 SCAN_FIELD("ns=", be16, ns);
5232 SCAN_FIELD("id=", be16, id);
5233 } SCAN_END(OVS_KEY_ATTR_PACKET_TYPE);
5234
f59cb331
YY
5235 /* nsh is nested, it needs special process */
5236 int ret = parse_odp_nsh_key_mask_attr(s, key, mask);
5237 if (ret < 0) {
5238 return ret;
5239 } else {
5240 s += ret;
5241 }
3d2fbd70 5242
2d18eae8 5243 /* Encap open-coded. */
fea393b1
BP
5244 if (!strncmp(s, "encap(", 6)) {
5245 const char *start = s;
e6cc0bab 5246 size_t encap, encap_mask = 0;
fea393b1
BP
5247
5248 encap = nl_msg_start_nested(key, OVS_KEY_ATTR_ENCAP);
e6cc0bab
AZ
5249 if (mask) {
5250 encap_mask = nl_msg_start_nested(mask, OVS_KEY_ATTR_ENCAP);
5251 }
fea393b1
BP
5252
5253 s += 6;
5254 for (;;) {
5255 int retval;
5256
70fbe375 5257 s += strspn(s, delimiters);
fea393b1
BP
5258 if (!*s) {
5259 return -EINVAL;
5260 } else if (*s == ')') {
5261 break;
5262 }
5263
e6cc0bab 5264 retval = parse_odp_key_mask_attr(s, port_names, key, mask);
fea393b1
BP
5265 if (retval < 0) {
5266 return retval;
5267 }
5268 s += retval;
5269 }
5270 s++;
5271
5272 nl_msg_end_nested(key, encap);
e6cc0bab
AZ
5273 if (mask) {
5274 nl_msg_end_nested(mask, encap_mask);
5275 }
fea393b1
BP
5276
5277 return s - start;
5278 }
5279
3bffc610
BP
5280 return -EINVAL;
5281}
5282
df2c07f4
JP
5283/* Parses the string representation of a datapath flow key, in the
5284 * format output by odp_flow_key_format(). Returns 0 if successful,
5285 * otherwise a positive errno value. On success, the flow key is
5286 * appended to 'key' as a series of Netlink attributes. On failure, no
5287 * data is appended to 'key'. Either way, 'key''s data might be
5288 * reallocated.
3bffc610 5289 *
44bac24b
BP
5290 * If 'port_names' is nonnull, it points to an simap that maps from a port name
5291 * to a port number. (Port names may be used instead of port numbers in
5292 * in_port.)
b2a60db8 5293 *
3bffc610
BP
5294 * On success, the attributes appended to 'key' are individually syntactically
5295 * valid, but they may not be valid as a sequence. 'key' might, for example,
34118cae 5296 * have duplicated keys. odp_flow_key_to_flow() will detect those errors. */
3bffc610 5297int
e6cc0bab
AZ
5298odp_flow_from_string(const char *s, const struct simap *port_names,
5299 struct ofpbuf *key, struct ofpbuf *mask)
3bffc610 5300{
6fd6ed71 5301 const size_t old_size = key->size;
3bffc610
BP
5302 for (;;) {
5303 int retval;
5304
7202cbe5 5305 s += strspn(s, delimiters);
3bffc610
BP
5306 if (!*s) {
5307 return 0;
5308 }
5309
e6cc0bab 5310 retval = parse_odp_key_mask_attr(s, port_names, key, mask);
3bffc610 5311 if (retval < 0) {
6fd6ed71 5312 key->size = old_size;
3bffc610
BP
5313 return -retval;
5314 }
5315 s += retval;
5316 }
5317
5318 return 0;
5319}
5320
7257b535 5321static uint8_t
3cea18ec 5322ovs_to_odp_frag(uint8_t nw_frag, bool is_mask)
7257b535 5323{
3cea18ec
JR
5324 if (is_mask) {
5325 /* Netlink interface 'enum ovs_frag_type' is an 8-bit enumeration type,
5326 * not a set of flags or bitfields. Hence, if the struct flow nw_frag
5327 * mask, which is a set of bits, has the FLOW_NW_FRAG_ANY as zero, we
5328 * must use a zero mask for the netlink frag field, and all ones mask
5329 * otherwise. */
5330 return (nw_frag & FLOW_NW_FRAG_ANY) ? UINT8_MAX : 0;
5331 }
2c0f0be1
JR
5332 return !(nw_frag & FLOW_NW_FRAG_ANY) ? OVS_FRAG_TYPE_NONE
5333 : nw_frag & FLOW_NW_FRAG_LATER ? OVS_FRAG_TYPE_LATER
5334 : OVS_FRAG_TYPE_FIRST;
7257b535
BP
5335}
5336
3cea18ec
JR
5337static void get_ethernet_key(const struct flow *, struct ovs_key_ethernet *);
5338static void put_ethernet_key(const struct ovs_key_ethernet *, struct flow *);
5339static void get_ipv4_key(const struct flow *, struct ovs_key_ipv4 *,
5340 bool is_mask);
5341static void put_ipv4_key(const struct ovs_key_ipv4 *, struct flow *,
5342 bool is_mask);
5343static void get_ipv6_key(const struct flow *, struct ovs_key_ipv6 *,
5344 bool is_mask);
5345static void put_ipv6_key(const struct ovs_key_ipv6 *, struct flow *,
5346 bool is_mask);
5347static void get_arp_key(const struct flow *, struct ovs_key_arp *);
5348static void put_arp_key(const struct ovs_key_arp *, struct flow *);
e60e935b
SRCSA
5349static void get_nd_key(const struct flow *, struct ovs_key_nd *);
5350static void put_nd_key(const struct ovs_key_nd *, struct flow *);
3d2fbd70
JS
5351static void get_nsh_key(const struct flow *flow, struct ovs_key_nsh *nsh,
5352 bool is_mask);
5353static void put_nsh_key(const struct ovs_key_nsh *nsh, struct flow *flow,
5354 bool is_mask);
3cea18ec
JR
5355
5356/* These share the same layout. */
5357union ovs_key_tp {
5358 struct ovs_key_tcp tcp;
5359 struct ovs_key_udp udp;
5360 struct ovs_key_sctp sctp;
5361};
5362
5363static void get_tp_key(const struct flow *, union ovs_key_tp *);
5364static void put_tp_key(const union ovs_key_tp *, struct flow *);
431495b1 5365
661cbcd5 5366static void
5262eea1
JG
5367odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms,
5368 bool export_mask, struct ofpbuf *buf)
14608a15 5369{
df2c07f4 5370 struct ovs_key_ethernet *eth_key;
f0fb825a
EG
5371 size_t encap[FLOW_MAX_VLAN_HEADERS] = {0};
5372 size_t max_vlans;
5262eea1 5373 const struct flow *flow = parms->flow;
beb75a40
JS
5374 const struct flow *mask = parms->mask;
5375 const struct flow *data = export_mask ? mask : flow;
661cbcd5 5376
54bb0348 5377 nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, data->skb_priority);
abff858b 5378
ffe4c74f 5379 if (flow_tnl_dst_is_set(&flow->tunnel) || export_mask) {
ec1f6f32
JG
5380 tun_key_to_attr(buf, &data->tunnel, &parms->flow->tunnel,
5381 parms->key_buf);
36956a7d
BP
5382 }
5383
1362e248 5384 nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->pkt_mark);
72e8bf28 5385
07659514
JS
5386 if (parms->support.ct_state) {
5387 nl_msg_put_u32(buf, OVS_KEY_ATTR_CT_STATE,
5388 ovs_to_odp_ct_state(data->ct_state));
5389 }
5390 if (parms->support.ct_zone) {
5391 nl_msg_put_u16(buf, OVS_KEY_ATTR_CT_ZONE, data->ct_zone);
5392 }
8e53fe8c
JS
5393 if (parms->support.ct_mark) {
5394 nl_msg_put_u32(buf, OVS_KEY_ATTR_CT_MARK, data->ct_mark);
5395 }
9daf2348
JS
5396 if (parms->support.ct_label) {
5397 nl_msg_put_unspec(buf, OVS_KEY_ATTR_CT_LABELS, &data->ct_label,
5398 sizeof(data->ct_label));
5399 }
7b5bbe5d
JS
5400 if (flow->ct_nw_proto) {
5401 if (parms->support.ct_orig_tuple
5402 && flow->dl_type == htons(ETH_TYPE_IP)) {
daf4d3c1
JR
5403 struct ovs_key_ct_tuple_ipv4 ct = {
5404 data->ct_nw_src,
5405 data->ct_nw_dst,
5406 data->ct_tp_src,
5407 data->ct_tp_dst,
5408 data->ct_nw_proto,
5409 };
5410 nl_msg_put_unspec(buf, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, &ct,
5411 sizeof ct);
7b5bbe5d
JS
5412 } else if (parms->support.ct_orig_tuple6
5413 && flow->dl_type == htons(ETH_TYPE_IPV6)) {
daf4d3c1
JR
5414 struct ovs_key_ct_tuple_ipv6 ct = {
5415 data->ct_ipv6_src,
5416 data->ct_ipv6_dst,
5417 data->ct_tp_src,
5418 data->ct_tp_dst,
5419 data->ct_nw_proto,
5420 };
5421 nl_msg_put_unspec(buf, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, &ct,
5422 sizeof ct);
5423 }
5424 }
2494ccd7 5425 if (parms->support.recirc) {
572f732a 5426 nl_msg_put_u32(buf, OVS_KEY_ATTR_RECIRC_ID, data->recirc_id);
572f732a
AZ
5427 nl_msg_put_u32(buf, OVS_KEY_ATTR_DP_HASH, data->dp_hash);
5428 }
5429
098d2a97 5430 /* Add an ingress port attribute if this is a mask or 'in_port.odp_port'
661cbcd5 5431 * is not the magical value "ODPP_NONE". */
098d2a97
JG
5432 if (export_mask || flow->in_port.odp_port != ODPP_NONE) {
5433 nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, data->in_port.odp_port);
18886b60 5434 }
36956a7d 5435
3d4b2e6e 5436 nl_msg_put_be32(buf, OVS_KEY_ATTR_PACKET_TYPE, data->packet_type);
36956a7d 5437
f0fb825a
EG
5438 if (OVS_UNLIKELY(parms->probe)) {
5439 max_vlans = FLOW_MAX_VLAN_HEADERS;
5440 } else {
5441 max_vlans = MIN(parms->support.max_vlan_headers, flow_vlan_limit);
5442 }
f0fb825a 5443
beb75a40
JS
5444 /* Conditionally add L2 attributes for Ethernet packets */
5445 if (flow->packet_type == htonl(PT_ETH)) {
5446 eth_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ETHERNET,
5447 sizeof *eth_key);
5448 get_ethernet_key(data, eth_key);
5449
5450 for (int encaps = 0; encaps < max_vlans; encaps++) {
5451 ovs_be16 tpid = flow->vlans[encaps].tpid;
5452
5453 if (flow->vlans[encaps].tci == htons(0)) {
5454 if (eth_type_vlan(flow->dl_type)) {
5455 /* If VLAN was truncated the tpid is in dl_type */
5456 tpid = flow->dl_type;
5457 } else {
5458 break;
5459 }
f0fb825a 5460 }
f0fb825a 5461
beb75a40
JS
5462 if (export_mask) {
5463 nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, OVS_BE16_MAX);
5464 } else {
5465 nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, tpid);
5466 }
5467 nl_msg_put_be16(buf, OVS_KEY_ATTR_VLAN, data->vlans[encaps].tci);
5468 encap[encaps] = nl_msg_start_nested(buf, OVS_KEY_ATTR_ENCAP);
5469 if (flow->vlans[encaps].tci == htons(0)) {
5470 goto unencap;
5471 }
8ddc056d 5472 }
36956a7d
BP
5473 }
5474
5475 if (ntohs(flow->dl_type) < ETH_TYPE_MIN) {
661cbcd5
JP
5476 /* For backwards compatibility with kernels that don't support
5477 * wildcarding, the following convention is used to encode the
5478 * OVS_KEY_ATTR_ETHERTYPE for key and mask:
5479 *
5480 * key mask matches
5481 * -------- -------- -------
5482 * >0x5ff 0xffff Specified Ethernet II Ethertype.
5483 * >0x5ff 0 Any Ethernet II or non-Ethernet II frame.
5484 * <none> 0xffff Any non-Ethernet II frame (except valid
5485 * 802.3 SNAP packet with valid eth_type).
5486 */
fbfe01de 5487 if (export_mask) {
b8266395 5488 nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, OVS_BE16_MAX);
661cbcd5 5489 }
fea393b1 5490 goto unencap;
36956a7d
BP
5491 }
5492
661cbcd5 5493 nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, data->dl_type);
36956a7d 5494
f0fb825a
EG
5495 if (eth_type_vlan(flow->dl_type)) {
5496 goto unencap;
5497 }
5498
36956a7d 5499 if (flow->dl_type == htons(ETH_TYPE_IP)) {
df2c07f4 5500 struct ovs_key_ipv4 *ipv4_key;
36956a7d 5501
df2c07f4 5502 ipv4_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV4,
36956a7d 5503 sizeof *ipv4_key);
3cea18ec 5504 get_ipv4_key(data, ipv4_key, export_mask);
d31f1109 5505 } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
df2c07f4 5506 struct ovs_key_ipv6 *ipv6_key;
d31f1109 5507
df2c07f4 5508 ipv6_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV6,
d31f1109 5509 sizeof *ipv6_key);
3cea18ec 5510 get_ipv6_key(data, ipv6_key, export_mask);
8087f5ff
MM
5511 } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
5512 flow->dl_type == htons(ETH_TYPE_RARP)) {
df2c07f4 5513 struct ovs_key_arp *arp_key;
d31f1109 5514
3cea18ec
JR
5515 arp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ARP,
5516 sizeof *arp_key);
5517 get_arp_key(data, arp_key);
b0a17866 5518 } else if (eth_type_mpls(flow->dl_type)) {
b02475c5 5519 struct ovs_key_mpls *mpls_key;
8bfd0fda 5520 int i, n;
b02475c5 5521
8bfd0fda 5522 n = flow_count_mpls_labels(flow, NULL);
5262eea1 5523 if (export_mask) {
2494ccd7 5524 n = MIN(n, parms->support.max_mpls_depth);
5262eea1 5525 }
b02475c5 5526 mpls_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_MPLS,
8bfd0fda
BP
5527 n * sizeof *mpls_key);
5528 for (i = 0; i < n; i++) {
5529 mpls_key[i].mpls_lse = data->mpls_lse[i];
5530 }
3d2fbd70 5531 } else if (flow->dl_type == htons(ETH_TYPE_NSH)) {
f59cb331 5532 nsh_key_to_attr(buf, &data->nsh, NULL, 0, export_mask);
b02475c5
SH
5533 }
5534
48cecbdc 5535 if (is_ip_any(flow) && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) {
6767a2cc 5536 if (flow->nw_proto == IPPROTO_TCP) {
3cea18ec 5537 union ovs_key_tp *tcp_key;
36956a7d 5538
df2c07f4 5539 tcp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_TCP,
36956a7d 5540 sizeof *tcp_key);
3cea18ec 5541 get_tp_key(data, tcp_key);
7cb32412 5542 if (data->tcp_flags || (mask && mask->tcp_flags)) {
dc235f7f
JR
5543 nl_msg_put_be16(buf, OVS_KEY_ATTR_TCP_FLAGS, data->tcp_flags);
5544 }
6767a2cc 5545 } else if (flow->nw_proto == IPPROTO_UDP) {
3cea18ec 5546 union ovs_key_tp *udp_key;
36956a7d 5547
df2c07f4 5548 udp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_UDP,
36956a7d 5549 sizeof *udp_key);
3cea18ec 5550 get_tp_key(data, udp_key);
c6bcb685 5551 } else if (flow->nw_proto == IPPROTO_SCTP) {
3cea18ec 5552 union ovs_key_tp *sctp_key;
c6bcb685
JS
5553
5554 sctp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_SCTP,
5555 sizeof *sctp_key);
3cea18ec 5556 get_tp_key(data, sctp_key);
d31f1109
JP
5557 } else if (flow->dl_type == htons(ETH_TYPE_IP)
5558 && flow->nw_proto == IPPROTO_ICMP) {
df2c07f4 5559 struct ovs_key_icmp *icmp_key;
36956a7d 5560
df2c07f4 5561 icmp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ICMP,
36956a7d 5562 sizeof *icmp_key);
661cbcd5
JP
5563 icmp_key->icmp_type = ntohs(data->tp_src);
5564 icmp_key->icmp_code = ntohs(data->tp_dst);
d31f1109
JP
5565 } else if (flow->dl_type == htons(ETH_TYPE_IPV6)
5566 && flow->nw_proto == IPPROTO_ICMPV6) {
df2c07f4 5567 struct ovs_key_icmpv6 *icmpv6_key;
d31f1109 5568
df2c07f4 5569 icmpv6_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ICMPV6,
d31f1109 5570 sizeof *icmpv6_key);
661cbcd5
JP
5571 icmpv6_key->icmpv6_type = ntohs(data->tp_src);
5572 icmpv6_key->icmpv6_code = ntohs(data->tp_dst);
685a51a5 5573
c17fcc0a 5574 if (is_nd(flow, NULL)
a63e3dc9
DDP
5575 /* Even though 'tp_src' and 'tp_dst' are 16 bits wide, ICMP
5576 * type and code are 8 bits wide. Therefore, an exact match
5577 * looks like htons(0xff), not htons(0xffff). See
5578 * xlate_wc_finish() for details. */
5579 && (!export_mask || (data->tp_src == htons(0xff)
5580 && data->tp_dst == htons(0xff)))) {
6f8dbd27 5581
df2c07f4 5582 struct ovs_key_nd *nd_key;
685a51a5 5583
df2c07f4 5584 nd_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ND,
685a51a5 5585 sizeof *nd_key);
932c96b7 5586 nd_key->nd_target = data->nd_target;
74ff3298
JR
5587 nd_key->nd_sll = data->arp_sha;
5588 nd_key->nd_tll = data->arp_tha;
685a51a5 5589 }
36956a7d 5590 }
36956a7d 5591 }
fea393b1
BP
5592
5593unencap:
f0fb825a
EG
5594 for (int encaps = max_vlans - 1; encaps >= 0; encaps--) {
5595 if (encap[encaps]) {
5596 nl_msg_end_nested(buf, encap[encaps]);
5597 }
fea393b1 5598 }
36956a7d 5599}
661cbcd5
JP
5600
5601/* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'.
661cbcd5
JP
5602 *
5603 * 'buf' must have at least ODPUTIL_FLOW_KEY_BYTES bytes of space, or be
5262eea1 5604 * capable of being expanded to allow for that much space. */
661cbcd5 5605void
5262eea1
JG
5606odp_flow_key_from_flow(const struct odp_flow_key_parms *parms,
5607 struct ofpbuf *buf)
661cbcd5 5608{
5262eea1 5609 odp_flow_key_from_flow__(parms, false, buf);
661cbcd5
JP
5610}
5611
5612/* Appends a representation of 'mask' as OVS_KEY_ATTR_* attributes to
5262eea1 5613 * 'buf'.
661cbcd5
JP
5614 *
5615 * 'buf' must have at least ODPUTIL_FLOW_KEY_BYTES bytes of space, or be
5262eea1 5616 * capable of being expanded to allow for that much space. */
661cbcd5 5617void
5262eea1
JG
5618odp_flow_key_from_mask(const struct odp_flow_key_parms *parms,
5619 struct ofpbuf *buf)
661cbcd5 5620{
5262eea1 5621 odp_flow_key_from_flow__(parms, true, buf);
661cbcd5 5622}
36956a7d 5623
758c456d
JR
5624/* Generate ODP flow key from the given packet metadata */
5625void
beb75a40 5626odp_key_from_dp_packet(struct ofpbuf *buf, const struct dp_packet *packet)
758c456d 5627{
beb75a40
JS
5628 const struct pkt_metadata *md = &packet->md;
5629
758c456d
JR
5630 nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, md->skb_priority);
5631
ffe4c74f 5632 if (flow_tnl_dst_is_set(&md->tunnel)) {
ec1f6f32 5633 tun_key_to_attr(buf, &md->tunnel, &md->tunnel, NULL);
758c456d
JR
5634 }
5635
5636 nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, md->pkt_mark);
5637
07659514
JS
5638 if (md->ct_state) {
5639 nl_msg_put_u32(buf, OVS_KEY_ATTR_CT_STATE,
5640 ovs_to_odp_ct_state(md->ct_state));
5641 if (md->ct_zone) {
5642 nl_msg_put_u16(buf, OVS_KEY_ATTR_CT_ZONE, md->ct_zone);
5643 }
8e53fe8c
JS
5644 if (md->ct_mark) {
5645 nl_msg_put_u32(buf, OVS_KEY_ATTR_CT_MARK, md->ct_mark);
5646 }
2ff8484b 5647 if (!ovs_u128_is_zero(md->ct_label)) {
9daf2348
JS
5648 nl_msg_put_unspec(buf, OVS_KEY_ATTR_CT_LABELS, &md->ct_label,
5649 sizeof(md->ct_label));
5650 }
daf4d3c1
JR
5651 if (md->ct_orig_tuple_ipv6) {
5652 if (md->ct_orig_tuple.ipv6.ipv6_proto) {
5653 nl_msg_put_unspec(buf, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
5654 &md->ct_orig_tuple.ipv6,
5655 sizeof md->ct_orig_tuple.ipv6);
5656 }
5657 } else {
5658 if (md->ct_orig_tuple.ipv4.ipv4_proto) {
5659 nl_msg_put_unspec(buf, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
5660 &md->ct_orig_tuple.ipv4,
5661 sizeof md->ct_orig_tuple.ipv4);
5662 }
5663 }
07659514
JS
5664 }
5665
758c456d
JR
5666 /* Add an ingress port attribute if 'odp_in_port' is not the magical
5667 * value "ODPP_NONE". */
b5e7e61a
AZ
5668 if (md->in_port.odp_port != ODPP_NONE) {
5669 nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, md->in_port.odp_port);
758c456d 5670 }
beb75a40
JS
5671
5672 /* Add OVS_KEY_ATTR_ETHERNET for non-Ethernet packets */
5673 if (pt_ns(packet->packet_type) == OFPHTN_ETHERTYPE) {
5674 nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE,
5675 pt_ns_type_be(packet->packet_type));
5676 }
758c456d
JR
5677}
5678
5679/* Generate packet metadata from the given ODP flow key. */
5680void
beb75a40
JS
5681odp_key_to_dp_packet(const struct nlattr *key, size_t key_len,
5682 struct dp_packet *packet)
758c456d 5683{
beb75a40 5684 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
758c456d 5685 const struct nlattr *nla;
beb75a40
JS
5686 struct pkt_metadata *md = &packet->md;
5687 ovs_be32 packet_type = htonl(PT_UNKNOWN);
5688 ovs_be16 ethertype = 0;
758c456d 5689 size_t left;
758c456d 5690
35303d71 5691 pkt_metadata_init(md, ODPP_NONE);
758c456d
JR
5692
5693 NL_ATTR_FOR_EACH (nla, left, key, key_len) {
08ef583d 5694 enum ovs_key_attr type = nl_attr_type(nla);
758c456d 5695 size_t len = nl_attr_get_size(nla);
6b8da9e9
JG
5696 int expected_len = odp_key_attr_len(ovs_flow_key_attr_lens,
5697 OVS_KEY_ATTR_MAX, type);
758c456d
JR
5698
5699 if (len != expected_len && expected_len >= 0) {
5700 continue;
5701 }
5702
572f732a
AZ
5703 switch (type) {
5704 case OVS_KEY_ATTR_RECIRC_ID:
5705 md->recirc_id = nl_attr_get_u32(nla);
572f732a
AZ
5706 break;
5707 case OVS_KEY_ATTR_DP_HASH:
5708 md->dp_hash = nl_attr_get_u32(nla);
572f732a
AZ
5709 break;
5710 case OVS_KEY_ATTR_PRIORITY:
758c456d 5711 md->skb_priority = nl_attr_get_u32(nla);
572f732a
AZ
5712 break;
5713 case OVS_KEY_ATTR_SKB_MARK:
758c456d 5714 md->pkt_mark = nl_attr_get_u32(nla);
572f732a 5715 break;
07659514
JS
5716 case OVS_KEY_ATTR_CT_STATE:
5717 md->ct_state = odp_to_ovs_ct_state(nl_attr_get_u32(nla));
07659514
JS
5718 break;
5719 case OVS_KEY_ATTR_CT_ZONE:
5720 md->ct_zone = nl_attr_get_u16(nla);
07659514 5721 break;
8e53fe8c
JS
5722 case OVS_KEY_ATTR_CT_MARK:
5723 md->ct_mark = nl_attr_get_u32(nla);
8e53fe8c 5724 break;
9daf2348 5725 case OVS_KEY_ATTR_CT_LABELS: {
ab79d262 5726 md->ct_label = nl_attr_get_u128(nla);
9daf2348
JS
5727 break;
5728 }
daf4d3c1
JR
5729 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4: {
5730 const struct ovs_key_ct_tuple_ipv4 *ct = nl_attr_get(nla);
5731 md->ct_orig_tuple.ipv4 = *ct;
5732 md->ct_orig_tuple_ipv6 = false;
daf4d3c1
JR
5733 break;
5734 }
5735 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6: {
5736 const struct ovs_key_ct_tuple_ipv6 *ct = nl_attr_get(nla);
5737
5738 md->ct_orig_tuple.ipv6 = *ct;
5739 md->ct_orig_tuple_ipv6 = true;
daf4d3c1
JR
5740 break;
5741 }
572f732a 5742 case OVS_KEY_ATTR_TUNNEL: {
758c456d
JR
5743 enum odp_key_fitness res;
5744
8d8ab6c2 5745 res = odp_tun_key_from_attr(nla, &md->tunnel);
758c456d
JR
5746 if (res == ODP_FIT_ERROR) {
5747 memset(&md->tunnel, 0, sizeof md->tunnel);
758c456d 5748 }
572f732a
AZ
5749 break;
5750 }
5751 case OVS_KEY_ATTR_IN_PORT:
b5e7e61a 5752 md->in_port.odp_port = nl_attr_get_odp_port(nla);
572f732a 5753 break;
beb75a40
JS
5754 case OVS_KEY_ATTR_ETHERNET:
5755 /* Presence of OVS_KEY_ATTR_ETHERNET indicates Ethernet packet. */
5756 packet_type = htonl(PT_ETH);
beb75a40
JS
5757 break;
5758 case OVS_KEY_ATTR_ETHERTYPE:
5759 ethertype = nl_attr_get_be16(nla);
beb75a40 5760 break;
08ef583d
YHW
5761 case OVS_KEY_ATTR_UNSPEC:
5762 case OVS_KEY_ATTR_ENCAP:
5763 case OVS_KEY_ATTR_VLAN:
5764 case OVS_KEY_ATTR_IPV4:
5765 case OVS_KEY_ATTR_IPV6:
5766 case OVS_KEY_ATTR_TCP:
5767 case OVS_KEY_ATTR_UDP:
5768 case OVS_KEY_ATTR_ICMP:
5769 case OVS_KEY_ATTR_ICMPV6:
5770 case OVS_KEY_ATTR_ARP:
5771 case OVS_KEY_ATTR_ND:
5772 case OVS_KEY_ATTR_SCTP:
5773 case OVS_KEY_ATTR_TCP_FLAGS:
5774 case OVS_KEY_ATTR_MPLS:
5775 case OVS_KEY_ATTR_PACKET_TYPE:
3d2fbd70 5776 case OVS_KEY_ATTR_NSH:
08ef583d 5777 case __OVS_KEY_ATTR_MAX:
572f732a
AZ
5778 default:
5779 break;
758c456d 5780 }
758c456d 5781 }
beb75a40
JS
5782
5783 if (packet_type == htonl(PT_ETH)) {
5784 packet->packet_type = htonl(PT_ETH);
5785 } else if (packet_type == htonl(PT_UNKNOWN) && ethertype != 0) {
5786 packet->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE,
5787 ntohs(ethertype));
5788 } else {
5789 VLOG_ERR_RL(&rl, "Packet without ETHERTYPE. Unknown packet_type.");
5790 }
758c456d
JR
5791}
5792
b0f7b9b5
BP
5793uint32_t
5794odp_flow_key_hash(const struct nlattr *key, size_t key_len)
5795{
5796 BUILD_ASSERT_DECL(!(NLA_ALIGNTO % sizeof(uint32_t)));
0a96a21b 5797 return hash_bytes32(ALIGNED_CAST(const uint32_t *, key), key_len, 0);
b0f7b9b5
BP
5798}
5799
34118cae
BP
5800static void
5801log_odp_key_attributes(struct vlog_rate_limit *rl, const char *title,
b0f7b9b5 5802 uint64_t attrs, int out_of_range_attr,
34118cae
BP
5803 const struct nlattr *key, size_t key_len)
5804{
5805 struct ds s;
5806 int i;
5807
b0f7b9b5 5808 if (VLOG_DROP_DBG(rl)) {
34118cae
BP
5809 return;
5810 }
5811
5812 ds_init(&s);
b0f7b9b5
BP
5813 for (i = 0; i < 64; i++) {
5814 if (attrs & (UINT64_C(1) << i)) {
e6603631
BP
5815 char namebuf[OVS_KEY_ATTR_BUFSIZE];
5816
5817 ds_put_format(&s, " %s",
5818 ovs_key_attr_to_string(i, namebuf, sizeof namebuf));
34118cae
BP
5819 }
5820 }
b0f7b9b5
BP
5821 if (out_of_range_attr) {
5822 ds_put_format(&s, " %d (and possibly others)", out_of_range_attr);
5823 }
34118cae
BP
5824
5825 ds_put_cstr(&s, ": ");
5826 odp_flow_key_format(key, key_len, &s);
5827
b0f7b9b5 5828 VLOG_DBG("%s:%s", title, ds_cstr(&s));
34118cae
BP
5829 ds_destroy(&s);
5830}
5831
3cea18ec
JR
5832static uint8_t
5833odp_to_ovs_frag(uint8_t odp_frag, bool is_mask)
7257b535 5834{
34118cae
BP
5835 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
5836
3cea18ec
JR
5837 if (is_mask) {
5838 return odp_frag ? FLOW_NW_FRAG_MASK : 0;
5839 }
5840
9e44d715 5841 if (odp_frag > OVS_FRAG_TYPE_LATER) {
b0f7b9b5 5842 VLOG_ERR_RL(&rl, "invalid frag %"PRIu8" in flow key", odp_frag);
3cea18ec 5843 return 0xff; /* Error. */
7257b535
BP
5844 }
5845
3cea18ec
JR
5846 return (odp_frag == OVS_FRAG_TYPE_NONE) ? 0
5847 : (odp_frag == OVS_FRAG_TYPE_FIRST) ? FLOW_NW_FRAG_ANY
5848 : FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER;
7257b535
BP
5849}
5850
b0f7b9b5 5851static bool
fea393b1 5852parse_flow_nlattrs(const struct nlattr *key, size_t key_len,
b0f7b9b5
BP
5853 const struct nlattr *attrs[], uint64_t *present_attrsp,
5854 int *out_of_range_attrp)
36956a7d 5855{
b0f7b9b5 5856 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10);
36956a7d 5857 const struct nlattr *nla;
34118cae 5858 uint64_t present_attrs;
36956a7d
BP
5859 size_t left;
5860
2aef1214 5861 BUILD_ASSERT(OVS_KEY_ATTR_MAX < CHAR_BIT * sizeof present_attrs);
34118cae 5862 present_attrs = 0;
b0f7b9b5 5863 *out_of_range_attrp = 0;
36956a7d 5864 NL_ATTR_FOR_EACH (nla, left, key, key_len) {
34118cae
BP
5865 uint16_t type = nl_attr_type(nla);
5866 size_t len = nl_attr_get_size(nla);
6b8da9e9
JG
5867 int expected_len = odp_key_attr_len(ovs_flow_key_attr_lens,
5868 OVS_KEY_ATTR_MAX, type);
34118cae 5869
b0f7b9b5 5870 if (len != expected_len && expected_len >= 0) {
e6603631
BP
5871 char namebuf[OVS_KEY_ATTR_BUFSIZE];
5872
34582733 5873 VLOG_ERR_RL(&rl, "attribute %s has length %"PRIuSIZE" but should have "
e6603631
BP
5874 "length %d", ovs_key_attr_to_string(type, namebuf,
5875 sizeof namebuf),
b0f7b9b5
BP
5876 len, expected_len);
5877 return false;
34118cae
BP
5878 }
5879
2aef1214 5880 if (type > OVS_KEY_ATTR_MAX) {
b0f7b9b5
BP
5881 *out_of_range_attrp = type;
5882 } else {
5883 if (present_attrs & (UINT64_C(1) << type)) {
e6603631
BP
5884 char namebuf[OVS_KEY_ATTR_BUFSIZE];
5885
b0f7b9b5 5886 VLOG_ERR_RL(&rl, "duplicate %s attribute in flow key",
e6603631
BP
5887 ovs_key_attr_to_string(type,
5888 namebuf, sizeof namebuf));
b0f7b9b5
BP
5889 return false;
5890 }
5891
5892 present_attrs |= UINT64_C(1) << type;
5893 attrs[type] = nla;
5894 }
34118cae
BP
5895 }
5896 if (left) {
5897 VLOG_ERR_RL(&rl, "trailing garbage in flow key");
b0f7b9b5 5898 return false;
34118cae
BP
5899 }
5900
fea393b1 5901 *present_attrsp = present_attrs;
b0f7b9b5 5902 return true;
fea393b1
BP
5903}
5904
b0f7b9b5
BP
5905static enum odp_key_fitness
5906check_expectations(uint64_t present_attrs, int out_of_range_attr,
5907 uint64_t expected_attrs,
fea393b1
BP
5908 const struct nlattr *key, size_t key_len)
5909{
5910 uint64_t missing_attrs;
5911 uint64_t extra_attrs;
5912
5913 missing_attrs = expected_attrs & ~present_attrs;
5914 if (missing_attrs) {
b0f7b9b5
BP
5915 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10);
5916 log_odp_key_attributes(&rl, "expected but not present",
5917 missing_attrs, 0, key, key_len);
5918 return ODP_FIT_TOO_LITTLE;
fea393b1
BP
5919 }
5920
5921 extra_attrs = present_attrs & ~expected_attrs;
b0f7b9b5
BP
5922 if (extra_attrs || out_of_range_attr) {
5923 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10);
5924 log_odp_key_attributes(&rl, "present but not expected",
5925 extra_attrs, out_of_range_attr, key, key_len);
5926 return ODP_FIT_TOO_MUCH;
fea393b1
BP
5927 }
5928
b0f7b9b5 5929 return ODP_FIT_PERFECT;
fea393b1
BP
5930}
5931
b0f7b9b5
BP
5932static bool
5933parse_ethertype(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
5934 uint64_t present_attrs, uint64_t *expected_attrs,
4a221615 5935 struct flow *flow, const struct flow *src_flow)
fea393b1
BP
5936{
5937 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
4a221615 5938 bool is_mask = flow != src_flow;
36956a7d 5939
fea393b1 5940 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ETHERTYPE)) {
34118cae 5941 flow->dl_type = nl_attr_get_be16(attrs[OVS_KEY_ATTR_ETHERTYPE]);
4a221615 5942 if (!is_mask && ntohs(flow->dl_type) < ETH_TYPE_MIN) {
34118cae
BP
5943 VLOG_ERR_RL(&rl, "invalid Ethertype %"PRIu16" in flow key",
5944 ntohs(flow->dl_type));
b0f7b9b5 5945 return false;
34118cae 5946 }
4a221615
GY
5947 if (is_mask && ntohs(src_flow->dl_type) < ETH_TYPE_MIN &&
5948 flow->dl_type != htons(0xffff)) {
5949 return false;
5950 }
b0f7b9b5 5951 *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ETHERTYPE;
34118cae 5952 } else {
4a221615 5953 if (!is_mask) {
beb75a40
JS
5954 /* Default ethertype for well-known L3 packets. */
5955 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV4)) {
5956 flow->dl_type = htons(ETH_TYPE_IP);
5957 } else if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV6)) {
5958 flow->dl_type = htons(ETH_TYPE_IPV6);
5959 } else if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS)) {
5960 flow->dl_type = htons(ETH_TYPE_MPLS);
5961 } else {
5962 flow->dl_type = htons(FLOW_DL_TYPE_NONE);
5963 }
5964 } else if (src_flow->packet_type != htonl(PT_ETH)) {
5965 /* dl_type is mandatory for non-Ethernet packets */
5966 flow->dl_type = htons(0xffff);
4a221615
GY
5967 } else if (ntohs(src_flow->dl_type) < ETH_TYPE_MIN) {
5968 /* See comments in odp_flow_key_from_flow__(). */
5969 VLOG_ERR_RL(&rl, "mask expected for non-Ethernet II frame");
5970 return false;
5971 }
34118cae 5972 }
b0f7b9b5
BP
5973 return true;
5974}
5975
5976static enum odp_key_fitness
b02475c5
SH
5977parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
5978 uint64_t present_attrs, int out_of_range_attr,
5979 uint64_t expected_attrs, struct flow *flow,
4a221615 5980 const struct nlattr *key, size_t key_len,
91a77332 5981 const struct flow *src_flow)
b0f7b9b5
BP
5982{
5983 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
4a221615
GY
5984 bool is_mask = src_flow != flow;
5985 const void *check_start = NULL;
5986 size_t check_len = 0;
5987 enum ovs_key_attr expected_bit = 0xff;
5988
5989 if (eth_type_mpls(src_flow->dl_type)) {
7e6621e9 5990 if (!is_mask || present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS)) {
91a77332 5991 expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_MPLS);
7e6621e9
JS
5992 }
5993 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS)) {
5994 size_t size = nl_attr_get_size(attrs[OVS_KEY_ATTR_MPLS]);
5995 const ovs_be32 *mpls_lse = nl_attr_get(attrs[OVS_KEY_ATTR_MPLS]);
5996 int n = size / sizeof(ovs_be32);
5997 int i;
4a221615 5998
7e6621e9
JS
5999 if (!size || size % sizeof(ovs_be32)) {
6000 return ODP_FIT_ERROR;
91a77332 6001 }
8bfd0fda 6002 if (flow->mpls_lse[0] && flow->dl_type != htons(0xffff)) {
4a221615
GY
6003 return ODP_FIT_ERROR;
6004 }
8bfd0fda 6005
7e6621e9
JS
6006 for (i = 0; i < n && i < FLOW_MAX_MPLS_LABELS; i++) {
6007 flow->mpls_lse[i] = mpls_lse[i];
6008 }
6009 if (n > FLOW_MAX_MPLS_LABELS) {
6010 return ODP_FIT_TOO_MUCH;
6011 }
8bfd0fda 6012
7e6621e9
JS
6013 if (!is_mask) {
6014 /* BOS may be set only in the innermost label. */
6015 for (i = 0; i < n - 1; i++) {
6016 if (flow->mpls_lse[i] & htonl(MPLS_BOS_MASK)) {
6017 return ODP_FIT_ERROR;
6018 }
8bfd0fda 6019 }
8bfd0fda 6020
7e6621e9
JS
6021 /* BOS must be set in the innermost label. */
6022 if (n < FLOW_MAX_MPLS_LABELS
6023 && !(flow->mpls_lse[n - 1] & htonl(MPLS_BOS_MASK))) {
6024 return ODP_FIT_TOO_LITTLE;
6025 }
8bfd0fda
BP
6026 }
6027 }
6028
4a221615
GY
6029 goto done;
6030 } else if (src_flow->dl_type == htons(ETH_TYPE_IP)) {
6031 if (!is_mask) {
6032 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV4;
b02475c5 6033 }
fea393b1 6034 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV4)) {
34118cae 6035 const struct ovs_key_ipv4 *ipv4_key;
36956a7d 6036
34118cae 6037 ipv4_key = nl_attr_get(attrs[OVS_KEY_ATTR_IPV4]);
3cea18ec
JR
6038 put_ipv4_key(ipv4_key, flow, is_mask);
6039 if (flow->nw_frag > FLOW_NW_FRAG_MASK) {
6040 return ODP_FIT_ERROR;
6041 }
4a221615 6042 if (is_mask) {
4a221615
GY
6043 check_start = ipv4_key;
6044 check_len = sizeof *ipv4_key;
6045 expected_bit = OVS_KEY_ATTR_IPV4;
36956a7d 6046 }
34118cae 6047 }
4a221615
GY
6048 } else if (src_flow->dl_type == htons(ETH_TYPE_IPV6)) {
6049 if (!is_mask) {
6050 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV6;
6051 }
fea393b1 6052 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV6)) {
34118cae 6053 const struct ovs_key_ipv6 *ipv6_key;
36956a7d 6054
34118cae 6055 ipv6_key = nl_attr_get(attrs[OVS_KEY_ATTR_IPV6]);
3cea18ec
JR
6056 put_ipv6_key(ipv6_key, flow, is_mask);
6057 if (flow->nw_frag > FLOW_NW_FRAG_MASK) {
6058 return ODP_FIT_ERROR;
6059 }
4a221615 6060 if (is_mask) {
4a221615
GY
6061 check_start = ipv6_key;
6062 check_len = sizeof *ipv6_key;
6063 expected_bit = OVS_KEY_ATTR_IPV6;
d31f1109 6064 }
34118cae 6065 }
4a221615
GY
6066 } else if (src_flow->dl_type == htons(ETH_TYPE_ARP) ||
6067 src_flow->dl_type == htons(ETH_TYPE_RARP)) {
6068 if (!is_mask) {
6069 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ARP;
6070 }
fea393b1 6071 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ARP)) {
34118cae 6072 const struct ovs_key_arp *arp_key;
d31f1109 6073
34118cae 6074 arp_key = nl_attr_get(attrs[OVS_KEY_ATTR_ARP]);
4a221615 6075 if (!is_mask && (arp_key->arp_op & htons(0xff00))) {
34118cae
BP
6076 VLOG_ERR_RL(&rl, "unsupported ARP opcode %"PRIu16" in flow "
6077 "key", ntohs(arp_key->arp_op));
b0f7b9b5 6078 return ODP_FIT_ERROR;
36956a7d 6079 }
3cea18ec 6080 put_arp_key(arp_key, flow);
4a221615
GY
6081 if (is_mask) {
6082 check_start = arp_key;
6083 check_len = sizeof *arp_key;
6084 expected_bit = OVS_KEY_ATTR_ARP;
6085 }
6086 }
3d2fbd70
JS
6087 } else if (src_flow->dl_type == htons(ETH_TYPE_NSH)) {
6088 if (!is_mask) {
6089 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_NSH;
6090 }
6091 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_NSH)) {
81fdabb9 6092 odp_nsh_key_from_attr(attrs[OVS_KEY_ATTR_NSH], &flow->nsh, NULL);
3d2fbd70 6093 if (is_mask) {
f59cb331
YY
6094 check_start = nl_attr_get(attrs[OVS_KEY_ATTR_NSH]);
6095 check_len = nl_attr_get_size(attrs[OVS_KEY_ATTR_NSH]);
3d2fbd70
JS
6096 expected_bit = OVS_KEY_ATTR_NSH;
6097 }
6098 }
4a221615
GY
6099 } else {
6100 goto done;
6101 }
df4eeb20 6102 if (check_len > 0) { /* Happens only when 'is_mask'. */
4a221615
GY
6103 if (!is_all_zeros(check_start, check_len) &&
6104 flow->dl_type != htons(0xffff)) {
6105 return ODP_FIT_ERROR;
6106 } else {
6107 expected_attrs |= UINT64_C(1) << expected_bit;
36956a7d 6108 }
36956a7d 6109 }
36956a7d 6110
4a221615
GY
6111 expected_bit = OVS_KEY_ATTR_UNSPEC;
6112 if (src_flow->nw_proto == IPPROTO_TCP
6113 && (src_flow->dl_type == htons(ETH_TYPE_IP) ||
6114 src_flow->dl_type == htons(ETH_TYPE_IPV6))
6115 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
6116 if (!is_mask) {
6117 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TCP;
6118 }
fea393b1 6119 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TCP)) {
3cea18ec 6120 const union ovs_key_tp *tcp_key;
36956a7d 6121
34118cae 6122 tcp_key = nl_attr_get(attrs[OVS_KEY_ATTR_TCP]);
3cea18ec 6123 put_tp_key(tcp_key, flow);
4a221615
GY
6124 expected_bit = OVS_KEY_ATTR_TCP;
6125 }
dc235f7f
JR
6126 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TCP_FLAGS)) {
6127 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TCP_FLAGS;
6128 flow->tcp_flags = nl_attr_get_be16(attrs[OVS_KEY_ATTR_TCP_FLAGS]);
6129 }
4a221615
GY
6130 } else if (src_flow->nw_proto == IPPROTO_UDP
6131 && (src_flow->dl_type == htons(ETH_TYPE_IP) ||
6132 src_flow->dl_type == htons(ETH_TYPE_IPV6))
6133 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
6134 if (!is_mask) {
6135 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_UDP;
7257b535 6136 }
fea393b1 6137 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_UDP)) {
3cea18ec 6138 const union ovs_key_tp *udp_key;
34118cae
BP
6139
6140 udp_key = nl_attr_get(attrs[OVS_KEY_ATTR_UDP]);
3cea18ec 6141 put_tp_key(udp_key, flow);
4a221615
GY
6142 expected_bit = OVS_KEY_ATTR_UDP;
6143 }
12848ebf
GS
6144 } else if (src_flow->nw_proto == IPPROTO_SCTP
6145 && (src_flow->dl_type == htons(ETH_TYPE_IP) ||
6146 src_flow->dl_type == htons(ETH_TYPE_IPV6))
6147 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
c6bcb685
JS
6148 if (!is_mask) {
6149 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_SCTP;
6150 }
6151 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_SCTP)) {
3cea18ec 6152 const union ovs_key_tp *sctp_key;
c6bcb685
JS
6153
6154 sctp_key = nl_attr_get(attrs[OVS_KEY_ATTR_SCTP]);
3cea18ec 6155 put_tp_key(sctp_key, flow);
c6bcb685
JS
6156 expected_bit = OVS_KEY_ATTR_SCTP;
6157 }
4a221615
GY
6158 } else if (src_flow->nw_proto == IPPROTO_ICMP
6159 && src_flow->dl_type == htons(ETH_TYPE_IP)
6160 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
6161 if (!is_mask) {
6162 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ICMP;
d31f1109 6163 }
fea393b1 6164 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ICMP)) {
34118cae
BP
6165 const struct ovs_key_icmp *icmp_key;
6166
6167 icmp_key = nl_attr_get(attrs[OVS_KEY_ATTR_ICMP]);
6168 flow->tp_src = htons(icmp_key->icmp_type);
6169 flow->tp_dst = htons(icmp_key->icmp_code);
4a221615
GY
6170 expected_bit = OVS_KEY_ATTR_ICMP;
6171 }
6172 } else if (src_flow->nw_proto == IPPROTO_ICMPV6
6173 && src_flow->dl_type == htons(ETH_TYPE_IPV6)
6174 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
6175 if (!is_mask) {
6176 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ICMPV6;
685a51a5 6177 }
fea393b1 6178 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ICMPV6)) {
34118cae
BP
6179 const struct ovs_key_icmpv6 *icmpv6_key;
6180
6181 icmpv6_key = nl_attr_get(attrs[OVS_KEY_ATTR_ICMPV6]);
6182 flow->tp_src = htons(icmpv6_key->icmpv6_type);
6183 flow->tp_dst = htons(icmpv6_key->icmpv6_code);
4a221615 6184 expected_bit = OVS_KEY_ATTR_ICMPV6;
c17fcc0a 6185 if (is_nd(src_flow, NULL)) {
4a221615
GY
6186 if (!is_mask) {
6187 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND;
6188 }
fea393b1 6189 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ND)) {
34118cae
BP
6190 const struct ovs_key_nd *nd_key;
6191
6192 nd_key = nl_attr_get(attrs[OVS_KEY_ATTR_ND]);
932c96b7 6193 flow->nd_target = nd_key->nd_target;
74ff3298
JR
6194 flow->arp_sha = nd_key->nd_sll;
6195 flow->arp_tha = nd_key->nd_tll;
4a221615 6196 if (is_mask) {
a63e3dc9
DDP
6197 /* Even though 'tp_src' and 'tp_dst' are 16 bits wide,
6198 * ICMP type and code are 8 bits wide. Therefore, an
6199 * exact match looks like htons(0xff), not
6200 * htons(0xffff). See xlate_wc_finish() for details.
6201 * */
53cb9c3e 6202 if (!is_all_zeros(nd_key, sizeof *nd_key) &&
a63e3dc9
DDP
6203 (flow->tp_src != htons(0xff) ||
6204 flow->tp_dst != htons(0xff))) {
4a221615
GY
6205 return ODP_FIT_ERROR;
6206 } else {
6207 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND;
6208 }
6209 }
34118cae
BP
6210 }
6211 }
7257b535 6212 }
34118cae 6213 }
4a221615
GY
6214 if (is_mask && expected_bit != OVS_KEY_ATTR_UNSPEC) {
6215 if ((flow->tp_src || flow->tp_dst) && flow->nw_proto != 0xff) {
6216 return ODP_FIT_ERROR;
6217 } else {
6218 expected_attrs |= UINT64_C(1) << expected_bit;
6219 }
6220 }
7257b535 6221
4a221615 6222done:
b0f7b9b5
BP
6223 return check_expectations(present_attrs, out_of_range_attr, expected_attrs,
6224 key, key_len);
6225}
6226
6227/* Parse 802.1Q header then encapsulated L3 attributes. */
6228static enum odp_key_fitness
6229parse_8021q_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
6230 uint64_t present_attrs, int out_of_range_attr,
6231 uint64_t expected_attrs, struct flow *flow,
4a221615
GY
6232 const struct nlattr *key, size_t key_len,
6233 const struct flow *src_flow)
b0f7b9b5
BP
6234{
6235 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
4a221615 6236 bool is_mask = src_flow != flow;
b0f7b9b5 6237
f0fb825a 6238 const struct nlattr *encap;
b0f7b9b5 6239 enum odp_key_fitness encap_fitness;
f0fb825a
EG
6240 enum odp_key_fitness fitness = ODP_FIT_ERROR;
6241 int encaps = 0;
b0f7b9b5 6242
f0fb825a
EG
6243 while (encaps < flow_vlan_limit &&
6244 (is_mask
6245 ? (src_flow->vlans[encaps].tci & htons(VLAN_CFI)) != 0
6246 : eth_type_vlan(flow->dl_type))) {
6247
6248 encap = (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ENCAP)
6249 ? attrs[OVS_KEY_ATTR_ENCAP] : NULL);
6250
6251 /* Calculate fitness of outer attributes. */
6252 if (!is_mask) {
6253 expected_attrs |= ((UINT64_C(1) << OVS_KEY_ATTR_VLAN) |
6254 (UINT64_C(1) << OVS_KEY_ATTR_ENCAP));
6255 } else {
6256 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_VLAN)) {
6257 expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_VLAN);
6258 }
6259 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ENCAP)) {
6260 expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_ENCAP);
6261 }
4a221615 6262 }
f0fb825a
EG
6263 fitness = check_expectations(present_attrs, out_of_range_attr,
6264 expected_attrs, key, key_len);
6265
6266 /* Set vlan_tci.
6267 * Remove the TPID from dl_type since it's not the real Ethertype. */
6268 flow->vlans[encaps].tpid = flow->dl_type;
6269 flow->dl_type = htons(0);
6270 flow->vlans[encaps].tci =
6271 (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_VLAN)
6272 ? nl_attr_get_be16(attrs[OVS_KEY_ATTR_VLAN])
6273 : htons(0));
6274 if (!is_mask) {
f889568f 6275 if (!(present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_VLAN)) ||
6276 !(present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ENCAP))) {
f0fb825a
EG
6277 return ODP_FIT_TOO_LITTLE;
6278 } else if (flow->vlans[encaps].tci == htons(0)) {
6279 /* Corner case for a truncated 802.1Q header. */
6280 if (fitness == ODP_FIT_PERFECT && nl_attr_get_size(encap)) {
6281 return ODP_FIT_TOO_MUCH;
6282 }
6283 return fitness;
6284 } else if (!(flow->vlans[encaps].tci & htons(VLAN_CFI))) {
6285 VLOG_ERR_RL(&rl, "OVS_KEY_ATTR_VLAN 0x%04"PRIx16" is nonzero "
6286 "but CFI bit is not set",
6287 ntohs(flow->vlans[encaps].tci));
6288 return ODP_FIT_ERROR;
6289 }
6290 } else {
6291 if (!(present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ENCAP))) {
6292 return fitness;
6293 }
4a221615 6294 }
b0f7b9b5 6295
f0fb825a
EG
6296 /* Now parse the encapsulated attributes. */
6297 if (!parse_flow_nlattrs(nl_attr_get(encap), nl_attr_get_size(encap),
6298 attrs, &present_attrs, &out_of_range_attr)) {
3e634810
BP
6299 return ODP_FIT_ERROR;
6300 }
f0fb825a
EG
6301 expected_attrs = 0;
6302
6303 if (!parse_ethertype(attrs, present_attrs, &expected_attrs,
6304 flow, src_flow)) {
6305 return ODP_FIT_ERROR;
4a221615 6306 }
4a221615 6307
f0fb825a 6308 encaps++;
b0f7b9b5 6309 }
b0f7b9b5 6310
b02475c5 6311 encap_fitness = parse_l2_5_onward(attrs, present_attrs, out_of_range_attr,
4a221615
GY
6312 expected_attrs, flow, key, key_len,
6313 src_flow);
b0f7b9b5
BP
6314
6315 /* The overall fitness is the worse of the outer and inner attributes. */
6316 return MAX(fitness, encap_fitness);
6317}
6318
4a221615
GY
6319static enum odp_key_fitness
6320odp_flow_key_to_flow__(const struct nlattr *key, size_t key_len,
8d8ab6c2 6321 struct flow *flow, const struct flow *src_flow)
b0f7b9b5 6322{
b0f7b9b5
BP
6323 const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1];
6324 uint64_t expected_attrs;
6325 uint64_t present_attrs;
6326 int out_of_range_attr;
4a221615 6327 bool is_mask = src_flow != flow;
b0f7b9b5
BP
6328
6329 memset(flow, 0, sizeof *flow);
6330
6331 /* Parse attributes. */
6332 if (!parse_flow_nlattrs(key, key_len, attrs, &present_attrs,
6333 &out_of_range_attr)) {
6334 return ODP_FIT_ERROR;
6335 }
6336 expected_attrs = 0;
6337
6338 /* Metadata. */
572f732a
AZ
6339 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_RECIRC_ID)) {
6340 flow->recirc_id = nl_attr_get_u32(attrs[OVS_KEY_ATTR_RECIRC_ID]);
6341 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_RECIRC_ID;
6342 } else if (is_mask) {
8c1b077f 6343 /* Always exact match recirc_id if it is not specified. */
572f732a
AZ
6344 flow->recirc_id = UINT32_MAX;
6345 }
6346
6347 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_DP_HASH)) {
6348 flow->dp_hash = nl_attr_get_u32(attrs[OVS_KEY_ATTR_DP_HASH]);
6349 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_DP_HASH;
6350 }
b0f7b9b5 6351 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_PRIORITY)) {
deedf7e7 6352 flow->skb_priority = nl_attr_get_u32(attrs[OVS_KEY_ATTR_PRIORITY]);
b0f7b9b5
BP
6353 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_PRIORITY;
6354 }
6355
72e8bf28 6356 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_SKB_MARK)) {
1362e248 6357 flow->pkt_mark = nl_attr_get_u32(attrs[OVS_KEY_ATTR_SKB_MARK]);
72e8bf28
AA
6358 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_SKB_MARK;
6359 }
6360
07659514
JS
6361 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_CT_STATE)) {
6362 uint32_t odp_state = nl_attr_get_u32(attrs[OVS_KEY_ATTR_CT_STATE]);
6363
6364 flow->ct_state = odp_to_ovs_ct_state(odp_state);
6365 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_CT_STATE;
6366 }
6367 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_CT_ZONE)) {
6368 flow->ct_zone = nl_attr_get_u16(attrs[OVS_KEY_ATTR_CT_ZONE]);
6369 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_CT_ZONE;
6370 }
8e53fe8c
JS
6371 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_CT_MARK)) {
6372 flow->ct_mark = nl_attr_get_u32(attrs[OVS_KEY_ATTR_CT_MARK]);
6373 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_CT_MARK;
6374 }
9daf2348 6375 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_CT_LABELS)) {
ab79d262 6376 flow->ct_label = nl_attr_get_u128(attrs[OVS_KEY_ATTR_CT_LABELS]);
9daf2348
JS
6377 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_CT_LABELS;
6378 }
daf4d3c1
JR
6379 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4)) {
6380 const struct ovs_key_ct_tuple_ipv4 *ct = nl_attr_get(attrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]);
6381 flow->ct_nw_src = ct->ipv4_src;
6382 flow->ct_nw_dst = ct->ipv4_dst;
6383 flow->ct_nw_proto = ct->ipv4_proto;
6384 flow->ct_tp_src = ct->src_port;
6385 flow->ct_tp_dst = ct->dst_port;
6386 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4;
6387 }
6388 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6)) {
6389 const struct ovs_key_ct_tuple_ipv6 *ct = nl_attr_get(attrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6]);
6390
6391 flow->ct_ipv6_src = ct->ipv6_src;
6392 flow->ct_ipv6_dst = ct->ipv6_dst;
6393 flow->ct_nw_proto = ct->ipv6_proto;
6394 flow->ct_tp_src = ct->src_port;
6395 flow->ct_tp_dst = ct->dst_port;
6396 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6;
6397 }
07659514 6398
9b405f1a
PS
6399 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TUNNEL)) {
6400 enum odp_key_fitness res;
05fb0928 6401
8d8ab6c2
JG
6402 res = odp_tun_key_from_attr__(attrs[OVS_KEY_ATTR_TUNNEL], is_mask,
6403 &flow->tunnel);
9b405f1a
PS
6404 if (res == ODP_FIT_ERROR) {
6405 return ODP_FIT_ERROR;
6406 } else if (res == ODP_FIT_PERFECT) {
6407 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TUNNEL;
05fb0928
JR
6408 }
6409 }
6410
b0f7b9b5 6411 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IN_PORT)) {
4e022ec0
AW
6412 flow->in_port.odp_port
6413 = nl_attr_get_odp_port(attrs[OVS_KEY_ATTR_IN_PORT]);
b0f7b9b5 6414 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IN_PORT;
4a221615 6415 } else if (!is_mask) {
4e022ec0 6416 flow->in_port.odp_port = ODPP_NONE;
b0f7b9b5
BP
6417 }
6418
beb75a40
JS
6419 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_PACKET_TYPE)) {
6420 flow->packet_type
6421 = nl_attr_get_be32(attrs[OVS_KEY_ATTR_PACKET_TYPE]);
6422 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_PACKET_TYPE;
6423 } else if (!is_mask) {
6424 flow->packet_type = htonl(PT_ETH);
6425 }
6426
6427 /* Check for Ethernet header. */
b0f7b9b5
BP
6428 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ETHERNET)) {
6429 const struct ovs_key_ethernet *eth_key;
6430
6431 eth_key = nl_attr_get(attrs[OVS_KEY_ATTR_ETHERNET]);
3cea18ec 6432 put_ethernet_key(eth_key, flow);
beb75a40
JS
6433 if (!is_mask) {
6434 flow->packet_type = htonl(PT_ETH);
4a221615 6435 }
4a221615 6436 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ETHERNET;
b0f7b9b5 6437 }
beb75a40
JS
6438 else if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ETHERTYPE)) {
6439 ovs_be16 ethertype = nl_attr_get_be16(attrs[OVS_KEY_ATTR_ETHERTYPE]);
6440 if (!is_mask) {
6441 flow->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE,
6442 ntohs(ethertype));
6443 }
6444 expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ETHERTYPE;
6445 }
b0f7b9b5
BP
6446
6447 /* Get Ethertype or 802.1Q TPID or FLOW_DL_TYPE_NONE. */
4a221615 6448 if (!parse_ethertype(attrs, present_attrs, &expected_attrs, flow,
beb75a40 6449 src_flow)) {
b0f7b9b5
BP
6450 return ODP_FIT_ERROR;
6451 }
6452
21e70add 6453 if (is_mask
f0fb825a
EG
6454 ? (src_flow->vlans[0].tci & htons(VLAN_CFI)) != 0
6455 : eth_type_vlan(src_flow->dl_type)) {
b0f7b9b5 6456 return parse_8021q_onward(attrs, present_attrs, out_of_range_attr,
4a221615
GY
6457 expected_attrs, flow, key, key_len, src_flow);
6458 }
6459 if (is_mask) {
449b8131 6460 /* A missing VLAN mask means exact match on vlan_tci 0 (== no VLAN). */
f0fb825a
EG
6461 flow->vlans[0].tpid = htons(0xffff);
6462 flow->vlans[0].tci = htons(0xffff);
4a221615 6463 if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_VLAN)) {
f0fb825a 6464 flow->vlans[0].tci = nl_attr_get_be16(attrs[OVS_KEY_ATTR_VLAN]);
4a221615
GY
6465 expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_VLAN);
6466 }
b0f7b9b5 6467 }
b02475c5 6468 return parse_l2_5_onward(attrs, present_attrs, out_of_range_attr,
4a221615
GY
6469 expected_attrs, flow, key, key_len, src_flow);
6470}
6471
6472/* Converts the 'key_len' bytes of OVS_KEY_ATTR_* attributes in 'key' to a flow
6473 * structure in 'flow'. Returns an ODP_FIT_* value that indicates how well
6474 * 'key' fits our expectations for what a flow key should contain.
6475 *
6476 * The 'in_port' will be the datapath's understanding of the port. The
6477 * caller will need to translate with odp_port_to_ofp_port() if the
6478 * OpenFlow port is needed.
6479 *
6480 * This function doesn't take the packet itself as an argument because none of
6481 * the currently understood OVS_KEY_ATTR_* attributes require it. Currently,
6482 * it is always possible to infer which additional attribute(s) should appear
6483 * by looking at the attributes for lower-level protocols, e.g. if the network
6484 * protocol in OVS_KEY_ATTR_IPV4 or OVS_KEY_ATTR_IPV6 is IPPROTO_TCP then we
6485 * know that a OVS_KEY_ATTR_TCP attribute must appear and that otherwise it
6486 * must be absent. */
6487enum odp_key_fitness
6488odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
6489 struct flow *flow)
6490{
8d8ab6c2 6491 return odp_flow_key_to_flow__(key, key_len, flow, flow);
4a221615
GY
6492}
6493
8d8ab6c2
JG
6494/* Converts the 'mask_key_len' bytes of OVS_KEY_ATTR_* attributes in 'mask_key'
6495 * to a mask structure in 'mask'. 'flow' must be a previously translated flow
6496 * corresponding to 'mask' and similarly flow_key/flow_key_len must be the
6497 * attributes from that flow. Returns an ODP_FIT_* value that indicates how
6498 * well 'key' fits our expectations for what a flow key should contain. */
6499enum odp_key_fitness
6500odp_flow_key_to_mask(const struct nlattr *mask_key, size_t mask_key_len,
6501 struct flow_wildcards *mask, const struct flow *src_flow)
ca8d3442
DDP
6502{
6503 if (mask_key_len) {
6504 return odp_flow_key_to_flow__(mask_key, mask_key_len,
8d8ab6c2 6505 &mask->masks, src_flow);
ca8d3442
DDP
6506
6507 } else {
6508 /* A missing mask means that the flow should be exact matched.
6509 * Generate an appropriate exact wildcard for the flow. */
6510 flow_wildcards_init_for_packet(mask, src_flow);
6511
6512 return ODP_FIT_PERFECT;
6513 }
6514}
39db78a0 6515
8b668ee3
PB
6516/* Converts the netlink formated key/mask to match.
6517 * Fails if odp_flow_key_from_key/mask and odp_flow_key_key/mask
6518 * disagree on the acceptable form of flow */
6519int
6520parse_key_and_mask_to_match(const struct nlattr *key, size_t key_len,
6521 const struct nlattr *mask, size_t mask_len,
6522 struct match *match)
6523{
6524 enum odp_key_fitness fitness;
6525
6526 fitness = odp_flow_key_to_flow(key, key_len, &match->flow);
6527 if (fitness) {
6528 /* This should not happen: it indicates that
6529 * odp_flow_key_from_flow() and odp_flow_key_to_flow() disagree on
6530 * the acceptable form of a flow. Log the problem as an error,
6531 * with enough details to enable debugging. */
6532 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
6533
6534 if (!VLOG_DROP_ERR(&rl)) {
6535 struct ds s;
6536
6537 ds_init(&s);
6538 odp_flow_format(key, key_len, NULL, 0, NULL, &s, true);
6539 VLOG_ERR("internal error parsing flow key %s", ds_cstr(&s));
6540 ds_destroy(&s);
6541 }
6542
6543 return EINVAL;
6544 }
6545
6546 fitness = odp_flow_key_to_mask(mask, mask_len, &match->wc, &match->flow);
6547 if (fitness) {
6548 /* This should not happen: it indicates that
6549 * odp_flow_key_from_mask() and odp_flow_key_to_mask()
6550 * disagree on the acceptable form of a mask. Log the problem
6551 * as an error, with enough details to enable debugging. */
6552 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
6553
6554 if (!VLOG_DROP_ERR(&rl)) {
6555 struct ds s;
6556
6557 ds_init(&s);
6558 odp_flow_format(key, key_len, mask, mask_len, NULL, &s,
6559 true);
6560 VLOG_ERR("internal error parsing flow mask %s (%s)",
6561 ds_cstr(&s), odp_key_fitness_to_string(fitness));
6562 ds_destroy(&s);
6563 }
6564
6565 return EINVAL;
6566 }
6567
6568 return 0;
6569}
6570
6814e51f
BP
6571/* Returns 'fitness' as a string, for use in debug messages. */
6572const char *
6573odp_key_fitness_to_string(enum odp_key_fitness fitness)
6574{
6575 switch (fitness) {
6576 case ODP_FIT_PERFECT:
6577 return "OK";
6578 case ODP_FIT_TOO_MUCH:
6579 return "too_much";
6580 case ODP_FIT_TOO_LITTLE:
6581 return "too_little";
6582 case ODP_FIT_ERROR:
6583 return "error";
6584 default:
6585 return "<unknown>";
6586 }
6587}
6588
39db78a0 6589/* Appends an OVS_ACTION_ATTR_USERSPACE action to 'odp_actions' that specifies
e995e3df
BP
6590 * Netlink PID 'pid'. If 'userdata' is nonnull, adds a userdata attribute
6591 * whose contents are the 'userdata_size' bytes at 'userdata' and returns the
6592 * offset within 'odp_actions' of the start of the cookie. (If 'userdata' is
6593 * null, then the return value is not meaningful.) */
39db78a0 6594size_t
e995e3df
BP
6595odp_put_userspace_action(uint32_t pid,
6596 const void *userdata, size_t userdata_size,
8b7ea2d4 6597 odp_port_t tunnel_out_port,
7321bda3 6598 bool include_actions,
39db78a0
BP
6599 struct ofpbuf *odp_actions)
6600{
e995e3df 6601 size_t userdata_ofs;
39db78a0
BP
6602 size_t offset;
6603
6604 offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_USERSPACE);
6605 nl_msg_put_u32(odp_actions, OVS_USERSPACE_ATTR_PID, pid);
e995e3df 6606 if (userdata) {
6fd6ed71 6607 userdata_ofs = odp_actions->size + NLA_HDRLEN;
96ed775f
BP
6608
6609 /* The OVS kernel module before OVS 1.11 and the upstream Linux kernel
6610 * module before Linux 3.10 required the userdata to be exactly 8 bytes
6611 * long:
6612 *
6613 * - The kernel rejected shorter userdata with -ERANGE.
6614 *
6615 * - The kernel silently dropped userdata beyond the first 8 bytes.
6616 *
6617 * Thus, for maximum compatibility, always put at least 8 bytes. (We
6618 * separately disable features that required more than 8 bytes.) */
6619 memcpy(nl_msg_put_unspec_zero(odp_actions, OVS_USERSPACE_ATTR_USERDATA,
6620 MAX(8, userdata_size)),
6621 userdata, userdata_size);
e995e3df
BP
6622 } else {
6623 userdata_ofs = 0;
39db78a0 6624 }
8b7ea2d4
WZ
6625 if (tunnel_out_port != ODPP_NONE) {
6626 nl_msg_put_odp_port(odp_actions, OVS_USERSPACE_ATTR_EGRESS_TUN_PORT,
6627 tunnel_out_port);
6628 }
7321bda3
NM
6629 if (include_actions) {
6630 nl_msg_put_flag(odp_actions, OVS_USERSPACE_ATTR_ACTIONS);
6631 }
39db78a0
BP
6632 nl_msg_end_nested(odp_actions, offset);
6633
e995e3df 6634 return userdata_ofs;
39db78a0 6635}
b9ad7294 6636
88fc5281
JS
6637void
6638odp_put_pop_eth_action(struct ofpbuf *odp_actions)
6639{
6640 nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_ETH);
6641}
6642
6643void
6644odp_put_push_eth_action(struct ofpbuf *odp_actions,
6645 const struct eth_addr *eth_src,
6646 const struct eth_addr *eth_dst)
6647{
6648 struct ovs_action_push_eth eth;
6649
6650 memset(&eth, 0, sizeof eth);
6651 if (eth_src) {
6652 eth.addresses.eth_src = *eth_src;
6653 }
6654 if (eth_dst) {
6655 eth.addresses.eth_dst = *eth_dst;
6656 }
6657
6658 nl_msg_put_unspec(odp_actions, OVS_ACTION_ATTR_PUSH_ETH,
6659 &eth, sizeof eth);
6660}
6661
b9ad7294
EJ
6662void
6663odp_put_tunnel_action(const struct flow_tnl *tunnel,
6664 struct ofpbuf *odp_actions)
6665{
6666 size_t offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_SET);
ec1f6f32 6667 tun_key_to_attr(odp_actions, tunnel, tunnel, NULL);
b9ad7294
EJ
6668 nl_msg_end_nested(odp_actions, offset);
6669}
a36de779
PS
6670
6671void
6672odp_put_tnl_push_action(struct ofpbuf *odp_actions,
6673 struct ovs_action_push_tnl *data)
6674{
6675 int size = offsetof(struct ovs_action_push_tnl, header);
6676
6677 size += data->header_len;
6678 nl_msg_put_unspec(odp_actions, OVS_ACTION_ATTR_TUNNEL_PUSH, data, size);
6679}
6680
5bbda0aa
EJ
6681\f
6682/* The commit_odp_actions() function and its helpers. */
6683
6684static void
6685commit_set_action(struct ofpbuf *odp_actions, enum ovs_key_attr key_type,
6686 const void *key, size_t key_size)
6687{
6688 size_t offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_SET);
6689 nl_msg_put_unspec(odp_actions, key_type, key, key_size);
6690 nl_msg_end_nested(odp_actions, offset);
6691}
6692
6d670e7f
JR
6693/* Masked set actions have a mask following the data within the netlink
6694 * attribute. The unmasked bits in the data will be cleared as the data
6695 * is copied to the action. */
6696void
6697commit_masked_set_action(struct ofpbuf *odp_actions,
6698 enum ovs_key_attr key_type,
6699 const void *key_, const void *mask_, size_t key_size)
6700{
6701 size_t offset = nl_msg_start_nested(odp_actions,
6702 OVS_ACTION_ATTR_SET_MASKED);
6703 char *data = nl_msg_put_unspec_uninit(odp_actions, key_type, key_size * 2);
6704 const char *key = key_, *mask = mask_;
6705
6706 memcpy(data + key_size, mask, key_size);
6707 /* Clear unmasked bits while copying. */
6708 while (key_size--) {
6709 *data++ = *key++ & *mask++;
6710 }
6711 nl_msg_end_nested(odp_actions, offset);
6712}
6713
b9ad7294
EJ
6714/* If any of the flow key data that ODP actions can modify are different in
6715 * 'base->tunnel' and 'flow->tunnel', appends a set_tunnel ODP action to
6716 * 'odp_actions' that change the flow tunneling information in key from
6717 * 'base->tunnel' into 'flow->tunnel', and then changes 'base->tunnel' in the
6718 * same way. In other words, operates the same as commit_odp_actions(), but
6719 * only on tunneling information. */
6720void
6721commit_odp_tunnel_action(const struct flow *flow, struct flow *base,
5bbda0aa
EJ
6722 struct ofpbuf *odp_actions)
6723{
ffe4c74f
JB
6724 /* A valid IPV4_TUNNEL must have non-zero ip_dst; a valid IPv6 tunnel
6725 * must have non-zero ipv6_dst. */
6726 if (flow_tnl_dst_is_set(&flow->tunnel)) {
fc80de30
JR
6727 if (!memcmp(&base->tunnel, &flow->tunnel, sizeof base->tunnel)) {
6728 return;
6729 }
6730 memcpy(&base->tunnel, &flow->tunnel, sizeof base->tunnel);
b9ad7294 6731 odp_put_tunnel_action(&base->tunnel, odp_actions);
05fb0928 6732 }
5bbda0aa
EJ
6733}
6734
d23df9a8
JR
6735static bool
6736commit(enum ovs_key_attr attr, bool use_masked_set,
6737 const void *key, void *base, void *mask, size_t size,
6738 struct ofpbuf *odp_actions)
5bbda0aa 6739{
d23df9a8
JR
6740 if (memcmp(key, base, size)) {
6741 bool fully_masked = odp_mask_is_exact(attr, mask, size);
5bbda0aa 6742
d23df9a8
JR
6743 if (use_masked_set && !fully_masked) {
6744 commit_masked_set_action(odp_actions, attr, key, mask, size);
6745 } else {
6746 if (!fully_masked) {
6747 memset(mask, 0xff, size);
6748 }
6749 commit_set_action(odp_actions, attr, key, size);
6750 }
6751 memcpy(base, key, size);
6752 return true;
6753 } else {
6754 /* Mask bits are set when we have either read or set the corresponding
6755 * values. Masked bits will be exact-matched, no need to set them
6756 * if the value did not actually change. */
6757 return false;
5bbda0aa 6758 }
d23df9a8 6759}
5bbda0aa 6760
d23df9a8
JR
6761static void
6762get_ethernet_key(const struct flow *flow, struct ovs_key_ethernet *eth)
6763{
74ff3298
JR
6764 eth->eth_src = flow->dl_src;
6765 eth->eth_dst = flow->dl_dst;
d23df9a8 6766}
1dd35f8a 6767
d23df9a8
JR
6768static void
6769put_ethernet_key(const struct ovs_key_ethernet *eth, struct flow *flow)
6770{
74ff3298
JR
6771 flow->dl_src = eth->eth_src;
6772 flow->dl_dst = eth->eth_dst;
d23df9a8 6773}
5bbda0aa 6774
d23df9a8 6775static void
f839892a
JS
6776commit_set_ether_action(const struct flow *flow, struct flow *base_flow,
6777 struct ofpbuf *odp_actions,
6778 struct flow_wildcards *wc,
6779 bool use_masked)
d23df9a8
JR
6780{
6781 struct ovs_key_ethernet key, base, mask;
5bbda0aa 6782
f839892a
JS
6783 if (flow->packet_type != htonl(PT_ETH)) {
6784 return;
6785 }
6786
d23df9a8
JR
6787 get_ethernet_key(flow, &key);
6788 get_ethernet_key(base_flow, &base);
6789 get_ethernet_key(&wc->masks, &mask);
6790
6791 if (commit(OVS_KEY_ATTR_ETHERNET, use_masked,
6792 &key, &base, &mask, sizeof key, odp_actions)) {
6793 put_ethernet_key(&base, base_flow);
6794 put_ethernet_key(&mask, &wc->masks);
6795 }
5bbda0aa
EJ
6796}
6797
6798static void
f0fb825a
EG
6799commit_vlan_action(const struct flow* flow, struct flow *base,
6800 struct ofpbuf *odp_actions, struct flow_wildcards *wc)
5bbda0aa 6801{
f0fb825a
EG
6802 int base_n = flow_count_vlan_headers(base);
6803 int flow_n = flow_count_vlan_headers(flow);
6804 flow_skip_common_vlan_headers(base, &base_n, flow, &flow_n);
1dd35f8a 6805
f0fb825a
EG
6806 /* Pop all mismatching vlan of base, push those of flow */
6807 for (; base_n >= 0; base_n--) {
5bbda0aa 6808 nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_VLAN);
f0fb825a 6809 wc->masks.vlans[base_n].qtag = OVS_BE32_MAX;
5bbda0aa
EJ
6810 }
6811
f0fb825a 6812 for (; flow_n >= 0; flow_n--) {
5bbda0aa
EJ
6813 struct ovs_action_push_vlan vlan;
6814
f0fb825a
EG
6815 vlan.vlan_tpid = flow->vlans[flow_n].tpid;
6816 vlan.vlan_tci = flow->vlans[flow_n].tci;
5bbda0aa
EJ
6817 nl_msg_put_unspec(odp_actions, OVS_ACTION_ATTR_PUSH_VLAN,
6818 &vlan, sizeof vlan);
6819 }
f0fb825a 6820 memcpy(base->vlans, flow->vlans, sizeof(base->vlans));
5bbda0aa
EJ
6821}
6822
22d38fca 6823/* Wildcarding already done at action translation time. */
b02475c5
SH
6824static void
6825commit_mpls_action(const struct flow *flow, struct flow *base,
22d38fca 6826 struct ofpbuf *odp_actions)
b02475c5 6827{
22d38fca
JR
6828 int base_n = flow_count_mpls_labels(base, NULL);
6829 int flow_n = flow_count_mpls_labels(flow, NULL);
8bfd0fda 6830 int common_n = flow_count_common_mpls_labels(flow, flow_n, base, base_n,
22d38fca 6831 NULL);
8bfd0fda
BP
6832
6833 while (base_n > common_n) {
6834 if (base_n - 1 == common_n && flow_n > common_n) {
6835 /* If there is only one more LSE in base than there are common
6836 * between base and flow; and flow has at least one more LSE than
6837 * is common then the topmost LSE of base may be updated using
6838 * set */
6839 struct ovs_key_mpls mpls_key;
6840
6841 mpls_key.mpls_lse = flow->mpls_lse[flow_n - base_n];
6842 commit_set_action(odp_actions, OVS_KEY_ATTR_MPLS,
6843 &mpls_key, sizeof mpls_key);
6844 flow_set_mpls_lse(base, 0, mpls_key.mpls_lse);
6845 common_n++;
6846 } else {
6847 /* Otherwise, if there more LSEs in base than are common between
6848 * base and flow then pop the topmost one. */
6849 ovs_be16 dl_type;
6850 bool popped;
6851
6852 /* If all the LSEs are to be popped and this is not the outermost
6853 * LSE then use ETH_TYPE_MPLS as the ethertype parameter of the
6854 * POP_MPLS action instead of flow->dl_type.
6855 *
6856 * This is because the POP_MPLS action requires its ethertype
6857 * argument to be an MPLS ethernet type but in this case
6858 * flow->dl_type will be a non-MPLS ethernet type.
6859 *
6860 * When the final POP_MPLS action occurs it use flow->dl_type and
6861 * the and the resulting packet will have the desired dl_type. */
6862 if ((!eth_type_mpls(flow->dl_type)) && base_n > 1) {
6863 dl_type = htons(ETH_TYPE_MPLS);
6864 } else {
6865 dl_type = flow->dl_type;
6866 }
6867 nl_msg_put_be16(odp_actions, OVS_ACTION_ATTR_POP_MPLS, dl_type);
22d38fca 6868 popped = flow_pop_mpls(base, base_n, flow->dl_type, NULL);
8bfd0fda
BP
6869 ovs_assert(popped);
6870 base_n--;
6871 }
b02475c5
SH
6872 }
6873
8bfd0fda
BP
6874 /* If, after the above popping and setting, there are more LSEs in flow
6875 * than base then some LSEs need to be pushed. */
6876 while (base_n < flow_n) {
b02475c5
SH
6877 struct ovs_action_push_mpls *mpls;
6878
8bfd0fda
BP
6879 mpls = nl_msg_put_unspec_zero(odp_actions,
6880 OVS_ACTION_ATTR_PUSH_MPLS,
9ddf12cc 6881 sizeof *mpls);
b02475c5 6882 mpls->mpls_ethertype = flow->dl_type;
8bfd0fda 6883 mpls->mpls_lse = flow->mpls_lse[flow_n - base_n - 1];
742c0ac3
JR
6884 /* Update base flow's MPLS stack, but do not clear L3. We need the L3
6885 * headers if the flow is restored later due to returning from a patch
6886 * port or group bucket. */
6887 flow_push_mpls(base, base_n, mpls->mpls_ethertype, NULL, false);
8bfd0fda
BP
6888 flow_set_mpls_lse(base, 0, mpls->mpls_lse);
6889 base_n++;
b0a17866 6890 }
b02475c5
SH
6891}
6892
5bbda0aa 6893static void
3cea18ec 6894get_ipv4_key(const struct flow *flow, struct ovs_key_ipv4 *ipv4, bool is_mask)
5bbda0aa 6895{
d23df9a8
JR
6896 ipv4->ipv4_src = flow->nw_src;
6897 ipv4->ipv4_dst = flow->nw_dst;
6898 ipv4->ipv4_proto = flow->nw_proto;
6899 ipv4->ipv4_tos = flow->nw_tos;
6900 ipv4->ipv4_ttl = flow->nw_ttl;
3cea18ec 6901 ipv4->ipv4_frag = ovs_to_odp_frag(flow->nw_frag, is_mask);
d23df9a8 6902}
5bbda0aa 6903
d23df9a8 6904static void
3cea18ec 6905put_ipv4_key(const struct ovs_key_ipv4 *ipv4, struct flow *flow, bool is_mask)
d23df9a8
JR
6906{
6907 flow->nw_src = ipv4->ipv4_src;
6908 flow->nw_dst = ipv4->ipv4_dst;
6909 flow->nw_proto = ipv4->ipv4_proto;
6910 flow->nw_tos = ipv4->ipv4_tos;
6911 flow->nw_ttl = ipv4->ipv4_ttl;
3cea18ec 6912 flow->nw_frag = odp_to_ovs_frag(ipv4->ipv4_frag, is_mask);
d23df9a8
JR
6913}
6914
6915static void
6916commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow,
6917 struct ofpbuf *odp_actions, struct flow_wildcards *wc,
6918 bool use_masked)
6919{
6920 struct ovs_key_ipv4 key, mask, base;
5bbda0aa 6921
d23df9a8
JR
6922 /* Check that nw_proto and nw_frag remain unchanged. */
6923 ovs_assert(flow->nw_proto == base_flow->nw_proto &&
6924 flow->nw_frag == base_flow->nw_frag);
1dd35f8a 6925
3cea18ec
JR
6926 get_ipv4_key(flow, &key, false);
6927 get_ipv4_key(base_flow, &base, false);
6928 get_ipv4_key(&wc->masks, &mask, true);
d23df9a8
JR
6929 mask.ipv4_proto = 0; /* Not writeable. */
6930 mask.ipv4_frag = 0; /* Not writable. */
5bbda0aa 6931
d23df9a8
JR
6932 if (commit(OVS_KEY_ATTR_IPV4, use_masked, &key, &base, &mask, sizeof key,
6933 odp_actions)) {
3cea18ec 6934 put_ipv4_key(&base, base_flow, false);
d23df9a8 6935 if (mask.ipv4_proto != 0) { /* Mask was changed by commit(). */
3cea18ec 6936 put_ipv4_key(&mask, &wc->masks, true);
d23df9a8
JR
6937 }
6938 }
5bbda0aa
EJ
6939}
6940
c4f2731d 6941static void
3cea18ec 6942get_ipv6_key(const struct flow *flow, struct ovs_key_ipv6 *ipv6, bool is_mask)
c4f2731d 6943{
932c96b7
JR
6944 ipv6->ipv6_src = flow->ipv6_src;
6945 ipv6->ipv6_dst = flow->ipv6_dst;
d23df9a8
JR
6946 ipv6->ipv6_label = flow->ipv6_label;
6947 ipv6->ipv6_proto = flow->nw_proto;
6948 ipv6->ipv6_tclass = flow->nw_tos;
6949 ipv6->ipv6_hlimit = flow->nw_ttl;
3cea18ec 6950 ipv6->ipv6_frag = ovs_to_odp_frag(flow->nw_frag, is_mask);
d23df9a8 6951}
c4f2731d 6952
d23df9a8 6953static void
3cea18ec 6954put_ipv6_key(const struct ovs_key_ipv6 *ipv6, struct flow *flow, bool is_mask)
d23df9a8 6955{
932c96b7
JR
6956 flow->ipv6_src = ipv6->ipv6_src;
6957 flow->ipv6_dst = ipv6->ipv6_dst;
d23df9a8
JR
6958 flow->ipv6_label = ipv6->ipv6_label;
6959 flow->nw_proto = ipv6->ipv6_proto;
6960 flow->nw_tos = ipv6->ipv6_tclass;
6961 flow->nw_ttl = ipv6->ipv6_hlimit;
3cea18ec 6962 flow->nw_frag = odp_to_ovs_frag(ipv6->ipv6_frag, is_mask);
d23df9a8 6963}
c4f2731d 6964
d23df9a8
JR
6965static void
6966commit_set_ipv6_action(const struct flow *flow, struct flow *base_flow,
6967 struct ofpbuf *odp_actions, struct flow_wildcards *wc,
6968 bool use_masked)
6969{
6970 struct ovs_key_ipv6 key, mask, base;
1dd35f8a 6971
d23df9a8
JR
6972 /* Check that nw_proto and nw_frag remain unchanged. */
6973 ovs_assert(flow->nw_proto == base_flow->nw_proto &&
6974 flow->nw_frag == base_flow->nw_frag);
c4f2731d 6975
3cea18ec
JR
6976 get_ipv6_key(flow, &key, false);
6977 get_ipv6_key(base_flow, &base, false);
6978 get_ipv6_key(&wc->masks, &mask, true);
d23df9a8
JR
6979 mask.ipv6_proto = 0; /* Not writeable. */
6980 mask.ipv6_frag = 0; /* Not writable. */
c4f2731d 6981
d23df9a8
JR
6982 if (commit(OVS_KEY_ATTR_IPV6, use_masked, &key, &base, &mask, sizeof key,
6983 odp_actions)) {
3cea18ec 6984 put_ipv6_key(&base, base_flow, false);
d23df9a8 6985 if (mask.ipv6_proto != 0) { /* Mask was changed by commit(). */
3cea18ec 6986 put_ipv6_key(&mask, &wc->masks, true);
d23df9a8
JR
6987 }
6988 }
c4f2731d
PS
6989}
6990
d23df9a8
JR
6991static void
6992get_arp_key(const struct flow *flow, struct ovs_key_arp *arp)
f6c8a6b1 6993{
d23df9a8
JR
6994 /* ARP key has padding, clear it. */
6995 memset(arp, 0, sizeof *arp);
f6c8a6b1 6996
d23df9a8
JR
6997 arp->arp_sip = flow->nw_src;
6998 arp->arp_tip = flow->nw_dst;
6999 arp->arp_op = htons(flow->nw_proto);
74ff3298
JR
7000 arp->arp_sha = flow->arp_sha;
7001 arp->arp_tha = flow->arp_tha;
d23df9a8 7002}
f6c8a6b1 7003
d23df9a8
JR
7004static void
7005put_arp_key(const struct ovs_key_arp *arp, struct flow *flow)
7006{
7007 flow->nw_src = arp->arp_sip;
7008 flow->nw_dst = arp->arp_tip;
7009 flow->nw_proto = ntohs(arp->arp_op);
74ff3298
JR
7010 flow->arp_sha = arp->arp_sha;
7011 flow->arp_tha = arp->arp_tha;
d23df9a8 7012}
f6c8a6b1 7013
d23df9a8
JR
7014static enum slow_path_reason
7015commit_set_arp_action(const struct flow *flow, struct flow *base_flow,
7016 struct ofpbuf *odp_actions, struct flow_wildcards *wc)
7017{
7018 struct ovs_key_arp key, mask, base;
f6c8a6b1 7019
d23df9a8
JR
7020 get_arp_key(flow, &key);
7021 get_arp_key(base_flow, &base);
7022 get_arp_key(&wc->masks, &mask);
f6c8a6b1 7023
d23df9a8
JR
7024 if (commit(OVS_KEY_ATTR_ARP, true, &key, &base, &mask, sizeof key,
7025 odp_actions)) {
7026 put_arp_key(&base, base_flow);
7027 put_arp_key(&mask, &wc->masks);
7028 return SLOW_ACTION;
7029 }
7030 return 0;
f6c8a6b1
BP
7031}
7032
f6ecf944
JP
7033static void
7034get_icmp_key(const struct flow *flow, struct ovs_key_icmp *icmp)
7035{
7036 /* icmp_type and icmp_code are stored in tp_src and tp_dst, respectively */
7037 icmp->icmp_type = ntohs(flow->tp_src);
7038 icmp->icmp_code = ntohs(flow->tp_dst);
7039}
7040
7041static void
7042put_icmp_key(const struct ovs_key_icmp *icmp, struct flow *flow)
7043{
7044 /* icmp_type and icmp_code are stored in tp_src and tp_dst, respectively */
7045 flow->tp_src = htons(icmp->icmp_type);
7046 flow->tp_dst = htons(icmp->icmp_code);
7047}
7048
7049static enum slow_path_reason
7050commit_set_icmp_action(const struct flow *flow, struct flow *base_flow,
7051 struct ofpbuf *odp_actions, struct flow_wildcards *wc)
7052{
7053 struct ovs_key_icmp key, mask, base;
7054 enum ovs_key_attr attr;
7055
a75636c8 7056 if (is_icmpv4(flow, NULL)) {
efa6665e 7057 attr = OVS_KEY_ATTR_ICMP;
a75636c8 7058 } else if (is_icmpv6(flow, NULL)) {
efa6665e
DDP
7059 attr = OVS_KEY_ATTR_ICMPV6;
7060 } else {
7061 return 0;
7062 }
7063
f6ecf944
JP
7064 get_icmp_key(flow, &key);
7065 get_icmp_key(base_flow, &base);
7066 get_icmp_key(&wc->masks, &mask);
7067
f6ecf944
JP
7068 if (commit(attr, false, &key, &base, &mask, sizeof key, odp_actions)) {
7069 put_icmp_key(&base, base_flow);
7070 put_icmp_key(&mask, &wc->masks);
7071 return SLOW_ACTION;
7072 }
7073 return 0;
7074}
7075
e60e935b
SRCSA
7076static void
7077get_nd_key(const struct flow *flow, struct ovs_key_nd *nd)
7078{
932c96b7 7079 nd->nd_target = flow->nd_target;
e60e935b 7080 /* nd_sll and nd_tll are stored in arp_sha and arp_tha, respectively */
74ff3298
JR
7081 nd->nd_sll = flow->arp_sha;
7082 nd->nd_tll = flow->arp_tha;
e60e935b
SRCSA
7083}
7084
7085static void
7086put_nd_key(const struct ovs_key_nd *nd, struct flow *flow)
7087{
932c96b7 7088 flow->nd_target = nd->nd_target;
e60e935b 7089 /* nd_sll and nd_tll are stored in arp_sha and arp_tha, respectively */
74ff3298
JR
7090 flow->arp_sha = nd->nd_sll;
7091 flow->arp_tha = nd->nd_tll;
e60e935b
SRCSA
7092}
7093
7094static enum slow_path_reason
7095commit_set_nd_action(const struct flow *flow, struct flow *base_flow,
7096 struct ofpbuf *odp_actions,
7097 struct flow_wildcards *wc, bool use_masked)
7098{
7099 struct ovs_key_nd key, mask, base;
7100
7101 get_nd_key(flow, &key);
7102 get_nd_key(base_flow, &base);
7103 get_nd_key(&wc->masks, &mask);
7104
7105 if (commit(OVS_KEY_ATTR_ND, use_masked, &key, &base, &mask, sizeof key,
7106 odp_actions)) {
7107 put_nd_key(&base, base_flow);
7108 put_nd_key(&mask, &wc->masks);
7109 return SLOW_ACTION;
7110 }
7111
7112 return 0;
7113}
7114
f6c8a6b1 7115static enum slow_path_reason
c4f2731d 7116commit_set_nw_action(const struct flow *flow, struct flow *base,
d23df9a8
JR
7117 struct ofpbuf *odp_actions, struct flow_wildcards *wc,
7118 bool use_masked)
c4f2731d 7119{
f6c8a6b1 7120 /* Check if 'flow' really has an L3 header. */
c4f2731d 7121 if (!flow->nw_proto) {
f6c8a6b1 7122 return 0;
c4f2731d
PS
7123 }
7124
f6c8a6b1
BP
7125 switch (ntohs(base->dl_type)) {
7126 case ETH_TYPE_IP:
d23df9a8 7127 commit_set_ipv4_action(flow, base, odp_actions, wc, use_masked);
f6c8a6b1
BP
7128 break;
7129
7130 case ETH_TYPE_IPV6:
d23df9a8 7131 commit_set_ipv6_action(flow, base, odp_actions, wc, use_masked);
e60e935b 7132 return commit_set_nd_action(flow, base, odp_actions, wc, use_masked);
f6c8a6b1
BP
7133
7134 case ETH_TYPE_ARP:
7135 return commit_set_arp_action(flow, base, odp_actions, wc);
c4f2731d 7136 }
f6c8a6b1
BP
7137
7138 return 0;
c4f2731d
PS
7139}
7140
17553f27 7141static inline void
3d2fbd70
JS
7142get_nsh_key(const struct flow *flow, struct ovs_key_nsh *nsh, bool is_mask)
7143{
17553f27
YY
7144 *nsh = flow->nsh;
7145 if (!is_mask) {
7146 if (nsh->mdtype != NSH_M_TYPE1) {
7147 memset(nsh->context, 0, sizeof(nsh->context));
3d2fbd70
JS
7148 }
7149 }
7150}
7151
17553f27 7152static inline void
3d2fbd70
JS
7153put_nsh_key(const struct ovs_key_nsh *nsh, struct flow *flow,
7154 bool is_mask OVS_UNUSED)
7155{
17553f27
YY
7156 flow->nsh = *nsh;
7157 if (flow->nsh.mdtype != NSH_M_TYPE1) {
7158 memset(flow->nsh.context, 0, sizeof(flow->nsh.context));
3d2fbd70
JS
7159 }
7160}
7161
f59cb331 7162static bool
17553f27 7163commit_nsh(const struct ovs_key_nsh * flow_nsh, bool use_masked_set,
f59cb331
YY
7164 const struct ovs_key_nsh *key, struct ovs_key_nsh *base,
7165 struct ovs_key_nsh *mask, size_t size,
7166 struct ofpbuf *odp_actions)
7167{
7168 enum ovs_key_attr attr = OVS_KEY_ATTR_NSH;
7169
7170 if (memcmp(key, base, size) == 0) {
7171 /* Mask bits are set when we have either read or set the corresponding
7172 * values. Masked bits will be exact-matched, no need to set them
7173 * if the value did not actually change. */
7174 return false;
7175 }
7176
7177 bool fully_masked = odp_mask_is_exact(attr, mask, size);
7178
7179 if (use_masked_set && !fully_masked) {
7180 size_t nsh_key_ofs;
7181 struct ovs_nsh_key_base nsh_base;
7182 struct ovs_nsh_key_base nsh_base_mask;
7183 struct ovs_nsh_key_md1 md1;
7184 struct ovs_nsh_key_md1 md1_mask;
7185 size_t offset = nl_msg_start_nested(odp_actions,
7186 OVS_ACTION_ATTR_SET_MASKED);
7187
7188 nsh_base.flags = key->flags;
17553f27 7189 nsh_base.ttl = key->ttl;
f59cb331
YY
7190 nsh_base.mdtype = key->mdtype;
7191 nsh_base.np = key->np;
7192 nsh_base.path_hdr = key->path_hdr;
7193
7194 nsh_base_mask.flags = mask->flags;
17553f27 7195 nsh_base_mask.ttl = mask->ttl;
f59cb331
YY
7196 nsh_base_mask.mdtype = mask->mdtype;
7197 nsh_base_mask.np = mask->np;
7198 nsh_base_mask.path_hdr = mask->path_hdr;
7199
7200 /* OVS_KEY_ATTR_NSH keys */
7201 nsh_key_ofs = nl_msg_start_nested(odp_actions, OVS_KEY_ATTR_NSH);
7202
81fdabb9 7203 /* put value and mask for OVS_NSH_KEY_ATTR_BASE */
f59cb331
YY
7204 char *data = nl_msg_put_unspec_uninit(odp_actions,
7205 OVS_NSH_KEY_ATTR_BASE,
81fdabb9 7206 2 * sizeof(nsh_base));
f59cb331
YY
7207 const char *lkey = (char *)&nsh_base, *lmask = (char *)&nsh_base_mask;
7208 size_t lkey_size = sizeof(nsh_base);
7209
7210 while (lkey_size--) {
7211 *data++ = *lkey++ & *lmask++;
7212 }
81fdabb9
YY
7213 lmask = (char *)&nsh_base_mask;
7214 memcpy(data, lmask, sizeof(nsh_base_mask));
f59cb331
YY
7215
7216 switch (key->mdtype) {
7217 case NSH_M_TYPE1:
7218 memcpy(md1.context, key->context, sizeof key->context);
7219 memcpy(md1_mask.context, mask->context, sizeof mask->context);
7220
81fdabb9 7221 /* put value and mask for OVS_NSH_KEY_ATTR_MD1 */
f59cb331
YY
7222 data = nl_msg_put_unspec_uninit(odp_actions,
7223 OVS_NSH_KEY_ATTR_MD1,
81fdabb9 7224 2 * sizeof(md1));
f59cb331
YY
7225 lkey = (char *)&md1;
7226 lmask = (char *)&md1_mask;
7227 lkey_size = sizeof(md1);
7228
7229 while (lkey_size--) {
7230 *data++ = *lkey++ & *lmask++;
7231 }
f59cb331
YY
7232 lmask = (char *)&md1_mask;
7233 memcpy(data, lmask, sizeof(md1_mask));
7234 break;
7235 case NSH_M_TYPE2:
7236 default:
7237 /* No match support for other MD formats yet. */
7238 break;
7239 }
81fdabb9 7240
f59cb331
YY
7241 nl_msg_end_nested(odp_actions, nsh_key_ofs);
7242
7243 nl_msg_end_nested(odp_actions, offset);
7244 } else {
7245 if (!fully_masked) {
7246 memset(mask, 0xff, size);
7247 }
7248 size_t offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_SET);
7249 nsh_key_to_attr(odp_actions, flow_nsh, NULL, 0, false);
7250 nl_msg_end_nested(odp_actions, offset);
7251 }
7252 memcpy(base, key, size);
7253 return true;
7254}
7255
3d2fbd70
JS
7256static void
7257commit_set_nsh_action(const struct flow *flow, struct flow *base_flow,
7258 struct ofpbuf *odp_actions,
7259 struct flow_wildcards *wc,
7260 bool use_masked)
7261{
7262 struct ovs_key_nsh key, mask, base;
7263
7264 if (flow->dl_type != htons(ETH_TYPE_NSH) ||
7265 !memcmp(&base_flow->nsh, &flow->nsh, sizeof base_flow->nsh)) {
7266 return;
7267 }
7268
7269 /* Check that mdtype and np remain unchanged. */
7270 ovs_assert(flow->nsh.mdtype == base_flow->nsh.mdtype &&
7271 flow->nsh.np == base_flow->nsh.np);
7272
7273 get_nsh_key(flow, &key, false);
7274 get_nsh_key(base_flow, &base, false);
7275 get_nsh_key(&wc->masks, &mask, true);
7276 mask.mdtype = 0; /* Not writable. */
7277 mask.np = 0; /* Not writable. */
7278
f59cb331
YY
7279 if (commit_nsh(&base_flow->nsh, use_masked, &key, &base, &mask,
7280 sizeof key, odp_actions)) {
3d2fbd70
JS
7281 put_nsh_key(&base, base_flow, false);
7282 if (mask.mdtype != 0) { /* Mask was changed by commit(). */
7283 put_nsh_key(&mask, &wc->masks, true);
7284 }
7285 }
7286}
7287
d23df9a8
JR
7288/* TCP, UDP, and SCTP keys have the same layout. */
7289BUILD_ASSERT_DECL(sizeof(struct ovs_key_tcp) == sizeof(struct ovs_key_udp) &&
7290 sizeof(struct ovs_key_tcp) == sizeof(struct ovs_key_sctp));
7291
5bbda0aa 7292static void
3cea18ec 7293get_tp_key(const struct flow *flow, union ovs_key_tp *tp)
5bbda0aa 7294{
3cea18ec
JR
7295 tp->tcp.tcp_src = flow->tp_src;
7296 tp->tcp.tcp_dst = flow->tp_dst;
d23df9a8
JR
7297}
7298
7299static void
3cea18ec 7300put_tp_key(const union ovs_key_tp *tp, struct flow *flow)
d23df9a8 7301{
3cea18ec
JR
7302 flow->tp_src = tp->tcp.tcp_src;
7303 flow->tp_dst = tp->tcp.tcp_dst;
d23df9a8
JR
7304}
7305
7306static void
7307commit_set_port_action(const struct flow *flow, struct flow *base_flow,
7308 struct ofpbuf *odp_actions, struct flow_wildcards *wc,
7309 bool use_masked)
7310{
7311 enum ovs_key_attr key_type;
3cea18ec 7312 union ovs_key_tp key, mask, base;
d23df9a8 7313
791a09be
SH
7314 /* Check if 'flow' really has an L3 header. */
7315 if (!flow->nw_proto) {
7316 return;
7317 }
7318
d23df9a8 7319 if (!is_ip_any(base_flow)) {
5bbda0aa
EJ
7320 return;
7321 }
7322
5bbda0aa 7323 if (flow->nw_proto == IPPROTO_TCP) {
d23df9a8 7324 key_type = OVS_KEY_ATTR_TCP;
5bbda0aa 7325 } else if (flow->nw_proto == IPPROTO_UDP) {
d23df9a8 7326 key_type = OVS_KEY_ATTR_UDP;
c6bcb685 7327 } else if (flow->nw_proto == IPPROTO_SCTP) {
d23df9a8
JR
7328 key_type = OVS_KEY_ATTR_SCTP;
7329 } else {
7330 return;
7331 }
c6bcb685 7332
d23df9a8
JR
7333 get_tp_key(flow, &key);
7334 get_tp_key(base_flow, &base);
7335 get_tp_key(&wc->masks, &mask);
c6bcb685 7336
d23df9a8
JR
7337 if (commit(key_type, use_masked, &key, &base, &mask, sizeof key,
7338 odp_actions)) {
7339 put_tp_key(&base, base_flow);
7340 put_tp_key(&mask, &wc->masks);
5bbda0aa
EJ
7341 }
7342}
7343
7344static void
d23df9a8 7345commit_set_priority_action(const struct flow *flow, struct flow *base_flow,
1dd35f8a 7346 struct ofpbuf *odp_actions,
d23df9a8
JR
7347 struct flow_wildcards *wc,
7348 bool use_masked)
5bbda0aa 7349{
d23df9a8 7350 uint32_t key, mask, base;
1dd35f8a 7351
d23df9a8
JR
7352 key = flow->skb_priority;
7353 base = base_flow->skb_priority;
7354 mask = wc->masks.skb_priority;
5bbda0aa 7355
d23df9a8
JR
7356 if (commit(OVS_KEY_ATTR_PRIORITY, use_masked, &key, &base, &mask,
7357 sizeof key, odp_actions)) {
7358 base_flow->skb_priority = base;
7359 wc->masks.skb_priority = mask;
7360 }
5bbda0aa
EJ
7361}
7362
72e8bf28 7363static void
d23df9a8 7364commit_set_pkt_mark_action(const struct flow *flow, struct flow *base_flow,
1dd35f8a 7365 struct ofpbuf *odp_actions,
d23df9a8
JR
7366 struct flow_wildcards *wc,
7367 bool use_masked)
72e8bf28 7368{
d23df9a8 7369 uint32_t key, mask, base;
1dd35f8a 7370
d23df9a8
JR
7371 key = flow->pkt_mark;
7372 base = base_flow->pkt_mark;
7373 mask = wc->masks.pkt_mark;
72e8bf28 7374
d23df9a8
JR
7375 if (commit(OVS_KEY_ATTR_SKB_MARK, use_masked, &key, &base, &mask,
7376 sizeof key, odp_actions)) {
7377 base_flow->pkt_mark = base;
7378 wc->masks.pkt_mark = mask;
7379 }
72e8bf28 7380}
7fd91025 7381
1fc11c59 7382static void
f59cb331 7383odp_put_pop_nsh_action(struct ofpbuf *odp_actions)
1fc11c59 7384{
f59cb331 7385 nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_NSH);
1fc11c59
JS
7386}
7387
7388static void
f59cb331 7389odp_put_push_nsh_action(struct ofpbuf *odp_actions,
1fc11c59
JS
7390 const struct flow *flow,
7391 struct ofpbuf *encap_data)
7392{
f59cb331
YY
7393 uint8_t * metadata = NULL;
7394 uint8_t md_size = 0;
1fc11c59 7395
f59cb331 7396 switch (flow->nsh.mdtype) {
1fc11c59
JS
7397 case NSH_M_TYPE2:
7398 if (encap_data) {
f59cb331
YY
7399 ovs_assert(encap_data->size < NSH_CTX_HDRS_MAX_LEN);
7400 metadata = encap_data->data;
7401 md_size = encap_data->size;
1fc11c59 7402 } else {
f59cb331 7403 md_size = 0;
1fc11c59
JS
7404 }
7405 break;
7406 default:
f59cb331 7407 md_size = 0;
1fc11c59
JS
7408 break;
7409 }
f59cb331
YY
7410 size_t offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_PUSH_NSH);
7411 nsh_key_to_attr(odp_actions, &flow->nsh, metadata, md_size, false);
7412 nl_msg_end_nested(odp_actions, offset);
1fc11c59
JS
7413}
7414
f839892a
JS
7415static void
7416commit_packet_type_change(const struct flow *flow,
7417 struct flow *base_flow,
7418 struct ofpbuf *odp_actions,
7419 struct flow_wildcards *wc,
1fc11c59
JS
7420 bool pending_encap,
7421 struct ofpbuf *encap_data)
f839892a
JS
7422{
7423 if (flow->packet_type == base_flow->packet_type) {
7424 return;
7425 }
7426
7427 if (pending_encap) {
7428 switch (ntohl(flow->packet_type)) {
7429 case PT_ETH: {
7430 /* push_eth */
7431 odp_put_push_eth_action(odp_actions, &flow->dl_src,
7432 &flow->dl_dst);
7433 base_flow->packet_type = flow->packet_type;
7434 base_flow->dl_src = flow->dl_src;
7435 base_flow->dl_dst = flow->dl_dst;
7436 break;
7437 }
1fc11c59 7438 case PT_NSH:
f59cb331
YY
7439 /* push_nsh */
7440 odp_put_push_nsh_action(odp_actions, flow, encap_data);
1fc11c59
JS
7441 base_flow->packet_type = flow->packet_type;
7442 /* Update all packet headers in base_flow. */
7443 memcpy(&base_flow->dl_dst, &flow->dl_dst,
7444 sizeof(*flow) - offsetof(struct flow, dl_dst));
7445 break;
f839892a 7446 default:
1fc11c59
JS
7447 /* Only the above protocols are supported for encap.
7448 * The check is done at action translation. */
f839892a
JS
7449 OVS_NOT_REACHED();
7450 }
7451 } else {
1fc11c59 7452 /* This is an explicit or implicit decap case. */
f839892a
JS
7453 if (pt_ns(flow->packet_type) == OFPHTN_ETHERTYPE &&
7454 base_flow->packet_type == htonl(PT_ETH)) {
1fc11c59 7455 /* Generate pop_eth and continue without recirculation. */
f839892a
JS
7456 odp_put_pop_eth_action(odp_actions);
7457 base_flow->packet_type = flow->packet_type;
7458 base_flow->dl_src = eth_addr_zero;
7459 base_flow->dl_dst = eth_addr_zero;
7460 } else {
1fc11c59
JS
7461 /* All other decap cases require recirculation.
7462 * No need to update the base flow here. */
7463 switch (ntohl(base_flow->packet_type)) {
7464 case PT_NSH:
f59cb331
YY
7465 /* pop_nsh. */
7466 odp_put_pop_nsh_action(odp_actions);
1fc11c59
JS
7467 break;
7468 default:
7469 /* Checks are done during translation. */
7470 OVS_NOT_REACHED();
7471 }
f839892a
JS
7472 }
7473 }
7474
7475 wc->masks.packet_type = OVS_BE32_MAX;
7476}
7477
5bbda0aa
EJ
7478/* If any of the flow key data that ODP actions can modify are different in
7479 * 'base' and 'flow', appends ODP actions to 'odp_actions' that change the flow
b9ad7294
EJ
7480 * key from 'base' into 'flow', and then changes 'base' the same way. Does not
7481 * commit set_tunnel actions. Users should call commit_odp_tunnel_action()
1dd35f8a 7482 * in addition to this function if needed. Sets fields in 'wc' that are
7fd91025
BP
7483 * used as part of the action.
7484 *
7485 * Returns a reason to force processing the flow's packets into the userspace
7486 * slow path, if there is one, otherwise 0. */
7487enum slow_path_reason
5bbda0aa 7488commit_odp_actions(const struct flow *flow, struct flow *base,
d23df9a8 7489 struct ofpbuf *odp_actions, struct flow_wildcards *wc,
1fc11c59
JS
7490 bool use_masked, bool pending_encap,
7491 struct ofpbuf *encap_data)
5bbda0aa 7492{
f6ecf944 7493 enum slow_path_reason slow1, slow2;
742c0ac3 7494 bool mpls_done = false;
f6c8a6b1 7495
1fc11c59
JS
7496 commit_packet_type_change(flow, base, odp_actions, wc,
7497 pending_encap, encap_data);
f839892a 7498 commit_set_ether_action(flow, base, odp_actions, wc, use_masked);
742c0ac3
JR
7499 /* Make packet a non-MPLS packet before committing L3/4 actions,
7500 * which would otherwise do nothing. */
7501 if (eth_type_mpls(base->dl_type) && !eth_type_mpls(flow->dl_type)) {
7502 commit_mpls_action(flow, base, odp_actions);
7503 mpls_done = true;
7504 }
3d2fbd70 7505 commit_set_nsh_action(flow, base, odp_actions, wc, use_masked);
f6ecf944 7506 slow1 = commit_set_nw_action(flow, base, odp_actions, wc, use_masked);
d23df9a8 7507 commit_set_port_action(flow, base, odp_actions, wc, use_masked);
f6ecf944 7508 slow2 = commit_set_icmp_action(flow, base, odp_actions, wc);
742c0ac3
JR
7509 if (!mpls_done) {
7510 commit_mpls_action(flow, base, odp_actions);
7511 }
f0fb825a 7512 commit_vlan_action(flow, base, odp_actions, wc);
d23df9a8
JR
7513 commit_set_priority_action(flow, base, odp_actions, wc, use_masked);
7514 commit_set_pkt_mark_action(flow, base, odp_actions, wc, use_masked);
7fd91025 7515
f6ecf944 7516 return slow1 ? slow1 : slow2;
5bbda0aa 7517}