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