]> git.proxmox.com Git - ovs.git/blame - lib/ofp-flow.c
ofp-port: Drop of useless indirection in ofputil_pull_ofp14_port_stats().
[ovs.git] / lib / ofp-flow.c
CommitLineData
0d71302e
BP
1/*
2 * Copyright (c) 2008-2017 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <config.h>
18#include "openvswitch/ofp-flow.h"
19#include <errno.h>
20#include "byte-order.h"
dfc77282 21#include "colors.h"
0d71302e
BP
22#include "flow.h"
23#include "nx-match.h"
24#include "openvswitch/ofp-actions.h"
25#include "openvswitch/ofp-group.h"
26#include "openvswitch/ofp-match.h"
27#include "openvswitch/ofp-msgs.h"
28#include "openvswitch/ofp-parse.h"
29#include "openvswitch/ofp-port.h"
dfc77282 30#include "openvswitch/ofp-print.h"
0d71302e
BP
31#include "openvswitch/ofp-table.h"
32#include "openvswitch/ofpbuf.h"
33#include "openvswitch/vlog.h"
34#include "util.h"
c7b02b80 35#include "ox-stat.h"
0d71302e
BP
36
37VLOG_DEFINE_THIS_MODULE(ofp_flow);
38
39static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
225c33ba 40\f
0d71302e
BP
41struct ofputil_flow_mod_flag {
42 uint16_t raw_flag;
43 enum ofp_version min_version, max_version;
44 enum ofputil_flow_mod_flags flag;
45};
46
47static const struct ofputil_flow_mod_flag ofputil_flow_mod_flags[] = {
48 { OFPFF_SEND_FLOW_REM, OFP10_VERSION, 0, OFPUTIL_FF_SEND_FLOW_REM },
49 { OFPFF_CHECK_OVERLAP, OFP10_VERSION, 0, OFPUTIL_FF_CHECK_OVERLAP },
50 { OFPFF10_EMERG, OFP10_VERSION, OFP10_VERSION,
51 OFPUTIL_FF_EMERG },
52 { OFPFF12_RESET_COUNTS, OFP12_VERSION, 0, OFPUTIL_FF_RESET_COUNTS },
53 { OFPFF13_NO_PKT_COUNTS, OFP13_VERSION, 0, OFPUTIL_FF_NO_PKT_COUNTS },
54 { OFPFF13_NO_BYT_COUNTS, OFP13_VERSION, 0, OFPUTIL_FF_NO_BYT_COUNTS },
55 { 0, 0, 0, 0 },
56};
57
58static enum ofperr
59ofputil_decode_flow_mod_flags(ovs_be16 raw_flags_,
60 enum ofp_flow_mod_command command,
61 enum ofp_version version,
62 enum ofputil_flow_mod_flags *flagsp)
63{
64 uint16_t raw_flags = ntohs(raw_flags_);
65 const struct ofputil_flow_mod_flag *f;
66
67 *flagsp = 0;
68 for (f = ofputil_flow_mod_flags; f->raw_flag; f++) {
69 if (raw_flags & f->raw_flag
70 && version >= f->min_version
71 && (!f->max_version || version <= f->max_version)) {
72 raw_flags &= ~f->raw_flag;
73 *flagsp |= f->flag;
74 }
75 }
76
77 /* In OF1.0 and OF1.1, "add" always resets counters, and other commands
78 * never do.
79 *
80 * In OF1.2 and later, OFPFF12_RESET_COUNTS controls whether each command
81 * resets counters. */
82 if ((version == OFP10_VERSION || version == OFP11_VERSION)
83 && command == OFPFC_ADD) {
84 *flagsp |= OFPUTIL_FF_RESET_COUNTS;
85 }
86
87 return raw_flags ? OFPERR_OFPFMFC_BAD_FLAGS : 0;
88}
89
90static ovs_be16
91ofputil_encode_flow_mod_flags(enum ofputil_flow_mod_flags flags,
92 enum ofp_version version)
93{
94 const struct ofputil_flow_mod_flag *f;
95 uint16_t raw_flags;
96
97 raw_flags = 0;
98 for (f = ofputil_flow_mod_flags; f->raw_flag; f++) {
99 if (f->flag & flags
100 && version >= f->min_version
101 && (!f->max_version || version <= f->max_version)) {
102 raw_flags |= f->raw_flag;
103 }
104 }
105
106 return htons(raw_flags);
107}
108
dfc77282
BP
109void
110ofputil_flow_mod_flags_format(struct ds *s, enum ofputil_flow_mod_flags flags)
111{
112 if (flags & OFPUTIL_FF_SEND_FLOW_REM) {
113 ds_put_cstr(s, "send_flow_rem ");
114 }
115 if (flags & OFPUTIL_FF_CHECK_OVERLAP) {
116 ds_put_cstr(s, "check_overlap ");
117 }
118 if (flags & OFPUTIL_FF_RESET_COUNTS) {
119 ds_put_cstr(s, "reset_counts ");
120 }
121 if (flags & OFPUTIL_FF_NO_PKT_COUNTS) {
122 ds_put_cstr(s, "no_packet_counts ");
123 }
124 if (flags & OFPUTIL_FF_NO_BYT_COUNTS) {
125 ds_put_cstr(s, "no_byte_counts ");
126 }
127 if (flags & OFPUTIL_FF_HIDDEN_FIELDS) {
128 ds_put_cstr(s, "allow_hidden_fields ");
129 }
130 if (flags & OFPUTIL_FF_NO_READONLY) {
131 ds_put_cstr(s, "no_readonly_table ");
132 }
133}
134
0d71302e
BP
135/* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
136 * flow_mod in 'fm'. Returns 0 if successful, otherwise an OpenFlow error
137 * code.
138 *
139 * Uses 'ofpacts' to store the abstract OFPACT_* version of 'oh''s actions.
140 * The caller must initialize 'ofpacts' and retains ownership of it.
141 * 'fm->ofpacts' will point into the 'ofpacts' buffer.
142 *
6a6b7060
BP
143 * On success, the caller must eventually destroy fm->match.
144 *
0d71302e
BP
145 * Does not validate the flow_mod actions. The caller should do that, with
146 * ofpacts_check(). */
147enum ofperr
148ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
149 const struct ofp_header *oh,
150 enum ofputil_protocol protocol,
151 const struct tun_table *tun_table,
152 const struct vl_mff_map *vl_mff_map,
153 struct ofpbuf *ofpacts,
154 ofp_port_t max_port, uint8_t max_table)
155{
156 ovs_be16 raw_flags;
157 enum ofperr error;
6a6b7060 158 struct match match;
0d71302e
BP
159 struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
160 enum ofpraw raw = ofpraw_pull_assert(&b);
161 if (raw == OFPRAW_OFPT11_FLOW_MOD) {
162 /* Standard OpenFlow 1.1+ flow_mod. */
163 const struct ofp11_flow_mod *ofm;
164
165 ofm = ofpbuf_pull(&b, sizeof *ofm);
166
6a6b7060 167 error = ofputil_pull_ofp11_match(&b, tun_table, vl_mff_map, &match,
0d71302e
BP
168 NULL);
169 if (error) {
170 return error;
171 }
172
173 /* Translate the message. */
174 fm->priority = ntohs(ofm->priority);
175 if (ofm->command == OFPFC_ADD
176 || (oh->version == OFP11_VERSION
177 && (ofm->command == OFPFC_MODIFY ||
178 ofm->command == OFPFC_MODIFY_STRICT)
179 && ofm->cookie_mask == htonll(0))) {
180 /* In OpenFlow 1.1 only, a "modify" or "modify-strict" that does
181 * not match on the cookie is treated as an "add" if there is no
182 * match. */
183 fm->cookie = htonll(0);
184 fm->cookie_mask = htonll(0);
185 fm->new_cookie = ofm->cookie;
186 } else {
187 fm->cookie = ofm->cookie;
188 fm->cookie_mask = ofm->cookie_mask;
189 fm->new_cookie = OVS_BE64_MAX;
190 }
191 fm->modify_cookie = false;
192 fm->command = ofm->command;
193
194 /* Get table ID.
195 *
196 * OF1.1 entirely forbids table_id == OFPTT_ALL.
197 * OF1.2+ allows table_id == OFPTT_ALL only for deletes. */
198 fm->table_id = ofm->table_id;
199 if (fm->table_id == OFPTT_ALL
200 && (oh->version == OFP11_VERSION
201 || (ofm->command != OFPFC_DELETE &&
202 ofm->command != OFPFC_DELETE_STRICT))) {
203 return OFPERR_OFPFMFC_BAD_TABLE_ID;
204 }
205
206 fm->idle_timeout = ntohs(ofm->idle_timeout);
207 fm->hard_timeout = ntohs(ofm->hard_timeout);
208 if (oh->version >= OFP14_VERSION && ofm->command == OFPFC_ADD) {
209 fm->importance = ntohs(ofm->importance);
210 } else {
211 fm->importance = 0;
212 }
213 fm->buffer_id = ntohl(ofm->buffer_id);
214 error = ofputil_port_from_ofp11(ofm->out_port, &fm->out_port);
215 if (error) {
216 return error;
217 }
218
219 fm->out_group = (ofm->command == OFPFC_DELETE ||
220 ofm->command == OFPFC_DELETE_STRICT
221 ? ntohl(ofm->out_group)
222 : OFPG_ANY);
223 raw_flags = ofm->flags;
224 } else {
225 uint16_t command;
226
227 if (raw == OFPRAW_OFPT10_FLOW_MOD) {
228 /* Standard OpenFlow 1.0 flow_mod. */
229 const struct ofp10_flow_mod *ofm;
230
231 /* Get the ofp10_flow_mod. */
232 ofm = ofpbuf_pull(&b, sizeof *ofm);
233
234 /* Translate the rule. */
6a6b7060
BP
235 ofputil_match_from_ofp10_match(&ofm->match, &match);
236 ofputil_normalize_match(&match);
0d71302e
BP
237
238 /* OpenFlow 1.0 says that exact-match rules have to have the
239 * highest possible priority. */
240 fm->priority = (ofm->match.wildcards & htonl(OFPFW10_ALL)
241 ? ntohs(ofm->priority)
242 : UINT16_MAX);
243
244 /* Translate the message. */
245 command = ntohs(ofm->command);
246 fm->cookie = htonll(0);
247 fm->cookie_mask = htonll(0);
248 fm->new_cookie = ofm->cookie;
249 fm->idle_timeout = ntohs(ofm->idle_timeout);
250 fm->hard_timeout = ntohs(ofm->hard_timeout);
251 fm->importance = 0;
252 fm->buffer_id = ntohl(ofm->buffer_id);
253 fm->out_port = u16_to_ofp(ntohs(ofm->out_port));
254 fm->out_group = OFPG_ANY;
255 raw_flags = ofm->flags;
256 } else if (raw == OFPRAW_NXT_FLOW_MOD) {
257 /* Nicira extended flow_mod. */
258 const struct nx_flow_mod *nfm;
259
260 /* Dissect the message. */
261 nfm = ofpbuf_pull(&b, sizeof *nfm);
262 error = nx_pull_match(&b, ntohs(nfm->match_len),
6a6b7060 263 &match, &fm->cookie, &fm->cookie_mask,
0d71302e
BP
264 false, tun_table, vl_mff_map);
265 if (error) {
266 return error;
267 }
268
269 /* Translate the message. */
270 command = ntohs(nfm->command);
271 if ((command & 0xff) == OFPFC_ADD && fm->cookie_mask) {
272 /* Flow additions may only set a new cookie, not match an
273 * existing cookie. */
274 return OFPERR_NXBRC_NXM_INVALID;
275 }
276 fm->priority = ntohs(nfm->priority);
277 fm->new_cookie = nfm->cookie;
278 fm->idle_timeout = ntohs(nfm->idle_timeout);
279 fm->hard_timeout = ntohs(nfm->hard_timeout);
280 fm->importance = 0;
281 fm->buffer_id = ntohl(nfm->buffer_id);
282 fm->out_port = u16_to_ofp(ntohs(nfm->out_port));
283 fm->out_group = OFPG_ANY;
284 raw_flags = nfm->flags;
285 } else {
286 OVS_NOT_REACHED();
287 }
288
289 fm->modify_cookie = fm->new_cookie != OVS_BE64_MAX;
290 if (protocol & OFPUTIL_P_TID) {
291 fm->command = command & 0xff;
292 fm->table_id = command >> 8;
293 } else {
294 if (command > 0xff) {
295 VLOG_WARN_RL(&rl, "flow_mod has explicit table_id "
296 "but flow_mod_table_id extension is not enabled");
297 }
298 fm->command = command;
299 fm->table_id = 0xff;
300 }
301 }
302
303 /* Check for mismatched conntrack original direction tuple address fields
304 * w.r.t. the IP version of the match. */
6a6b7060
BP
305 if (((match.wc.masks.ct_nw_src || match.wc.masks.ct_nw_dst)
306 && match.flow.dl_type != htons(ETH_TYPE_IP))
307 || ((ipv6_addr_is_set(&match.wc.masks.ct_ipv6_src)
308 || ipv6_addr_is_set(&match.wc.masks.ct_ipv6_dst))
309 && match.flow.dl_type != htons(ETH_TYPE_IPV6))) {
0d71302e
BP
310 return OFPERR_OFPBAC_MATCH_INCONSISTENT;
311 }
312
313 if (fm->command > OFPFC_DELETE_STRICT) {
314 return OFPERR_OFPFMFC_BAD_COMMAND;
315 }
316
317 fm->ofpacts_tlv_bitmap = 0;
318 error = ofpacts_pull_openflow_instructions(&b, b.size, oh->version,
319 vl_mff_map,
320 &fm->ofpacts_tlv_bitmap,
321 ofpacts);
322 if (error) {
323 return error;
324 }
325 fm->ofpacts = ofpacts->data;
326 fm->ofpacts_len = ofpacts->size;
327
328 error = ofputil_decode_flow_mod_flags(raw_flags, fm->command,
329 oh->version, &fm->flags);
330 if (error) {
331 return error;
332 }
333
334 if (fm->flags & OFPUTIL_FF_EMERG) {
335 /* We do not support the OpenFlow 1.0 emergency flow cache, which
336 * is not required in OpenFlow 1.0.1 and removed from OpenFlow 1.1.
337 *
338 * OpenFlow 1.0 specifies the error code to use when idle_timeout
339 * or hard_timeout is nonzero. Otherwise, there is no good error
340 * code, so just state that the flow table is full. */
341 return (fm->hard_timeout || fm->idle_timeout
342 ? OFPERR_OFPFMFC_BAD_EMERG_TIMEOUT
343 : OFPERR_OFPFMFC_TABLE_FULL);
344 }
345
ae6f7530
BP
346 struct ofpact_check_params cp = {
347 .match = &match,
348 .max_ports = max_port,
349 .table_id = fm->table_id,
350 .n_tables = max_table
351 };
6a6b7060 352 error = ofpacts_check_consistency(fm->ofpacts, fm->ofpacts_len,
ae6f7530 353 protocol, &cp);
6a6b7060
BP
354 if (!error) {
355 minimatch_init(&fm->match, &match);
356 }
357 return error;
0d71302e
BP
358}
359
360static ovs_be16
361ofputil_tid_command(const struct ofputil_flow_mod *fm,
362 enum ofputil_protocol protocol)
363{
364 return htons(protocol & OFPUTIL_P_TID
365 ? (fm->command & 0xff) | (fm->table_id << 8)
366 : fm->command);
367}
368
369/* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to
370 * 'protocol' and returns the message. */
371struct ofpbuf *
372ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
373 enum ofputil_protocol protocol)
374{
375 enum ofp_version version = ofputil_protocol_to_ofp_version(protocol);
376 ovs_be16 raw_flags = ofputil_encode_flow_mod_flags(fm->flags, version);
377 struct ofpbuf *msg;
378
6a6b7060
BP
379 struct match match;
380 minimatch_expand(&fm->match, &match);
381
0d71302e
BP
382 switch (protocol) {
383 case OFPUTIL_P_OF11_STD:
384 case OFPUTIL_P_OF12_OXM:
385 case OFPUTIL_P_OF13_OXM:
386 case OFPUTIL_P_OF14_OXM:
387 case OFPUTIL_P_OF15_OXM:
388 case OFPUTIL_P_OF16_OXM: {
389 struct ofp11_flow_mod *ofm;
390 int tailroom;
391
392 tailroom = ofputil_match_typical_len(protocol) + fm->ofpacts_len;
393 msg = ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD, version, tailroom);
394 ofm = ofpbuf_put_zeros(msg, sizeof *ofm);
395 if ((protocol == OFPUTIL_P_OF11_STD
396 && (fm->command == OFPFC_MODIFY ||
397 fm->command == OFPFC_MODIFY_STRICT)
398 && fm->cookie_mask == htonll(0))
399 || fm->command == OFPFC_ADD) {
400 ofm->cookie = fm->new_cookie;
401 } else {
402 ofm->cookie = fm->cookie & fm->cookie_mask;
403 }
404 ofm->cookie_mask = fm->cookie_mask;
405 if (fm->table_id != OFPTT_ALL
406 || (protocol != OFPUTIL_P_OF11_STD
407 && (fm->command == OFPFC_DELETE ||
408 fm->command == OFPFC_DELETE_STRICT))) {
409 ofm->table_id = fm->table_id;
410 } else {
411 ofm->table_id = 0;
412 }
413 ofm->command = fm->command;
414 ofm->idle_timeout = htons(fm->idle_timeout);
415 ofm->hard_timeout = htons(fm->hard_timeout);
416 ofm->priority = htons(fm->priority);
417 ofm->buffer_id = htonl(fm->buffer_id);
418 ofm->out_port = ofputil_port_to_ofp11(fm->out_port);
419 ofm->out_group = htonl(fm->out_group);
420 ofm->flags = raw_flags;
421 if (version >= OFP14_VERSION && fm->command == OFPFC_ADD) {
422 ofm->importance = htons(fm->importance);
423 } else {
424 ofm->importance = 0;
425 }
6a6b7060 426 ofputil_put_ofp11_match(msg, &match, protocol);
0d71302e
BP
427 ofpacts_put_openflow_instructions(fm->ofpacts, fm->ofpacts_len, msg,
428 version);
429 break;
430 }
431
432 case OFPUTIL_P_OF10_STD:
433 case OFPUTIL_P_OF10_STD_TID: {
434 struct ofp10_flow_mod *ofm;
435
436 msg = ofpraw_alloc(OFPRAW_OFPT10_FLOW_MOD, OFP10_VERSION,
437 fm->ofpacts_len);
438 ofm = ofpbuf_put_zeros(msg, sizeof *ofm);
6a6b7060 439 ofputil_match_to_ofp10_match(&match, &ofm->match);
0d71302e
BP
440 ofm->cookie = fm->new_cookie;
441 ofm->command = ofputil_tid_command(fm, protocol);
442 ofm->idle_timeout = htons(fm->idle_timeout);
443 ofm->hard_timeout = htons(fm->hard_timeout);
444 ofm->priority = htons(fm->priority);
445 ofm->buffer_id = htonl(fm->buffer_id);
446 ofm->out_port = htons(ofp_to_u16(fm->out_port));
447 ofm->flags = raw_flags;
448 ofpacts_put_openflow_actions(fm->ofpacts, fm->ofpacts_len, msg,
449 version);
450 break;
451 }
452
453 case OFPUTIL_P_OF10_NXM:
454 case OFPUTIL_P_OF10_NXM_TID: {
455 struct nx_flow_mod *nfm;
456 int match_len;
457
458 msg = ofpraw_alloc(OFPRAW_NXT_FLOW_MOD, OFP10_VERSION,
459 NXM_TYPICAL_LEN + fm->ofpacts_len);
460 nfm = ofpbuf_put_zeros(msg, sizeof *nfm);
461 nfm->command = ofputil_tid_command(fm, protocol);
462 nfm->cookie = fm->new_cookie;
6a6b7060 463 match_len = nx_put_match(msg, &match, fm->cookie, fm->cookie_mask);
0d71302e
BP
464 nfm = msg->msg;
465 nfm->idle_timeout = htons(fm->idle_timeout);
466 nfm->hard_timeout = htons(fm->hard_timeout);
467 nfm->priority = htons(fm->priority);
468 nfm->buffer_id = htonl(fm->buffer_id);
469 nfm->out_port = htons(ofp_to_u16(fm->out_port));
470 nfm->flags = raw_flags;
471 nfm->match_len = htons(match_len);
472 ofpacts_put_openflow_actions(fm->ofpacts, fm->ofpacts_len, msg,
473 version);
474 break;
475 }
476
477 default:
478 OVS_NOT_REACHED();
479 }
480
481 ofpmsg_update_length(msg);
482 return msg;
483}
484
dfc77282
BP
485enum ofperr
486ofputil_flow_mod_format(struct ds *s, const struct ofp_header *oh,
487 const struct ofputil_port_map *port_map,
488 const struct ofputil_table_map *table_map,
489 int verbosity)
490{
491 struct ofputil_flow_mod fm;
492 struct ofpbuf ofpacts;
493 bool need_priority;
494 enum ofperr error;
495 enum ofpraw raw;
496 enum ofputil_protocol protocol;
497
498 protocol = ofputil_protocol_from_ofp_version(oh->version);
499 protocol = ofputil_protocol_set_tid(protocol, true);
500
501 ofpbuf_init(&ofpacts, 64);
502 error = ofputil_decode_flow_mod(&fm, oh, protocol, NULL, NULL, &ofpacts,
503 OFPP_MAX, 255);
504 if (error) {
505 ofpbuf_uninit(&ofpacts);
506 return error;
507 }
508
509 ds_put_char(s, ' ');
510 switch (fm.command) {
511 case OFPFC_ADD:
512 ds_put_cstr(s, "ADD");
513 break;
514 case OFPFC_MODIFY:
515 ds_put_cstr(s, "MOD");
516 break;
517 case OFPFC_MODIFY_STRICT:
518 ds_put_cstr(s, "MOD_STRICT");
519 break;
520 case OFPFC_DELETE:
521 ds_put_cstr(s, "DEL");
522 break;
523 case OFPFC_DELETE_STRICT:
524 ds_put_cstr(s, "DEL_STRICT");
525 break;
526 default:
527 ds_put_format(s, "cmd:%d", fm.command);
528 }
529 if (fm.table_id != 0
530 || ofputil_table_map_get_name(table_map, fm.table_id)) {
531 ds_put_format(s, " table:");
532 ofputil_format_table(fm.table_id, table_map, s);
533 }
534
535 ds_put_char(s, ' ');
536 ofpraw_decode(&raw, oh);
537 if (verbosity >= 3 && raw == OFPRAW_OFPT10_FLOW_MOD) {
538 const struct ofp10_flow_mod *ofm = ofpmsg_body(oh);
539 ofp10_match_print(s, &ofm->match, port_map, verbosity);
540
541 /* ofp_print_match() doesn't print priority. */
542 need_priority = true;
543 } else if (verbosity >= 3 && raw == OFPRAW_NXT_FLOW_MOD) {
544 const struct nx_flow_mod *nfm = ofpmsg_body(oh);
545 const void *nxm = nfm + 1;
546 char *nxm_s;
547
548 nxm_s = nx_match_to_string(nxm, ntohs(nfm->match_len));
549 ds_put_cstr(s, nxm_s);
550 free(nxm_s);
551
552 /* nx_match_to_string() doesn't print priority. */
553 need_priority = true;
554 } else {
6a6b7060
BP
555 struct match match;
556 minimatch_expand(&fm.match, &match);
557 match_format(&match, port_map, s, fm.priority);
dfc77282
BP
558
559 /* match_format() does print priority. */
560 need_priority = false;
561 }
562
563 if (ds_last(s) != ' ') {
564 ds_put_char(s, ' ');
565 }
566 if (fm.new_cookie != htonll(0) && fm.new_cookie != OVS_BE64_MAX) {
567 ds_put_format(s, "cookie:0x%"PRIx64" ", ntohll(fm.new_cookie));
568 }
569 if (fm.cookie_mask != htonll(0)) {
570 ds_put_format(s, "cookie:0x%"PRIx64"/0x%"PRIx64" ",
571 ntohll(fm.cookie), ntohll(fm.cookie_mask));
572 }
573 if (fm.idle_timeout != OFP_FLOW_PERMANENT) {
574 ds_put_format(s, "idle:%"PRIu16" ", fm.idle_timeout);
575 }
576 if (fm.hard_timeout != OFP_FLOW_PERMANENT) {
577 ds_put_format(s, "hard:%"PRIu16" ", fm.hard_timeout);
578 }
579 if (fm.importance != 0) {
580 ds_put_format(s, "importance:%"PRIu16" ", fm.importance);
581 }
582 if (fm.priority != OFP_DEFAULT_PRIORITY && need_priority) {
583 ds_put_format(s, "pri:%d ", fm.priority);
584 }
585 if (fm.buffer_id != UINT32_MAX) {
586 ds_put_format(s, "buf:0x%"PRIx32" ", fm.buffer_id);
587 }
588 if (fm.out_port != OFPP_ANY) {
589 ds_put_format(s, "out_port:");
590 ofputil_format_port(fm.out_port, port_map, s);
591 ds_put_char(s, ' ');
592 }
593
594 if (oh->version == OFP10_VERSION || oh->version == OFP11_VERSION) {
595 /* Don't print the reset_counts flag for OF1.0 and OF1.1 because those
596 * versions don't really have such a flag and printing one is likely to
597 * confuse people. */
598 fm.flags &= ~OFPUTIL_FF_RESET_COUNTS;
599 }
600 ofputil_flow_mod_flags_format(s, fm.flags);
601
602 ds_put_cstr(s, "actions=");
603 struct ofpact_format_params fp = {
604 .port_map = port_map,
605 .table_map = table_map,
606 .s = s,
607 };
608 ofpacts_format(fm.ofpacts, fm.ofpacts_len, &fp);
609 ofpbuf_uninit(&ofpacts);
6a6b7060 610 minimatch_destroy(&fm.match);
dfc77282
BP
611
612 return 0;
613}
614
0d71302e
BP
615static enum ofperr
616ofputil_decode_ofpst10_flow_request(struct ofputil_flow_stats_request *fsr,
617 const struct ofp10_flow_stats_request *ofsr,
618 bool aggregate)
619{
620 fsr->aggregate = aggregate;
621 ofputil_match_from_ofp10_match(&ofsr->match, &fsr->match);
622 fsr->out_port = u16_to_ofp(ntohs(ofsr->out_port));
623 fsr->out_group = OFPG_ANY;
624 fsr->table_id = ofsr->table_id;
625 fsr->cookie = fsr->cookie_mask = htonll(0);
626
627 return 0;
628}
629
630static enum ofperr
631ofputil_decode_ofpst11_flow_request(struct ofputil_flow_stats_request *fsr,
632 struct ofpbuf *b, bool aggregate,
633 const struct tun_table *tun_table,
634 const struct vl_mff_map *vl_mff_map)
635{
636 const struct ofp11_flow_stats_request *ofsr;
637 enum ofperr error;
638
639 ofsr = ofpbuf_pull(b, sizeof *ofsr);
640 fsr->aggregate = aggregate;
641 fsr->table_id = ofsr->table_id;
642 error = ofputil_port_from_ofp11(ofsr->out_port, &fsr->out_port);
643 if (error) {
644 return error;
645 }
646 fsr->out_group = ntohl(ofsr->out_group);
647 fsr->cookie = ofsr->cookie;
648 fsr->cookie_mask = ofsr->cookie_mask;
649 error = ofputil_pull_ofp11_match(b, tun_table, vl_mff_map, &fsr->match,
650 NULL);
651 if (error) {
652 return error;
653 }
654
655 return 0;
656}
657
658static enum ofperr
659ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr,
660 struct ofpbuf *b, bool aggregate,
661 const struct tun_table *tun_table,
662 const struct vl_mff_map *vl_mff_map)
663{
664 const struct nx_flow_stats_request *nfsr;
665 enum ofperr error;
666
667 nfsr = ofpbuf_pull(b, sizeof *nfsr);
668 error = nx_pull_match(b, ntohs(nfsr->match_len), &fsr->match,
669 &fsr->cookie, &fsr->cookie_mask, false, tun_table,
670 vl_mff_map);
671 if (error) {
672 return error;
673 }
674 if (b->size) {
675 return OFPERR_OFPBRC_BAD_LEN;
676 }
677
678 fsr->aggregate = aggregate;
679 fsr->out_port = u16_to_ofp(ntohs(nfsr->out_port));
680 fsr->out_group = OFPG_ANY;
681 fsr->table_id = nfsr->table_id;
682
683 return 0;
684}
685
686/* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
687 * request 'oh', into an abstract flow_stats_request in 'fsr'. Returns 0 if
688 * successful, otherwise an OpenFlow error code.
689 *
690 * 'vl_mff_map' is an optional parameter that is used to validate the length
691 * of variable length mf_fields in 'match'. If it is not provided, the
692 * default mf_fields with maximum length will be used. */
693enum ofperr
694ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request *fsr,
695 const struct ofp_header *oh,
696 const struct tun_table *tun_table,
697 const struct vl_mff_map *vl_mff_map)
698{
699 struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
700 enum ofpraw raw = ofpraw_pull_assert(&b);
701 switch ((int) raw) {
702 case OFPRAW_OFPST10_FLOW_REQUEST:
703 return ofputil_decode_ofpst10_flow_request(fsr, b.data, false);
704
705 case OFPRAW_OFPST10_AGGREGATE_REQUEST:
706 return ofputil_decode_ofpst10_flow_request(fsr, b.data, true);
707
708 case OFPRAW_OFPST11_FLOW_REQUEST:
709 return ofputil_decode_ofpst11_flow_request(fsr, &b, false, tun_table,
710 vl_mff_map);
711
712 case OFPRAW_OFPST11_AGGREGATE_REQUEST:
713 return ofputil_decode_ofpst11_flow_request(fsr, &b, true, tun_table,
714 vl_mff_map);
715
c7b02b80
S
716 case OFPRAW_OFPST15_AGGREGATE_REQUEST:
717 return ofputil_decode_ofpst11_flow_request(fsr, &b, true,
718 tun_table, vl_mff_map);
719
0d71302e
BP
720 case OFPRAW_NXST_FLOW_REQUEST:
721 return ofputil_decode_nxst_flow_request(fsr, &b, false, tun_table,
722 vl_mff_map);
723
724 case OFPRAW_NXST_AGGREGATE_REQUEST:
725 return ofputil_decode_nxst_flow_request(fsr, &b, true, tun_table,
726 vl_mff_map);
727
728 default:
729 /* Hey, the caller lied. */
730 OVS_NOT_REACHED();
731 }
732}
733
734/* Converts abstract flow_stats_request 'fsr' into an OFPST_FLOW,
735 * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
736 * 'protocol', and returns the message. */
737struct ofpbuf *
738ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
739 enum ofputil_protocol protocol)
740{
741 struct ofpbuf *msg;
742 enum ofpraw raw;
743
744 switch (protocol) {
745 case OFPUTIL_P_OF11_STD:
746 case OFPUTIL_P_OF12_OXM:
747 case OFPUTIL_P_OF13_OXM:
748 case OFPUTIL_P_OF14_OXM:
749 case OFPUTIL_P_OF15_OXM:
750 case OFPUTIL_P_OF16_OXM: {
751 struct ofp11_flow_stats_request *ofsr;
752
c7b02b80
S
753 if (protocol > OFPUTIL_P_OF14_OXM) {
754 raw = (fsr->aggregate
755 ? OFPRAW_OFPST15_AGGREGATE_REQUEST
756 : OFPRAW_OFPST11_FLOW_REQUEST);
757 } else {
758 raw = (fsr->aggregate
759 ? OFPRAW_OFPST11_AGGREGATE_REQUEST
760 : OFPRAW_OFPST11_FLOW_REQUEST);
761 }
0d71302e
BP
762 msg = ofpraw_alloc(raw, ofputil_protocol_to_ofp_version(protocol),
763 ofputil_match_typical_len(protocol));
764 ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr);
765 ofsr->table_id = fsr->table_id;
766 ofsr->out_port = ofputil_port_to_ofp11(fsr->out_port);
767 ofsr->out_group = htonl(fsr->out_group);
768 ofsr->cookie = fsr->cookie;
769 ofsr->cookie_mask = fsr->cookie_mask;
770 ofputil_put_ofp11_match(msg, &fsr->match, protocol);
771 break;
772 }
773
774 case OFPUTIL_P_OF10_STD:
775 case OFPUTIL_P_OF10_STD_TID: {
776 struct ofp10_flow_stats_request *ofsr;
777
778 raw = (fsr->aggregate
779 ? OFPRAW_OFPST10_AGGREGATE_REQUEST
780 : OFPRAW_OFPST10_FLOW_REQUEST);
781 msg = ofpraw_alloc(raw, OFP10_VERSION, 0);
782 ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr);
783 ofputil_match_to_ofp10_match(&fsr->match, &ofsr->match);
784 ofsr->table_id = fsr->table_id;
785 ofsr->out_port = htons(ofp_to_u16(fsr->out_port));
786 break;
787 }
788
789 case OFPUTIL_P_OF10_NXM:
790 case OFPUTIL_P_OF10_NXM_TID: {
791 struct nx_flow_stats_request *nfsr;
792 int match_len;
793
794 raw = (fsr->aggregate
795 ? OFPRAW_NXST_AGGREGATE_REQUEST
796 : OFPRAW_NXST_FLOW_REQUEST);
797 msg = ofpraw_alloc(raw, OFP10_VERSION, NXM_TYPICAL_LEN);
798 ofpbuf_put_zeros(msg, sizeof *nfsr);
799 match_len = nx_put_match(msg, &fsr->match,
800 fsr->cookie, fsr->cookie_mask);
801
802 nfsr = msg->msg;
803 nfsr->out_port = htons(ofp_to_u16(fsr->out_port));
804 nfsr->match_len = htons(match_len);
805 nfsr->table_id = fsr->table_id;
806 break;
807 }
808
809 default:
810 OVS_NOT_REACHED();
811 }
812
813 return msg;
814}
815
dfc77282
BP
816void
817ofputil_flow_stats_request_format(struct ds *s,
818 const struct ofputil_flow_stats_request *fsr,
819 const struct ofputil_port_map *port_map,
820 const struct ofputil_table_map *table_map)
821{
822 if (fsr->table_id != 0xff) {
823 ds_put_format(s, " table=");
824 ofputil_format_table(fsr->table_id, table_map, s);
825 }
826
827 if (fsr->out_port != OFPP_ANY) {
828 ds_put_cstr(s, " out_port=");
829 ofputil_format_port(fsr->out_port, port_map, s);
830 }
831
832 ds_put_char(s, ' ');
833 match_format(&fsr->match, port_map, s, OFP_DEFAULT_PRIORITY);
834}
835
0d71302e
BP
836char * OVS_WARN_UNUSED_RESULT
837parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
838 bool aggregate, const char *string,
839 const struct ofputil_port_map *port_map,
840 const struct ofputil_table_map *table_map,
841 enum ofputil_protocol *usable_protocols)
842{
843 struct ofputil_flow_mod fm;
844 char *error;
845
846 error = parse_ofp_str(&fm, -1, string, port_map, table_map,
847 usable_protocols);
848 if (error) {
849 return error;
850 }
851
852 /* Special table ID support not required for stats requests. */
853 if (*usable_protocols & OFPUTIL_P_OF10_STD_TID) {
854 *usable_protocols |= OFPUTIL_P_OF10_STD;
855 }
856 if (*usable_protocols & OFPUTIL_P_OF10_NXM_TID) {
857 *usable_protocols |= OFPUTIL_P_OF10_NXM;
858 }
859
860 fsr->aggregate = aggregate;
861 fsr->cookie = fm.cookie;
862 fsr->cookie_mask = fm.cookie_mask;
6a6b7060 863 minimatch_expand(&fm.match, &fsr->match);
0d71302e
BP
864 fsr->out_port = fm.out_port;
865 fsr->out_group = fm.out_group;
866 fsr->table_id = fm.table_id;
6a6b7060
BP
867
868 minimatch_destroy(&fm.match);
869
0d71302e
BP
870 return NULL;
871}
872
873/* Converts an OFPST_FLOW or NXST_FLOW reply in 'msg' into an abstract
874 * ofputil_flow_stats in 'fs'.
875 *
876 * Multiple OFPST_FLOW or NXST_FLOW replies can be packed into a single
877 * OpenFlow message. Calling this function multiple times for a single 'msg'
878 * iterates through the replies. The caller must initially leave 'msg''s layer
879 * pointers null and not modify them between calls.
880 *
881 * Most switches don't send the values needed to populate fs->idle_age and
882 * fs->hard_age, so those members will usually be set to 0. If the switch from
883 * which 'msg' originated is known to implement NXT_FLOW_AGE, then pass
884 * 'flow_age_extension' as true so that the contents of 'msg' determine the
885 * 'idle_age' and 'hard_age' members in 'fs'.
886 *
887 * Uses 'ofpacts' to store the abstract OFPACT_* version of the flow stats
888 * reply's actions. The caller must initialize 'ofpacts' and retains ownership
889 * of it. 'fs->ofpacts' will point into the 'ofpacts' buffer.
890 *
891 * Returns 0 if successful, EOF if no replies were left in this 'msg',
0ef2d6ce 892 * otherwise an OFPERR_* value. */
0d71302e
BP
893int
894ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
895 struct ofpbuf *msg,
896 bool flow_age_extension,
897 struct ofpbuf *ofpacts)
898{
899 const struct ofp_header *oh;
900 size_t instructions_len;
901 enum ofperr error;
902 enum ofpraw raw;
903
904 error = (msg->header ? ofpraw_decode(&raw, msg->header)
905 : ofpraw_pull(&raw, msg));
906 if (error) {
907 return error;
908 }
909 oh = msg->header;
910
911 if (!msg->size) {
912 return EOF;
c7b02b80
S
913 } else if (raw == OFPRAW_OFPST15_FLOW_REPLY) {
914 const struct ofp15_flow_desc *ofd;
915 size_t length;
916 uint16_t padded_match_len;
917 uint16_t stat_len;
918 uint8_t oxs_field_set;
919
920 ofd = ofpbuf_try_pull(msg, sizeof *ofd);
921 if (!ofd) {
922 VLOG_WARN_RL(&rl, "OFPST_FLOW reply has %" PRIu32
923 " leftover " "bytes at end", msg->size);
924 return EINVAL;
925 }
926
927 length = ntohs(ofd->length);
928 if (length < sizeof *ofd) {
929 VLOG_WARN_RL(&rl, "OFPST_FLOW reply claims invalid "
930 "length %" PRIuSIZE, length);
931 return EINVAL;
932 }
933
934 if (ofputil_pull_ofp11_match(msg, NULL, NULL, &fs->match,
935 &padded_match_len)) {
936 VLOG_WARN_RL(&rl, "OFPST_FLOW reply bad match");
937 return EINVAL;
938 }
939
940 fs->priority = ntohs(ofd->priority);
941 fs->table_id = ofd->table_id;
942 fs->cookie = ofd->cookie;
943 fs->idle_timeout = ntohs(ofd->idle_timeout);
944 fs->hard_timeout = ntohs(ofd->hard_timeout);
945 fs->importance = ntohs(ofd->importance);
946
947 error = ofputil_decode_flow_mod_flags(ofd->flags, -1, oh->version,
948 &fs->flags);
949 if (error) {
950 return error;
951 }
952
953 struct oxs_stats oxs;
954 if (oxs_pull_stat(msg, &oxs, &stat_len, &oxs_field_set)) {
955 VLOG_WARN_RL(&rl, "OXS OFPST_FLOW reply bad stats");
956 return EINVAL;
957 }
958 fs->duration_sec = oxs.duration_sec;
959 fs->duration_nsec = oxs.duration_nsec;
960 fs->packet_count = oxs.packet_count;
961 fs->byte_count = oxs.byte_count;
962 fs->idle_age = oxs.idle_age == UINT32_MAX ? -1 : oxs.idle_age;
82d5b337 963 fs->hard_age = -1;
c7b02b80
S
964
965 instructions_len = length - sizeof *ofd - padded_match_len - stat_len;
0d71302e
BP
966 } else if (raw == OFPRAW_OFPST11_FLOW_REPLY
967 || raw == OFPRAW_OFPST13_FLOW_REPLY) {
968 const struct ofp11_flow_stats *ofs;
969 size_t length;
970 uint16_t padded_match_len;
971
972 ofs = ofpbuf_try_pull(msg, sizeof *ofs);
973 if (!ofs) {
974 VLOG_WARN_RL(&rl, "OFPST_FLOW reply has %"PRIu32" leftover "
975 "bytes at end", msg->size);
0ef2d6ce 976 return OFPERR_OFPBRC_BAD_LEN;
0d71302e
BP
977 }
978
979 length = ntohs(ofs->length);
980 if (length < sizeof *ofs) {
981 VLOG_WARN_RL(&rl, "OFPST_FLOW reply claims invalid "
982 "length %"PRIuSIZE, length);
0ef2d6ce 983 return OFPERR_OFPBRC_BAD_LEN;
0d71302e
BP
984 }
985
0ef2d6ce
BP
986 error = ofputil_pull_ofp11_match(msg, NULL, NULL, &fs->match,
987 &padded_match_len);
988 if (error) {
0d71302e 989 VLOG_WARN_RL(&rl, "OFPST_FLOW reply bad match");
0ef2d6ce 990 return error;
0d71302e
BP
991 }
992 instructions_len = length - sizeof *ofs - padded_match_len;
993
994 fs->priority = ntohs(ofs->priority);
995 fs->table_id = ofs->table_id;
996 fs->duration_sec = ntohl(ofs->duration_sec);
997 fs->duration_nsec = ntohl(ofs->duration_nsec);
998 fs->idle_timeout = ntohs(ofs->idle_timeout);
999 fs->hard_timeout = ntohs(ofs->hard_timeout);
1000 if (oh->version >= OFP14_VERSION) {
1001 fs->importance = ntohs(ofs->importance);
1002 } else {
1003 fs->importance = 0;
1004 }
1005 if (raw == OFPRAW_OFPST13_FLOW_REPLY) {
1006 error = ofputil_decode_flow_mod_flags(ofs->flags, -1, oh->version,
1007 &fs->flags);
1008 if (error) {
1009 return error;
1010 }
1011 } else {
1012 fs->flags = 0;
1013 }
1014 fs->idle_age = -1;
1015 fs->hard_age = -1;
1016 fs->cookie = ofs->cookie;
1017 fs->packet_count = ntohll(ofs->packet_count);
1018 fs->byte_count = ntohll(ofs->byte_count);
1019 } else if (raw == OFPRAW_OFPST10_FLOW_REPLY) {
1020 const struct ofp10_flow_stats *ofs;
1021 size_t length;
1022
1023 ofs = ofpbuf_try_pull(msg, sizeof *ofs);
1024 if (!ofs) {
1025 VLOG_WARN_RL(&rl, "OFPST_FLOW reply has %"PRIu32" leftover "
1026 "bytes at end", msg->size);
0ef2d6ce 1027 return OFPERR_OFPBRC_BAD_LEN;
0d71302e
BP
1028 }
1029
1030 length = ntohs(ofs->length);
1031 if (length < sizeof *ofs) {
1032 VLOG_WARN_RL(&rl, "OFPST_FLOW reply claims invalid "
1033 "length %"PRIuSIZE, length);
0ef2d6ce 1034 return OFPERR_OFPBRC_BAD_LEN;
0d71302e
BP
1035 }
1036 instructions_len = length - sizeof *ofs;
1037
1038 fs->cookie = get_32aligned_be64(&ofs->cookie);
1039 ofputil_match_from_ofp10_match(&ofs->match, &fs->match);
1040 fs->priority = ntohs(ofs->priority);
1041 fs->table_id = ofs->table_id;
1042 fs->duration_sec = ntohl(ofs->duration_sec);
1043 fs->duration_nsec = ntohl(ofs->duration_nsec);
1044 fs->idle_timeout = ntohs(ofs->idle_timeout);
1045 fs->hard_timeout = ntohs(ofs->hard_timeout);
1046 fs->importance = 0;
1047 fs->idle_age = -1;
1048 fs->hard_age = -1;
1049 fs->packet_count = ntohll(get_32aligned_be64(&ofs->packet_count));
1050 fs->byte_count = ntohll(get_32aligned_be64(&ofs->byte_count));
1051 fs->flags = 0;
1052 } else if (raw == OFPRAW_NXST_FLOW_REPLY) {
1053 const struct nx_flow_stats *nfs;
1054 size_t match_len, length;
1055
1056 nfs = ofpbuf_try_pull(msg, sizeof *nfs);
1057 if (!nfs) {
1058 VLOG_WARN_RL(&rl, "NXST_FLOW reply has %"PRIu32" leftover "
1059 "bytes at end", msg->size);
0ef2d6ce 1060 return OFPERR_OFPBRC_BAD_LEN;
0d71302e
BP
1061 }
1062
1063 length = ntohs(nfs->length);
1064 match_len = ntohs(nfs->match_len);
1065 if (length < sizeof *nfs + ROUND_UP(match_len, 8)) {
1066 VLOG_WARN_RL(&rl, "NXST_FLOW reply with match_len=%"PRIuSIZE" "
1067 "claims invalid length %"PRIuSIZE, match_len, length);
0ef2d6ce 1068 return OFPERR_OFPBRC_BAD_LEN;
0d71302e 1069 }
0ef2d6ce
BP
1070 error = nx_pull_match(msg, match_len, &fs->match, NULL, NULL, false,
1071 NULL, NULL);
1072 if (error) {
1073 return error;
0d71302e
BP
1074 }
1075 instructions_len = length - sizeof *nfs - ROUND_UP(match_len, 8);
1076
1077 fs->cookie = nfs->cookie;
1078 fs->table_id = nfs->table_id;
1079 fs->duration_sec = ntohl(nfs->duration_sec);
1080 fs->duration_nsec = ntohl(nfs->duration_nsec);
1081 fs->priority = ntohs(nfs->priority);
1082 fs->idle_timeout = ntohs(nfs->idle_timeout);
1083 fs->hard_timeout = ntohs(nfs->hard_timeout);
1084 fs->importance = 0;
1085 fs->idle_age = -1;
1086 fs->hard_age = -1;
1087 if (flow_age_extension) {
1088 if (nfs->idle_age) {
1089 fs->idle_age = ntohs(nfs->idle_age) - 1;
1090 }
1091 if (nfs->hard_age) {
1092 fs->hard_age = ntohs(nfs->hard_age) - 1;
1093 }
1094 }
1095 fs->packet_count = ntohll(nfs->packet_count);
1096 fs->byte_count = ntohll(nfs->byte_count);
1097 fs->flags = 0;
1098 } else {
1099 OVS_NOT_REACHED();
1100 }
1101
0ef2d6ce
BP
1102 error = ofpacts_pull_openflow_instructions(msg, instructions_len,
1103 oh->version, NULL, NULL,
1104 ofpacts);
1105 if (error) {
0d71302e 1106 VLOG_WARN_RL(&rl, "OFPST_FLOW reply bad instructions");
0ef2d6ce 1107 return error;
0d71302e
BP
1108 }
1109 fs->ofpacts = ofpacts->data;
1110 fs->ofpacts_len = ofpacts->size;
1111
1112 return 0;
1113}
1114
1115/* Returns 'count' unchanged except that UINT64_MAX becomes 0.
1116 *
1117 * We use this in situations where OVS internally uses UINT64_MAX to mean
1118 * "value unknown" but OpenFlow 1.0 does not define any unknown value. */
1119static uint64_t
1120unknown_to_zero(uint64_t count)
1121{
1122 return count != UINT64_MAX ? count : 0;
1123}
1124
1125/* Appends an OFPST_FLOW or NXST_FLOW reply that contains the data in 'fs' to
1126 * those already present in the list of ofpbufs in 'replies'. 'replies' should
1127 * have been initialized with ofpmp_init(). */
1128void
1129ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
1130 struct ovs_list *replies,
1131 const struct tun_table *tun_table)
1132{
1133 struct ofputil_flow_stats *fs_ = CONST_CAST(struct ofputil_flow_stats *,
1134 fs);
1135 const struct tun_table *orig_tun_table;
1136 struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies));
1137 size_t start_ofs = reply->size;
1138 enum ofp_version version = ofpmp_version(replies);
1139 enum ofpraw raw = ofpmp_decode_raw(replies);
1140
1141 orig_tun_table = fs->match.flow.tunnel.metadata.tab;
1142 fs_->match.flow.tunnel.metadata.tab = tun_table;
1143
c7b02b80
S
1144 if (raw == OFPRAW_OFPST15_FLOW_REPLY) {
1145 struct ofp15_flow_desc *ofd;
1146
1147 ofpbuf_put_uninit(reply, sizeof *ofd);
1148 oxm_put_match(reply, &fs->match, version);
1149
1150 struct oxs_stats oxs = {
1151 .duration_sec = fs->duration_sec,
1152 .duration_nsec = fs->duration_nsec,
1153 .idle_age = fs->idle_age >= 0 ? fs->idle_age : UINT32_MAX,
1154 .packet_count = fs->packet_count,
1155 .byte_count = fs->byte_count,
1156 .flow_count = UINT32_MAX,
1157 };
1158 oxs_put_stats(reply, &oxs);
1159
1160 ofpacts_put_openflow_instructions(fs->ofpacts, fs->ofpacts_len, reply,
1161 version);
1162
1163 ofd = ofpbuf_at_assert(reply, start_ofs, sizeof *ofd);
1164 ofd->length = htons(reply->size - start_ofs);
1165 ofd->table_id = fs->table_id;
1166 ofd->priority = htons(fs->priority);
1167 ofd->idle_timeout = htons(fs->idle_timeout);
1168 ofd->hard_timeout = htons(fs->hard_timeout);
1169 ofd->cookie = fs->cookie;
1170 memset(ofd->pad2, 0, sizeof ofd->pad2);
1171 ofd->pad = 0;
1172 ofd->importance = htons(fs->importance);
1173 ofd->flags = ofputil_encode_flow_mod_flags(fs->flags, version);
1174 } else if (raw == OFPRAW_OFPST11_FLOW_REPLY ||
1175 raw == OFPRAW_OFPST13_FLOW_REPLY) {
0d71302e
BP
1176 struct ofp11_flow_stats *ofs;
1177
1178 ofpbuf_put_uninit(reply, sizeof *ofs);
1179 oxm_put_match(reply, &fs->match, version);
1180 ofpacts_put_openflow_instructions(fs->ofpacts, fs->ofpacts_len, reply,
1181 version);
1182
1183 ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
1184 ofs->length = htons(reply->size - start_ofs);
1185 ofs->table_id = fs->table_id;
1186 ofs->pad = 0;
1187 ofs->duration_sec = htonl(fs->duration_sec);
1188 ofs->duration_nsec = htonl(fs->duration_nsec);
1189 ofs->priority = htons(fs->priority);
1190 ofs->idle_timeout = htons(fs->idle_timeout);
1191 ofs->hard_timeout = htons(fs->hard_timeout);
1192 if (version >= OFP14_VERSION) {
1193 ofs->importance = htons(fs->importance);
1194 } else {
1195 ofs->importance = 0;
1196 }
1197 if (raw == OFPRAW_OFPST13_FLOW_REPLY) {
1198 ofs->flags = ofputil_encode_flow_mod_flags(fs->flags, version);
1199 } else {
1200 ofs->flags = 0;
1201 }
1202 memset(ofs->pad2, 0, sizeof ofs->pad2);
1203 ofs->cookie = fs->cookie;
1204 ofs->packet_count = htonll(unknown_to_zero(fs->packet_count));
1205 ofs->byte_count = htonll(unknown_to_zero(fs->byte_count));
1206 } else if (raw == OFPRAW_OFPST10_FLOW_REPLY) {
1207 struct ofp10_flow_stats *ofs;
1208
1209 ofpbuf_put_uninit(reply, sizeof *ofs);
1210 ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply,
1211 version);
1212 ofs = ofpbuf_at_assert(reply, start_ofs, sizeof *ofs);
1213 ofs->length = htons(reply->size - start_ofs);
1214 ofs->table_id = fs->table_id;
1215 ofs->pad = 0;
1216 ofputil_match_to_ofp10_match(&fs->match, &ofs->match);
1217 ofs->duration_sec = htonl(fs->duration_sec);
1218 ofs->duration_nsec = htonl(fs->duration_nsec);
1219 ofs->priority = htons(fs->priority);
1220 ofs->idle_timeout = htons(fs->idle_timeout);
1221 ofs->hard_timeout = htons(fs->hard_timeout);
1222 memset(ofs->pad2, 0, sizeof ofs->pad2);
1223 put_32aligned_be64(&ofs->cookie, fs->cookie);
1224 put_32aligned_be64(&ofs->packet_count,
1225 htonll(unknown_to_zero(fs->packet_count)));
1226 put_32aligned_be64(&ofs->byte_count,
1227 htonll(unknown_to_zero(fs->byte_count)));
1228 } else if (raw == OFPRAW_NXST_FLOW_REPLY) {
1229 struct nx_flow_stats *nfs;
1230 int match_len;
1231
1232 ofpbuf_put_uninit(reply, sizeof *nfs);
1233 match_len = nx_put_match(reply, &fs->match, 0, 0);
1234 ofpacts_put_openflow_actions(fs->ofpacts, fs->ofpacts_len, reply,
1235 version);
1236 nfs = ofpbuf_at_assert(reply, start_ofs, sizeof *nfs);
1237 nfs->length = htons(reply->size - start_ofs);
1238 nfs->table_id = fs->table_id;
1239 nfs->pad = 0;
1240 nfs->duration_sec = htonl(fs->duration_sec);
1241 nfs->duration_nsec = htonl(fs->duration_nsec);
1242 nfs->priority = htons(fs->priority);
1243 nfs->idle_timeout = htons(fs->idle_timeout);
1244 nfs->hard_timeout = htons(fs->hard_timeout);
1245 nfs->idle_age = htons(fs->idle_age < 0 ? 0
1246 : fs->idle_age < UINT16_MAX ? fs->idle_age + 1
1247 : UINT16_MAX);
1248 nfs->hard_age = htons(fs->hard_age < 0 ? 0
1249 : fs->hard_age < UINT16_MAX ? fs->hard_age + 1
1250 : UINT16_MAX);
1251 nfs->match_len = htons(match_len);
1252 nfs->cookie = fs->cookie;
1253 nfs->packet_count = htonll(fs->packet_count);
1254 nfs->byte_count = htonll(fs->byte_count);
1255 } else {
1256 OVS_NOT_REACHED();
1257 }
1258
1259 ofpmp_postappend(replies, start_ofs);
1260 fs_->match.flow.tunnel.metadata.tab = orig_tun_table;
1261}
1262
c7b02b80
S
1263static void
1264print_flow_stat(struct ds *string, const char *leader, uint64_t stat)
1265{
1266 ds_put_format(string, "%s%s=%s", colors.param, leader, colors.end);
1267 if (stat != UINT64_MAX) {
1268 ds_put_format(string, "%"PRIu64, stat);
1269 } else {
1270 ds_put_char(string, '?');
1271 }
1272 ds_put_cstr(string, ", ");
1273}
1274
dfc77282
BP
1275/* Appends a textual form of 'fs' to 'string', translating port numbers to
1276 * names using 'port_map' (if provided). If 'show_stats' is true, the output
1277 * includes the flow duration, packet and byte counts, and its idle and hard
1278 * ages, otherwise they are omitted. */
1279void
1280ofputil_flow_stats_format(struct ds *string,
1281 const struct ofputil_flow_stats *fs,
1282 const struct ofputil_port_map *port_map,
1283 const struct ofputil_table_map *table_map,
1284 bool show_stats)
1285{
1286 if (show_stats || fs->cookie) {
1287 ds_put_format(string, "%scookie=%s0x%"PRIx64", ",
1288 colors.param, colors.end, ntohll(fs->cookie));
1289 }
1290 if (show_stats) {
1291 ds_put_format(string, "%sduration=%s", colors.param, colors.end);
1292 ofp_print_duration(string, fs->duration_sec, fs->duration_nsec);
1293 ds_put_cstr(string, ", ");
1294 }
1295
1296 if (show_stats || fs->table_id
1297 || ofputil_table_map_get_name(table_map, fs->table_id) != NULL) {
1298 ds_put_format(string, "%stable=%s", colors.special, colors.end);
1299 ofputil_format_table(fs->table_id, table_map, string);
1300 ds_put_cstr(string, ", ");
1301 }
1302 if (show_stats) {
c7b02b80
S
1303 print_flow_stat(string, "n_packets", fs->packet_count);
1304 print_flow_stat(string, "n_bytes", fs->byte_count);
dfc77282
BP
1305 }
1306 if (fs->idle_timeout != OFP_FLOW_PERMANENT) {
1307 ds_put_format(string, "%sidle_timeout=%s%"PRIu16", ",
1308 colors.param, colors.end, fs->idle_timeout);
1309 }
1310 if (fs->hard_timeout != OFP_FLOW_PERMANENT) {
1311 ds_put_format(string, "%shard_timeout=%s%"PRIu16", ",
1312 colors.param, colors.end, fs->hard_timeout);
1313 }
1314 if (fs->flags) {
1315 ofputil_flow_mod_flags_format(string, fs->flags);
1316 }
1317 if (fs->importance != 0) {
1318 ds_put_format(string, "%simportance=%s%"PRIu16", ",
1319 colors.param, colors.end, fs->importance);
1320 }
1321 if (show_stats && fs->idle_age >= 0) {
1322 ds_put_format(string, "%sidle_age=%s%d, ",
1323 colors.param, colors.end, fs->idle_age);
1324 }
1325 if (show_stats && fs->hard_age >= 0 && fs->hard_age != fs->duration_sec) {
1326 ds_put_format(string, "%shard_age=%s%d, ",
1327 colors.param, colors.end, fs->hard_age);
1328 }
1329
1330 /* Print the match, followed by a space (but omit the space if the match
1331 * was an empty string). */
1332 size_t length = string->length;
1333 match_format(&fs->match, port_map, string, fs->priority);
1334 if (string->length != length) {
1335 ds_put_char(string, ' ');
1336 }
1337
1338 ds_put_format(string, "%sactions=%s", colors.actions, colors.end);
1339 struct ofpact_format_params fp = {
1340 .port_map = port_map,
1341 .table_map = table_map,
1342 .s = string,
1343 };
1344 ofpacts_format(fs->ofpacts, fs->ofpacts_len, &fp);
1345}
1346
0d71302e
BP
1347/* Converts abstract ofputil_aggregate_stats 'stats' into an OFPST_AGGREGATE or
1348 * NXST_AGGREGATE reply matching 'request', and returns the message. */
1349struct ofpbuf *
1350ofputil_encode_aggregate_stats_reply(
1351 const struct ofputil_aggregate_stats *stats,
1352 const struct ofp_header *request)
1353{
1354 struct ofp_aggregate_stats_reply *asr;
1355 uint64_t packet_count;
1356 uint64_t byte_count;
1357 struct ofpbuf *msg;
1358 enum ofpraw raw;
1359
1360 ofpraw_decode(&raw, request);
c7b02b80
S
1361 if (raw == OFPRAW_OFPST15_AGGREGATE_REQUEST) {
1362 msg = ofpraw_alloc_stats_reply(request, 0);
1363
1364 struct oxs_stats oxs = {
1365 .duration_sec = UINT32_MAX,
1366 .duration_nsec = UINT32_MAX,
1367 .idle_age = UINT32_MAX,
1368 .packet_count = stats->packet_count,
1369 .byte_count = stats->byte_count,
1370 .flow_count = stats->flow_count,
1371 };
1372 oxs_put_stats(msg, &oxs);
0d71302e 1373 } else {
c7b02b80
S
1374 if (raw == OFPRAW_OFPST10_AGGREGATE_REQUEST) {
1375 packet_count = unknown_to_zero(stats->packet_count);
1376 byte_count = unknown_to_zero(stats->byte_count);
1377 } else {
1378 packet_count = stats->packet_count;
1379 byte_count = stats->byte_count;
1380 }
0d71302e 1381
c7b02b80
S
1382 msg = ofpraw_alloc_stats_reply(request, 0);
1383 asr = ofpbuf_put_zeros(msg, sizeof *asr);
1384 put_32aligned_be64(&asr->packet_count, htonll(packet_count));
1385 put_32aligned_be64(&asr->byte_count, htonll(byte_count));
1386 asr->flow_count = htonl(stats->flow_count);
1387 }
0d71302e
BP
1388 return msg;
1389}
1390
1391enum ofperr
1392ofputil_decode_aggregate_stats_reply(struct ofputil_aggregate_stats *stats,
1393 const struct ofp_header *reply)
1394{
1395 struct ofpbuf msg = ofpbuf_const_initializer(reply, ntohs(reply->length));
c7b02b80 1396 enum ofpraw raw;
0d71302e 1397
c7b02b80
S
1398 raw = ofpraw_pull_assert(&msg);
1399 if (raw == OFPRAW_OFPST15_AGGREGATE_REPLY) {
1400 struct oxs_stats oxs;
1401 uint16_t statlen;
1402 uint8_t oxs_field_set;
1403 enum ofperr error = oxs_pull_stat(&msg, &oxs, &statlen,
1404 &oxs_field_set);
1405 if (error) {
1406 return error;
1407 }
1408 stats->packet_count = oxs.packet_count;
1409 stats->byte_count = oxs.byte_count;
1410 stats->flow_count = oxs.flow_count;
1411 } else {
1412 struct ofp_aggregate_stats_reply *asr = msg.msg;
1413 stats->packet_count = ntohll(get_32aligned_be64(&asr->packet_count));
1414 stats->byte_count = ntohll(get_32aligned_be64(&asr->byte_count));
1415 stats->flow_count = ntohl(asr->flow_count);
1416 }
0d71302e
BP
1417
1418 return 0;
1419}
1420
dfc77282
BP
1421void
1422ofputil_aggregate_stats_format(struct ds *s,
1423 const struct ofputil_aggregate_stats *as)
1424{
1425 ds_put_format(s, " packet_count=%"PRIu64, as->packet_count);
1426 ds_put_format(s, " byte_count=%"PRIu64, as->byte_count);
1427 ds_put_format(s, " flow_count=%"PRIu32, as->flow_count);
1428}
0d71302e
BP
1429\f
1430/* Parses 'str_value' as the value of subfield 'name', and updates
1431 * 'match' appropriately. Restricts the set of usable protocols to ones
1432 * supporting the parsed field.
1433 *
1434 * Returns NULL if successful, otherwise a malloc()'d string describing the
1435 * error. The caller is responsible for freeing the returned string. */
1436static char * OVS_WARN_UNUSED_RESULT
1437parse_subfield(const char *name, const char *str_value, struct match *match,
1438 enum ofputil_protocol *usable_protocols)
1439{
1440 struct mf_subfield sf;
1441 char *error;
1442
1443 error = mf_parse_subfield(&sf, name);
1444 if (!error) {
1445 union mf_value val;
1446 char *tail;
1447 if (parse_int_string(str_value, (uint8_t *)&val, sf.field->n_bytes,
1448 &tail) || *tail != 0) {
1449 return xasprintf("%s: cannot parse integer value: %s", name,
1450 str_value);
1451 }
1452 if (!bitwise_is_all_zeros(&val, sf.field->n_bytes, sf.n_bits,
1453 sf.field->n_bytes * 8 - sf.n_bits)) {
1454 struct ds ds;
1455
1456 ds_init(&ds);
1457 mf_format(sf.field, &val, NULL, NULL, &ds);
1458 error = xasprintf("%s: value %s does not fit into %d bits",
1459 name, ds_cstr(&ds), sf.n_bits);
1460 ds_destroy(&ds);
1461 return error;
1462 }
1463
1464 const struct mf_field *field = sf.field;
1465 union mf_value value, mask;
1466 unsigned int size = field->n_bytes;
1467
1468 mf_get(field, match, &value, &mask);
1469 bitwise_copy(&val, size, 0, &value, size, sf.ofs, sf.n_bits);
1470 bitwise_one ( &mask, size, sf.ofs, sf.n_bits);
1471 *usable_protocols &= mf_set(field, &value, &mask, match, &error);
1472
1473 match_add_ethernet_prereq(match, sf.field);
1474 }
1475 return error;
1476}
1477
1478static char * OVS_WARN_UNUSED_RESULT
1479parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,
1480 const struct ofputil_port_map *port_map,
1481 const struct ofputil_table_map *table_map,
1482 enum ofputil_protocol *usable_protocols)
1483{
1484 enum {
1485 F_OUT_PORT = 1 << 0,
1486 F_ACTIONS = 1 << 1,
1487 F_IMPORTANCE = 1 << 2,
1488 F_TIMEOUT = 1 << 3,
1489 F_PRIORITY = 1 << 4,
1490 F_FLAGS = 1 << 5,
1491 } fields;
1492 char *act_str = NULL;
1493 char *name, *value;
1494
1495 *usable_protocols = OFPUTIL_P_ANY;
1496
1497 if (command == -2) {
1498 size_t len;
1499
1500 string += strspn(string, " \t\r\n"); /* Skip white space. */
1501 len = strcspn(string, ", \t\r\n"); /* Get length of the first token. */
1502
1503 if (!strncmp(string, "add", len)) {
1504 command = OFPFC_ADD;
1505 } else if (!strncmp(string, "delete", len)) {
1506 command = OFPFC_DELETE;
1507 } else if (!strncmp(string, "delete_strict", len)) {
1508 command = OFPFC_DELETE_STRICT;
1509 } else if (!strncmp(string, "modify", len)) {
1510 command = OFPFC_MODIFY;
1511 } else if (!strncmp(string, "modify_strict", len)) {
1512 command = OFPFC_MODIFY_STRICT;
1513 } else {
1514 len = 0;
1515 command = OFPFC_ADD;
1516 }
1517 string += len;
1518 }
1519
1520 switch (command) {
1521 case -1:
1522 fields = F_OUT_PORT;
1523 break;
1524
1525 case OFPFC_ADD:
1526 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS | F_IMPORTANCE;
1527 break;
1528
1529 case OFPFC_DELETE:
1530 fields = F_OUT_PORT;
1531 break;
1532
1533 case OFPFC_DELETE_STRICT:
1534 fields = F_OUT_PORT | F_PRIORITY;
1535 break;
1536
1537 case OFPFC_MODIFY:
1538 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
1539 break;
1540
1541 case OFPFC_MODIFY_STRICT:
1542 fields = F_ACTIONS | F_TIMEOUT | F_PRIORITY | F_FLAGS;
1543 break;
1544
1545 default:
1546 OVS_NOT_REACHED();
1547 }
1548
1549 *fm = (struct ofputil_flow_mod) {
0d71302e
BP
1550 .priority = OFP_DEFAULT_PRIORITY,
1551 .table_id = 0xff,
1552 .command = command,
1553 .buffer_id = UINT32_MAX,
1554 .out_port = OFPP_ANY,
1555 .out_group = OFPG_ANY,
1556 };
1557 /* For modify, by default, don't update the cookie. */
1558 if (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT) {
1559 fm->new_cookie = OVS_BE64_MAX;
1560 }
1561
1562 if (fields & F_ACTIONS) {
1563 act_str = ofp_extract_actions(string);
1564 if (!act_str) {
1565 return xstrdup("must specify an action");
1566 }
1567 }
1568
6a6b7060 1569 struct match match = MATCH_CATCHALL_INITIALIZER;
0d71302e
BP
1570 while (ofputil_parse_key_value(&string, &name, &value)) {
1571 const struct ofp_protocol *p;
1572 const struct mf_field *mf;
1573 char *error = NULL;
1574
1575 if (ofp_parse_protocol(name, &p)) {
6a6b7060 1576 match_set_dl_type(&match, htons(p->dl_type));
0d71302e 1577 if (p->nw_proto) {
6a6b7060 1578 match_set_nw_proto(&match, p->nw_proto);
0d71302e 1579 }
6a6b7060 1580 match_set_default_packet_type(&match);
0d71302e 1581 } else if (!strcmp(name, "eth")) {
6a6b7060 1582 match_set_packet_type(&match, htonl(PT_ETH));
0d71302e
BP
1583 } else if (fields & F_FLAGS && !strcmp(name, "send_flow_rem")) {
1584 fm->flags |= OFPUTIL_FF_SEND_FLOW_REM;
1585 } else if (fields & F_FLAGS && !strcmp(name, "check_overlap")) {
1586 fm->flags |= OFPUTIL_FF_CHECK_OVERLAP;
1587 } else if (fields & F_FLAGS && !strcmp(name, "reset_counts")) {
1588 fm->flags |= OFPUTIL_FF_RESET_COUNTS;
1589 *usable_protocols &= OFPUTIL_P_OF12_UP;
1590 } else if (fields & F_FLAGS && !strcmp(name, "no_packet_counts")) {
1591 fm->flags |= OFPUTIL_FF_NO_PKT_COUNTS;
1592 *usable_protocols &= OFPUTIL_P_OF13_UP;
1593 } else if (fields & F_FLAGS && !strcmp(name, "no_byte_counts")) {
1594 fm->flags |= OFPUTIL_FF_NO_BYT_COUNTS;
1595 *usable_protocols &= OFPUTIL_P_OF13_UP;
1596 } else if (!strcmp(name, "no_readonly_table")
1597 || !strcmp(name, "allow_hidden_fields")) {
1598 /* ignore these fields. */
1599 } else if ((mf = mf_from_name(name)) != NULL) {
1600 error = ofp_parse_field(mf, value, port_map,
6a6b7060 1601 &match, usable_protocols);
0d71302e 1602 } else if (strchr(name, '[')) {
6a6b7060 1603 error = parse_subfield(name, value, &match, usable_protocols);
0d71302e
BP
1604 } else {
1605 if (!*value) {
1606 return xasprintf("field %s missing value", name);
1607 }
1608
1609 if (!strcmp(name, "table")) {
1610 if (!ofputil_table_from_string(value, table_map,
1611 &fm->table_id)) {
1612 return xasprintf("unknown table \"%s\"", value);
1613 }
1614 if (fm->table_id != 0xff) {
1615 *usable_protocols &= OFPUTIL_P_TID;
1616 }
1617 } else if (fields & F_OUT_PORT && !strcmp(name, "out_port")) {
1618 if (!ofputil_port_from_string(value, port_map,
1619 &fm->out_port)) {
1620 error = xasprintf("%s is not a valid OpenFlow port",
1621 value);
1622 }
1623 } else if (fields & F_OUT_PORT && !strcmp(name, "out_group")) {
1624 *usable_protocols &= OFPUTIL_P_OF11_UP;
1625 if (!ofputil_group_from_string(value, &fm->out_group)) {
1626 error = xasprintf("%s is not a valid OpenFlow group",
1627 value);
1628 }
1629 } else if (fields & F_PRIORITY && !strcmp(name, "priority")) {
1630 uint16_t priority = 0;
1631
1632 error = str_to_u16(value, name, &priority);
1633 fm->priority = priority;
1634 } else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) {
1635 error = str_to_u16(value, name, &fm->idle_timeout);
1636 } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) {
1637 error = str_to_u16(value, name, &fm->hard_timeout);
1638 } else if (fields & F_IMPORTANCE && !strcmp(name, "importance")) {
1639 error = str_to_u16(value, name, &fm->importance);
1640 } else if (!strcmp(name, "cookie")) {
1641 char *mask = strchr(value, '/');
1642
1643 if (mask) {
1644 /* A mask means we're searching for a cookie. */
1645 if (command == OFPFC_ADD) {
1646 return xstrdup("flow additions cannot use "
1647 "a cookie mask");
1648 }
1649 *mask = '\0';
1650 error = str_to_be64(value, &fm->cookie);
1651 if (error) {
1652 return error;
1653 }
1654 error = str_to_be64(mask + 1, &fm->cookie_mask);
1655
1656 /* Matching of the cookie is only supported through NXM or
1657 * OF1.1+. */
1658 if (fm->cookie_mask != htonll(0)) {
1659 *usable_protocols &= OFPUTIL_P_NXM_OF11_UP;
1660 }
1661 } else {
1662 /* No mask means that the cookie is being set. */
1663 if (command != OFPFC_ADD && command != OFPFC_MODIFY
1664 && command != OFPFC_MODIFY_STRICT) {
1665 return xstrdup("cannot set cookie");
1666 }
1667 error = str_to_be64(value, &fm->new_cookie);
1668 fm->modify_cookie = true;
1669 }
1670 } else if (!strcmp(name, "duration")
1671 || !strcmp(name, "n_packets")
1672 || !strcmp(name, "n_bytes")
1673 || !strcmp(name, "idle_age")
1674 || !strcmp(name, "hard_age")) {
1675 /* Ignore these, so that users can feed the output of
1676 * "ovs-ofctl dump-flows" back into commands that parse
1677 * flows. */
1678 } else {
1679 error = xasprintf("unknown keyword %s", name);
1680 }
1681 }
1682
1683 if (error) {
1684 return error;
1685 }
1686 }
1687 /* Copy ethertype to flow->dl_type for matches on packet_type
1688 * (OFPHTN_ETHERTYPE, ethertype). */
6a6b7060
BP
1689 if (match.wc.masks.packet_type == OVS_BE32_MAX &&
1690 pt_ns(match.flow.packet_type) == OFPHTN_ETHERTYPE) {
1691 match.flow.dl_type = pt_ns_type_be(match.flow.packet_type);
0d71302e
BP
1692 }
1693 /* Check for usable protocol interdependencies between match fields. */
6a6b7060
BP
1694 if (match.flow.dl_type == htons(ETH_TYPE_IPV6)) {
1695 const struct flow_wildcards *wc = &match.wc;
0d71302e
BP
1696 /* Only NXM and OXM support matching L3 and L4 fields within IPv6.
1697 *
1698 * (IPv6 specific fields as well as arp_sha, arp_tha, nw_frag, and
1699 * nw_ttl are covered elsewhere so they don't need to be included in
1700 * this test too.)
1701 */
1702 if (wc->masks.nw_proto || wc->masks.nw_tos
1703 || wc->masks.tp_src || wc->masks.tp_dst) {
1704 *usable_protocols &= OFPUTIL_P_NXM_OXM_ANY;
1705 }
1706 }
1707 if (!fm->cookie_mask && fm->new_cookie == OVS_BE64_MAX
1708 && (command == OFPFC_MODIFY || command == OFPFC_MODIFY_STRICT)) {
1709 /* On modifies without a mask, we are supposed to add a flow if
1710 * one does not exist. If a cookie wasn't been specified, use a
1711 * default of zero. */
1712 fm->new_cookie = htonll(0);
1713 }
1714 if (fields & F_ACTIONS) {
1715 enum ofputil_protocol action_usable_protocols;
1716 struct ofpbuf ofpacts;
1717 char *error;
1718
1719 ofpbuf_init(&ofpacts, 32);
1720 struct ofpact_parse_params pp = {
1721 .port_map = port_map,
1722 .table_map = table_map,
1723 .ofpacts = &ofpacts,
1724 .usable_protocols = &action_usable_protocols
1725 };
1726 error = ofpacts_parse_instructions(act_str, &pp);
1727 *usable_protocols &= action_usable_protocols;
1728 if (!error) {
1729 enum ofperr err;
1730
ae6f7530
BP
1731 struct ofpact_check_params cp = {
1732 .match = &match,
1733 .max_ports = OFPP_MAX,
1734 .table_id = fm->table_id,
1735 .n_tables = 255,
1736 };
1737 err = ofpacts_check(ofpacts.data, ofpacts.size, &cp);
1738 *usable_protocols &= cp.usable_protocols;
0d71302e
BP
1739 if (!err && !*usable_protocols) {
1740 err = OFPERR_OFPBAC_MATCH_INCONSISTENT;
1741 }
1742 if (err) {
1743 error = xasprintf("actions are invalid with specified match "
1744 "(%s)", ofperr_to_string(err));
1745 }
1746
1747 }
1748 if (error) {
1749 ofpbuf_uninit(&ofpacts);
1750 return error;
1751 }
1752
1753 fm->ofpacts_len = ofpacts.size;
1754 fm->ofpacts = ofpbuf_steal_data(&ofpacts);
1755 } else {
1756 fm->ofpacts_len = 0;
1757 fm->ofpacts = NULL;
1758 }
6a6b7060 1759 minimatch_init(&fm->match, &match);
0d71302e
BP
1760
1761 return NULL;
1762}
1763
1764/* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
1765 * page) into 'fm' for sending the specified flow_mod 'command' to a switch.
1766 * Returns the set of usable protocols in '*usable_protocols'.
1767 *
1768 * To parse syntax for an OFPT_FLOW_MOD (or NXT_FLOW_MOD), use an OFPFC_*
1769 * constant for 'command'. To parse syntax for an OFPST_FLOW or
1770 * OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'.
1771 *
1772 * If 'command' is given as -2, 'str_' may begin with a command name ("add",
1773 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
1774 * name is treated as "add".
1775 *
1776 * Returns NULL if successful, otherwise a malloc()'d string describing the
6a6b7060
BP
1777 * error. The caller is responsible for freeing the returned string.
1778 *
1779 * On success, the caller is responsible for freeing fm->ofpacts and
1780 * fm->match. */
0d71302e
BP
1781char * OVS_WARN_UNUSED_RESULT
1782parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_,
1783 const struct ofputil_port_map *port_map,
1784 const struct ofputil_table_map *table_map,
1785 enum ofputil_protocol *usable_protocols)
1786{
1787 char *string = xstrdup(str_);
1788 char *error;
1789
1790 error = parse_ofp_str__(fm, command, string, port_map, table_map,
1791 usable_protocols);
1792 if (error) {
1793 fm->ofpacts = NULL;
1794 fm->ofpacts_len = 0;
1795 }
1796
1797 free(string);
1798 return error;
1799}
1800
0960a98b
BP
1801/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
1802 * (one of OFPFC_*) into 'fm'.
1803 *
1804 * If 'command' is given as -2, 'string' may begin with a command name ("add",
1805 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
1806 * name is treated as "add".
1807 *
1808 * Returns NULL if successful, otherwise a malloc()'d string describing the
1809 * error. The caller is responsible for freeing the returned string. */
1810char * OVS_WARN_UNUSED_RESULT
1811parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string,
1812 const struct ofputil_port_map *port_map,
1813 const struct ofputil_table_map *table_map,
1814 int command,
1815 enum ofputil_protocol *usable_protocols)
1816{
1817 char *error = parse_ofp_str(fm, command, string, port_map, table_map,
1818 usable_protocols);
1819
1820 if (!error) {
1821 /* Normalize a copy of the match. This ensures that non-normalized
1822 * flows get logged but doesn't affect what gets sent to the switch, so
1823 * that the switch can do whatever it likes with the flow. */
6a6b7060
BP
1824 struct match match;
1825 minimatch_expand(&fm->match, &match);
1826 ofputil_normalize_match(&match);
0960a98b
BP
1827 }
1828
1829 return error;
1830}
1831
0d71302e
BP
1832/* Opens file 'file_name' and reads each line as a flow_mod of the specified
1833 * type (one of OFPFC_*). Stores each flow_mod in '*fm', an array allocated
1834 * on the caller's behalf, and the number of flow_mods in '*n_fms'.
1835 *
1836 * If 'command' is given as -2, each line may start with a command name
1837 * ("add", "modify", "delete", "modify_strict", or "delete_strict"). A missing
1838 * command name is treated as "add".
1839 *
1840 * Returns NULL if successful, otherwise a malloc()'d string describing the
1841 * error. The caller is responsible for freeing the returned string. */
1842char * OVS_WARN_UNUSED_RESULT
1843parse_ofp_flow_mod_file(const char *file_name,
1844 const struct ofputil_port_map *port_map,
1845 const struct ofputil_table_map *table_map,
1846 int command,
1847 struct ofputil_flow_mod **fms, size_t *n_fms,
1848 enum ofputil_protocol *usable_protocols)
1849{
1850 size_t allocated_fms;
1851 int line_number;
1852 FILE *stream;
1853 struct ds s;
1854
1855 *usable_protocols = OFPUTIL_P_ANY;
1856
1857 *fms = NULL;
1858 *n_fms = 0;
1859
1860 stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
1861 if (stream == NULL) {
1862 return xasprintf("%s: open failed (%s)",
1863 file_name, ovs_strerror(errno));
1864 }
1865
1866 allocated_fms = *n_fms;
1867 ds_init(&s);
1868 line_number = 0;
1869 while (!ds_get_preprocessed_line(&s, stream, &line_number)) {
1870 char *error;
1871 enum ofputil_protocol usable;
1872
1873 if (*n_fms >= allocated_fms) {
1874 *fms = x2nrealloc(*fms, &allocated_fms, sizeof **fms);
1875 }
1876 error = parse_ofp_flow_mod_str(&(*fms)[*n_fms], ds_cstr(&s), port_map,
1877 table_map, command, &usable);
1878 if (error) {
1879 char *err_msg;
1880 size_t i;
1881
1882 for (i = 0; i < *n_fms; i++) {
1883 free(CONST_CAST(struct ofpact *, (*fms)[i].ofpacts));
6a6b7060 1884 minimatch_destroy(&(*fms)[i].match);
0d71302e
BP
1885 }
1886 free(*fms);
1887 *fms = NULL;
1888 *n_fms = 0;
1889
1890 ds_destroy(&s);
1891 if (stream != stdin) {
1892 fclose(stream);
1893 }
1894
1895 err_msg = xasprintf("%s:%d: %s", file_name, line_number, error);
1896 free(error);
1897 return err_msg;
1898 }
1899 *usable_protocols &= usable; /* Each line can narrow the set. */
1900 *n_fms += 1;
1901 }
1902
1903 ds_destroy(&s);
1904 if (stream != stdin) {
1905 fclose(stream);
1906 }
1907 return NULL;
1908}
1909
1910/* Parses a specification of a flow from 's' into 'flow'. 's' must take the
1911 * form FIELD=VALUE[,FIELD=VALUE]... where each FIELD is the name of a
1912 * mf_field. Fields must be specified in a natural order for satisfying
1913 * prerequisites. If 'wc' is specified, masks the field in 'wc' for each of the
1914 * field specified in flow. If the map, 'names_portno' is specfied, converts
1915 * the in_port name into port no while setting the 'flow'.
1916 *
1917 * Returns NULL on success, otherwise a malloc()'d string that explains the
1918 * problem. */
1919char *
1920parse_ofp_exact_flow(struct flow *flow, struct flow_wildcards *wc,
1921 const struct tun_table *tun_table, const char *s,
1922 const struct ofputil_port_map *port_map)
1923{
1924 char *pos, *key, *value_s;
1925 char *error = NULL;
1926 char *copy;
1927
1928 memset(flow, 0, sizeof *flow);
1929 if (wc) {
1930 memset(wc, 0, sizeof *wc);
1931 }
1932 flow->tunnel.metadata.tab = tun_table;
1933
1934 pos = copy = xstrdup(s);
1935 while (ofputil_parse_key_value(&pos, &key, &value_s)) {
1936 const struct ofp_protocol *p;
1937 if (ofp_parse_protocol(key, &p)) {
1938 if (flow->dl_type) {
1939 error = xasprintf("%s: Ethernet type set multiple times", s);
1940 goto exit;
1941 }
1942 flow->dl_type = htons(p->dl_type);
1943 if (wc) {
1944 wc->masks.dl_type = OVS_BE16_MAX;
1945 }
1946
1947 if (p->nw_proto) {
1948 if (flow->nw_proto) {
1949 error = xasprintf("%s: network protocol set "
1950 "multiple times", s);
1951 goto exit;
1952 }
1953 flow->nw_proto = p->nw_proto;
1954 if (wc) {
1955 wc->masks.nw_proto = UINT8_MAX;
1956 }
1957 }
1958 } else {
1959 const struct mf_field *mf;
1960 union mf_value value;
1961 char *field_error;
1962
1963 mf = mf_from_name(key);
1964 if (!mf) {
1965 error = xasprintf("%s: unknown field %s", s, key);
1966 goto exit;
1967 }
1968
1969 if (!mf_are_prereqs_ok(mf, flow, NULL)) {
1970 error = xasprintf("%s: prerequisites not met for setting %s",
1971 s, key);
1972 goto exit;
1973 }
1974
1975 if (mf_is_set(mf, flow)) {
1976 error = xasprintf("%s: field %s set multiple times", s, key);
1977 goto exit;
1978 }
1979
1980 field_error = mf_parse_value(mf, value_s, port_map, &value);
1981 if (field_error) {
1982 error = xasprintf("%s: bad value for %s (%s)",
1983 s, key, field_error);
1984 free(field_error);
1985 goto exit;
1986 }
1987
1988 mf_set_flow_value(mf, &value, flow);
1989 if (wc) {
1990 mf_mask_field(mf, wc);
1991 }
1992 }
1993 }
1994
1995 if (!flow->in_port.ofp_port) {
1996 flow->in_port.ofp_port = OFPP_NONE;
1997 }
1998
1999exit:
2000 free(copy);
2001
2002 if (error) {
2003 memset(flow, 0, sizeof *flow);
2004 if (wc) {
2005 memset(wc, 0, sizeof *wc);
2006 }
2007 }
2008 return error;
2009}