2 * Copyright (c) 2008-2017, 2019 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "openvswitch/ofp-flow.h"
20 #include "byte-order.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"
30 #include "openvswitch/ofp-print.h"
31 #include "openvswitch/ofp-table.h"
32 #include "openvswitch/ofpbuf.h"
33 #include "openvswitch/vlog.h"
37 VLOG_DEFINE_THIS_MODULE(ofp_flow
);
39 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
41 struct ofputil_flow_mod_flag
{
43 enum ofp_version min_version
, max_version
;
44 enum ofputil_flow_mod_flags flag
;
47 static const struct ofputil_flow_mod_flag ofputil_flow_mod_flags
[] = {
48 { OFPFF_SEND_FLOW_REM
, OFP10_VERSION
, 0, OFPUTIL_FF_SEND_FLOW_REM
},
49 { OFPFF_CHECK_OVERLAP
, OFP10_VERSION
, 0, OFPUTIL_FF_CHECK_OVERLAP
},
50 { OFPFF10_EMERG
, OFP10_VERSION
, OFP10_VERSION
,
52 { OFPFF12_RESET_COUNTS
, OFP12_VERSION
, 0, OFPUTIL_FF_RESET_COUNTS
},
53 { OFPFF13_NO_PKT_COUNTS
, OFP13_VERSION
, 0, OFPUTIL_FF_NO_PKT_COUNTS
},
54 { OFPFF13_NO_BYT_COUNTS
, OFP13_VERSION
, 0, OFPUTIL_FF_NO_BYT_COUNTS
},
59 ofputil_decode_flow_mod_flags(ovs_be16 raw_flags_
,
60 enum ofp_flow_mod_command command
,
61 enum ofp_version version
,
62 enum ofputil_flow_mod_flags
*flagsp
)
64 uint16_t raw_flags
= ntohs(raw_flags_
);
65 const struct ofputil_flow_mod_flag
*f
;
68 for (f
= ofputil_flow_mod_flags
; f
->raw_flag
; f
++) {
69 if (raw_flags
& f
->raw_flag
70 && version
>= f
->min_version
71 && (!f
->max_version
|| version
<= f
->max_version
)) {
72 raw_flags
&= ~f
->raw_flag
;
77 /* In OF1.0 and OF1.1, "add" always resets counters, and other commands
80 * In OF1.2 and later, OFPFF12_RESET_COUNTS controls whether each command
82 if ((version
== OFP10_VERSION
|| version
== OFP11_VERSION
)
83 && command
== OFPFC_ADD
) {
84 *flagsp
|= OFPUTIL_FF_RESET_COUNTS
;
87 return raw_flags
? OFPERR_OFPFMFC_BAD_FLAGS
: 0;
91 ofputil_encode_flow_mod_flags(enum ofputil_flow_mod_flags flags
,
92 enum ofp_version version
)
94 const struct ofputil_flow_mod_flag
*f
;
98 for (f
= ofputil_flow_mod_flags
; f
->raw_flag
; f
++) {
100 && version
>= f
->min_version
101 && (!f
->max_version
|| version
<= f
->max_version
)) {
102 raw_flags
|= f
->raw_flag
;
106 return htons(raw_flags
);
110 ofputil_flow_mod_flags_format(struct ds
*s
, enum ofputil_flow_mod_flags flags
)
112 if (flags
& OFPUTIL_FF_SEND_FLOW_REM
) {
113 ds_put_cstr(s
, "send_flow_rem ");
115 if (flags
& OFPUTIL_FF_CHECK_OVERLAP
) {
116 ds_put_cstr(s
, "check_overlap ");
118 if (flags
& OFPUTIL_FF_RESET_COUNTS
) {
119 ds_put_cstr(s
, "reset_counts ");
121 if (flags
& OFPUTIL_FF_NO_PKT_COUNTS
) {
122 ds_put_cstr(s
, "no_packet_counts ");
124 if (flags
& OFPUTIL_FF_NO_BYT_COUNTS
) {
125 ds_put_cstr(s
, "no_byte_counts ");
127 if (flags
& OFPUTIL_FF_HIDDEN_FIELDS
) {
128 ds_put_cstr(s
, "allow_hidden_fields ");
130 if (flags
& OFPUTIL_FF_NO_READONLY
) {
131 ds_put_cstr(s
, "no_readonly_table ");
135 /* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
136 * flow_mod in 'fm'. Returns 0 if successful, otherwise an OpenFlow error
139 * Uses 'ofpacts' to store the abstract OFPACT_* version of 'oh''s actions.
140 * The caller must initialize 'ofpacts' and retains ownership of it.
141 * 'fm->ofpacts' will point into the 'ofpacts' buffer.
143 * On success, the caller must eventually destroy fm->match.
145 * Does not validate the flow_mod actions. The caller should do that, with
146 * ofpacts_check(). */
148 ofputil_decode_flow_mod(struct ofputil_flow_mod
*fm
,
149 const struct ofp_header
*oh
,
150 enum ofputil_protocol protocol
,
151 const struct tun_table
*tun_table
,
152 const struct vl_mff_map
*vl_mff_map
,
153 struct ofpbuf
*ofpacts
,
154 ofp_port_t max_port
, uint8_t max_table
)
159 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
160 enum ofpraw raw
= ofpraw_pull_assert(&b
);
161 if (raw
== OFPRAW_OFPT11_FLOW_MOD
) {
162 /* Standard OpenFlow 1.1+ flow_mod. */
163 const struct ofp11_flow_mod
*ofm
;
165 ofm
= ofpbuf_pull(&b
, sizeof *ofm
);
167 error
= ofputil_pull_ofp11_match(&b
, tun_table
, vl_mff_map
, &match
,
173 /* Translate the message. */
174 fm
->priority
= ntohs(ofm
->priority
);
175 if (ofm
->command
== OFPFC_ADD
176 || (oh
->version
== OFP11_VERSION
177 && (ofm
->command
== OFPFC_MODIFY
||
178 ofm
->command
== OFPFC_MODIFY_STRICT
)
179 && ofm
->cookie_mask
== htonll(0))) {
180 /* In OpenFlow 1.1 only, a "modify" or "modify-strict" that does
181 * not match on the cookie is treated as an "add" if there is no
183 fm
->cookie
= htonll(0);
184 fm
->cookie_mask
= htonll(0);
185 fm
->new_cookie
= ofm
->cookie
;
187 fm
->cookie
= ofm
->cookie
;
188 fm
->cookie_mask
= ofm
->cookie_mask
;
189 fm
->new_cookie
= OVS_BE64_MAX
;
191 fm
->modify_cookie
= false;
192 fm
->command
= ofm
->command
;
196 * OF1.1 entirely forbids table_id == OFPTT_ALL.
197 * OF1.2+ allows table_id == OFPTT_ALL only for deletes. */
198 fm
->table_id
= ofm
->table_id
;
199 if (fm
->table_id
== OFPTT_ALL
200 && (oh
->version
== OFP11_VERSION
201 || (ofm
->command
!= OFPFC_DELETE
&&
202 ofm
->command
!= OFPFC_DELETE_STRICT
))) {
203 return OFPERR_OFPFMFC_BAD_TABLE_ID
;
206 fm
->idle_timeout
= ntohs(ofm
->idle_timeout
);
207 fm
->hard_timeout
= ntohs(ofm
->hard_timeout
);
208 if (oh
->version
>= OFP14_VERSION
&& ofm
->command
== OFPFC_ADD
) {
209 fm
->importance
= ntohs(ofm
->importance
);
213 fm
->buffer_id
= ntohl(ofm
->buffer_id
);
214 error
= ofputil_port_from_ofp11(ofm
->out_port
, &fm
->out_port
);
219 fm
->out_group
= (ofm
->command
== OFPFC_DELETE
||
220 ofm
->command
== OFPFC_DELETE_STRICT
221 ? ntohl(ofm
->out_group
)
223 raw_flags
= ofm
->flags
;
227 if (raw
== OFPRAW_OFPT10_FLOW_MOD
) {
228 /* Standard OpenFlow 1.0 flow_mod. */
229 const struct ofp10_flow_mod
*ofm
;
231 /* Get the ofp10_flow_mod. */
232 ofm
= ofpbuf_pull(&b
, sizeof *ofm
);
234 /* Translate the rule. */
235 ofputil_match_from_ofp10_match(&ofm
->match
, &match
);
236 ofputil_normalize_match(&match
);
238 /* OpenFlow 1.0 says that exact-match rules have to have the
239 * highest possible priority. */
240 fm
->priority
= (ofm
->match
.wildcards
& htonl(OFPFW10_ALL
)
241 ? ntohs(ofm
->priority
)
244 /* Translate the message. */
245 command
= ntohs(ofm
->command
);
246 fm
->cookie
= htonll(0);
247 fm
->cookie_mask
= htonll(0);
248 fm
->new_cookie
= ofm
->cookie
;
249 fm
->idle_timeout
= ntohs(ofm
->idle_timeout
);
250 fm
->hard_timeout
= ntohs(ofm
->hard_timeout
);
252 fm
->buffer_id
= ntohl(ofm
->buffer_id
);
253 fm
->out_port
= u16_to_ofp(ntohs(ofm
->out_port
));
254 fm
->out_group
= OFPG_ANY
;
255 raw_flags
= ofm
->flags
;
256 } else if (raw
== OFPRAW_NXT_FLOW_MOD
) {
257 /* Nicira extended flow_mod. */
258 const struct nx_flow_mod
*nfm
;
260 /* Dissect the message. */
261 nfm
= ofpbuf_pull(&b
, sizeof *nfm
);
262 error
= nx_pull_match(&b
, ntohs(nfm
->match_len
),
263 &match
, &fm
->cookie
, &fm
->cookie_mask
,
264 false, tun_table
, vl_mff_map
);
269 /* Translate the message. */
270 command
= ntohs(nfm
->command
);
271 if ((command
& 0xff) == OFPFC_ADD
&& fm
->cookie_mask
) {
272 /* Flow additions may only set a new cookie, not match an
273 * existing cookie. */
274 return OFPERR_NXBRC_NXM_INVALID
;
276 fm
->priority
= ntohs(nfm
->priority
);
277 fm
->new_cookie
= nfm
->cookie
;
278 fm
->idle_timeout
= ntohs(nfm
->idle_timeout
);
279 fm
->hard_timeout
= ntohs(nfm
->hard_timeout
);
281 fm
->buffer_id
= ntohl(nfm
->buffer_id
);
282 fm
->out_port
= u16_to_ofp(ntohs(nfm
->out_port
));
283 fm
->out_group
= OFPG_ANY
;
284 raw_flags
= nfm
->flags
;
289 fm
->modify_cookie
= fm
->new_cookie
!= OVS_BE64_MAX
;
290 if (protocol
& OFPUTIL_P_TID
) {
291 fm
->command
= command
& 0xff;
292 fm
->table_id
= command
>> 8;
294 if (command
> 0xff) {
295 VLOG_WARN_RL(&rl
, "flow_mod has explicit table_id "
296 "but flow_mod_table_id extension is not enabled");
298 fm
->command
= command
;
303 /* Check for mismatched conntrack original direction tuple address fields
304 * w.r.t. the IP version of the match. */
305 if (((match
.wc
.masks
.ct_nw_src
|| match
.wc
.masks
.ct_nw_dst
)
306 && match
.flow
.dl_type
!= htons(ETH_TYPE_IP
))
307 || ((ipv6_addr_is_set(&match
.wc
.masks
.ct_ipv6_src
)
308 || ipv6_addr_is_set(&match
.wc
.masks
.ct_ipv6_dst
))
309 && match
.flow
.dl_type
!= htons(ETH_TYPE_IPV6
))) {
310 return OFPERR_OFPBAC_MATCH_INCONSISTENT
;
313 if (fm
->command
> OFPFC_DELETE_STRICT
) {
314 return OFPERR_OFPFMFC_BAD_COMMAND
;
317 fm
->ofpacts_tlv_bitmap
= 0;
318 error
= ofpacts_pull_openflow_instructions(&b
, b
.size
, oh
->version
,
320 &fm
->ofpacts_tlv_bitmap
,
325 fm
->ofpacts
= ofpacts
->data
;
326 fm
->ofpacts_len
= ofpacts
->size
;
328 error
= ofputil_decode_flow_mod_flags(raw_flags
, fm
->command
,
329 oh
->version
, &fm
->flags
);
334 if (fm
->flags
& OFPUTIL_FF_EMERG
) {
335 /* We do not support the OpenFlow 1.0 emergency flow cache, which
336 * is not required in OpenFlow 1.0.1 and removed from OpenFlow 1.1.
338 * OpenFlow 1.0 specifies the error code to use when idle_timeout
339 * or hard_timeout is nonzero. Otherwise, there is no good error
340 * code, so just state that the flow table is full. */
341 return (fm
->hard_timeout
|| fm
->idle_timeout
342 ? OFPERR_OFPFMFC_BAD_EMERG_TIMEOUT
343 : OFPERR_OFPFMFC_TABLE_FULL
);
346 struct ofpact_check_params cp
= {
348 .max_ports
= max_port
,
349 .table_id
= fm
->table_id
,
350 .n_tables
= max_table
352 error
= ofpacts_check_consistency(fm
->ofpacts
, fm
->ofpacts_len
,
355 minimatch_init(&fm
->match
, &match
);
361 ofputil_tid_command(const struct ofputil_flow_mod
*fm
,
362 enum ofputil_protocol protocol
)
364 return htons(protocol
& OFPUTIL_P_TID
365 ? (fm
->command
& 0xff) | (fm
->table_id
<< 8)
369 /* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to
370 * 'protocol' and returns the message. */
372 ofputil_encode_flow_mod(const struct ofputil_flow_mod
*fm
,
373 enum ofputil_protocol protocol
)
375 enum ofp_version version
= ofputil_protocol_to_ofp_version(protocol
);
376 ovs_be16 raw_flags
= ofputil_encode_flow_mod_flags(fm
->flags
, version
);
380 minimatch_expand(&fm
->match
, &match
);
383 case OFPUTIL_P_OF11_STD
:
384 case OFPUTIL_P_OF12_OXM
:
385 case OFPUTIL_P_OF13_OXM
:
386 case OFPUTIL_P_OF14_OXM
:
387 case OFPUTIL_P_OF15_OXM
: {
388 struct ofp11_flow_mod
*ofm
;
391 tailroom
= ofputil_match_typical_len(protocol
) + fm
->ofpacts_len
;
392 msg
= ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD
, version
, tailroom
);
393 ofm
= ofpbuf_put_zeros(msg
, sizeof *ofm
);
394 if ((protocol
== OFPUTIL_P_OF11_STD
395 && (fm
->command
== OFPFC_MODIFY
||
396 fm
->command
== OFPFC_MODIFY_STRICT
)
397 && fm
->cookie_mask
== htonll(0))
398 || fm
->command
== OFPFC_ADD
) {
399 ofm
->cookie
= fm
->new_cookie
;
401 ofm
->cookie
= fm
->cookie
& fm
->cookie_mask
;
403 ofm
->cookie_mask
= fm
->cookie_mask
;
404 if (fm
->table_id
!= OFPTT_ALL
405 || (protocol
!= OFPUTIL_P_OF11_STD
406 && (fm
->command
== OFPFC_DELETE
||
407 fm
->command
== OFPFC_DELETE_STRICT
))) {
408 ofm
->table_id
= fm
->table_id
;
412 ofm
->command
= fm
->command
;
413 ofm
->idle_timeout
= htons(fm
->idle_timeout
);
414 ofm
->hard_timeout
= htons(fm
->hard_timeout
);
415 ofm
->priority
= htons(fm
->priority
);
416 ofm
->buffer_id
= htonl(fm
->buffer_id
);
417 ofm
->out_port
= ofputil_port_to_ofp11(fm
->out_port
);
418 ofm
->out_group
= htonl(fm
->out_group
);
419 ofm
->flags
= raw_flags
;
420 if (version
>= OFP14_VERSION
&& fm
->command
== OFPFC_ADD
) {
421 ofm
->importance
= htons(fm
->importance
);
425 ofputil_put_ofp11_match(msg
, &match
, protocol
);
426 ofpacts_put_openflow_instructions(fm
->ofpacts
, fm
->ofpacts_len
, msg
,
431 case OFPUTIL_P_OF10_STD
:
432 case OFPUTIL_P_OF10_STD_TID
: {
433 struct ofp10_flow_mod
*ofm
;
435 msg
= ofpraw_alloc(OFPRAW_OFPT10_FLOW_MOD
, OFP10_VERSION
,
437 ofm
= ofpbuf_put_zeros(msg
, sizeof *ofm
);
438 ofputil_match_to_ofp10_match(&match
, &ofm
->match
);
439 ofm
->cookie
= fm
->new_cookie
;
440 ofm
->command
= ofputil_tid_command(fm
, protocol
);
441 ofm
->idle_timeout
= htons(fm
->idle_timeout
);
442 ofm
->hard_timeout
= htons(fm
->hard_timeout
);
443 ofm
->priority
= htons(fm
->priority
);
444 ofm
->buffer_id
= htonl(fm
->buffer_id
);
445 ofm
->out_port
= htons(ofp_to_u16(fm
->out_port
));
446 ofm
->flags
= raw_flags
;
447 ofpacts_put_openflow_actions(fm
->ofpacts
, fm
->ofpacts_len
, msg
,
452 case OFPUTIL_P_OF10_NXM
:
453 case OFPUTIL_P_OF10_NXM_TID
: {
454 struct nx_flow_mod
*nfm
;
457 msg
= ofpraw_alloc(OFPRAW_NXT_FLOW_MOD
, OFP10_VERSION
,
458 NXM_TYPICAL_LEN
+ fm
->ofpacts_len
);
459 nfm
= ofpbuf_put_zeros(msg
, sizeof *nfm
);
460 nfm
->command
= ofputil_tid_command(fm
, protocol
);
461 nfm
->cookie
= fm
->new_cookie
;
462 match_len
= nx_put_match(msg
, &match
, fm
->cookie
, fm
->cookie_mask
);
464 nfm
->idle_timeout
= htons(fm
->idle_timeout
);
465 nfm
->hard_timeout
= htons(fm
->hard_timeout
);
466 nfm
->priority
= htons(fm
->priority
);
467 nfm
->buffer_id
= htonl(fm
->buffer_id
);
468 nfm
->out_port
= htons(ofp_to_u16(fm
->out_port
));
469 nfm
->flags
= raw_flags
;
470 nfm
->match_len
= htons(match_len
);
471 ofpacts_put_openflow_actions(fm
->ofpacts
, fm
->ofpacts_len
, msg
,
480 ofpmsg_update_length(msg
);
485 ofputil_flow_mod_format(struct ds
*s
, const struct ofp_header
*oh
,
486 const struct ofputil_port_map
*port_map
,
487 const struct ofputil_table_map
*table_map
,
490 struct ofputil_flow_mod fm
;
491 struct ofpbuf ofpacts
;
495 enum ofputil_protocol protocol
;
497 protocol
= ofputil_protocol_from_ofp_version(oh
->version
);
498 protocol
= ofputil_protocol_set_tid(protocol
, true);
500 ofpbuf_init(&ofpacts
, 64);
501 error
= ofputil_decode_flow_mod(&fm
, oh
, protocol
, NULL
, NULL
, &ofpacts
,
504 ofpbuf_uninit(&ofpacts
);
509 switch (fm
.command
) {
511 ds_put_cstr(s
, "ADD");
514 ds_put_cstr(s
, "MOD");
516 case OFPFC_MODIFY_STRICT
:
517 ds_put_cstr(s
, "MOD_STRICT");
520 ds_put_cstr(s
, "DEL");
522 case OFPFC_DELETE_STRICT
:
523 ds_put_cstr(s
, "DEL_STRICT");
526 ds_put_format(s
, "cmd:%d", fm
.command
);
529 || ofputil_table_map_get_name(table_map
, fm
.table_id
)) {
530 ds_put_format(s
, " table:");
531 ofputil_format_table(fm
.table_id
, table_map
, s
);
535 ofpraw_decode(&raw
, oh
);
536 if (verbosity
>= 3 && raw
== OFPRAW_OFPT10_FLOW_MOD
) {
537 const struct ofp10_flow_mod
*ofm
= ofpmsg_body(oh
);
538 ofp10_match_print(s
, &ofm
->match
, port_map
, verbosity
);
540 /* ofp_print_match() doesn't print priority. */
541 need_priority
= true;
542 } else if (verbosity
>= 3 && raw
== OFPRAW_NXT_FLOW_MOD
) {
543 const struct nx_flow_mod
*nfm
= ofpmsg_body(oh
);
544 const void *nxm
= nfm
+ 1;
547 nxm_s
= nx_match_to_string(nxm
, ntohs(nfm
->match_len
));
548 ds_put_cstr(s
, nxm_s
);
551 /* nx_match_to_string() doesn't print priority. */
552 need_priority
= true;
555 minimatch_expand(&fm
.match
, &match
);
556 match_format(&match
, port_map
, s
, fm
.priority
);
558 /* match_format() does print priority. */
559 need_priority
= false;
562 if (ds_last(s
) != ' ') {
565 if (fm
.new_cookie
!= htonll(0) && fm
.new_cookie
!= OVS_BE64_MAX
) {
566 ds_put_format(s
, "cookie:0x%"PRIx64
" ", ntohll(fm
.new_cookie
));
568 if (fm
.cookie_mask
!= htonll(0)) {
569 ds_put_format(s
, "cookie:0x%"PRIx64
"/0x%"PRIx64
" ",
570 ntohll(fm
.cookie
), ntohll(fm
.cookie_mask
));
572 if (fm
.idle_timeout
!= OFP_FLOW_PERMANENT
) {
573 ds_put_format(s
, "idle:%"PRIu16
" ", fm
.idle_timeout
);
575 if (fm
.hard_timeout
!= OFP_FLOW_PERMANENT
) {
576 ds_put_format(s
, "hard:%"PRIu16
" ", fm
.hard_timeout
);
578 if (fm
.importance
!= 0) {
579 ds_put_format(s
, "importance:%"PRIu16
" ", fm
.importance
);
581 if (fm
.priority
!= OFP_DEFAULT_PRIORITY
&& need_priority
) {
582 ds_put_format(s
, "pri:%d ", fm
.priority
);
584 if (fm
.buffer_id
!= UINT32_MAX
) {
585 ds_put_format(s
, "buf:0x%"PRIx32
" ", fm
.buffer_id
);
587 if (fm
.out_port
!= OFPP_ANY
) {
588 ds_put_format(s
, "out_port:");
589 ofputil_format_port(fm
.out_port
, port_map
, s
);
593 if (oh
->version
== OFP10_VERSION
|| oh
->version
== OFP11_VERSION
) {
594 /* Don't print the reset_counts flag for OF1.0 and OF1.1 because those
595 * versions don't really have such a flag and printing one is likely to
597 fm
.flags
&= ~OFPUTIL_FF_RESET_COUNTS
;
599 ofputil_flow_mod_flags_format(s
, fm
.flags
);
601 ds_put_cstr(s
, "actions=");
602 struct ofpact_format_params fp
= {
603 .port_map
= port_map
,
604 .table_map
= table_map
,
607 ofpacts_format(fm
.ofpacts
, fm
.ofpacts_len
, &fp
);
608 ofpbuf_uninit(&ofpacts
);
609 minimatch_destroy(&fm
.match
);
615 ofputil_decode_ofpst10_flow_request(struct ofputil_flow_stats_request
*fsr
,
616 const struct ofp10_flow_stats_request
*ofsr
,
619 fsr
->aggregate
= aggregate
;
620 ofputil_match_from_ofp10_match(&ofsr
->match
, &fsr
->match
);
621 fsr
->out_port
= u16_to_ofp(ntohs(ofsr
->out_port
));
622 fsr
->out_group
= OFPG_ANY
;
623 fsr
->table_id
= ofsr
->table_id
;
624 fsr
->cookie
= fsr
->cookie_mask
= htonll(0);
630 ofputil_decode_ofpst11_flow_request(struct ofputil_flow_stats_request
*fsr
,
631 struct ofpbuf
*b
, bool aggregate
,
632 const struct tun_table
*tun_table
,
633 const struct vl_mff_map
*vl_mff_map
)
635 const struct ofp11_flow_stats_request
*ofsr
;
638 ofsr
= ofpbuf_pull(b
, sizeof *ofsr
);
639 fsr
->aggregate
= aggregate
;
640 fsr
->table_id
= ofsr
->table_id
;
641 error
= ofputil_port_from_ofp11(ofsr
->out_port
, &fsr
->out_port
);
645 fsr
->out_group
= ntohl(ofsr
->out_group
);
646 fsr
->cookie
= ofsr
->cookie
;
647 fsr
->cookie_mask
= ofsr
->cookie_mask
;
648 error
= ofputil_pull_ofp11_match(b
, tun_table
, vl_mff_map
, &fsr
->match
,
658 ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request
*fsr
,
659 struct ofpbuf
*b
, bool aggregate
,
660 const struct tun_table
*tun_table
,
661 const struct vl_mff_map
*vl_mff_map
)
663 const struct nx_flow_stats_request
*nfsr
;
666 nfsr
= ofpbuf_pull(b
, sizeof *nfsr
);
667 error
= nx_pull_match(b
, ntohs(nfsr
->match_len
), &fsr
->match
,
668 &fsr
->cookie
, &fsr
->cookie_mask
, false, tun_table
,
674 return OFPERR_OFPBRC_BAD_LEN
;
677 fsr
->aggregate
= aggregate
;
678 fsr
->out_port
= u16_to_ofp(ntohs(nfsr
->out_port
));
679 fsr
->out_group
= OFPG_ANY
;
680 fsr
->table_id
= nfsr
->table_id
;
685 /* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
686 * request 'oh', into an abstract flow_stats_request in 'fsr'. Returns 0 if
687 * successful, otherwise an OpenFlow error code.
689 * 'vl_mff_map' is an optional parameter that is used to validate the length
690 * of variable length mf_fields in 'match'. If it is not provided, the
691 * default mf_fields with maximum length will be used. */
693 ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request
*fsr
,
694 const struct ofp_header
*oh
,
695 const struct tun_table
*tun_table
,
696 const struct vl_mff_map
*vl_mff_map
)
698 struct ofpbuf b
= ofpbuf_const_initializer(oh
, ntohs(oh
->length
));
699 enum ofpraw raw
= ofpraw_pull_assert(&b
);
701 case OFPRAW_OFPST10_FLOW_REQUEST
:
702 return ofputil_decode_ofpst10_flow_request(fsr
, b
.data
, false);
704 case OFPRAW_OFPST10_AGGREGATE_REQUEST
:
705 return ofputil_decode_ofpst10_flow_request(fsr
, b
.data
, true);
707 case OFPRAW_OFPST11_FLOW_REQUEST
:
708 return ofputil_decode_ofpst11_flow_request(fsr
, &b
, false, tun_table
,
711 case OFPRAW_OFPST11_AGGREGATE_REQUEST
:
712 return ofputil_decode_ofpst11_flow_request(fsr
, &b
, true, tun_table
,
715 case OFPRAW_OFPST15_AGGREGATE_REQUEST
:
716 return ofputil_decode_ofpst11_flow_request(fsr
, &b
, true,
717 tun_table
, vl_mff_map
);
719 case OFPRAW_NXST_FLOW_REQUEST
:
720 return ofputil_decode_nxst_flow_request(fsr
, &b
, false, tun_table
,
723 case OFPRAW_NXST_AGGREGATE_REQUEST
:
724 return ofputil_decode_nxst_flow_request(fsr
, &b
, true, tun_table
,
728 /* Hey, the caller lied. */
733 /* Converts abstract flow_stats_request 'fsr' into an OFPST_FLOW,
734 * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
735 * 'protocol', and returns the message. */
737 ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request
*fsr
,
738 enum ofputil_protocol protocol
)
744 case OFPUTIL_P_OF11_STD
:
745 case OFPUTIL_P_OF12_OXM
:
746 case OFPUTIL_P_OF13_OXM
:
747 case OFPUTIL_P_OF14_OXM
:
748 case OFPUTIL_P_OF15_OXM
: {
749 struct ofp11_flow_stats_request
*ofsr
;
751 if (protocol
> OFPUTIL_P_OF14_OXM
) {
752 raw
= (fsr
->aggregate
753 ? OFPRAW_OFPST15_AGGREGATE_REQUEST
754 : OFPRAW_OFPST11_FLOW_REQUEST
);
756 raw
= (fsr
->aggregate
757 ? OFPRAW_OFPST11_AGGREGATE_REQUEST
758 : OFPRAW_OFPST11_FLOW_REQUEST
);
760 msg
= ofpraw_alloc(raw
, ofputil_protocol_to_ofp_version(protocol
),
761 ofputil_match_typical_len(protocol
));
762 ofsr
= ofpbuf_put_zeros(msg
, sizeof *ofsr
);
763 ofsr
->table_id
= fsr
->table_id
;
764 ofsr
->out_port
= ofputil_port_to_ofp11(fsr
->out_port
);
765 ofsr
->out_group
= htonl(fsr
->out_group
);
766 ofsr
->cookie
= fsr
->cookie
;
767 ofsr
->cookie_mask
= fsr
->cookie_mask
;
768 ofputil_put_ofp11_match(msg
, &fsr
->match
, protocol
);
772 case OFPUTIL_P_OF10_STD
:
773 case OFPUTIL_P_OF10_STD_TID
: {
774 struct ofp10_flow_stats_request
*ofsr
;
776 raw
= (fsr
->aggregate
777 ? OFPRAW_OFPST10_AGGREGATE_REQUEST
778 : OFPRAW_OFPST10_FLOW_REQUEST
);
779 msg
= ofpraw_alloc(raw
, OFP10_VERSION
, 0);
780 ofsr
= ofpbuf_put_zeros(msg
, sizeof *ofsr
);
781 ofputil_match_to_ofp10_match(&fsr
->match
, &ofsr
->match
);
782 ofsr
->table_id
= fsr
->table_id
;
783 ofsr
->out_port
= htons(ofp_to_u16(fsr
->out_port
));
787 case OFPUTIL_P_OF10_NXM
:
788 case OFPUTIL_P_OF10_NXM_TID
: {
789 struct nx_flow_stats_request
*nfsr
;
792 raw
= (fsr
->aggregate
793 ? OFPRAW_NXST_AGGREGATE_REQUEST
794 : OFPRAW_NXST_FLOW_REQUEST
);
795 msg
= ofpraw_alloc(raw
, OFP10_VERSION
, NXM_TYPICAL_LEN
);
796 ofpbuf_put_zeros(msg
, sizeof *nfsr
);
797 match_len
= nx_put_match(msg
, &fsr
->match
,
798 fsr
->cookie
, fsr
->cookie_mask
);
801 nfsr
->out_port
= htons(ofp_to_u16(fsr
->out_port
));
802 nfsr
->match_len
= htons(match_len
);
803 nfsr
->table_id
= fsr
->table_id
;
815 ofputil_flow_stats_request_format(struct ds
*s
,
816 const struct ofputil_flow_stats_request
*fsr
,
817 const struct ofputil_port_map
*port_map
,
818 const struct ofputil_table_map
*table_map
)
820 if (fsr
->table_id
!= 0xff) {
821 ds_put_format(s
, " table=");
822 ofputil_format_table(fsr
->table_id
, table_map
, s
);
825 if (fsr
->out_port
!= OFPP_ANY
) {
826 ds_put_cstr(s
, " out_port=");
827 ofputil_format_port(fsr
->out_port
, port_map
, s
);
831 match_format(&fsr
->match
, port_map
, s
, OFP_DEFAULT_PRIORITY
);
834 char * OVS_WARN_UNUSED_RESULT
835 parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request
*fsr
,
836 bool aggregate
, const char *string
,
837 const struct ofputil_port_map
*port_map
,
838 const struct ofputil_table_map
*table_map
,
839 enum ofputil_protocol
*usable_protocols
)
841 struct ofputil_flow_mod fm
;
844 error
= parse_ofp_str(&fm
, -1, string
, port_map
, table_map
,
850 /* Special table ID support not required for stats requests. */
851 if (*usable_protocols
& OFPUTIL_P_OF10_STD_TID
) {
852 *usable_protocols
|= OFPUTIL_P_OF10_STD
;
854 if (*usable_protocols
& OFPUTIL_P_OF10_NXM_TID
) {
855 *usable_protocols
|= OFPUTIL_P_OF10_NXM
;
858 fsr
->aggregate
= aggregate
;
859 fsr
->cookie
= fm
.cookie
;
860 fsr
->cookie_mask
= fm
.cookie_mask
;
861 minimatch_expand(&fm
.match
, &fsr
->match
);
862 fsr
->out_port
= fm
.out_port
;
863 fsr
->out_group
= fm
.out_group
;
864 fsr
->table_id
= fm
.table_id
;
866 minimatch_destroy(&fm
.match
);
871 /* Converts an OFPST_FLOW or NXST_FLOW reply in 'msg' into an abstract
872 * ofputil_flow_stats in 'fs'.
874 * Multiple OFPST_FLOW or NXST_FLOW replies can be packed into a single
875 * OpenFlow message. Calling this function multiple times for a single 'msg'
876 * iterates through the replies. The caller must initially leave 'msg''s layer
877 * pointers null and not modify them between calls.
879 * Most switches don't send the values needed to populate fs->idle_age and
880 * fs->hard_age, so those members will usually be set to 0. If the switch from
881 * which 'msg' originated is known to implement NXT_FLOW_AGE, then pass
882 * 'flow_age_extension' as true so that the contents of 'msg' determine the
883 * 'idle_age' and 'hard_age' members in 'fs'.
885 * Uses 'ofpacts' to store the abstract OFPACT_* version of the flow stats
886 * reply's actions. The caller must initialize 'ofpacts' and retains ownership
887 * of it. 'fs->ofpacts' will point into the 'ofpacts' buffer.
889 * Returns 0 if successful, EOF if no replies were left in this 'msg',
890 * otherwise an OFPERR_* value. */
892 ofputil_decode_flow_stats_reply(struct ofputil_flow_stats
*fs
,
894 bool flow_age_extension
,
895 struct ofpbuf
*ofpacts
)
897 const struct ofp_header
*oh
;
898 size_t instructions_len
;
902 error
= (msg
->header
? ofpraw_decode(&raw
, msg
->header
)
903 : ofpraw_pull(&raw
, msg
));
911 } else if (raw
== OFPRAW_OFPST15_FLOW_REPLY
) {
912 const struct ofp15_flow_desc
*ofd
;
914 uint16_t padded_match_len
;
916 uint8_t oxs_field_set
;
918 ofd
= ofpbuf_try_pull(msg
, sizeof *ofd
);
920 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply has %" PRIu32
921 " leftover " "bytes at end", msg
->size
);
925 length
= ntohs(ofd
->length
);
926 if (length
< sizeof *ofd
) {
927 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply claims invalid "
928 "length %" PRIuSIZE
, length
);
932 if (ofputil_pull_ofp11_match(msg
, NULL
, NULL
, &fs
->match
,
933 &padded_match_len
)) {
934 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply bad match");
938 fs
->priority
= ntohs(ofd
->priority
);
939 fs
->table_id
= ofd
->table_id
;
940 fs
->cookie
= ofd
->cookie
;
941 fs
->idle_timeout
= ntohs(ofd
->idle_timeout
);
942 fs
->hard_timeout
= ntohs(ofd
->hard_timeout
);
943 fs
->importance
= ntohs(ofd
->importance
);
945 error
= ofputil_decode_flow_mod_flags(ofd
->flags
, -1, oh
->version
,
951 struct oxs_stats oxs
;
952 if (oxs_pull_stat(msg
, &oxs
, &stat_len
, &oxs_field_set
)) {
953 VLOG_WARN_RL(&rl
, "OXS OFPST_FLOW reply bad stats");
956 fs
->duration_sec
= oxs
.duration_sec
;
957 fs
->duration_nsec
= oxs
.duration_nsec
;
958 fs
->packet_count
= oxs
.packet_count
;
959 fs
->byte_count
= oxs
.byte_count
;
960 fs
->idle_age
= oxs
.idle_age
== UINT32_MAX
? -1 : oxs
.idle_age
;
963 instructions_len
= length
- sizeof *ofd
- padded_match_len
- stat_len
;
964 } else if (raw
== OFPRAW_OFPST11_FLOW_REPLY
965 || raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
966 const struct ofp11_flow_stats
*ofs
;
968 uint16_t padded_match_len
;
970 ofs
= ofpbuf_try_pull(msg
, sizeof *ofs
);
972 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply has %"PRIu32
" leftover "
973 "bytes at end", msg
->size
);
974 return OFPERR_OFPBRC_BAD_LEN
;
977 length
= ntohs(ofs
->length
);
978 if (length
< sizeof *ofs
) {
979 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply claims invalid "
980 "length %"PRIuSIZE
, length
);
981 return OFPERR_OFPBRC_BAD_LEN
;
984 error
= ofputil_pull_ofp11_match(msg
, NULL
, NULL
, &fs
->match
,
987 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply bad match");
990 instructions_len
= length
- sizeof *ofs
- padded_match_len
;
992 fs
->priority
= ntohs(ofs
->priority
);
993 fs
->table_id
= ofs
->table_id
;
994 fs
->duration_sec
= ntohl(ofs
->duration_sec
);
995 fs
->duration_nsec
= ntohl(ofs
->duration_nsec
);
996 fs
->idle_timeout
= ntohs(ofs
->idle_timeout
);
997 fs
->hard_timeout
= ntohs(ofs
->hard_timeout
);
998 if (oh
->version
>= OFP14_VERSION
) {
999 fs
->importance
= ntohs(ofs
->importance
);
1003 if (raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
1004 error
= ofputil_decode_flow_mod_flags(ofs
->flags
, -1, oh
->version
,
1014 fs
->cookie
= ofs
->cookie
;
1015 fs
->packet_count
= ntohll(ofs
->packet_count
);
1016 fs
->byte_count
= ntohll(ofs
->byte_count
);
1017 } else if (raw
== OFPRAW_OFPST10_FLOW_REPLY
) {
1018 const struct ofp10_flow_stats
*ofs
;
1021 ofs
= ofpbuf_try_pull(msg
, sizeof *ofs
);
1023 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply has %"PRIu32
" leftover "
1024 "bytes at end", msg
->size
);
1025 return OFPERR_OFPBRC_BAD_LEN
;
1028 length
= ntohs(ofs
->length
);
1029 if (length
< sizeof *ofs
) {
1030 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply claims invalid "
1031 "length %"PRIuSIZE
, length
);
1032 return OFPERR_OFPBRC_BAD_LEN
;
1034 instructions_len
= length
- sizeof *ofs
;
1036 fs
->cookie
= get_32aligned_be64(&ofs
->cookie
);
1037 ofputil_match_from_ofp10_match(&ofs
->match
, &fs
->match
);
1038 fs
->priority
= ntohs(ofs
->priority
);
1039 fs
->table_id
= ofs
->table_id
;
1040 fs
->duration_sec
= ntohl(ofs
->duration_sec
);
1041 fs
->duration_nsec
= ntohl(ofs
->duration_nsec
);
1042 fs
->idle_timeout
= ntohs(ofs
->idle_timeout
);
1043 fs
->hard_timeout
= ntohs(ofs
->hard_timeout
);
1047 fs
->packet_count
= ntohll(get_32aligned_be64(&ofs
->packet_count
));
1048 fs
->byte_count
= ntohll(get_32aligned_be64(&ofs
->byte_count
));
1050 } else if (raw
== OFPRAW_NXST_FLOW_REPLY
) {
1051 const struct nx_flow_stats
*nfs
;
1052 size_t match_len
, length
;
1054 nfs
= ofpbuf_try_pull(msg
, sizeof *nfs
);
1056 VLOG_WARN_RL(&rl
, "NXST_FLOW reply has %"PRIu32
" leftover "
1057 "bytes at end", msg
->size
);
1058 return OFPERR_OFPBRC_BAD_LEN
;
1061 length
= ntohs(nfs
->length
);
1062 match_len
= ntohs(nfs
->match_len
);
1063 if (length
< sizeof *nfs
+ ROUND_UP(match_len
, 8)) {
1064 VLOG_WARN_RL(&rl
, "NXST_FLOW reply with match_len=%"PRIuSIZE
" "
1065 "claims invalid length %"PRIuSIZE
, match_len
, length
);
1066 return OFPERR_OFPBRC_BAD_LEN
;
1068 error
= nx_pull_match(msg
, match_len
, &fs
->match
, NULL
, NULL
, false,
1073 instructions_len
= length
- sizeof *nfs
- ROUND_UP(match_len
, 8);
1075 fs
->cookie
= nfs
->cookie
;
1076 fs
->table_id
= nfs
->table_id
;
1077 fs
->duration_sec
= ntohl(nfs
->duration_sec
);
1078 fs
->duration_nsec
= ntohl(nfs
->duration_nsec
);
1079 fs
->priority
= ntohs(nfs
->priority
);
1080 fs
->idle_timeout
= ntohs(nfs
->idle_timeout
);
1081 fs
->hard_timeout
= ntohs(nfs
->hard_timeout
);
1085 if (flow_age_extension
) {
1086 if (nfs
->idle_age
) {
1087 fs
->idle_age
= ntohs(nfs
->idle_age
) - 1;
1089 if (nfs
->hard_age
) {
1090 fs
->hard_age
= ntohs(nfs
->hard_age
) - 1;
1093 fs
->packet_count
= ntohll(nfs
->packet_count
);
1094 fs
->byte_count
= ntohll(nfs
->byte_count
);
1100 error
= ofpacts_pull_openflow_instructions(msg
, instructions_len
,
1101 oh
->version
, NULL
, NULL
,
1104 VLOG_WARN_RL(&rl
, "OFPST_FLOW reply bad instructions");
1107 fs
->ofpacts
= ofpacts
->data
;
1108 fs
->ofpacts_len
= ofpacts
->size
;
1113 /* Returns 'count' unchanged except that UINT64_MAX becomes 0.
1115 * We use this in situations where OVS internally uses UINT64_MAX to mean
1116 * "value unknown" but OpenFlow 1.0 does not define any unknown value. */
1118 unknown_to_zero(uint64_t count
)
1120 return count
!= UINT64_MAX
? count
: 0;
1123 /* Appends an OFPST_FLOW or NXST_FLOW reply that contains the data in 'fs' to
1124 * those already present in the list of ofpbufs in 'replies'. 'replies' should
1125 * have been initialized with ofpmp_init(). */
1127 ofputil_append_flow_stats_reply(const struct ofputil_flow_stats
*fs
,
1128 struct ovs_list
*replies
,
1129 const struct tun_table
*tun_table
)
1131 struct ofputil_flow_stats
*fs_
= CONST_CAST(struct ofputil_flow_stats
*,
1133 const struct tun_table
*orig_tun_table
;
1134 struct ofpbuf
*reply
= ofpbuf_from_list(ovs_list_back(replies
));
1135 size_t start_ofs
= reply
->size
;
1136 enum ofp_version version
= ofpmp_version(replies
);
1137 enum ofpraw raw
= ofpmp_decode_raw(replies
);
1139 orig_tun_table
= fs
->match
.flow
.tunnel
.metadata
.tab
;
1140 fs_
->match
.flow
.tunnel
.metadata
.tab
= tun_table
;
1142 if (raw
== OFPRAW_OFPST15_FLOW_REPLY
) {
1143 struct ofp15_flow_desc
*ofd
;
1145 ofpbuf_put_uninit(reply
, sizeof *ofd
);
1146 oxm_put_match(reply
, &fs
->match
, version
);
1148 struct oxs_stats oxs
= {
1149 .duration_sec
= fs
->duration_sec
,
1150 .duration_nsec
= fs
->duration_nsec
,
1151 .idle_age
= fs
->idle_age
>= 0 ? fs
->idle_age
: UINT32_MAX
,
1152 .packet_count
= fs
->packet_count
,
1153 .byte_count
= fs
->byte_count
,
1154 .flow_count
= UINT32_MAX
,
1156 oxs_put_stats(reply
, &oxs
);
1158 ofpacts_put_openflow_instructions(fs
->ofpacts
, fs
->ofpacts_len
, reply
,
1161 ofd
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *ofd
);
1162 ofd
->length
= htons(reply
->size
- start_ofs
);
1163 ofd
->table_id
= fs
->table_id
;
1164 ofd
->priority
= htons(fs
->priority
);
1165 ofd
->idle_timeout
= htons(fs
->idle_timeout
);
1166 ofd
->hard_timeout
= htons(fs
->hard_timeout
);
1167 ofd
->cookie
= fs
->cookie
;
1168 memset(ofd
->pad2
, 0, sizeof ofd
->pad2
);
1170 ofd
->importance
= htons(fs
->importance
);
1171 ofd
->flags
= ofputil_encode_flow_mod_flags(fs
->flags
, version
);
1172 } else if (raw
== OFPRAW_OFPST11_FLOW_REPLY
||
1173 raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
1174 struct ofp11_flow_stats
*ofs
;
1176 ofpbuf_put_uninit(reply
, sizeof *ofs
);
1177 oxm_put_match(reply
, &fs
->match
, version
);
1178 ofpacts_put_openflow_instructions(fs
->ofpacts
, fs
->ofpacts_len
, reply
,
1181 ofs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *ofs
);
1182 ofs
->length
= htons(reply
->size
- start_ofs
);
1183 ofs
->table_id
= fs
->table_id
;
1185 ofs
->duration_sec
= htonl(fs
->duration_sec
);
1186 ofs
->duration_nsec
= htonl(fs
->duration_nsec
);
1187 ofs
->priority
= htons(fs
->priority
);
1188 ofs
->idle_timeout
= htons(fs
->idle_timeout
);
1189 ofs
->hard_timeout
= htons(fs
->hard_timeout
);
1190 if (version
>= OFP14_VERSION
) {
1191 ofs
->importance
= htons(fs
->importance
);
1193 ofs
->importance
= 0;
1195 if (raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
1196 ofs
->flags
= ofputil_encode_flow_mod_flags(fs
->flags
, version
);
1200 memset(ofs
->pad2
, 0, sizeof ofs
->pad2
);
1201 ofs
->cookie
= fs
->cookie
;
1202 ofs
->packet_count
= htonll(unknown_to_zero(fs
->packet_count
));
1203 ofs
->byte_count
= htonll(unknown_to_zero(fs
->byte_count
));
1204 } else if (raw
== OFPRAW_OFPST10_FLOW_REPLY
) {
1205 struct ofp10_flow_stats
*ofs
;
1207 ofpbuf_put_uninit(reply
, sizeof *ofs
);
1208 ofpacts_put_openflow_actions(fs
->ofpacts
, fs
->ofpacts_len
, reply
,
1210 ofs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *ofs
);
1211 ofs
->length
= htons(reply
->size
- start_ofs
);
1212 ofs
->table_id
= fs
->table_id
;
1214 ofputil_match_to_ofp10_match(&fs
->match
, &ofs
->match
);
1215 ofs
->duration_sec
= htonl(fs
->duration_sec
);
1216 ofs
->duration_nsec
= htonl(fs
->duration_nsec
);
1217 ofs
->priority
= htons(fs
->priority
);
1218 ofs
->idle_timeout
= htons(fs
->idle_timeout
);
1219 ofs
->hard_timeout
= htons(fs
->hard_timeout
);
1220 memset(ofs
->pad2
, 0, sizeof ofs
->pad2
);
1221 put_32aligned_be64(&ofs
->cookie
, fs
->cookie
);
1222 put_32aligned_be64(&ofs
->packet_count
,
1223 htonll(unknown_to_zero(fs
->packet_count
)));
1224 put_32aligned_be64(&ofs
->byte_count
,
1225 htonll(unknown_to_zero(fs
->byte_count
)));
1226 } else if (raw
== OFPRAW_NXST_FLOW_REPLY
) {
1227 struct nx_flow_stats
*nfs
;
1230 ofpbuf_put_uninit(reply
, sizeof *nfs
);
1231 match_len
= nx_put_match(reply
, &fs
->match
, 0, 0);
1232 ofpacts_put_openflow_actions(fs
->ofpacts
, fs
->ofpacts_len
, reply
,
1234 nfs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *nfs
);
1235 nfs
->length
= htons(reply
->size
- start_ofs
);
1236 nfs
->table_id
= fs
->table_id
;
1238 nfs
->duration_sec
= htonl(fs
->duration_sec
);
1239 nfs
->duration_nsec
= htonl(fs
->duration_nsec
);
1240 nfs
->priority
= htons(fs
->priority
);
1241 nfs
->idle_timeout
= htons(fs
->idle_timeout
);
1242 nfs
->hard_timeout
= htons(fs
->hard_timeout
);
1243 nfs
->idle_age
= htons(fs
->idle_age
< 0 ? 0
1244 : fs
->idle_age
< UINT16_MAX
? fs
->idle_age
+ 1
1246 nfs
->hard_age
= htons(fs
->hard_age
< 0 ? 0
1247 : fs
->hard_age
< UINT16_MAX
? fs
->hard_age
+ 1
1249 nfs
->match_len
= htons(match_len
);
1250 nfs
->cookie
= fs
->cookie
;
1251 nfs
->packet_count
= htonll(fs
->packet_count
);
1252 nfs
->byte_count
= htonll(fs
->byte_count
);
1257 ofpmp_postappend(replies
, start_ofs
);
1258 fs_
->match
.flow
.tunnel
.metadata
.tab
= orig_tun_table
;
1262 print_flow_stat(struct ds
*string
, const char *leader
, uint64_t stat
)
1264 ds_put_format(string
, "%s%s=%s", colors
.param
, leader
, colors
.end
);
1265 if (stat
!= UINT64_MAX
) {
1266 ds_put_format(string
, "%"PRIu64
, stat
);
1268 ds_put_char(string
, '?');
1270 ds_put_cstr(string
, ", ");
1273 /* Appends a textual form of 'fs' to 'string', translating port numbers to
1274 * names using 'port_map' (if provided). If 'show_stats' is true, the output
1275 * includes the flow duration, packet and byte counts, and its idle and hard
1276 * ages, otherwise they are omitted. */
1278 ofputil_flow_stats_format(struct ds
*string
,
1279 const struct ofputil_flow_stats
*fs
,
1280 const struct ofputil_port_map
*port_map
,
1281 const struct ofputil_table_map
*table_map
,
1284 if (show_stats
|| fs
->cookie
) {
1285 ds_put_format(string
, "%scookie=%s0x%"PRIx64
", ",
1286 colors
.param
, colors
.end
, ntohll(fs
->cookie
));
1289 ds_put_format(string
, "%sduration=%s", colors
.param
, colors
.end
);
1290 ofp_print_duration(string
, fs
->duration_sec
, fs
->duration_nsec
);
1291 ds_put_cstr(string
, ", ");
1294 if (show_stats
|| fs
->table_id
1295 || ofputil_table_map_get_name(table_map
, fs
->table_id
) != NULL
) {
1296 ds_put_format(string
, "%stable=%s", colors
.special
, colors
.end
);
1297 ofputil_format_table(fs
->table_id
, table_map
, string
);
1298 ds_put_cstr(string
, ", ");
1301 print_flow_stat(string
, "n_packets", fs
->packet_count
);
1302 print_flow_stat(string
, "n_bytes", fs
->byte_count
);
1304 if (fs
->idle_timeout
!= OFP_FLOW_PERMANENT
) {
1305 ds_put_format(string
, "%sidle_timeout=%s%"PRIu16
", ",
1306 colors
.param
, colors
.end
, fs
->idle_timeout
);
1308 if (fs
->hard_timeout
!= OFP_FLOW_PERMANENT
) {
1309 ds_put_format(string
, "%shard_timeout=%s%"PRIu16
", ",
1310 colors
.param
, colors
.end
, fs
->hard_timeout
);
1313 ofputil_flow_mod_flags_format(string
, fs
->flags
);
1315 if (fs
->importance
!= 0) {
1316 ds_put_format(string
, "%simportance=%s%"PRIu16
", ",
1317 colors
.param
, colors
.end
, fs
->importance
);
1319 if (show_stats
&& fs
->idle_age
>= 0) {
1320 ds_put_format(string
, "%sidle_age=%s%d, ",
1321 colors
.param
, colors
.end
, fs
->idle_age
);
1323 if (show_stats
&& fs
->hard_age
>= 0 && fs
->hard_age
!= fs
->duration_sec
) {
1324 ds_put_format(string
, "%shard_age=%s%d, ",
1325 colors
.param
, colors
.end
, fs
->hard_age
);
1328 /* Print the match, followed by a space (but omit the space if the match
1329 * was an empty string). */
1330 size_t length
= string
->length
;
1331 match_format(&fs
->match
, port_map
, string
, fs
->priority
);
1332 if (string
->length
!= length
) {
1333 ds_put_char(string
, ' ');
1336 ds_put_format(string
, "%sactions=%s", colors
.actions
, colors
.end
);
1337 struct ofpact_format_params fp
= {
1338 .port_map
= port_map
,
1339 .table_map
= table_map
,
1342 ofpacts_format(fs
->ofpacts
, fs
->ofpacts_len
, &fp
);
1345 /* Converts abstract ofputil_aggregate_stats 'stats' into an OFPST_AGGREGATE or
1346 * NXST_AGGREGATE reply matching 'request', and returns the message. */
1348 ofputil_encode_aggregate_stats_reply(
1349 const struct ofputil_aggregate_stats
*stats
,
1350 const struct ofp_header
*request
)
1352 struct ofp_aggregate_stats_reply
*asr
;
1353 uint64_t packet_count
;
1354 uint64_t byte_count
;
1358 ofpraw_decode(&raw
, request
);
1359 if (raw
== OFPRAW_OFPST15_AGGREGATE_REQUEST
) {
1360 msg
= ofpraw_alloc_stats_reply(request
, 0);
1362 struct oxs_stats oxs
= {
1363 .duration_sec
= UINT32_MAX
,
1364 .duration_nsec
= UINT32_MAX
,
1365 .idle_age
= UINT32_MAX
,
1366 .packet_count
= stats
->packet_count
,
1367 .byte_count
= stats
->byte_count
,
1368 .flow_count
= stats
->flow_count
,
1370 oxs_put_stats(msg
, &oxs
);
1372 if (raw
== OFPRAW_OFPST10_AGGREGATE_REQUEST
) {
1373 packet_count
= unknown_to_zero(stats
->packet_count
);
1374 byte_count
= unknown_to_zero(stats
->byte_count
);
1376 packet_count
= stats
->packet_count
;
1377 byte_count
= stats
->byte_count
;
1380 msg
= ofpraw_alloc_stats_reply(request
, 0);
1381 asr
= ofpbuf_put_zeros(msg
, sizeof *asr
);
1382 put_32aligned_be64(&asr
->packet_count
, htonll(packet_count
));
1383 put_32aligned_be64(&asr
->byte_count
, htonll(byte_count
));
1384 asr
->flow_count
= htonl(stats
->flow_count
);
1390 ofputil_decode_aggregate_stats_reply(struct ofputil_aggregate_stats
*stats
,
1391 const struct ofp_header
*reply
)
1393 struct ofpbuf msg
= ofpbuf_const_initializer(reply
, ntohs(reply
->length
));
1396 raw
= ofpraw_pull_assert(&msg
);
1397 if (raw
== OFPRAW_OFPST15_AGGREGATE_REPLY
) {
1398 struct oxs_stats oxs
;
1400 uint8_t oxs_field_set
;
1401 enum ofperr error
= oxs_pull_stat(&msg
, &oxs
, &statlen
,
1406 stats
->packet_count
= oxs
.packet_count
;
1407 stats
->byte_count
= oxs
.byte_count
;
1408 stats
->flow_count
= oxs
.flow_count
;
1410 struct ofp_aggregate_stats_reply
*asr
= msg
.msg
;
1411 stats
->packet_count
= ntohll(get_32aligned_be64(&asr
->packet_count
));
1412 stats
->byte_count
= ntohll(get_32aligned_be64(&asr
->byte_count
));
1413 stats
->flow_count
= ntohl(asr
->flow_count
);
1420 ofputil_aggregate_stats_format(struct ds
*s
,
1421 const struct ofputil_aggregate_stats
*as
)
1423 ds_put_format(s
, " packet_count=%"PRIu64
, as
->packet_count
);
1424 ds_put_format(s
, " byte_count=%"PRIu64
, as
->byte_count
);
1425 ds_put_format(s
, " flow_count=%"PRIu32
, as
->flow_count
);
1428 /* Parses 'str_value' as the value of subfield 'name', and updates
1429 * 'match' appropriately. Restricts the set of usable protocols to ones
1430 * supporting the parsed field.
1432 * Returns NULL if successful, otherwise a malloc()'d string describing the
1433 * error. The caller is responsible for freeing the returned string. */
1434 static char * OVS_WARN_UNUSED_RESULT
1435 parse_subfield(const char *name
, const char *str_value
, struct match
*match
,
1436 enum ofputil_protocol
*usable_protocols
)
1438 struct mf_subfield sf
;
1441 error
= mf_parse_subfield(&sf
, name
);
1445 if (parse_int_string(str_value
, (uint8_t *)&val
, sf
.field
->n_bytes
,
1446 &tail
) || *tail
!= 0) {
1447 return xasprintf("%s: cannot parse integer value: %s", name
,
1450 if (!bitwise_is_all_zeros(&val
, sf
.field
->n_bytes
, sf
.n_bits
,
1451 sf
.field
->n_bytes
* 8 - sf
.n_bits
)) {
1455 mf_format(sf
.field
, &val
, NULL
, NULL
, &ds
);
1456 error
= xasprintf("%s: value %s does not fit into %d bits",
1457 name
, ds_cstr(&ds
), sf
.n_bits
);
1462 const struct mf_field
*field
= sf
.field
;
1463 union mf_value value
, mask
;
1464 unsigned int size
= field
->n_bytes
;
1466 mf_get(field
, match
, &value
, &mask
);
1467 bitwise_copy(&val
, size
, 0, &value
, size
, sf
.ofs
, sf
.n_bits
);
1468 bitwise_one ( &mask
, size
, sf
.ofs
, sf
.n_bits
);
1469 *usable_protocols
&= mf_set(field
, &value
, &mask
, match
, &error
);
1471 match_add_ethernet_prereq(match
, sf
.field
);
1476 static char * OVS_WARN_UNUSED_RESULT
1477 parse_ofp_str__(struct ofputil_flow_mod
*fm
, int command
, char *string
,
1478 const struct ofputil_port_map
*port_map
,
1479 const struct ofputil_table_map
*table_map
,
1480 enum ofputil_protocol
*usable_protocols
)
1483 F_OUT_PORT
= 1 << 0,
1485 F_IMPORTANCE
= 1 << 2,
1487 F_PRIORITY
= 1 << 4,
1490 char *act_str
= NULL
;
1493 *usable_protocols
= OFPUTIL_P_ANY
;
1495 if (command
== -2) {
1498 string
+= strspn(string
, " \t\r\n"); /* Skip white space. */
1499 len
= strcspn(string
, ", \t\r\n"); /* Get length of the first token. */
1501 if (!strncmp(string
, "add", len
)) {
1502 command
= OFPFC_ADD
;
1503 } else if (!strncmp(string
, "delete", len
)) {
1504 command
= OFPFC_DELETE
;
1505 } else if (!strncmp(string
, "delete_strict", len
)) {
1506 command
= OFPFC_DELETE_STRICT
;
1507 } else if (!strncmp(string
, "modify", len
)) {
1508 command
= OFPFC_MODIFY
;
1509 } else if (!strncmp(string
, "modify_strict", len
)) {
1510 command
= OFPFC_MODIFY_STRICT
;
1513 command
= OFPFC_ADD
;
1520 fields
= F_OUT_PORT
;
1524 fields
= F_ACTIONS
| F_TIMEOUT
| F_PRIORITY
| F_FLAGS
| F_IMPORTANCE
;
1528 fields
= F_OUT_PORT
;
1531 case OFPFC_DELETE_STRICT
:
1532 fields
= F_OUT_PORT
| F_PRIORITY
;
1536 fields
= F_ACTIONS
| F_TIMEOUT
| F_PRIORITY
| F_FLAGS
;
1539 case OFPFC_MODIFY_STRICT
:
1540 fields
= F_ACTIONS
| F_TIMEOUT
| F_PRIORITY
| F_FLAGS
;
1547 *fm
= (struct ofputil_flow_mod
) {
1548 .priority
= OFP_DEFAULT_PRIORITY
,
1551 .buffer_id
= UINT32_MAX
,
1552 .out_port
= OFPP_ANY
,
1553 .out_group
= OFPG_ANY
,
1555 /* For modify, by default, don't update the cookie. */
1556 if (command
== OFPFC_MODIFY
|| command
== OFPFC_MODIFY_STRICT
) {
1557 fm
->new_cookie
= OVS_BE64_MAX
;
1560 if (fields
& F_ACTIONS
) {
1561 act_str
= ofp_extract_actions(string
);
1563 return xstrdup("must specify an action");
1567 struct match match
= MATCH_CATCHALL_INITIALIZER
;
1568 while (ofputil_parse_key_value(&string
, &name
, &value
)) {
1569 const struct ofp_protocol
*p
;
1570 const struct mf_field
*mf
;
1573 if (ofp_parse_protocol(name
, &p
)) {
1574 match_set_dl_type(&match
, htons(p
->dl_type
));
1576 match_set_nw_proto(&match
, p
->nw_proto
);
1578 match_set_default_packet_type(&match
);
1579 } else if (!strcmp(name
, "eth")) {
1580 match_set_packet_type(&match
, htonl(PT_ETH
));
1581 } else if (fields
& F_FLAGS
&& !strcmp(name
, "send_flow_rem")) {
1582 fm
->flags
|= OFPUTIL_FF_SEND_FLOW_REM
;
1583 } else if (fields
& F_FLAGS
&& !strcmp(name
, "check_overlap")) {
1584 fm
->flags
|= OFPUTIL_FF_CHECK_OVERLAP
;
1585 } else if (fields
& F_FLAGS
&& !strcmp(name
, "reset_counts")) {
1586 fm
->flags
|= OFPUTIL_FF_RESET_COUNTS
;
1587 *usable_protocols
&= OFPUTIL_P_OF12_UP
;
1588 } else if (fields
& F_FLAGS
&& !strcmp(name
, "no_packet_counts")) {
1589 fm
->flags
|= OFPUTIL_FF_NO_PKT_COUNTS
;
1590 *usable_protocols
&= OFPUTIL_P_OF13_UP
;
1591 } else if (fields
& F_FLAGS
&& !strcmp(name
, "no_byte_counts")) {
1592 fm
->flags
|= OFPUTIL_FF_NO_BYT_COUNTS
;
1593 *usable_protocols
&= OFPUTIL_P_OF13_UP
;
1594 } else if (!strcmp(name
, "no_readonly_table")
1595 || !strcmp(name
, "allow_hidden_fields")) {
1596 /* ignore these fields. */
1597 } else if ((mf
= mf_from_name(name
)) != NULL
) {
1598 error
= ofp_parse_field(mf
, value
, port_map
,
1599 &match
, usable_protocols
);
1600 } else if (strchr(name
, '[')) {
1601 error
= parse_subfield(name
, value
, &match
, usable_protocols
);
1604 return xasprintf("field %s missing value", name
);
1607 if (!strcmp(name
, "table")) {
1608 if (!ofputil_table_from_string(value
, table_map
,
1610 return xasprintf("unknown table \"%s\"", value
);
1612 if (fm
->table_id
!= 0xff) {
1613 *usable_protocols
&= OFPUTIL_P_TID
;
1615 } else if (fields
& F_OUT_PORT
&& !strcmp(name
, "out_port")) {
1616 if (!ofputil_port_from_string(value
, port_map
,
1618 error
= xasprintf("%s is not a valid OpenFlow port",
1621 } else if (fields
& F_OUT_PORT
&& !strcmp(name
, "out_group")) {
1622 *usable_protocols
&= OFPUTIL_P_OF11_UP
;
1623 if (!ofputil_group_from_string(value
, &fm
->out_group
)) {
1624 error
= xasprintf("%s is not a valid OpenFlow group",
1627 } else if (fields
& F_PRIORITY
&& !strcmp(name
, "priority")) {
1628 uint16_t priority
= 0;
1630 error
= str_to_u16(value
, name
, &priority
);
1631 fm
->priority
= priority
;
1632 } else if (fields
& F_TIMEOUT
&& !strcmp(name
, "idle_timeout")) {
1633 error
= str_to_u16(value
, name
, &fm
->idle_timeout
);
1634 } else if (fields
& F_TIMEOUT
&& !strcmp(name
, "hard_timeout")) {
1635 error
= str_to_u16(value
, name
, &fm
->hard_timeout
);
1636 } else if (fields
& F_IMPORTANCE
&& !strcmp(name
, "importance")) {
1637 error
= str_to_u16(value
, name
, &fm
->importance
);
1638 } else if (!strcmp(name
, "cookie")) {
1639 char *mask
= strchr(value
, '/');
1642 /* A mask means we're searching for a cookie. */
1643 if (command
== OFPFC_ADD
) {
1644 return xstrdup("flow additions cannot use "
1648 error
= str_to_be64(value
, &fm
->cookie
);
1652 error
= str_to_be64(mask
+ 1, &fm
->cookie_mask
);
1654 /* Matching of the cookie is only supported through NXM or
1656 if (fm
->cookie_mask
!= htonll(0)) {
1657 *usable_protocols
&= OFPUTIL_P_NXM_OF11_UP
;
1660 /* No mask means that the cookie is being set. */
1661 if (command
!= OFPFC_ADD
&& command
!= OFPFC_MODIFY
1662 && command
!= OFPFC_MODIFY_STRICT
) {
1663 return xasprintf("cannot set cookie (to match on a "
1664 "cookie, specify a mask, e.g. "
1665 "cookie=%s/-1)", value
);
1667 error
= str_to_be64(value
, &fm
->new_cookie
);
1668 fm
->modify_cookie
= true;
1670 } else if (!strcmp(name
, "duration")
1671 || !strcmp(name
, "n_packets")
1672 || !strcmp(name
, "n_bytes")
1673 || !strcmp(name
, "idle_age")
1674 || !strcmp(name
, "hard_age")) {
1675 /* Ignore these, so that users can feed the output of
1676 * "ovs-ofctl dump-flows" back into commands that parse
1679 error
= xasprintf("unknown keyword %s", name
);
1687 /* Copy ethertype to flow->dl_type for matches on packet_type
1688 * (OFPHTN_ETHERTYPE, ethertype). */
1689 if (match
.wc
.masks
.packet_type
== OVS_BE32_MAX
&&
1690 pt_ns(match
.flow
.packet_type
) == OFPHTN_ETHERTYPE
) {
1691 match
.flow
.dl_type
= pt_ns_type_be(match
.flow
.packet_type
);
1693 /* Check for usable protocol interdependencies between match fields. */
1694 if (match
.flow
.dl_type
== htons(ETH_TYPE_IPV6
)) {
1695 const struct flow_wildcards
*wc
= &match
.wc
;
1696 /* Only NXM and OXM support matching L3 and L4 fields within IPv6.
1698 * (IPv6 specific fields as well as arp_sha, arp_tha, nw_frag, and
1699 * nw_ttl are covered elsewhere so they don't need to be included in
1702 if (wc
->masks
.nw_proto
|| wc
->masks
.nw_tos
1703 || wc
->masks
.tp_src
|| wc
->masks
.tp_dst
) {
1704 *usable_protocols
&= OFPUTIL_P_NXM_OXM_ANY
;
1707 if (!fm
->cookie_mask
&& fm
->new_cookie
== OVS_BE64_MAX
1708 && (command
== OFPFC_MODIFY
|| command
== OFPFC_MODIFY_STRICT
)) {
1709 /* On modifies without a mask, we are supposed to add a flow if
1710 * one does not exist. If a cookie wasn't been specified, use a
1711 * default of zero. */
1712 fm
->new_cookie
= htonll(0);
1714 if (fields
& F_ACTIONS
) {
1715 enum ofputil_protocol action_usable_protocols
;
1716 struct ofpbuf ofpacts
;
1719 ofpbuf_init(&ofpacts
, 32);
1720 struct ofpact_parse_params pp
= {
1721 .port_map
= port_map
,
1722 .table_map
= table_map
,
1723 .ofpacts
= &ofpacts
,
1724 .usable_protocols
= &action_usable_protocols
1726 error
= ofpacts_parse_instructions(act_str
, &pp
);
1727 *usable_protocols
&= action_usable_protocols
;
1731 struct ofpact_check_params cp
= {
1733 .max_ports
= OFPP_MAX
,
1734 .table_id
= fm
->table_id
,
1737 err
= ofpacts_check(ofpacts
.data
, ofpacts
.size
, &cp
);
1738 *usable_protocols
&= cp
.usable_protocols
;
1739 if (!err
&& !*usable_protocols
) {
1740 err
= OFPERR_OFPBAC_MATCH_INCONSISTENT
;
1743 error
= xasprintf("actions are invalid with specified match "
1744 "(%s)", ofperr_to_string(err
));
1749 ofpbuf_uninit(&ofpacts
);
1753 fm
->ofpacts_len
= ofpacts
.size
;
1754 fm
->ofpacts
= ofpbuf_steal_data(&ofpacts
);
1756 fm
->ofpacts_len
= 0;
1759 minimatch_init(&fm
->match
, &match
);
1764 /* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
1765 * page) into 'fm' for sending the specified flow_mod 'command' to a switch.
1766 * Returns the set of usable protocols in '*usable_protocols'.
1768 * To parse syntax for an OFPT_FLOW_MOD (or NXT_FLOW_MOD), use an OFPFC_*
1769 * constant for 'command'. To parse syntax for an OFPST_FLOW or
1770 * OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'.
1772 * If 'command' is given as -2, 'str_' may begin with a command name ("add",
1773 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
1774 * name is treated as "add".
1776 * Returns NULL if successful, otherwise a malloc()'d string describing the
1777 * error. The caller is responsible for freeing the returned string.
1779 * On success, the caller is responsible for freeing fm->ofpacts and
1781 char * OVS_WARN_UNUSED_RESULT
1782 parse_ofp_str(struct ofputil_flow_mod
*fm
, int command
, const char *str_
,
1783 const struct ofputil_port_map
*port_map
,
1784 const struct ofputil_table_map
*table_map
,
1785 enum ofputil_protocol
*usable_protocols
)
1787 char *string
= xstrdup(str_
);
1790 error
= parse_ofp_str__(fm
, command
, string
, port_map
, table_map
,
1794 fm
->ofpacts_len
= 0;
1801 /* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
1802 * (one of OFPFC_*) into 'fm'.
1804 * If 'command' is given as -2, 'string' may begin with a command name ("add",
1805 * "modify", "delete", "modify_strict", or "delete_strict"). A missing command
1806 * name is treated as "add".
1808 * Returns NULL if successful, otherwise a malloc()'d string describing the
1809 * error. The caller is responsible for freeing the returned string. */
1810 char * OVS_WARN_UNUSED_RESULT
1811 parse_ofp_flow_mod_str(struct ofputil_flow_mod
*fm
, const char *string
,
1812 const struct ofputil_port_map
*port_map
,
1813 const struct ofputil_table_map
*table_map
,
1815 enum ofputil_protocol
*usable_protocols
)
1817 char *error
= parse_ofp_str(fm
, command
, string
, port_map
, table_map
,
1821 /* Normalize a copy of the match. This ensures that non-normalized
1822 * flows get logged but doesn't affect what gets sent to the switch, so
1823 * that the switch can do whatever it likes with the flow. */
1825 minimatch_expand(&fm
->match
, &match
);
1826 ofputil_normalize_match(&match
);
1832 /* Opens file 'file_name' and reads each line as a flow_mod of the specified
1833 * type (one of OFPFC_*). Stores each flow_mod in '*fm', an array allocated
1834 * on the caller's behalf, and the number of flow_mods in '*n_fms'.
1836 * If 'command' is given as -2, each line may start with a command name
1837 * ("add", "modify", "delete", "modify_strict", or "delete_strict"). A missing
1838 * command name is treated as "add".
1840 * Returns NULL if successful, otherwise a malloc()'d string describing the
1841 * error. The caller is responsible for freeing the returned string. */
1842 char * OVS_WARN_UNUSED_RESULT
1843 parse_ofp_flow_mod_file(const char *file_name
,
1844 const struct ofputil_port_map
*port_map
,
1845 const struct ofputil_table_map
*table_map
,
1847 struct ofputil_flow_mod
**fms
, size_t *n_fms
,
1848 enum ofputil_protocol
*usable_protocols
)
1850 size_t allocated_fms
;
1855 *usable_protocols
= OFPUTIL_P_ANY
;
1860 stream
= !strcmp(file_name
, "-") ? stdin
: fopen(file_name
, "r");
1861 if (stream
== NULL
) {
1862 return xasprintf("%s: open failed (%s)",
1863 file_name
, ovs_strerror(errno
));
1866 allocated_fms
= *n_fms
;
1869 while (!ds_get_preprocessed_line(&s
, stream
, &line_number
)) {
1871 enum ofputil_protocol usable
;
1873 if (*n_fms
>= allocated_fms
) {
1874 *fms
= x2nrealloc(*fms
, &allocated_fms
, sizeof **fms
);
1876 error
= parse_ofp_flow_mod_str(&(*fms
)[*n_fms
], ds_cstr(&s
), port_map
,
1877 table_map
, command
, &usable
);
1882 for (i
= 0; i
< *n_fms
; i
++) {
1883 free(CONST_CAST(struct ofpact
*, (*fms
)[i
].ofpacts
));
1884 minimatch_destroy(&(*fms
)[i
].match
);
1891 if (stream
!= stdin
) {
1895 err_msg
= xasprintf("%s:%d: %s", file_name
, line_number
, error
);
1899 *usable_protocols
&= usable
; /* Each line can narrow the set. */
1904 if (stream
!= stdin
) {
1910 /* Parses a specification of a flow from 's' into 'flow'. 's' must take the
1911 * form FIELD=VALUE[,FIELD=VALUE]... where each FIELD is the name of a
1912 * mf_field. Fields must be specified in a natural order for satisfying
1913 * prerequisites. If 'wc' is specified, masks the field in 'wc' for each of the
1914 * field specified in flow. If the map, 'names_portno' is specfied, converts
1915 * the in_port name into port no while setting the 'flow'.
1917 * Returns NULL on success, otherwise a malloc()'d string that explains the
1920 parse_ofp_exact_flow(struct flow
*flow
, struct flow_wildcards
*wc
,
1921 const struct tun_table
*tun_table
, const char *s
,
1922 const struct ofputil_port_map
*port_map
)
1924 char *pos
, *key
, *value_s
;
1928 memset(flow
, 0, sizeof *flow
);
1930 memset(wc
, 0, sizeof *wc
);
1932 flow
->tunnel
.metadata
.tab
= tun_table
;
1934 pos
= copy
= xstrdup(s
);
1935 while (ofputil_parse_key_value(&pos
, &key
, &value_s
)) {
1936 const struct ofp_protocol
*p
;
1937 if (ofp_parse_protocol(key
, &p
)) {
1938 if (flow
->dl_type
) {
1939 error
= xasprintf("%s: Ethernet type set multiple times", s
);
1942 flow
->dl_type
= htons(p
->dl_type
);
1944 wc
->masks
.dl_type
= OVS_BE16_MAX
;
1948 if (flow
->nw_proto
) {
1949 error
= xasprintf("%s: network protocol set "
1950 "multiple times", s
);
1953 flow
->nw_proto
= p
->nw_proto
;
1955 wc
->masks
.nw_proto
= UINT8_MAX
;
1959 const struct mf_field
*mf
;
1960 union mf_value value
;
1963 mf
= mf_from_name(key
);
1965 error
= xasprintf("%s: unknown field %s", s
, key
);
1969 if (!mf_are_prereqs_ok(mf
, flow
, NULL
)) {
1970 error
= xasprintf("%s: prerequisites not met for setting %s",
1975 if (mf_is_set(mf
, flow
)) {
1976 error
= xasprintf("%s: field %s set multiple times", s
, key
);
1980 field_error
= mf_parse_value(mf
, value_s
, port_map
, &value
);
1982 error
= xasprintf("%s: bad value for %s (%s)",
1983 s
, key
, field_error
);
1988 mf_set_flow_value(mf
, &value
, flow
);
1990 mf_mask_field(mf
, wc
);
1995 if (!flow
->in_port
.ofp_port
) {
1996 flow
->in_port
.ofp_port
= OFPP_NONE
;
2003 memset(flow
, 0, sizeof *flow
);
2005 memset(wc
, 0, sizeof *wc
);