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