2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 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 "ofp-print.h"
22 #include <sys/types.h>
23 #include <netinet/in.h>
24 #include <netinet/icmp6.h>
27 #include "byte-order.h"
28 #include "classifier.h"
29 #include "dynamic-string.h"
31 #include "meta-flow.h"
32 #include "multipath.h"
35 #include "ofp-actions.h"
36 #include "ofp-errors.h"
42 #include "unaligned.h"
43 #include "type-props.h"
46 VLOG_DEFINE_THIS_MODULE(ofp_util
);
48 /* Rate limit for OpenFlow message parse errors. These always indicate a bug
49 * in the peer and so there's not much point in showing a lot of them. */
50 static struct vlog_rate_limit bad_ofmsg_rl
= VLOG_RATE_LIMIT_INIT(1, 5);
52 /* Given the wildcard bit count in the least-significant 6 of 'wcbits', returns
53 * an IP netmask with a 1 in each bit that must match and a 0 in each bit that
56 * The bits in 'wcbits' are in the format used in enum ofp_flow_wildcards: 0
57 * is exact match, 1 ignores the LSB, 2 ignores the 2 least-significant bits,
58 * ..., 32 and higher wildcard the entire field. This is the *opposite* of the
59 * usual convention where e.g. /24 indicates that 8 bits (not 24 bits) are
62 ofputil_wcbits_to_netmask(int wcbits
)
65 return wcbits
< 32 ? htonl(~((1u << wcbits
) - 1)) : 0;
68 /* Given the IP netmask 'netmask', returns the number of bits of the IP address
69 * that it wildcards, that is, the number of 0-bits in 'netmask', a number
70 * between 0 and 32 inclusive.
72 * If 'netmask' is not a CIDR netmask (see ip_is_cidr()), the return value will
73 * still be in the valid range but isn't otherwise meaningful. */
75 ofputil_netmask_to_wcbits(ovs_be32 netmask
)
77 return 32 - ip_count_cidr_bits(netmask
);
80 /* Converts the OpenFlow 1.0 wildcards in 'ofpfw' (OFPFW10_*) into a
81 * flow_wildcards in 'wc' for use in struct match. It is the caller's
82 * responsibility to handle the special case where the flow match's dl_vlan is
83 * set to OFP_VLAN_NONE. */
85 ofputil_wildcard_from_ofpfw10(uint32_t ofpfw
, struct flow_wildcards
*wc
)
87 BUILD_ASSERT_DECL(FLOW_WC_SEQ
== 21);
89 /* Initialize most of wc. */
90 flow_wildcards_init_catchall(wc
);
92 if (!(ofpfw
& OFPFW10_IN_PORT
)) {
93 wc
->masks
.in_port
.ofp_port
= u16_to_ofp(UINT16_MAX
);
96 if (!(ofpfw
& OFPFW10_NW_TOS
)) {
97 wc
->masks
.nw_tos
|= IP_DSCP_MASK
;
100 if (!(ofpfw
& OFPFW10_NW_PROTO
)) {
101 wc
->masks
.nw_proto
= UINT8_MAX
;
103 wc
->masks
.nw_src
= ofputil_wcbits_to_netmask(ofpfw
104 >> OFPFW10_NW_SRC_SHIFT
);
105 wc
->masks
.nw_dst
= ofputil_wcbits_to_netmask(ofpfw
106 >> OFPFW10_NW_DST_SHIFT
);
108 if (!(ofpfw
& OFPFW10_TP_SRC
)) {
109 wc
->masks
.tp_src
= OVS_BE16_MAX
;
111 if (!(ofpfw
& OFPFW10_TP_DST
)) {
112 wc
->masks
.tp_dst
= OVS_BE16_MAX
;
115 if (!(ofpfw
& OFPFW10_DL_SRC
)) {
116 memset(wc
->masks
.dl_src
, 0xff, ETH_ADDR_LEN
);
118 if (!(ofpfw
& OFPFW10_DL_DST
)) {
119 memset(wc
->masks
.dl_dst
, 0xff, ETH_ADDR_LEN
);
121 if (!(ofpfw
& OFPFW10_DL_TYPE
)) {
122 wc
->masks
.dl_type
= OVS_BE16_MAX
;
126 if (!(ofpfw
& OFPFW10_DL_VLAN_PCP
)) {
127 wc
->masks
.vlan_tci
|= htons(VLAN_PCP_MASK
| VLAN_CFI
);
129 if (!(ofpfw
& OFPFW10_DL_VLAN
)) {
130 wc
->masks
.vlan_tci
|= htons(VLAN_VID_MASK
| VLAN_CFI
);
134 /* Converts the ofp10_match in 'ofmatch' into a struct match in 'match'. */
136 ofputil_match_from_ofp10_match(const struct ofp10_match
*ofmatch
,
139 uint32_t ofpfw
= ntohl(ofmatch
->wildcards
) & OFPFW10_ALL
;
141 /* Initialize match->wc. */
142 memset(&match
->flow
, 0, sizeof match
->flow
);
143 ofputil_wildcard_from_ofpfw10(ofpfw
, &match
->wc
);
145 /* Initialize most of match->flow. */
146 match
->flow
.nw_src
= ofmatch
->nw_src
;
147 match
->flow
.nw_dst
= ofmatch
->nw_dst
;
148 match
->flow
.in_port
.ofp_port
= u16_to_ofp(ntohs(ofmatch
->in_port
));
149 match
->flow
.dl_type
= ofputil_dl_type_from_openflow(ofmatch
->dl_type
);
150 match
->flow
.tp_src
= ofmatch
->tp_src
;
151 match
->flow
.tp_dst
= ofmatch
->tp_dst
;
152 memcpy(match
->flow
.dl_src
, ofmatch
->dl_src
, ETH_ADDR_LEN
);
153 memcpy(match
->flow
.dl_dst
, ofmatch
->dl_dst
, ETH_ADDR_LEN
);
154 match
->flow
.nw_tos
= ofmatch
->nw_tos
& IP_DSCP_MASK
;
155 match
->flow
.nw_proto
= ofmatch
->nw_proto
;
157 /* Translate VLANs. */
158 if (!(ofpfw
& OFPFW10_DL_VLAN
) &&
159 ofmatch
->dl_vlan
== htons(OFP10_VLAN_NONE
)) {
160 /* Match only packets without 802.1Q header.
162 * When OFPFW10_DL_VLAN_PCP is wildcarded, this is obviously correct.
164 * If OFPFW10_DL_VLAN_PCP is matched, the flow match is contradictory,
165 * because we can't have a specific PCP without an 802.1Q header.
166 * However, older versions of OVS treated this as matching packets
167 * withut an 802.1Q header, so we do here too. */
168 match
->flow
.vlan_tci
= htons(0);
169 match
->wc
.masks
.vlan_tci
= htons(0xffff);
171 ovs_be16 vid
, pcp
, tci
;
173 vid
= ofmatch
->dl_vlan
& htons(VLAN_VID_MASK
);
174 pcp
= htons((ofmatch
->dl_vlan_pcp
<< VLAN_PCP_SHIFT
) & VLAN_PCP_MASK
);
175 tci
= vid
| pcp
| htons(VLAN_CFI
);
176 match
->flow
.vlan_tci
= tci
& match
->wc
.masks
.vlan_tci
;
180 match_zero_wildcarded_fields(match
);
183 /* Convert 'match' into the OpenFlow 1.0 match structure 'ofmatch'. */
185 ofputil_match_to_ofp10_match(const struct match
*match
,
186 struct ofp10_match
*ofmatch
)
188 const struct flow_wildcards
*wc
= &match
->wc
;
191 /* Figure out most OpenFlow wildcards. */
193 if (!wc
->masks
.in_port
.ofp_port
) {
194 ofpfw
|= OFPFW10_IN_PORT
;
196 if (!wc
->masks
.dl_type
) {
197 ofpfw
|= OFPFW10_DL_TYPE
;
199 if (!wc
->masks
.nw_proto
) {
200 ofpfw
|= OFPFW10_NW_PROTO
;
202 ofpfw
|= (ofputil_netmask_to_wcbits(wc
->masks
.nw_src
)
203 << OFPFW10_NW_SRC_SHIFT
);
204 ofpfw
|= (ofputil_netmask_to_wcbits(wc
->masks
.nw_dst
)
205 << OFPFW10_NW_DST_SHIFT
);
206 if (!(wc
->masks
.nw_tos
& IP_DSCP_MASK
)) {
207 ofpfw
|= OFPFW10_NW_TOS
;
209 if (!wc
->masks
.tp_src
) {
210 ofpfw
|= OFPFW10_TP_SRC
;
212 if (!wc
->masks
.tp_dst
) {
213 ofpfw
|= OFPFW10_TP_DST
;
215 if (eth_addr_is_zero(wc
->masks
.dl_src
)) {
216 ofpfw
|= OFPFW10_DL_SRC
;
218 if (eth_addr_is_zero(wc
->masks
.dl_dst
)) {
219 ofpfw
|= OFPFW10_DL_DST
;
222 /* Translate VLANs. */
223 ofmatch
->dl_vlan
= htons(0);
224 ofmatch
->dl_vlan_pcp
= 0;
225 if (match
->wc
.masks
.vlan_tci
== htons(0)) {
226 ofpfw
|= OFPFW10_DL_VLAN
| OFPFW10_DL_VLAN_PCP
;
227 } else if (match
->wc
.masks
.vlan_tci
& htons(VLAN_CFI
)
228 && !(match
->flow
.vlan_tci
& htons(VLAN_CFI
))) {
229 ofmatch
->dl_vlan
= htons(OFP10_VLAN_NONE
);
230 ofpfw
|= OFPFW10_DL_VLAN_PCP
;
232 if (!(match
->wc
.masks
.vlan_tci
& htons(VLAN_VID_MASK
))) {
233 ofpfw
|= OFPFW10_DL_VLAN
;
235 ofmatch
->dl_vlan
= htons(vlan_tci_to_vid(match
->flow
.vlan_tci
));
238 if (!(match
->wc
.masks
.vlan_tci
& htons(VLAN_PCP_MASK
))) {
239 ofpfw
|= OFPFW10_DL_VLAN_PCP
;
241 ofmatch
->dl_vlan_pcp
= vlan_tci_to_pcp(match
->flow
.vlan_tci
);
245 /* Compose most of the match structure. */
246 ofmatch
->wildcards
= htonl(ofpfw
);
247 ofmatch
->in_port
= htons(ofp_to_u16(match
->flow
.in_port
.ofp_port
));
248 memcpy(ofmatch
->dl_src
, match
->flow
.dl_src
, ETH_ADDR_LEN
);
249 memcpy(ofmatch
->dl_dst
, match
->flow
.dl_dst
, ETH_ADDR_LEN
);
250 ofmatch
->dl_type
= ofputil_dl_type_to_openflow(match
->flow
.dl_type
);
251 ofmatch
->nw_src
= match
->flow
.nw_src
;
252 ofmatch
->nw_dst
= match
->flow
.nw_dst
;
253 ofmatch
->nw_tos
= match
->flow
.nw_tos
& IP_DSCP_MASK
;
254 ofmatch
->nw_proto
= match
->flow
.nw_proto
;
255 ofmatch
->tp_src
= match
->flow
.tp_src
;
256 ofmatch
->tp_dst
= match
->flow
.tp_dst
;
257 memset(ofmatch
->pad1
, '\0', sizeof ofmatch
->pad1
);
258 memset(ofmatch
->pad2
, '\0', sizeof ofmatch
->pad2
);
262 ofputil_pull_ofp11_match(struct ofpbuf
*buf
, struct match
*match
,
263 uint16_t *padded_match_len
)
265 struct ofp11_match_header
*omh
= buf
->data
;
268 if (buf
->size
< sizeof *omh
) {
269 return OFPERR_OFPBMC_BAD_LEN
;
272 match_len
= ntohs(omh
->length
);
274 switch (ntohs(omh
->type
)) {
275 case OFPMT_STANDARD
: {
276 struct ofp11_match
*om
;
278 if (match_len
!= sizeof *om
|| buf
->size
< sizeof *om
) {
279 return OFPERR_OFPBMC_BAD_LEN
;
281 om
= ofpbuf_pull(buf
, sizeof *om
);
282 if (padded_match_len
) {
283 *padded_match_len
= match_len
;
285 return ofputil_match_from_ofp11_match(om
, match
);
289 if (padded_match_len
) {
290 *padded_match_len
= ROUND_UP(match_len
, 8);
292 return oxm_pull_match(buf
, match
);
295 return OFPERR_OFPBMC_BAD_TYPE
;
299 /* Converts the ofp11_match in 'ofmatch' into a struct match in 'match'.
300 * Returns 0 if successful, otherwise an OFPERR_* value. */
302 ofputil_match_from_ofp11_match(const struct ofp11_match
*ofmatch
,
305 uint16_t wc
= ntohl(ofmatch
->wildcards
);
306 uint8_t dl_src_mask
[ETH_ADDR_LEN
];
307 uint8_t dl_dst_mask
[ETH_ADDR_LEN
];
308 bool ipv4
, arp
, rarp
;
311 match_init_catchall(match
);
313 if (!(wc
& OFPFW11_IN_PORT
)) {
317 error
= ofputil_port_from_ofp11(ofmatch
->in_port
, &ofp_port
);
319 return OFPERR_OFPBMC_BAD_VALUE
;
321 match_set_in_port(match
, ofp_port
);
324 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
325 dl_src_mask
[i
] = ~ofmatch
->dl_src_mask
[i
];
327 match_set_dl_src_masked(match
, ofmatch
->dl_src
, dl_src_mask
);
329 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
330 dl_dst_mask
[i
] = ~ofmatch
->dl_dst_mask
[i
];
332 match_set_dl_dst_masked(match
, ofmatch
->dl_dst
, dl_dst_mask
);
334 if (!(wc
& OFPFW11_DL_VLAN
)) {
335 if (ofmatch
->dl_vlan
== htons(OFPVID11_NONE
)) {
336 /* Match only packets without a VLAN tag. */
337 match
->flow
.vlan_tci
= htons(0);
338 match
->wc
.masks
.vlan_tci
= OVS_BE16_MAX
;
340 if (ofmatch
->dl_vlan
== htons(OFPVID11_ANY
)) {
341 /* Match any packet with a VLAN tag regardless of VID. */
342 match
->flow
.vlan_tci
= htons(VLAN_CFI
);
343 match
->wc
.masks
.vlan_tci
= htons(VLAN_CFI
);
344 } else if (ntohs(ofmatch
->dl_vlan
) < 4096) {
345 /* Match only packets with the specified VLAN VID. */
346 match
->flow
.vlan_tci
= htons(VLAN_CFI
) | ofmatch
->dl_vlan
;
347 match
->wc
.masks
.vlan_tci
= htons(VLAN_CFI
| VLAN_VID_MASK
);
350 return OFPERR_OFPBMC_BAD_VALUE
;
353 if (!(wc
& OFPFW11_DL_VLAN_PCP
)) {
354 if (ofmatch
->dl_vlan_pcp
<= 7) {
355 match
->flow
.vlan_tci
|= htons(ofmatch
->dl_vlan_pcp
357 match
->wc
.masks
.vlan_tci
|= htons(VLAN_PCP_MASK
);
360 return OFPERR_OFPBMC_BAD_VALUE
;
366 if (!(wc
& OFPFW11_DL_TYPE
)) {
367 match_set_dl_type(match
,
368 ofputil_dl_type_from_openflow(ofmatch
->dl_type
));
371 ipv4
= match
->flow
.dl_type
== htons(ETH_TYPE_IP
);
372 arp
= match
->flow
.dl_type
== htons(ETH_TYPE_ARP
);
373 rarp
= match
->flow
.dl_type
== htons(ETH_TYPE_RARP
);
375 if (ipv4
&& !(wc
& OFPFW11_NW_TOS
)) {
376 if (ofmatch
->nw_tos
& ~IP_DSCP_MASK
) {
378 return OFPERR_OFPBMC_BAD_VALUE
;
381 match_set_nw_dscp(match
, ofmatch
->nw_tos
);
384 if (ipv4
|| arp
|| rarp
) {
385 if (!(wc
& OFPFW11_NW_PROTO
)) {
386 match_set_nw_proto(match
, ofmatch
->nw_proto
);
388 match_set_nw_src_masked(match
, ofmatch
->nw_src
, ~ofmatch
->nw_src_mask
);
389 match_set_nw_dst_masked(match
, ofmatch
->nw_dst
, ~ofmatch
->nw_dst_mask
);
392 #define OFPFW11_TP_ALL (OFPFW11_TP_SRC | OFPFW11_TP_DST)
393 if (ipv4
&& (wc
& OFPFW11_TP_ALL
) != OFPFW11_TP_ALL
) {
394 switch (match
->flow
.nw_proto
) {
396 /* "A.2.3 Flow Match Structures" in OF1.1 says:
398 * The tp_src and tp_dst fields will be ignored unless the
399 * network protocol specified is as TCP, UDP or SCTP.
401 * but I'm pretty sure we should support ICMP too, otherwise
402 * that's a regression from OF1.0. */
403 if (!(wc
& OFPFW11_TP_SRC
)) {
404 uint16_t icmp_type
= ntohs(ofmatch
->tp_src
);
405 if (icmp_type
< 0x100) {
406 match_set_icmp_type(match
, icmp_type
);
408 return OFPERR_OFPBMC_BAD_FIELD
;
411 if (!(wc
& OFPFW11_TP_DST
)) {
412 uint16_t icmp_code
= ntohs(ofmatch
->tp_dst
);
413 if (icmp_code
< 0x100) {
414 match_set_icmp_code(match
, icmp_code
);
416 return OFPERR_OFPBMC_BAD_FIELD
;
424 if (!(wc
& (OFPFW11_TP_SRC
))) {
425 match_set_tp_src(match
, ofmatch
->tp_src
);
427 if (!(wc
& (OFPFW11_TP_DST
))) {
428 match_set_tp_dst(match
, ofmatch
->tp_dst
);
433 /* OF1.1 says explicitly to ignore this. */
438 if (eth_type_mpls(match
->flow
.dl_type
)) {
439 enum { OFPFW11_MPLS_ALL
= OFPFW11_MPLS_LABEL
| OFPFW11_MPLS_TC
};
441 if ((wc
& OFPFW11_MPLS_ALL
) != OFPFW11_MPLS_ALL
) {
442 /* MPLS not supported. */
443 return OFPERR_OFPBMC_BAD_TAG
;
447 match_set_metadata_masked(match
, ofmatch
->metadata
,
448 ~ofmatch
->metadata_mask
);
453 /* Convert 'match' into the OpenFlow 1.1 match structure 'ofmatch'. */
455 ofputil_match_to_ofp11_match(const struct match
*match
,
456 struct ofp11_match
*ofmatch
)
461 memset(ofmatch
, 0, sizeof *ofmatch
);
462 ofmatch
->omh
.type
= htons(OFPMT_STANDARD
);
463 ofmatch
->omh
.length
= htons(OFPMT11_STANDARD_LENGTH
);
465 if (!match
->wc
.masks
.in_port
.ofp_port
) {
466 wc
|= OFPFW11_IN_PORT
;
468 ofmatch
->in_port
= ofputil_port_to_ofp11(match
->flow
.in_port
.ofp_port
);
471 memcpy(ofmatch
->dl_src
, match
->flow
.dl_src
, ETH_ADDR_LEN
);
472 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
473 ofmatch
->dl_src_mask
[i
] = ~match
->wc
.masks
.dl_src
[i
];
476 memcpy(ofmatch
->dl_dst
, match
->flow
.dl_dst
, ETH_ADDR_LEN
);
477 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
478 ofmatch
->dl_dst_mask
[i
] = ~match
->wc
.masks
.dl_dst
[i
];
481 if (match
->wc
.masks
.vlan_tci
== htons(0)) {
482 wc
|= OFPFW11_DL_VLAN
| OFPFW11_DL_VLAN_PCP
;
483 } else if (match
->wc
.masks
.vlan_tci
& htons(VLAN_CFI
)
484 && !(match
->flow
.vlan_tci
& htons(VLAN_CFI
))) {
485 ofmatch
->dl_vlan
= htons(OFPVID11_NONE
);
486 wc
|= OFPFW11_DL_VLAN_PCP
;
488 if (!(match
->wc
.masks
.vlan_tci
& htons(VLAN_VID_MASK
))) {
489 ofmatch
->dl_vlan
= htons(OFPVID11_ANY
);
491 ofmatch
->dl_vlan
= htons(vlan_tci_to_vid(match
->flow
.vlan_tci
));
494 if (!(match
->wc
.masks
.vlan_tci
& htons(VLAN_PCP_MASK
))) {
495 wc
|= OFPFW11_DL_VLAN_PCP
;
497 ofmatch
->dl_vlan_pcp
= vlan_tci_to_pcp(match
->flow
.vlan_tci
);
501 if (!match
->wc
.masks
.dl_type
) {
502 wc
|= OFPFW11_DL_TYPE
;
504 ofmatch
->dl_type
= ofputil_dl_type_to_openflow(match
->flow
.dl_type
);
507 if (!(match
->wc
.masks
.nw_tos
& IP_DSCP_MASK
)) {
508 wc
|= OFPFW11_NW_TOS
;
510 ofmatch
->nw_tos
= match
->flow
.nw_tos
& IP_DSCP_MASK
;
513 if (!match
->wc
.masks
.nw_proto
) {
514 wc
|= OFPFW11_NW_PROTO
;
516 ofmatch
->nw_proto
= match
->flow
.nw_proto
;
519 ofmatch
->nw_src
= match
->flow
.nw_src
;
520 ofmatch
->nw_src_mask
= ~match
->wc
.masks
.nw_src
;
521 ofmatch
->nw_dst
= match
->flow
.nw_dst
;
522 ofmatch
->nw_dst_mask
= ~match
->wc
.masks
.nw_dst
;
524 if (!match
->wc
.masks
.tp_src
) {
525 wc
|= OFPFW11_TP_SRC
;
527 ofmatch
->tp_src
= match
->flow
.tp_src
;
530 if (!match
->wc
.masks
.tp_dst
) {
531 wc
|= OFPFW11_TP_DST
;
533 ofmatch
->tp_dst
= match
->flow
.tp_dst
;
536 /* MPLS not supported. */
537 wc
|= OFPFW11_MPLS_LABEL
;
538 wc
|= OFPFW11_MPLS_TC
;
540 ofmatch
->metadata
= match
->flow
.metadata
;
541 ofmatch
->metadata_mask
= ~match
->wc
.masks
.metadata
;
543 ofmatch
->wildcards
= htonl(wc
);
546 /* Returns the "typical" length of a match for 'protocol', for use in
547 * estimating space to preallocate. */
549 ofputil_match_typical_len(enum ofputil_protocol protocol
)
552 case OFPUTIL_P_OF10_STD
:
553 case OFPUTIL_P_OF10_STD_TID
:
554 return sizeof(struct ofp10_match
);
556 case OFPUTIL_P_OF10_NXM
:
557 case OFPUTIL_P_OF10_NXM_TID
:
558 return NXM_TYPICAL_LEN
;
560 case OFPUTIL_P_OF11_STD
:
561 return sizeof(struct ofp11_match
);
563 case OFPUTIL_P_OF12_OXM
:
564 case OFPUTIL_P_OF13_OXM
:
565 return NXM_TYPICAL_LEN
;
572 /* Appends to 'b' an struct ofp11_match_header followed by a match that
573 * expresses 'match' properly for 'protocol', plus enough zero bytes to pad the
574 * data appended out to a multiple of 8. 'protocol' must be one that is usable
575 * in OpenFlow 1.1 or later.
577 * This function can cause 'b''s data to be reallocated.
579 * Returns the number of bytes appended to 'b', excluding the padding. Never
582 ofputil_put_ofp11_match(struct ofpbuf
*b
, const struct match
*match
,
583 enum ofputil_protocol protocol
)
586 case OFPUTIL_P_OF10_STD
:
587 case OFPUTIL_P_OF10_STD_TID
:
588 case OFPUTIL_P_OF10_NXM
:
589 case OFPUTIL_P_OF10_NXM_TID
:
592 case OFPUTIL_P_OF11_STD
: {
593 struct ofp11_match
*om
;
595 /* Make sure that no padding is needed. */
596 BUILD_ASSERT_DECL(sizeof *om
% 8 == 0);
598 om
= ofpbuf_put_uninit(b
, sizeof *om
);
599 ofputil_match_to_ofp11_match(match
, om
);
603 case OFPUTIL_P_OF12_OXM
:
604 case OFPUTIL_P_OF13_OXM
:
605 return oxm_put_match(b
, match
);
611 /* Given a 'dl_type' value in the format used in struct flow, returns the
612 * corresponding 'dl_type' value for use in an ofp10_match or ofp11_match
615 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type
)
617 return (flow_dl_type
== htons(FLOW_DL_TYPE_NONE
)
618 ? htons(OFP_DL_TYPE_NOT_ETH_TYPE
)
622 /* Given a 'dl_type' value in the format used in an ofp10_match or ofp11_match
623 * structure, returns the corresponding 'dl_type' value for use in struct
626 ofputil_dl_type_from_openflow(ovs_be16 ofp_dl_type
)
628 return (ofp_dl_type
== htons(OFP_DL_TYPE_NOT_ETH_TYPE
)
629 ? htons(FLOW_DL_TYPE_NONE
)
635 struct proto_abbrev
{
636 enum ofputil_protocol protocol
;
640 /* Most users really don't care about some of the differences between
641 * protocols. These abbreviations help with that. */
642 static const struct proto_abbrev proto_abbrevs
[] = {
643 { OFPUTIL_P_ANY
, "any" },
644 { OFPUTIL_P_OF10_STD_ANY
, "OpenFlow10" },
645 { OFPUTIL_P_OF10_NXM_ANY
, "NXM" },
646 { OFPUTIL_P_ANY_OXM
, "OXM" },
648 #define N_PROTO_ABBREVS ARRAY_SIZE(proto_abbrevs)
650 enum ofputil_protocol ofputil_flow_dump_protocols
[] = {
657 size_t ofputil_n_flow_dump_protocols
= ARRAY_SIZE(ofputil_flow_dump_protocols
);
659 /* Returns the set of ofputil_protocols that are supported with the given
660 * OpenFlow 'version'. 'version' should normally be an 8-bit OpenFlow version
661 * identifier (e.g. 0x01 for OpenFlow 1.0, 0x02 for OpenFlow 1.1). Returns 0
662 * if 'version' is not supported or outside the valid range. */
663 enum ofputil_protocol
664 ofputil_protocols_from_ofp_version(enum ofp_version version
)
668 return OFPUTIL_P_OF10_STD_ANY
| OFPUTIL_P_OF10_NXM_ANY
;
670 return OFPUTIL_P_OF11_STD
;
672 return OFPUTIL_P_OF12_OXM
;
674 return OFPUTIL_P_OF13_OXM
;
680 /* Returns the ofputil_protocol that is initially in effect on an OpenFlow
681 * connection that has negotiated the given 'version'. 'version' should
682 * normally be an 8-bit OpenFlow version identifier (e.g. 0x01 for OpenFlow
683 * 1.0, 0x02 for OpenFlow 1.1). Returns 0 if 'version' is not supported or
684 * outside the valid range. */
685 enum ofputil_protocol
686 ofputil_protocol_from_ofp_version(enum ofp_version version
)
688 return rightmost_1bit(ofputil_protocols_from_ofp_version(version
));
691 /* Returns the OpenFlow protocol version number (e.g. OFP10_VERSION,
692 * etc.) that corresponds to 'protocol'. */
694 ofputil_protocol_to_ofp_version(enum ofputil_protocol protocol
)
697 case OFPUTIL_P_OF10_STD
:
698 case OFPUTIL_P_OF10_STD_TID
:
699 case OFPUTIL_P_OF10_NXM
:
700 case OFPUTIL_P_OF10_NXM_TID
:
701 return OFP10_VERSION
;
702 case OFPUTIL_P_OF11_STD
:
703 return OFP11_VERSION
;
704 case OFPUTIL_P_OF12_OXM
:
705 return OFP12_VERSION
;
706 case OFPUTIL_P_OF13_OXM
:
707 return OFP13_VERSION
;
713 /* Returns a bitmap of OpenFlow versions that are supported by at
714 * least one of the 'protocols'. */
716 ofputil_protocols_to_version_bitmap(enum ofputil_protocol protocols
)
720 for (; protocols
; protocols
= zero_rightmost_1bit(protocols
)) {
721 enum ofputil_protocol protocol
= rightmost_1bit(protocols
);
723 bitmap
|= 1u << ofputil_protocol_to_ofp_version(protocol
);
729 /* Returns the set of protocols that are supported on top of the
730 * OpenFlow versions included in 'bitmap'. */
731 enum ofputil_protocol
732 ofputil_protocols_from_version_bitmap(uint32_t bitmap
)
734 enum ofputil_protocol protocols
= 0;
736 for (; bitmap
; bitmap
= zero_rightmost_1bit(bitmap
)) {
737 enum ofp_version version
= rightmost_1bit_idx(bitmap
);
739 protocols
|= ofputil_protocols_from_ofp_version(version
);
745 /* Returns true if 'protocol' is a single OFPUTIL_P_* value, false
748 ofputil_protocol_is_valid(enum ofputil_protocol protocol
)
750 return protocol
& OFPUTIL_P_ANY
&& is_pow2(protocol
);
753 /* Returns the equivalent of 'protocol' with the Nicira flow_mod_table_id
754 * extension turned on or off if 'enable' is true or false, respectively.
756 * This extension is only useful for protocols whose "standard" version does
757 * not allow specific tables to be modified. In particular, this is true of
758 * OpenFlow 1.0. In later versions of OpenFlow, a flow_mod request always
759 * specifies a table ID and so there is no need for such an extension. When
760 * 'protocol' is such a protocol that doesn't need a flow_mod_table_id
761 * extension, this function just returns its 'protocol' argument unchanged
762 * regardless of the value of 'enable'. */
763 enum ofputil_protocol
764 ofputil_protocol_set_tid(enum ofputil_protocol protocol
, bool enable
)
767 case OFPUTIL_P_OF10_STD
:
768 case OFPUTIL_P_OF10_STD_TID
:
769 return enable
? OFPUTIL_P_OF10_STD_TID
: OFPUTIL_P_OF10_STD
;
771 case OFPUTIL_P_OF10_NXM
:
772 case OFPUTIL_P_OF10_NXM_TID
:
773 return enable
? OFPUTIL_P_OF10_NXM_TID
: OFPUTIL_P_OF10_NXM
;
775 case OFPUTIL_P_OF11_STD
:
776 return OFPUTIL_P_OF11_STD
;
778 case OFPUTIL_P_OF12_OXM
:
779 return OFPUTIL_P_OF12_OXM
;
781 case OFPUTIL_P_OF13_OXM
:
782 return OFPUTIL_P_OF13_OXM
;
789 /* Returns the "base" version of 'protocol'. That is, if 'protocol' includes
790 * some extension to a standard protocol version, the return value is the
791 * standard version of that protocol without any extension. If 'protocol' is a
792 * standard protocol version, returns 'protocol' unchanged. */
793 enum ofputil_protocol
794 ofputil_protocol_to_base(enum ofputil_protocol protocol
)
796 return ofputil_protocol_set_tid(protocol
, false);
799 /* Returns 'new_base' with any extensions taken from 'cur'. */
800 enum ofputil_protocol
801 ofputil_protocol_set_base(enum ofputil_protocol cur
,
802 enum ofputil_protocol new_base
)
804 bool tid
= (cur
& OFPUTIL_P_TID
) != 0;
807 case OFPUTIL_P_OF10_STD
:
808 case OFPUTIL_P_OF10_STD_TID
:
809 return ofputil_protocol_set_tid(OFPUTIL_P_OF10_STD
, tid
);
811 case OFPUTIL_P_OF10_NXM
:
812 case OFPUTIL_P_OF10_NXM_TID
:
813 return ofputil_protocol_set_tid(OFPUTIL_P_OF10_NXM
, tid
);
815 case OFPUTIL_P_OF11_STD
:
816 return ofputil_protocol_set_tid(OFPUTIL_P_OF11_STD
, tid
);
818 case OFPUTIL_P_OF12_OXM
:
819 return ofputil_protocol_set_tid(OFPUTIL_P_OF12_OXM
, tid
);
821 case OFPUTIL_P_OF13_OXM
:
822 return ofputil_protocol_set_tid(OFPUTIL_P_OF13_OXM
, tid
);
829 /* Returns a string form of 'protocol', if a simple form exists (that is, if
830 * 'protocol' is either a single protocol or it is a combination of protocols
831 * that have a single abbreviation). Otherwise, returns NULL. */
833 ofputil_protocol_to_string(enum ofputil_protocol protocol
)
835 const struct proto_abbrev
*p
;
837 /* Use a "switch" statement for single-bit names so that we get a compiler
838 * warning if we forget any. */
840 case OFPUTIL_P_OF10_NXM
:
841 return "NXM-table_id";
843 case OFPUTIL_P_OF10_NXM_TID
:
844 return "NXM+table_id";
846 case OFPUTIL_P_OF10_STD
:
847 return "OpenFlow10-table_id";
849 case OFPUTIL_P_OF10_STD_TID
:
850 return "OpenFlow10+table_id";
852 case OFPUTIL_P_OF11_STD
:
855 case OFPUTIL_P_OF12_OXM
:
856 return "OXM-OpenFlow12";
858 case OFPUTIL_P_OF13_OXM
:
859 return "OXM-OpenFlow13";
862 /* Check abbreviations. */
863 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
864 if (protocol
== p
->protocol
) {
872 /* Returns a string that represents 'protocols'. The return value might be a
873 * comma-separated list if 'protocols' doesn't have a simple name. The return
874 * value is "none" if 'protocols' is 0.
876 * The caller must free the returned string (with free()). */
878 ofputil_protocols_to_string(enum ofputil_protocol protocols
)
882 ovs_assert(!(protocols
& ~OFPUTIL_P_ANY
));
883 if (protocols
== 0) {
884 return xstrdup("none");
889 const struct proto_abbrev
*p
;
893 ds_put_char(&s
, ',');
896 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
897 if ((protocols
& p
->protocol
) == p
->protocol
) {
898 ds_put_cstr(&s
, p
->name
);
899 protocols
&= ~p
->protocol
;
904 for (i
= 0; i
< CHAR_BIT
* sizeof(enum ofputil_protocol
); i
++) {
905 enum ofputil_protocol bit
= 1u << i
;
907 if (protocols
& bit
) {
908 ds_put_cstr(&s
, ofputil_protocol_to_string(bit
));
917 return ds_steal_cstr(&s
);
920 static enum ofputil_protocol
921 ofputil_protocol_from_string__(const char *s
, size_t n
)
923 const struct proto_abbrev
*p
;
926 for (i
= 0; i
< CHAR_BIT
* sizeof(enum ofputil_protocol
); i
++) {
927 enum ofputil_protocol bit
= 1u << i
;
928 const char *name
= ofputil_protocol_to_string(bit
);
930 if (name
&& n
== strlen(name
) && !strncasecmp(s
, name
, n
)) {
935 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
936 if (n
== strlen(p
->name
) && !strncasecmp(s
, p
->name
, n
)) {
944 /* Returns the nonempty set of protocols represented by 's', which can be a
945 * single protocol name or abbreviation or a comma-separated list of them.
947 * Aborts the program with an error message if 's' is invalid. */
948 enum ofputil_protocol
949 ofputil_protocols_from_string(const char *s
)
951 const char *orig_s
= s
;
952 enum ofputil_protocol protocols
;
956 enum ofputil_protocol p
;
965 p
= ofputil_protocol_from_string__(s
, n
);
967 ovs_fatal(0, "%.*s: unknown flow protocol", (int) n
, s
);
975 ovs_fatal(0, "%s: no flow protocol specified", orig_s
);
981 ofputil_version_from_string(const char *s
)
983 if (!strcasecmp(s
, "OpenFlow10")) {
984 return OFP10_VERSION
;
986 if (!strcasecmp(s
, "OpenFlow11")) {
987 return OFP11_VERSION
;
989 if (!strcasecmp(s
, "OpenFlow12")) {
990 return OFP12_VERSION
;
992 if (!strcasecmp(s
, "OpenFlow13")) {
993 return OFP13_VERSION
;
999 is_delimiter(unsigned char c
)
1001 return isspace(c
) || c
== ',';
1005 ofputil_versions_from_string(const char *s
)
1008 uint32_t bitmap
= 0;
1015 if (is_delimiter(s
[i
])) {
1020 while (s
[i
+ j
] && !is_delimiter(s
[i
+ j
])) {
1023 key
= xmemdup0(s
+ i
, j
);
1024 version
= ofputil_version_from_string(key
);
1026 VLOG_FATAL("Unknown OpenFlow version: \"%s\"", key
);
1029 bitmap
|= 1u << version
;
1037 ofputil_versions_from_strings(char ** const s
, size_t count
)
1039 uint32_t bitmap
= 0;
1042 int version
= ofputil_version_from_string(s
[count
]);
1044 VLOG_WARN("Unknown OpenFlow version: \"%s\"", s
[count
]);
1046 bitmap
|= 1u << version
;
1054 ofputil_version_to_string(enum ofp_version ofp_version
)
1056 switch (ofp_version
) {
1058 return "OpenFlow10";
1060 return "OpenFlow11";
1062 return "OpenFlow12";
1064 return "OpenFlow13";
1071 ofputil_packet_in_format_is_valid(enum nx_packet_in_format packet_in_format
)
1073 switch (packet_in_format
) {
1074 case NXPIF_OPENFLOW10
:
1083 ofputil_packet_in_format_to_string(enum nx_packet_in_format packet_in_format
)
1085 switch (packet_in_format
) {
1086 case NXPIF_OPENFLOW10
:
1087 return "openflow10";
1096 ofputil_packet_in_format_from_string(const char *s
)
1098 return (!strcmp(s
, "openflow10") ? NXPIF_OPENFLOW10
1099 : !strcmp(s
, "nxm") ? NXPIF_NXM
1104 ofputil_format_version(struct ds
*msg
, enum ofp_version version
)
1106 ds_put_format(msg
, "0x%02x", version
);
1110 ofputil_format_version_name(struct ds
*msg
, enum ofp_version version
)
1112 ds_put_cstr(msg
, ofputil_version_to_string(version
));
1116 ofputil_format_version_bitmap__(struct ds
*msg
, uint32_t bitmap
,
1117 void (*format_version
)(struct ds
*msg
,
1121 format_version(msg
, raw_ctz(bitmap
));
1122 bitmap
= zero_rightmost_1bit(bitmap
);
1124 ds_put_cstr(msg
, ", ");
1130 ofputil_format_version_bitmap(struct ds
*msg
, uint32_t bitmap
)
1132 ofputil_format_version_bitmap__(msg
, bitmap
, ofputil_format_version
);
1136 ofputil_format_version_bitmap_names(struct ds
*msg
, uint32_t bitmap
)
1138 ofputil_format_version_bitmap__(msg
, bitmap
, ofputil_format_version_name
);
1142 ofputil_decode_hello_bitmap(const struct ofp_hello_elem_header
*oheh
,
1143 uint32_t *allowed_versionsp
)
1145 uint16_t bitmap_len
= ntohs(oheh
->length
) - sizeof *oheh
;
1146 const ovs_be32
*bitmap
= ALIGNED_CAST(const ovs_be32
*, oheh
+ 1);
1147 uint32_t allowed_versions
;
1149 if (!bitmap_len
|| bitmap_len
% sizeof *bitmap
) {
1153 /* Only use the first 32-bit element of the bitmap as that is all the
1154 * current implementation supports. Subsequent elements are ignored which
1155 * should have no effect on session negotiation until Open vSwtich supports
1156 * wire-protocol versions greater than 31.
1158 allowed_versions
= ntohl(bitmap
[0]);
1160 if (allowed_versions
& 1) {
1161 /* There's no OpenFlow version 0. */
1162 VLOG_WARN_RL(&bad_ofmsg_rl
, "peer claims to support invalid OpenFlow "
1164 allowed_versions
&= ~1u;
1167 if (!allowed_versions
) {
1168 VLOG_WARN_RL(&bad_ofmsg_rl
, "peer does not support any OpenFlow "
1169 "version (between 0x01 and 0x1f)");
1173 *allowed_versionsp
= allowed_versions
;
1178 version_bitmap_from_version(uint8_t ofp_version
)
1180 return ((ofp_version
< 32 ? 1u << ofp_version
: 0) - 1) << 1;
1183 /* Decodes OpenFlow OFPT_HELLO message 'oh', storing into '*allowed_versions'
1184 * the set of OpenFlow versions for which 'oh' announces support.
1186 * Because of how OpenFlow defines OFPT_HELLO messages, this function is always
1187 * successful, and thus '*allowed_versions' is always initialized. However, it
1188 * returns false if 'oh' contains some data that could not be fully understood,
1189 * true if 'oh' was completely parsed. */
1191 ofputil_decode_hello(const struct ofp_header
*oh
, uint32_t *allowed_versions
)
1196 ofpbuf_use_const(&msg
, oh
, ntohs(oh
->length
));
1197 ofpbuf_pull(&msg
, sizeof *oh
);
1199 *allowed_versions
= version_bitmap_from_version(oh
->version
);
1201 const struct ofp_hello_elem_header
*oheh
;
1204 if (msg
.size
< sizeof *oheh
) {
1209 len
= ntohs(oheh
->length
);
1210 if (len
< sizeof *oheh
|| !ofpbuf_try_pull(&msg
, ROUND_UP(len
, 8))) {
1214 if (oheh
->type
!= htons(OFPHET_VERSIONBITMAP
)
1215 || !ofputil_decode_hello_bitmap(oheh
, allowed_versions
)) {
1223 /* Returns true if 'allowed_versions' needs to be accompanied by a version
1224 * bitmap to be correctly expressed in an OFPT_HELLO message. */
1226 should_send_version_bitmap(uint32_t allowed_versions
)
1228 return !is_pow2((allowed_versions
>> 1) + 1);
1231 /* Create an OFPT_HELLO message that expresses support for the OpenFlow
1232 * versions in the 'allowed_versions' bitmaps and returns the message. */
1234 ofputil_encode_hello(uint32_t allowed_versions
)
1236 enum ofp_version ofp_version
;
1239 ofp_version
= leftmost_1bit_idx(allowed_versions
);
1240 msg
= ofpraw_alloc(OFPRAW_OFPT_HELLO
, ofp_version
, 0);
1242 if (should_send_version_bitmap(allowed_versions
)) {
1243 struct ofp_hello_elem_header
*oheh
;
1246 map_len
= sizeof allowed_versions
;
1247 oheh
= ofpbuf_put_zeros(msg
, ROUND_UP(map_len
+ sizeof *oheh
, 8));
1248 oheh
->type
= htons(OFPHET_VERSIONBITMAP
);
1249 oheh
->length
= htons(map_len
+ sizeof *oheh
);
1250 *ALIGNED_CAST(ovs_be32
*, oheh
+ 1) = htonl(allowed_versions
);
1252 ofpmsg_update_length(msg
);
1258 /* Returns an OpenFlow message that, sent on an OpenFlow connection whose
1259 * protocol is 'current', at least partly transitions the protocol to 'want'.
1260 * Stores in '*next' the protocol that will be in effect on the OpenFlow
1261 * connection if the switch processes the returned message correctly. (If
1262 * '*next != want' then the caller will have to iterate.)
1264 * If 'current == want', or if it is not possible to transition from 'current'
1265 * to 'want' (because, for example, 'current' and 'want' use different OpenFlow
1266 * protocol versions), returns NULL and stores 'current' in '*next'. */
1268 ofputil_encode_set_protocol(enum ofputil_protocol current
,
1269 enum ofputil_protocol want
,
1270 enum ofputil_protocol
*next
)
1272 enum ofp_version cur_version
, want_version
;
1273 enum ofputil_protocol cur_base
, want_base
;
1274 bool cur_tid
, want_tid
;
1276 cur_version
= ofputil_protocol_to_ofp_version(current
);
1277 want_version
= ofputil_protocol_to_ofp_version(want
);
1278 if (cur_version
!= want_version
) {
1283 cur_base
= ofputil_protocol_to_base(current
);
1284 want_base
= ofputil_protocol_to_base(want
);
1285 if (cur_base
!= want_base
) {
1286 *next
= ofputil_protocol_set_base(current
, want_base
);
1288 switch (want_base
) {
1289 case OFPUTIL_P_OF10_NXM
:
1290 return ofputil_encode_nx_set_flow_format(NXFF_NXM
);
1292 case OFPUTIL_P_OF10_STD
:
1293 return ofputil_encode_nx_set_flow_format(NXFF_OPENFLOW10
);
1295 case OFPUTIL_P_OF11_STD
:
1296 case OFPUTIL_P_OF12_OXM
:
1297 case OFPUTIL_P_OF13_OXM
:
1298 /* There is only one variant of each OpenFlow 1.1+ protocol, and we
1299 * verified above that we're not trying to change versions. */
1302 case OFPUTIL_P_OF10_STD_TID
:
1303 case OFPUTIL_P_OF10_NXM_TID
:
1308 cur_tid
= (current
& OFPUTIL_P_TID
) != 0;
1309 want_tid
= (want
& OFPUTIL_P_TID
) != 0;
1310 if (cur_tid
!= want_tid
) {
1311 *next
= ofputil_protocol_set_tid(current
, want_tid
);
1312 return ofputil_make_flow_mod_table_id(want_tid
);
1315 ovs_assert(current
== want
);
1321 /* Returns an NXT_SET_FLOW_FORMAT message that can be used to set the flow
1322 * format to 'nxff'. */
1324 ofputil_encode_nx_set_flow_format(enum nx_flow_format nxff
)
1326 struct nx_set_flow_format
*sff
;
1329 ovs_assert(ofputil_nx_flow_format_is_valid(nxff
));
1331 msg
= ofpraw_alloc(OFPRAW_NXT_SET_FLOW_FORMAT
, OFP10_VERSION
, 0);
1332 sff
= ofpbuf_put_zeros(msg
, sizeof *sff
);
1333 sff
->format
= htonl(nxff
);
1338 /* Returns the base protocol if 'flow_format' is a valid NXFF_* value, false
1340 enum ofputil_protocol
1341 ofputil_nx_flow_format_to_protocol(enum nx_flow_format flow_format
)
1343 switch (flow_format
) {
1344 case NXFF_OPENFLOW10
:
1345 return OFPUTIL_P_OF10_STD
;
1348 return OFPUTIL_P_OF10_NXM
;
1355 /* Returns true if 'flow_format' is a valid NXFF_* value, false otherwise. */
1357 ofputil_nx_flow_format_is_valid(enum nx_flow_format flow_format
)
1359 return ofputil_nx_flow_format_to_protocol(flow_format
) != 0;
1362 /* Returns a string version of 'flow_format', which must be a valid NXFF_*
1365 ofputil_nx_flow_format_to_string(enum nx_flow_format flow_format
)
1367 switch (flow_format
) {
1368 case NXFF_OPENFLOW10
:
1369 return "openflow10";
1378 ofputil_make_set_packet_in_format(enum ofp_version ofp_version
,
1379 enum nx_packet_in_format packet_in_format
)
1381 struct nx_set_packet_in_format
*spif
;
1384 msg
= ofpraw_alloc(OFPRAW_NXT_SET_PACKET_IN_FORMAT
, ofp_version
, 0);
1385 spif
= ofpbuf_put_zeros(msg
, sizeof *spif
);
1386 spif
->format
= htonl(packet_in_format
);
1391 /* Returns an OpenFlow message that can be used to turn the flow_mod_table_id
1392 * extension on or off (according to 'flow_mod_table_id'). */
1394 ofputil_make_flow_mod_table_id(bool flow_mod_table_id
)
1396 struct nx_flow_mod_table_id
*nfmti
;
1399 msg
= ofpraw_alloc(OFPRAW_NXT_FLOW_MOD_TABLE_ID
, OFP10_VERSION
, 0);
1400 nfmti
= ofpbuf_put_zeros(msg
, sizeof *nfmti
);
1401 nfmti
->set
= flow_mod_table_id
;
1405 struct ofputil_flow_mod_flag
{
1407 enum ofp_version min_version
, max_version
;
1408 enum ofputil_flow_mod_flags flag
;
1411 static const struct ofputil_flow_mod_flag ofputil_flow_mod_flags
[] = {
1412 { OFPFF_SEND_FLOW_REM
, OFP10_VERSION
, 0, OFPUTIL_FF_SEND_FLOW_REM
},
1413 { OFPFF_CHECK_OVERLAP
, OFP10_VERSION
, 0, OFPUTIL_FF_CHECK_OVERLAP
},
1414 { OFPFF10_EMERG
, OFP10_VERSION
, OFP10_VERSION
,
1416 { OFPFF12_RESET_COUNTS
, OFP12_VERSION
, 0, OFPUTIL_FF_RESET_COUNTS
},
1417 { OFPFF13_NO_PKT_COUNTS
, OFP13_VERSION
, 0, OFPUTIL_FF_NO_PKT_COUNTS
},
1418 { OFPFF13_NO_BYT_COUNTS
, OFP13_VERSION
, 0, OFPUTIL_FF_NO_BYT_COUNTS
},
1423 ofputil_decode_flow_mod_flags(ovs_be16 raw_flags_
,
1424 enum ofp_flow_mod_command command
,
1425 enum ofp_version version
,
1426 enum ofputil_flow_mod_flags
*flagsp
)
1428 uint16_t raw_flags
= ntohs(raw_flags_
);
1429 const struct ofputil_flow_mod_flag
*f
;
1432 for (f
= ofputil_flow_mod_flags
; f
->raw_flag
; f
++) {
1433 if (raw_flags
& f
->raw_flag
1434 && version
>= f
->min_version
1435 && (!f
->max_version
|| version
<= f
->max_version
)) {
1436 raw_flags
&= ~f
->raw_flag
;
1441 /* In OF1.0 and OF1.1, "add" always resets counters, and other commands
1444 * In OF1.2 and later, OFPFF12_RESET_COUNTS controls whether each command
1445 * resets counters. */
1446 if ((version
== OFP10_VERSION
|| version
== OFP11_VERSION
)
1447 && command
== OFPFC_ADD
) {
1448 *flagsp
|= OFPUTIL_FF_RESET_COUNTS
;
1451 return raw_flags
? OFPERR_OFPFMFC_BAD_FLAGS
: 0;
1455 ofputil_encode_flow_mod_flags(enum ofputil_flow_mod_flags flags
,
1456 enum ofp_version version
)
1458 const struct ofputil_flow_mod_flag
*f
;
1462 for (f
= ofputil_flow_mod_flags
; f
->raw_flag
; f
++) {
1464 && version
>= f
->min_version
1465 && (!f
->max_version
|| version
<= f
->max_version
)) {
1466 raw_flags
|= f
->raw_flag
;
1470 return htons(raw_flags
);
1473 /* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
1474 * flow_mod in 'fm'. Returns 0 if successful, otherwise an OpenFlow error
1477 * Uses 'ofpacts' to store the abstract OFPACT_* version of 'oh''s actions.
1478 * The caller must initialize 'ofpacts' and retains ownership of it.
1479 * 'fm->ofpacts' will point into the 'ofpacts' buffer.
1481 * Does not validate the flow_mod actions. The caller should do that, with
1482 * ofpacts_check(). */
1484 ofputil_decode_flow_mod(struct ofputil_flow_mod
*fm
,
1485 const struct ofp_header
*oh
,
1486 enum ofputil_protocol protocol
,
1487 struct ofpbuf
*ofpacts
)
1494 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1495 raw
= ofpraw_pull_assert(&b
);
1496 if (raw
== OFPRAW_OFPT11_FLOW_MOD
) {
1497 /* Standard OpenFlow 1.1+ flow_mod. */
1498 const struct ofp11_flow_mod
*ofm
;
1500 ofm
= ofpbuf_pull(&b
, sizeof *ofm
);
1502 error
= ofputil_pull_ofp11_match(&b
, &fm
->match
, NULL
);
1507 error
= ofpacts_pull_openflow11_instructions(&b
, oh
->version
,
1513 /* Translate the message. */
1514 fm
->priority
= ntohs(ofm
->priority
);
1515 if (ofm
->command
== OFPFC_ADD
1516 || (oh
->version
== OFP11_VERSION
1517 && (ofm
->command
== OFPFC_MODIFY
||
1518 ofm
->command
== OFPFC_MODIFY_STRICT
)
1519 && ofm
->cookie_mask
== htonll(0))) {
1520 /* In OpenFlow 1.1 only, a "modify" or "modify-strict" that does
1521 * not match on the cookie is treated as an "add" if there is no
1523 fm
->cookie
= htonll(0);
1524 fm
->cookie_mask
= htonll(0);
1525 fm
->new_cookie
= ofm
->cookie
;
1527 fm
->cookie
= ofm
->cookie
;
1528 fm
->cookie_mask
= ofm
->cookie_mask
;
1529 fm
->new_cookie
= OVS_BE64_MAX
;
1531 fm
->modify_cookie
= false;
1532 fm
->command
= ofm
->command
;
1533 fm
->table_id
= ofm
->table_id
;
1534 fm
->idle_timeout
= ntohs(ofm
->idle_timeout
);
1535 fm
->hard_timeout
= ntohs(ofm
->hard_timeout
);
1536 fm
->buffer_id
= ntohl(ofm
->buffer_id
);
1537 error
= ofputil_port_from_ofp11(ofm
->out_port
, &fm
->out_port
);
1541 fm
->out_group
= ntohl(ofm
->out_group
);
1543 if ((ofm
->command
== OFPFC_DELETE
1544 || ofm
->command
== OFPFC_DELETE_STRICT
)
1545 && ofm
->out_group
!= htonl(OFPG_ANY
)) {
1546 return OFPERR_OFPFMFC_UNKNOWN
;
1548 raw_flags
= ofm
->flags
;
1552 if (raw
== OFPRAW_OFPT10_FLOW_MOD
) {
1553 /* Standard OpenFlow 1.0 flow_mod. */
1554 const struct ofp10_flow_mod
*ofm
;
1556 /* Get the ofp10_flow_mod. */
1557 ofm
= ofpbuf_pull(&b
, sizeof *ofm
);
1559 /* Translate the rule. */
1560 ofputil_match_from_ofp10_match(&ofm
->match
, &fm
->match
);
1561 ofputil_normalize_match(&fm
->match
);
1563 /* Now get the actions. */
1564 error
= ofpacts_pull_openflow10(&b
, b
.size
, ofpacts
);
1569 /* OpenFlow 1.0 says that exact-match rules have to have the
1570 * highest possible priority. */
1571 fm
->priority
= (ofm
->match
.wildcards
& htonl(OFPFW10_ALL
)
1572 ? ntohs(ofm
->priority
)
1575 /* Translate the message. */
1576 command
= ntohs(ofm
->command
);
1577 fm
->cookie
= htonll(0);
1578 fm
->cookie_mask
= htonll(0);
1579 fm
->new_cookie
= ofm
->cookie
;
1580 fm
->idle_timeout
= ntohs(ofm
->idle_timeout
);
1581 fm
->hard_timeout
= ntohs(ofm
->hard_timeout
);
1582 fm
->buffer_id
= ntohl(ofm
->buffer_id
);
1583 fm
->out_port
= u16_to_ofp(ntohs(ofm
->out_port
));
1584 fm
->out_group
= OFPG11_ANY
;
1585 raw_flags
= ofm
->flags
;
1586 } else if (raw
== OFPRAW_NXT_FLOW_MOD
) {
1587 /* Nicira extended flow_mod. */
1588 const struct nx_flow_mod
*nfm
;
1590 /* Dissect the message. */
1591 nfm
= ofpbuf_pull(&b
, sizeof *nfm
);
1592 error
= nx_pull_match(&b
, ntohs(nfm
->match_len
),
1593 &fm
->match
, &fm
->cookie
, &fm
->cookie_mask
);
1597 error
= ofpacts_pull_openflow10(&b
, b
.size
, ofpacts
);
1602 /* Translate the message. */
1603 command
= ntohs(nfm
->command
);
1604 if ((command
& 0xff) == OFPFC_ADD
&& fm
->cookie_mask
) {
1605 /* Flow additions may only set a new cookie, not match an
1606 * existing cookie. */
1607 return OFPERR_NXBRC_NXM_INVALID
;
1609 fm
->priority
= ntohs(nfm
->priority
);
1610 fm
->new_cookie
= nfm
->cookie
;
1611 fm
->idle_timeout
= ntohs(nfm
->idle_timeout
);
1612 fm
->hard_timeout
= ntohs(nfm
->hard_timeout
);
1613 fm
->buffer_id
= ntohl(nfm
->buffer_id
);
1614 fm
->out_port
= u16_to_ofp(ntohs(nfm
->out_port
));
1615 fm
->out_group
= OFPG11_ANY
;
1616 raw_flags
= nfm
->flags
;
1621 fm
->modify_cookie
= fm
->new_cookie
!= OVS_BE64_MAX
;
1622 if (protocol
& OFPUTIL_P_TID
) {
1623 fm
->command
= command
& 0xff;
1624 fm
->table_id
= command
>> 8;
1626 fm
->command
= command
;
1627 fm
->table_id
= 0xff;
1631 fm
->ofpacts
= ofpacts
->data
;
1632 fm
->ofpacts_len
= ofpacts
->size
;
1634 error
= ofputil_decode_flow_mod_flags(raw_flags
, fm
->command
,
1635 oh
->version
, &fm
->flags
);
1640 if (fm
->flags
& OFPUTIL_FF_EMERG
) {
1641 /* We do not support the OpenFlow 1.0 emergency flow cache, which
1642 * is not required in OpenFlow 1.0.1 and removed from OpenFlow 1.1.
1644 * OpenFlow 1.0 specifies the error code to use when idle_timeout
1645 * or hard_timeout is nonzero. Otherwise, there is no good error
1646 * code, so just state that the flow table is full. */
1647 return (fm
->hard_timeout
|| fm
->idle_timeout
1648 ? OFPERR_OFPFMFC_BAD_EMERG_TIMEOUT
1649 : OFPERR_OFPFMFC_TABLE_FULL
);
1656 ofputil_pull_bands(struct ofpbuf
*msg
, size_t len
, uint16_t *n_bands
,
1657 struct ofpbuf
*bands
)
1659 const struct ofp13_meter_band_header
*ombh
;
1660 struct ofputil_meter_band
*mb
;
1663 ombh
= ofpbuf_try_pull(msg
, len
);
1665 return OFPERR_OFPBRC_BAD_LEN
;
1668 while (len
>= sizeof (struct ofp13_meter_band_drop
)) {
1669 size_t ombh_len
= ntohs(ombh
->len
);
1670 /* All supported band types have the same length. */
1671 if (ombh_len
!= sizeof (struct ofp13_meter_band_drop
)) {
1672 return OFPERR_OFPBRC_BAD_LEN
;
1674 mb
= ofpbuf_put_uninit(bands
, sizeof *mb
);
1675 mb
->type
= ntohs(ombh
->type
);
1676 mb
->rate
= ntohl(ombh
->rate
);
1677 mb
->burst_size
= ntohl(ombh
->burst_size
);
1678 mb
->prec_level
= (mb
->type
== OFPMBT13_DSCP_REMARK
) ?
1679 ((struct ofp13_meter_band_dscp_remark
*)ombh
)->prec_level
: 0;
1682 ombh
= ALIGNED_CAST(struct ofp13_meter_band_header
*,
1683 (char *) ombh
+ ombh_len
);
1686 return OFPERR_OFPBRC_BAD_LEN
;
1693 ofputil_decode_meter_mod(const struct ofp_header
*oh
,
1694 struct ofputil_meter_mod
*mm
,
1695 struct ofpbuf
*bands
)
1697 const struct ofp13_meter_mod
*omm
;
1700 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1701 ofpraw_pull_assert(&b
);
1702 omm
= ofpbuf_pull(&b
, sizeof *omm
);
1704 /* Translate the message. */
1705 mm
->command
= ntohs(omm
->command
);
1706 mm
->meter
.meter_id
= ntohl(omm
->meter_id
);
1708 if (mm
->command
== OFPMC13_DELETE
) {
1709 mm
->meter
.flags
= 0;
1710 mm
->meter
.n_bands
= 0;
1711 mm
->meter
.bands
= NULL
;
1715 mm
->meter
.flags
= ntohs(omm
->flags
);
1716 mm
->meter
.bands
= bands
->data
;
1718 error
= ofputil_pull_bands(&b
, b
.size
, &mm
->meter
.n_bands
, bands
);
1727 ofputil_decode_meter_request(const struct ofp_header
*oh
, uint32_t *meter_id
)
1729 const struct ofp13_meter_multipart_request
*omr
= ofpmsg_body(oh
);
1730 *meter_id
= ntohl(omr
->meter_id
);
1734 ofputil_encode_meter_request(enum ofp_version ofp_version
,
1735 enum ofputil_meter_request_type type
,
1743 case OFPUTIL_METER_CONFIG
:
1744 raw
= OFPRAW_OFPST13_METER_CONFIG_REQUEST
;
1746 case OFPUTIL_METER_STATS
:
1747 raw
= OFPRAW_OFPST13_METER_REQUEST
;
1750 case OFPUTIL_METER_FEATURES
:
1751 raw
= OFPRAW_OFPST13_METER_FEATURES_REQUEST
;
1755 msg
= ofpraw_alloc(raw
, ofp_version
, 0);
1757 if (type
!= OFPUTIL_METER_FEATURES
) {
1758 struct ofp13_meter_multipart_request
*omr
;
1759 omr
= ofpbuf_put_zeros(msg
, sizeof *omr
);
1760 omr
->meter_id
= htonl(meter_id
);
1766 ofputil_put_bands(uint16_t n_bands
, const struct ofputil_meter_band
*mb
,
1771 for (n
= 0; n
< n_bands
; ++n
) {
1772 /* Currently all band types have same size. */
1773 struct ofp13_meter_band_dscp_remark
*ombh
;
1774 size_t ombh_len
= sizeof *ombh
;
1776 ombh
= ofpbuf_put_zeros(msg
, ombh_len
);
1778 ombh
->type
= htons(mb
->type
);
1779 ombh
->len
= htons(ombh_len
);
1780 ombh
->rate
= htonl(mb
->rate
);
1781 ombh
->burst_size
= htonl(mb
->burst_size
);
1782 ombh
->prec_level
= mb
->prec_level
;
1788 /* Encode a meter stat for 'mc' and append it to 'replies'. */
1790 ofputil_append_meter_config(struct list
*replies
,
1791 const struct ofputil_meter_config
*mc
)
1793 struct ofpbuf
*msg
= ofpbuf_from_list(list_back(replies
));
1794 size_t start_ofs
= msg
->size
;
1795 struct ofp13_meter_config
*reply
= ofpbuf_put_uninit(msg
, sizeof *reply
);
1796 reply
->flags
= htons(mc
->flags
);
1797 reply
->meter_id
= htonl(mc
->meter_id
);
1799 ofputil_put_bands(mc
->n_bands
, mc
->bands
, msg
);
1801 reply
->length
= htons(msg
->size
- start_ofs
);
1803 ofpmp_postappend(replies
, start_ofs
);
1806 /* Encode a meter stat for 'ms' and append it to 'replies'. */
1808 ofputil_append_meter_stats(struct list
*replies
,
1809 const struct ofputil_meter_stats
*ms
)
1811 struct ofp13_meter_stats
*reply
;
1815 len
= sizeof *reply
+ ms
->n_bands
* sizeof(struct ofp13_meter_band_stats
);
1816 reply
= ofpmp_append(replies
, len
);
1818 reply
->meter_id
= htonl(ms
->meter_id
);
1819 reply
->len
= htons(len
);
1820 memset(reply
->pad
, 0, sizeof reply
->pad
);
1821 reply
->flow_count
= htonl(ms
->flow_count
);
1822 reply
->packet_in_count
= htonll(ms
->packet_in_count
);
1823 reply
->byte_in_count
= htonll(ms
->byte_in_count
);
1824 reply
->duration_sec
= htonl(ms
->duration_sec
);
1825 reply
->duration_nsec
= htonl(ms
->duration_nsec
);
1827 for (n
= 0; n
< ms
->n_bands
; ++n
) {
1828 const struct ofputil_meter_band_stats
*src
= &ms
->bands
[n
];
1829 struct ofp13_meter_band_stats
*dst
= &reply
->band_stats
[n
];
1831 dst
->packet_band_count
= htonll(src
->packet_count
);
1832 dst
->byte_band_count
= htonll(src
->byte_count
);
1836 /* Converts an OFPMP_METER_CONFIG reply in 'msg' into an abstract
1837 * ofputil_meter_config in 'mc', with mc->bands pointing to bands decoded into
1838 * 'bands'. The caller must have initialized 'bands' and retains ownership of
1839 * it across the call.
1841 * Multiple OFPST13_METER_CONFIG replies can be packed into a single OpenFlow
1842 * message. Calling this function multiple times for a single 'msg' iterates
1843 * through the replies. 'bands' is cleared for each reply.
1845 * Returns 0 if successful, EOF if no replies were left in this 'msg',
1846 * otherwise a positive errno value. */
1848 ofputil_decode_meter_config(struct ofpbuf
*msg
,
1849 struct ofputil_meter_config
*mc
,
1850 struct ofpbuf
*bands
)
1852 const struct ofp13_meter_config
*omc
;
1855 /* Pull OpenFlow headers for the first call. */
1857 ofpraw_pull_assert(msg
);
1864 omc
= ofpbuf_try_pull(msg
, sizeof *omc
);
1866 VLOG_WARN_RL(&bad_ofmsg_rl
,
1867 "OFPMP_METER_CONFIG reply has %zu leftover bytes at end",
1869 return OFPERR_OFPBRC_BAD_LEN
;
1872 ofpbuf_clear(bands
);
1873 err
= ofputil_pull_bands(msg
, ntohs(omc
->length
) - sizeof *omc
,
1874 &mc
->n_bands
, bands
);
1878 mc
->meter_id
= ntohl(omc
->meter_id
);
1879 mc
->flags
= ntohs(omc
->flags
);
1880 mc
->bands
= bands
->data
;
1886 ofputil_pull_band_stats(struct ofpbuf
*msg
, size_t len
, uint16_t *n_bands
,
1887 struct ofpbuf
*bands
)
1889 const struct ofp13_meter_band_stats
*ombs
;
1890 struct ofputil_meter_band_stats
*mbs
;
1893 ombs
= ofpbuf_try_pull(msg
, len
);
1895 return OFPERR_OFPBRC_BAD_LEN
;
1898 n
= len
/ sizeof *ombs
;
1899 if (len
!= n
* sizeof *ombs
) {
1900 return OFPERR_OFPBRC_BAD_LEN
;
1903 mbs
= ofpbuf_put_uninit(bands
, len
);
1905 for (i
= 0; i
< n
; ++i
) {
1906 mbs
[i
].packet_count
= ntohll(ombs
[i
].packet_band_count
);
1907 mbs
[i
].byte_count
= ntohll(ombs
[i
].byte_band_count
);
1913 /* Converts an OFPMP_METER reply in 'msg' into an abstract
1914 * ofputil_meter_stats in 'ms', with ms->bands pointing to band stats
1915 * decoded into 'bands'.
1917 * Multiple OFPMP_METER replies can be packed into a single OpenFlow
1918 * message. Calling this function multiple times for a single 'msg' iterates
1919 * through the replies. 'bands' is cleared for each reply.
1921 * Returns 0 if successful, EOF if no replies were left in this 'msg',
1922 * otherwise a positive errno value. */
1924 ofputil_decode_meter_stats(struct ofpbuf
*msg
,
1925 struct ofputil_meter_stats
*ms
,
1926 struct ofpbuf
*bands
)
1928 const struct ofp13_meter_stats
*oms
;
1931 /* Pull OpenFlow headers for the first call. */
1933 ofpraw_pull_assert(msg
);
1940 oms
= ofpbuf_try_pull(msg
, sizeof *oms
);
1942 VLOG_WARN_RL(&bad_ofmsg_rl
,
1943 "OFPMP_METER reply has %zu leftover bytes at end",
1945 return OFPERR_OFPBRC_BAD_LEN
;
1948 ofpbuf_clear(bands
);
1949 err
= ofputil_pull_band_stats(msg
, ntohs(oms
->len
) - sizeof *oms
,
1950 &ms
->n_bands
, bands
);
1954 ms
->meter_id
= ntohl(oms
->meter_id
);
1955 ms
->flow_count
= ntohl(oms
->flow_count
);
1956 ms
->packet_in_count
= ntohll(oms
->packet_in_count
);
1957 ms
->byte_in_count
= ntohll(oms
->byte_in_count
);
1958 ms
->duration_sec
= ntohl(oms
->duration_sec
);
1959 ms
->duration_nsec
= ntohl(oms
->duration_nsec
);
1960 ms
->bands
= bands
->data
;
1966 ofputil_decode_meter_features(const struct ofp_header
*oh
,
1967 struct ofputil_meter_features
*mf
)
1969 const struct ofp13_meter_features
*omf
= ofpmsg_body(oh
);
1971 mf
->max_meters
= ntohl(omf
->max_meter
);
1972 mf
->band_types
= ntohl(omf
->band_types
);
1973 mf
->capabilities
= ntohl(omf
->capabilities
);
1974 mf
->max_bands
= omf
->max_bands
;
1975 mf
->max_color
= omf
->max_color
;
1979 ofputil_encode_meter_features_reply(const struct ofputil_meter_features
*mf
,
1980 const struct ofp_header
*request
)
1982 struct ofpbuf
*reply
;
1983 struct ofp13_meter_features
*omf
;
1985 reply
= ofpraw_alloc_stats_reply(request
, 0);
1986 omf
= ofpbuf_put_zeros(reply
, sizeof *omf
);
1988 omf
->max_meter
= htonl(mf
->max_meters
);
1989 omf
->band_types
= htonl(mf
->band_types
);
1990 omf
->capabilities
= htonl(mf
->capabilities
);
1991 omf
->max_bands
= mf
->max_bands
;
1992 omf
->max_color
= mf
->max_color
;
1998 ofputil_encode_meter_mod(enum ofp_version ofp_version
,
1999 const struct ofputil_meter_mod
*mm
)
2003 struct ofp13_meter_mod
*omm
;
2005 msg
= ofpraw_alloc(OFPRAW_OFPT13_METER_MOD
, ofp_version
,
2006 NXM_TYPICAL_LEN
+ mm
->meter
.n_bands
* 16);
2007 omm
= ofpbuf_put_zeros(msg
, sizeof *omm
);
2008 omm
->command
= htons(mm
->command
);
2009 if (mm
->command
!= OFPMC13_DELETE
) {
2010 omm
->flags
= htons(mm
->meter
.flags
);
2012 omm
->meter_id
= htonl(mm
->meter
.meter_id
);
2014 ofputil_put_bands(mm
->meter
.n_bands
, mm
->meter
.bands
, msg
);
2016 ofpmsg_update_length(msg
);
2021 ofputil_tid_command(const struct ofputil_flow_mod
*fm
,
2022 enum ofputil_protocol protocol
)
2024 return htons(protocol
& OFPUTIL_P_TID
2025 ? (fm
->command
& 0xff) | (fm
->table_id
<< 8)
2029 /* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to
2030 * 'protocol' and returns the message. */
2032 ofputil_encode_flow_mod(const struct ofputil_flow_mod
*fm
,
2033 enum ofputil_protocol protocol
)
2035 enum ofp_version version
= ofputil_protocol_to_ofp_version(protocol
);
2036 ovs_be16 raw_flags
= ofputil_encode_flow_mod_flags(fm
->flags
, version
);
2040 case OFPUTIL_P_OF11_STD
:
2041 case OFPUTIL_P_OF12_OXM
:
2042 case OFPUTIL_P_OF13_OXM
: {
2043 struct ofp11_flow_mod
*ofm
;
2046 tailroom
= ofputil_match_typical_len(protocol
) + fm
->ofpacts_len
;
2047 msg
= ofpraw_alloc(OFPRAW_OFPT11_FLOW_MOD
, version
, tailroom
);
2048 ofm
= ofpbuf_put_zeros(msg
, sizeof *ofm
);
2049 if ((protocol
== OFPUTIL_P_OF11_STD
2050 && (fm
->command
== OFPFC_MODIFY
||
2051 fm
->command
== OFPFC_MODIFY_STRICT
)
2052 && fm
->cookie_mask
== htonll(0))
2053 || fm
->command
== OFPFC_ADD
) {
2054 ofm
->cookie
= fm
->new_cookie
;
2056 ofm
->cookie
= fm
->cookie
;
2058 ofm
->cookie_mask
= fm
->cookie_mask
;
2059 ofm
->table_id
= fm
->table_id
;
2060 ofm
->command
= fm
->command
;
2061 ofm
->idle_timeout
= htons(fm
->idle_timeout
);
2062 ofm
->hard_timeout
= htons(fm
->hard_timeout
);
2063 ofm
->priority
= htons(fm
->priority
);
2064 ofm
->buffer_id
= htonl(fm
->buffer_id
);
2065 ofm
->out_port
= ofputil_port_to_ofp11(fm
->out_port
);
2066 ofm
->out_group
= htonl(fm
->out_group
);
2067 ofm
->flags
= raw_flags
;
2068 ofputil_put_ofp11_match(msg
, &fm
->match
, protocol
);
2069 ofpacts_put_openflow11_instructions(fm
->ofpacts
, fm
->ofpacts_len
, msg
);
2073 case OFPUTIL_P_OF10_STD
:
2074 case OFPUTIL_P_OF10_STD_TID
: {
2075 struct ofp10_flow_mod
*ofm
;
2077 msg
= ofpraw_alloc(OFPRAW_OFPT10_FLOW_MOD
, OFP10_VERSION
,
2079 ofm
= ofpbuf_put_zeros(msg
, sizeof *ofm
);
2080 ofputil_match_to_ofp10_match(&fm
->match
, &ofm
->match
);
2081 ofm
->cookie
= fm
->new_cookie
;
2082 ofm
->command
= ofputil_tid_command(fm
, protocol
);
2083 ofm
->idle_timeout
= htons(fm
->idle_timeout
);
2084 ofm
->hard_timeout
= htons(fm
->hard_timeout
);
2085 ofm
->priority
= htons(fm
->priority
);
2086 ofm
->buffer_id
= htonl(fm
->buffer_id
);
2087 ofm
->out_port
= htons(ofp_to_u16(fm
->out_port
));
2088 ofm
->flags
= raw_flags
;
2089 ofpacts_put_openflow10(fm
->ofpacts
, fm
->ofpacts_len
, msg
);
2093 case OFPUTIL_P_OF10_NXM
:
2094 case OFPUTIL_P_OF10_NXM_TID
: {
2095 struct nx_flow_mod
*nfm
;
2098 msg
= ofpraw_alloc(OFPRAW_NXT_FLOW_MOD
, OFP10_VERSION
,
2099 NXM_TYPICAL_LEN
+ fm
->ofpacts_len
);
2100 nfm
= ofpbuf_put_zeros(msg
, sizeof *nfm
);
2101 nfm
->command
= ofputil_tid_command(fm
, protocol
);
2102 nfm
->cookie
= fm
->new_cookie
;
2103 match_len
= nx_put_match(msg
, &fm
->match
, fm
->cookie
, fm
->cookie_mask
);
2105 nfm
->idle_timeout
= htons(fm
->idle_timeout
);
2106 nfm
->hard_timeout
= htons(fm
->hard_timeout
);
2107 nfm
->priority
= htons(fm
->priority
);
2108 nfm
->buffer_id
= htonl(fm
->buffer_id
);
2109 nfm
->out_port
= htons(ofp_to_u16(fm
->out_port
));
2110 nfm
->flags
= raw_flags
;
2111 nfm
->match_len
= htons(match_len
);
2112 ofpacts_put_openflow10(fm
->ofpacts
, fm
->ofpacts_len
, msg
);
2120 ofpmsg_update_length(msg
);
2125 ofputil_decode_ofpst10_flow_request(struct ofputil_flow_stats_request
*fsr
,
2126 const struct ofp10_flow_stats_request
*ofsr
,
2129 fsr
->aggregate
= aggregate
;
2130 ofputil_match_from_ofp10_match(&ofsr
->match
, &fsr
->match
);
2131 fsr
->out_port
= u16_to_ofp(ntohs(ofsr
->out_port
));
2132 fsr
->out_group
= OFPG11_ANY
;
2133 fsr
->table_id
= ofsr
->table_id
;
2134 fsr
->cookie
= fsr
->cookie_mask
= htonll(0);
2140 ofputil_decode_ofpst11_flow_request(struct ofputil_flow_stats_request
*fsr
,
2141 struct ofpbuf
*b
, bool aggregate
)
2143 const struct ofp11_flow_stats_request
*ofsr
;
2146 ofsr
= ofpbuf_pull(b
, sizeof *ofsr
);
2147 fsr
->aggregate
= aggregate
;
2148 fsr
->table_id
= ofsr
->table_id
;
2149 error
= ofputil_port_from_ofp11(ofsr
->out_port
, &fsr
->out_port
);
2153 fsr
->out_group
= ntohl(ofsr
->out_group
);
2154 fsr
->cookie
= ofsr
->cookie
;
2155 fsr
->cookie_mask
= ofsr
->cookie_mask
;
2156 error
= ofputil_pull_ofp11_match(b
, &fsr
->match
, NULL
);
2165 ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request
*fsr
,
2166 struct ofpbuf
*b
, bool aggregate
)
2168 const struct nx_flow_stats_request
*nfsr
;
2171 nfsr
= ofpbuf_pull(b
, sizeof *nfsr
);
2172 error
= nx_pull_match(b
, ntohs(nfsr
->match_len
), &fsr
->match
,
2173 &fsr
->cookie
, &fsr
->cookie_mask
);
2178 return OFPERR_OFPBRC_BAD_LEN
;
2181 fsr
->aggregate
= aggregate
;
2182 fsr
->out_port
= u16_to_ofp(ntohs(nfsr
->out_port
));
2183 fsr
->out_group
= OFPG11_ANY
;
2184 fsr
->table_id
= nfsr
->table_id
;
2189 /* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
2190 * request 'oh', into an abstract flow_stats_request in 'fsr'. Returns 0 if
2191 * successful, otherwise an OpenFlow error code. */
2193 ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request
*fsr
,
2194 const struct ofp_header
*oh
)
2199 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2200 raw
= ofpraw_pull_assert(&b
);
2201 switch ((int) raw
) {
2202 case OFPRAW_OFPST10_FLOW_REQUEST
:
2203 return ofputil_decode_ofpst10_flow_request(fsr
, b
.data
, false);
2205 case OFPRAW_OFPST10_AGGREGATE_REQUEST
:
2206 return ofputil_decode_ofpst10_flow_request(fsr
, b
.data
, true);
2208 case OFPRAW_OFPST11_FLOW_REQUEST
:
2209 return ofputil_decode_ofpst11_flow_request(fsr
, &b
, false);
2211 case OFPRAW_OFPST11_AGGREGATE_REQUEST
:
2212 return ofputil_decode_ofpst11_flow_request(fsr
, &b
, true);
2214 case OFPRAW_NXST_FLOW_REQUEST
:
2215 return ofputil_decode_nxst_flow_request(fsr
, &b
, false);
2217 case OFPRAW_NXST_AGGREGATE_REQUEST
:
2218 return ofputil_decode_nxst_flow_request(fsr
, &b
, true);
2221 /* Hey, the caller lied. */
2226 /* Converts abstract flow_stats_request 'fsr' into an OFPST_FLOW,
2227 * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
2228 * 'protocol', and returns the message. */
2230 ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request
*fsr
,
2231 enum ofputil_protocol protocol
)
2237 case OFPUTIL_P_OF11_STD
:
2238 case OFPUTIL_P_OF12_OXM
:
2239 case OFPUTIL_P_OF13_OXM
: {
2240 struct ofp11_flow_stats_request
*ofsr
;
2242 raw
= (fsr
->aggregate
2243 ? OFPRAW_OFPST11_AGGREGATE_REQUEST
2244 : OFPRAW_OFPST11_FLOW_REQUEST
);
2245 msg
= ofpraw_alloc(raw
, ofputil_protocol_to_ofp_version(protocol
),
2246 ofputil_match_typical_len(protocol
));
2247 ofsr
= ofpbuf_put_zeros(msg
, sizeof *ofsr
);
2248 ofsr
->table_id
= fsr
->table_id
;
2249 ofsr
->out_port
= ofputil_port_to_ofp11(fsr
->out_port
);
2250 ofsr
->out_group
= htonl(fsr
->out_group
);
2251 ofsr
->cookie
= fsr
->cookie
;
2252 ofsr
->cookie_mask
= fsr
->cookie_mask
;
2253 ofputil_put_ofp11_match(msg
, &fsr
->match
, protocol
);
2257 case OFPUTIL_P_OF10_STD
:
2258 case OFPUTIL_P_OF10_STD_TID
: {
2259 struct ofp10_flow_stats_request
*ofsr
;
2261 raw
= (fsr
->aggregate
2262 ? OFPRAW_OFPST10_AGGREGATE_REQUEST
2263 : OFPRAW_OFPST10_FLOW_REQUEST
);
2264 msg
= ofpraw_alloc(raw
, OFP10_VERSION
, 0);
2265 ofsr
= ofpbuf_put_zeros(msg
, sizeof *ofsr
);
2266 ofputil_match_to_ofp10_match(&fsr
->match
, &ofsr
->match
);
2267 ofsr
->table_id
= fsr
->table_id
;
2268 ofsr
->out_port
= htons(ofp_to_u16(fsr
->out_port
));
2272 case OFPUTIL_P_OF10_NXM
:
2273 case OFPUTIL_P_OF10_NXM_TID
: {
2274 struct nx_flow_stats_request
*nfsr
;
2277 raw
= (fsr
->aggregate
2278 ? OFPRAW_NXST_AGGREGATE_REQUEST
2279 : OFPRAW_NXST_FLOW_REQUEST
);
2280 msg
= ofpraw_alloc(raw
, OFP10_VERSION
, NXM_TYPICAL_LEN
);
2281 ofpbuf_put_zeros(msg
, sizeof *nfsr
);
2282 match_len
= nx_put_match(msg
, &fsr
->match
,
2283 fsr
->cookie
, fsr
->cookie_mask
);
2286 nfsr
->out_port
= htons(ofp_to_u16(fsr
->out_port
));
2287 nfsr
->match_len
= htons(match_len
);
2288 nfsr
->table_id
= fsr
->table_id
;
2299 /* Converts an OFPST_FLOW or NXST_FLOW reply in 'msg' into an abstract
2300 * ofputil_flow_stats in 'fs'.
2302 * Multiple OFPST_FLOW or NXST_FLOW replies can be packed into a single
2303 * OpenFlow message. Calling this function multiple times for a single 'msg'
2304 * iterates through the replies. The caller must initially leave 'msg''s layer
2305 * pointers null and not modify them between calls.
2307 * Most switches don't send the values needed to populate fs->idle_age and
2308 * fs->hard_age, so those members will usually be set to 0. If the switch from
2309 * which 'msg' originated is known to implement NXT_FLOW_AGE, then pass
2310 * 'flow_age_extension' as true so that the contents of 'msg' determine the
2311 * 'idle_age' and 'hard_age' members in 'fs'.
2313 * Uses 'ofpacts' to store the abstract OFPACT_* version of the flow stats
2314 * reply's actions. The caller must initialize 'ofpacts' and retains ownership
2315 * of it. 'fs->ofpacts' will point into the 'ofpacts' buffer.
2317 * Returns 0 if successful, EOF if no replies were left in this 'msg',
2318 * otherwise a positive errno value. */
2320 ofputil_decode_flow_stats_reply(struct ofputil_flow_stats
*fs
,
2322 bool flow_age_extension
,
2323 struct ofpbuf
*ofpacts
)
2325 const struct ofp_header
*oh
;
2330 ? ofpraw_decode(&raw
, msg
->l2
)
2331 : ofpraw_pull(&raw
, msg
));
2339 } else if (raw
== OFPRAW_OFPST11_FLOW_REPLY
2340 || raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
2341 const struct ofp11_flow_stats
*ofs
;
2343 uint16_t padded_match_len
;
2345 ofs
= ofpbuf_try_pull(msg
, sizeof *ofs
);
2347 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply has %zu leftover "
2348 "bytes at end", msg
->size
);
2352 length
= ntohs(ofs
->length
);
2353 if (length
< sizeof *ofs
) {
2354 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply claims invalid "
2355 "length %zu", length
);
2359 if (ofputil_pull_ofp11_match(msg
, &fs
->match
, &padded_match_len
)) {
2360 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply bad match");
2364 if (ofpacts_pull_openflow11_instructions(msg
, oh
->version
,
2365 length
- sizeof *ofs
-
2366 padded_match_len
, ofpacts
)) {
2367 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply bad instructions");
2371 fs
->priority
= ntohs(ofs
->priority
);
2372 fs
->table_id
= ofs
->table_id
;
2373 fs
->duration_sec
= ntohl(ofs
->duration_sec
);
2374 fs
->duration_nsec
= ntohl(ofs
->duration_nsec
);
2375 fs
->idle_timeout
= ntohs(ofs
->idle_timeout
);
2376 fs
->hard_timeout
= ntohs(ofs
->hard_timeout
);
2377 if (raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
2378 error
= ofputil_decode_flow_mod_flags(ofs
->flags
, -1, oh
->version
,
2388 fs
->cookie
= ofs
->cookie
;
2389 fs
->packet_count
= ntohll(ofs
->packet_count
);
2390 fs
->byte_count
= ntohll(ofs
->byte_count
);
2391 } else if (raw
== OFPRAW_OFPST10_FLOW_REPLY
) {
2392 const struct ofp10_flow_stats
*ofs
;
2395 ofs
= ofpbuf_try_pull(msg
, sizeof *ofs
);
2397 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply has %zu leftover "
2398 "bytes at end", msg
->size
);
2402 length
= ntohs(ofs
->length
);
2403 if (length
< sizeof *ofs
) {
2404 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply claims invalid "
2405 "length %zu", length
);
2409 if (ofpacts_pull_openflow10(msg
, length
- sizeof *ofs
, ofpacts
)) {
2413 fs
->cookie
= get_32aligned_be64(&ofs
->cookie
);
2414 ofputil_match_from_ofp10_match(&ofs
->match
, &fs
->match
);
2415 fs
->priority
= ntohs(ofs
->priority
);
2416 fs
->table_id
= ofs
->table_id
;
2417 fs
->duration_sec
= ntohl(ofs
->duration_sec
);
2418 fs
->duration_nsec
= ntohl(ofs
->duration_nsec
);
2419 fs
->idle_timeout
= ntohs(ofs
->idle_timeout
);
2420 fs
->hard_timeout
= ntohs(ofs
->hard_timeout
);
2423 fs
->packet_count
= ntohll(get_32aligned_be64(&ofs
->packet_count
));
2424 fs
->byte_count
= ntohll(get_32aligned_be64(&ofs
->byte_count
));
2426 } else if (raw
== OFPRAW_NXST_FLOW_REPLY
) {
2427 const struct nx_flow_stats
*nfs
;
2428 size_t match_len
, actions_len
, length
;
2430 nfs
= ofpbuf_try_pull(msg
, sizeof *nfs
);
2432 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW reply has %zu leftover "
2433 "bytes at end", msg
->size
);
2437 length
= ntohs(nfs
->length
);
2438 match_len
= ntohs(nfs
->match_len
);
2439 if (length
< sizeof *nfs
+ ROUND_UP(match_len
, 8)) {
2440 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW reply with match_len=%zu "
2441 "claims invalid length %zu", match_len
, length
);
2444 if (nx_pull_match(msg
, match_len
, &fs
->match
, NULL
, NULL
)) {
2448 actions_len
= length
- sizeof *nfs
- ROUND_UP(match_len
, 8);
2449 if (ofpacts_pull_openflow10(msg
, actions_len
, ofpacts
)) {
2453 fs
->cookie
= nfs
->cookie
;
2454 fs
->table_id
= nfs
->table_id
;
2455 fs
->duration_sec
= ntohl(nfs
->duration_sec
);
2456 fs
->duration_nsec
= ntohl(nfs
->duration_nsec
);
2457 fs
->priority
= ntohs(nfs
->priority
);
2458 fs
->idle_timeout
= ntohs(nfs
->idle_timeout
);
2459 fs
->hard_timeout
= ntohs(nfs
->hard_timeout
);
2462 if (flow_age_extension
) {
2463 if (nfs
->idle_age
) {
2464 fs
->idle_age
= ntohs(nfs
->idle_age
) - 1;
2466 if (nfs
->hard_age
) {
2467 fs
->hard_age
= ntohs(nfs
->hard_age
) - 1;
2470 fs
->packet_count
= ntohll(nfs
->packet_count
);
2471 fs
->byte_count
= ntohll(nfs
->byte_count
);
2477 fs
->ofpacts
= ofpacts
->data
;
2478 fs
->ofpacts_len
= ofpacts
->size
;
2483 /* Returns 'count' unchanged except that UINT64_MAX becomes 0.
2485 * We use this in situations where OVS internally uses UINT64_MAX to mean
2486 * "value unknown" but OpenFlow 1.0 does not define any unknown value. */
2488 unknown_to_zero(uint64_t count
)
2490 return count
!= UINT64_MAX
? count
: 0;
2493 /* Appends an OFPST_FLOW or NXST_FLOW reply that contains the data in 'fs' to
2494 * those already present in the list of ofpbufs in 'replies'. 'replies' should
2495 * have been initialized with ofpmp_init(). */
2497 ofputil_append_flow_stats_reply(const struct ofputil_flow_stats
*fs
,
2498 struct list
*replies
)
2500 struct ofpbuf
*reply
= ofpbuf_from_list(list_back(replies
));
2501 size_t start_ofs
= reply
->size
;
2504 ofpraw_decode_partial(&raw
, reply
->data
, reply
->size
);
2505 if (raw
== OFPRAW_OFPST11_FLOW_REPLY
|| raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
2506 const struct ofp_header
*oh
= reply
->data
;
2507 struct ofp11_flow_stats
*ofs
;
2509 ofpbuf_put_uninit(reply
, sizeof *ofs
);
2510 oxm_put_match(reply
, &fs
->match
);
2511 ofpacts_put_openflow11_instructions(fs
->ofpacts
, fs
->ofpacts_len
,
2514 ofs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *ofs
);
2515 ofs
->length
= htons(reply
->size
- start_ofs
);
2516 ofs
->table_id
= fs
->table_id
;
2518 ofs
->duration_sec
= htonl(fs
->duration_sec
);
2519 ofs
->duration_nsec
= htonl(fs
->duration_nsec
);
2520 ofs
->priority
= htons(fs
->priority
);
2521 ofs
->idle_timeout
= htons(fs
->idle_timeout
);
2522 ofs
->hard_timeout
= htons(fs
->hard_timeout
);
2523 if (raw
== OFPRAW_OFPST13_FLOW_REPLY
) {
2524 ofs
->flags
= ofputil_encode_flow_mod_flags(fs
->flags
, oh
->version
);
2528 memset(ofs
->pad2
, 0, sizeof ofs
->pad2
);
2529 ofs
->cookie
= fs
->cookie
;
2530 ofs
->packet_count
= htonll(unknown_to_zero(fs
->packet_count
));
2531 ofs
->byte_count
= htonll(unknown_to_zero(fs
->byte_count
));
2532 } else if (raw
== OFPRAW_OFPST10_FLOW_REPLY
) {
2533 struct ofp10_flow_stats
*ofs
;
2535 ofpbuf_put_uninit(reply
, sizeof *ofs
);
2536 ofpacts_put_openflow10(fs
->ofpacts
, fs
->ofpacts_len
, reply
);
2538 ofs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *ofs
);
2539 ofs
->length
= htons(reply
->size
- start_ofs
);
2540 ofs
->table_id
= fs
->table_id
;
2542 ofputil_match_to_ofp10_match(&fs
->match
, &ofs
->match
);
2543 ofs
->duration_sec
= htonl(fs
->duration_sec
);
2544 ofs
->duration_nsec
= htonl(fs
->duration_nsec
);
2545 ofs
->priority
= htons(fs
->priority
);
2546 ofs
->idle_timeout
= htons(fs
->idle_timeout
);
2547 ofs
->hard_timeout
= htons(fs
->hard_timeout
);
2548 memset(ofs
->pad2
, 0, sizeof ofs
->pad2
);
2549 put_32aligned_be64(&ofs
->cookie
, fs
->cookie
);
2550 put_32aligned_be64(&ofs
->packet_count
,
2551 htonll(unknown_to_zero(fs
->packet_count
)));
2552 put_32aligned_be64(&ofs
->byte_count
,
2553 htonll(unknown_to_zero(fs
->byte_count
)));
2554 } else if (raw
== OFPRAW_NXST_FLOW_REPLY
) {
2555 struct nx_flow_stats
*nfs
;
2558 ofpbuf_put_uninit(reply
, sizeof *nfs
);
2559 match_len
= nx_put_match(reply
, &fs
->match
, 0, 0);
2560 ofpacts_put_openflow10(fs
->ofpacts
, fs
->ofpacts_len
, reply
);
2562 nfs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *nfs
);
2563 nfs
->length
= htons(reply
->size
- start_ofs
);
2564 nfs
->table_id
= fs
->table_id
;
2566 nfs
->duration_sec
= htonl(fs
->duration_sec
);
2567 nfs
->duration_nsec
= htonl(fs
->duration_nsec
);
2568 nfs
->priority
= htons(fs
->priority
);
2569 nfs
->idle_timeout
= htons(fs
->idle_timeout
);
2570 nfs
->hard_timeout
= htons(fs
->hard_timeout
);
2571 nfs
->idle_age
= htons(fs
->idle_age
< 0 ? 0
2572 : fs
->idle_age
< UINT16_MAX
? fs
->idle_age
+ 1
2574 nfs
->hard_age
= htons(fs
->hard_age
< 0 ? 0
2575 : fs
->hard_age
< UINT16_MAX
? fs
->hard_age
+ 1
2577 nfs
->match_len
= htons(match_len
);
2578 nfs
->cookie
= fs
->cookie
;
2579 nfs
->packet_count
= htonll(fs
->packet_count
);
2580 nfs
->byte_count
= htonll(fs
->byte_count
);
2585 ofpmp_postappend(replies
, start_ofs
);
2588 /* Converts abstract ofputil_aggregate_stats 'stats' into an OFPST_AGGREGATE or
2589 * NXST_AGGREGATE reply matching 'request', and returns the message. */
2591 ofputil_encode_aggregate_stats_reply(
2592 const struct ofputil_aggregate_stats
*stats
,
2593 const struct ofp_header
*request
)
2595 struct ofp_aggregate_stats_reply
*asr
;
2596 uint64_t packet_count
;
2597 uint64_t byte_count
;
2601 ofpraw_decode(&raw
, request
);
2602 if (raw
== OFPRAW_OFPST10_AGGREGATE_REQUEST
) {
2603 packet_count
= unknown_to_zero(stats
->packet_count
);
2604 byte_count
= unknown_to_zero(stats
->byte_count
);
2606 packet_count
= stats
->packet_count
;
2607 byte_count
= stats
->byte_count
;
2610 msg
= ofpraw_alloc_stats_reply(request
, 0);
2611 asr
= ofpbuf_put_zeros(msg
, sizeof *asr
);
2612 put_32aligned_be64(&asr
->packet_count
, htonll(packet_count
));
2613 put_32aligned_be64(&asr
->byte_count
, htonll(byte_count
));
2614 asr
->flow_count
= htonl(stats
->flow_count
);
2620 ofputil_decode_aggregate_stats_reply(struct ofputil_aggregate_stats
*stats
,
2621 const struct ofp_header
*reply
)
2623 struct ofp_aggregate_stats_reply
*asr
;
2626 ofpbuf_use_const(&msg
, reply
, ntohs(reply
->length
));
2627 ofpraw_pull_assert(&msg
);
2630 stats
->packet_count
= ntohll(get_32aligned_be64(&asr
->packet_count
));
2631 stats
->byte_count
= ntohll(get_32aligned_be64(&asr
->byte_count
));
2632 stats
->flow_count
= ntohl(asr
->flow_count
);
2637 /* Converts an OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED message 'oh' into an
2638 * abstract ofputil_flow_removed in 'fr'. Returns 0 if successful, otherwise
2639 * an OpenFlow error code. */
2641 ofputil_decode_flow_removed(struct ofputil_flow_removed
*fr
,
2642 const struct ofp_header
*oh
)
2647 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2648 raw
= ofpraw_pull_assert(&b
);
2649 if (raw
== OFPRAW_OFPT11_FLOW_REMOVED
) {
2650 const struct ofp12_flow_removed
*ofr
;
2653 ofr
= ofpbuf_pull(&b
, sizeof *ofr
);
2655 error
= ofputil_pull_ofp11_match(&b
, &fr
->match
, NULL
);
2660 fr
->priority
= ntohs(ofr
->priority
);
2661 fr
->cookie
= ofr
->cookie
;
2662 fr
->reason
= ofr
->reason
;
2663 fr
->table_id
= ofr
->table_id
;
2664 fr
->duration_sec
= ntohl(ofr
->duration_sec
);
2665 fr
->duration_nsec
= ntohl(ofr
->duration_nsec
);
2666 fr
->idle_timeout
= ntohs(ofr
->idle_timeout
);
2667 fr
->hard_timeout
= ntohs(ofr
->hard_timeout
);
2668 fr
->packet_count
= ntohll(ofr
->packet_count
);
2669 fr
->byte_count
= ntohll(ofr
->byte_count
);
2670 } else if (raw
== OFPRAW_OFPT10_FLOW_REMOVED
) {
2671 const struct ofp10_flow_removed
*ofr
;
2673 ofr
= ofpbuf_pull(&b
, sizeof *ofr
);
2675 ofputil_match_from_ofp10_match(&ofr
->match
, &fr
->match
);
2676 fr
->priority
= ntohs(ofr
->priority
);
2677 fr
->cookie
= ofr
->cookie
;
2678 fr
->reason
= ofr
->reason
;
2680 fr
->duration_sec
= ntohl(ofr
->duration_sec
);
2681 fr
->duration_nsec
= ntohl(ofr
->duration_nsec
);
2682 fr
->idle_timeout
= ntohs(ofr
->idle_timeout
);
2683 fr
->hard_timeout
= 0;
2684 fr
->packet_count
= ntohll(ofr
->packet_count
);
2685 fr
->byte_count
= ntohll(ofr
->byte_count
);
2686 } else if (raw
== OFPRAW_NXT_FLOW_REMOVED
) {
2687 struct nx_flow_removed
*nfr
;
2690 nfr
= ofpbuf_pull(&b
, sizeof *nfr
);
2691 error
= nx_pull_match(&b
, ntohs(nfr
->match_len
), &fr
->match
,
2697 return OFPERR_OFPBRC_BAD_LEN
;
2700 fr
->priority
= ntohs(nfr
->priority
);
2701 fr
->cookie
= nfr
->cookie
;
2702 fr
->reason
= nfr
->reason
;
2703 fr
->table_id
= nfr
->table_id
? nfr
->table_id
- 1 : 255;
2704 fr
->duration_sec
= ntohl(nfr
->duration_sec
);
2705 fr
->duration_nsec
= ntohl(nfr
->duration_nsec
);
2706 fr
->idle_timeout
= ntohs(nfr
->idle_timeout
);
2707 fr
->hard_timeout
= 0;
2708 fr
->packet_count
= ntohll(nfr
->packet_count
);
2709 fr
->byte_count
= ntohll(nfr
->byte_count
);
2717 /* Converts abstract ofputil_flow_removed 'fr' into an OFPT_FLOW_REMOVED or
2718 * NXT_FLOW_REMOVED message 'oh' according to 'protocol', and returns the
2721 ofputil_encode_flow_removed(const struct ofputil_flow_removed
*fr
,
2722 enum ofputil_protocol protocol
)
2727 case OFPUTIL_P_OF11_STD
:
2728 case OFPUTIL_P_OF12_OXM
:
2729 case OFPUTIL_P_OF13_OXM
: {
2730 struct ofp12_flow_removed
*ofr
;
2732 msg
= ofpraw_alloc_xid(OFPRAW_OFPT11_FLOW_REMOVED
,
2733 ofputil_protocol_to_ofp_version(protocol
),
2735 ofputil_match_typical_len(protocol
));
2736 ofr
= ofpbuf_put_zeros(msg
, sizeof *ofr
);
2737 ofr
->cookie
= fr
->cookie
;
2738 ofr
->priority
= htons(fr
->priority
);
2739 ofr
->reason
= fr
->reason
;
2740 ofr
->table_id
= fr
->table_id
;
2741 ofr
->duration_sec
= htonl(fr
->duration_sec
);
2742 ofr
->duration_nsec
= htonl(fr
->duration_nsec
);
2743 ofr
->idle_timeout
= htons(fr
->idle_timeout
);
2744 ofr
->hard_timeout
= htons(fr
->hard_timeout
);
2745 ofr
->packet_count
= htonll(fr
->packet_count
);
2746 ofr
->byte_count
= htonll(fr
->byte_count
);
2747 ofputil_put_ofp11_match(msg
, &fr
->match
, protocol
);
2751 case OFPUTIL_P_OF10_STD
:
2752 case OFPUTIL_P_OF10_STD_TID
: {
2753 struct ofp10_flow_removed
*ofr
;
2755 msg
= ofpraw_alloc_xid(OFPRAW_OFPT10_FLOW_REMOVED
, OFP10_VERSION
,
2757 ofr
= ofpbuf_put_zeros(msg
, sizeof *ofr
);
2758 ofputil_match_to_ofp10_match(&fr
->match
, &ofr
->match
);
2759 ofr
->cookie
= fr
->cookie
;
2760 ofr
->priority
= htons(fr
->priority
);
2761 ofr
->reason
= fr
->reason
;
2762 ofr
->duration_sec
= htonl(fr
->duration_sec
);
2763 ofr
->duration_nsec
= htonl(fr
->duration_nsec
);
2764 ofr
->idle_timeout
= htons(fr
->idle_timeout
);
2765 ofr
->packet_count
= htonll(unknown_to_zero(fr
->packet_count
));
2766 ofr
->byte_count
= htonll(unknown_to_zero(fr
->byte_count
));
2770 case OFPUTIL_P_OF10_NXM
:
2771 case OFPUTIL_P_OF10_NXM_TID
: {
2772 struct nx_flow_removed
*nfr
;
2775 msg
= ofpraw_alloc_xid(OFPRAW_NXT_FLOW_REMOVED
, OFP10_VERSION
,
2776 htonl(0), NXM_TYPICAL_LEN
);
2777 nfr
= ofpbuf_put_zeros(msg
, sizeof *nfr
);
2778 match_len
= nx_put_match(msg
, &fr
->match
, 0, 0);
2781 nfr
->cookie
= fr
->cookie
;
2782 nfr
->priority
= htons(fr
->priority
);
2783 nfr
->reason
= fr
->reason
;
2784 nfr
->table_id
= fr
->table_id
+ 1;
2785 nfr
->duration_sec
= htonl(fr
->duration_sec
);
2786 nfr
->duration_nsec
= htonl(fr
->duration_nsec
);
2787 nfr
->idle_timeout
= htons(fr
->idle_timeout
);
2788 nfr
->match_len
= htons(match_len
);
2789 nfr
->packet_count
= htonll(fr
->packet_count
);
2790 nfr
->byte_count
= htonll(fr
->byte_count
);
2802 ofputil_decode_packet_in_finish(struct ofputil_packet_in
*pin
,
2803 struct match
*match
, struct ofpbuf
*b
)
2805 pin
->packet
= b
->data
;
2806 pin
->packet_len
= b
->size
;
2808 pin
->fmd
.in_port
= match
->flow
.in_port
.ofp_port
;
2809 pin
->fmd
.tun_id
= match
->flow
.tunnel
.tun_id
;
2810 pin
->fmd
.tun_src
= match
->flow
.tunnel
.ip_src
;
2811 pin
->fmd
.tun_dst
= match
->flow
.tunnel
.ip_dst
;
2812 pin
->fmd
.metadata
= match
->flow
.metadata
;
2813 memcpy(pin
->fmd
.regs
, match
->flow
.regs
, sizeof pin
->fmd
.regs
);
2814 pin
->fmd
.pkt_mark
= match
->flow
.pkt_mark
;
2818 ofputil_decode_packet_in(struct ofputil_packet_in
*pin
,
2819 const struct ofp_header
*oh
)
2824 memset(pin
, 0, sizeof *pin
);
2826 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2827 raw
= ofpraw_pull_assert(&b
);
2828 if (raw
== OFPRAW_OFPT13_PACKET_IN
|| raw
== OFPRAW_OFPT12_PACKET_IN
) {
2829 const struct ofp13_packet_in
*opi
;
2832 size_t packet_in_size
;
2834 if (raw
== OFPRAW_OFPT12_PACKET_IN
) {
2835 packet_in_size
= sizeof (struct ofp12_packet_in
);
2837 packet_in_size
= sizeof (struct ofp13_packet_in
);
2840 opi
= ofpbuf_pull(&b
, packet_in_size
);
2841 error
= oxm_pull_match_loose(&b
, &match
);
2846 if (!ofpbuf_try_pull(&b
, 2)) {
2847 return OFPERR_OFPBRC_BAD_LEN
;
2850 pin
->reason
= opi
->pi
.reason
;
2851 pin
->table_id
= opi
->pi
.table_id
;
2852 pin
->buffer_id
= ntohl(opi
->pi
.buffer_id
);
2853 pin
->total_len
= ntohs(opi
->pi
.total_len
);
2855 if (raw
== OFPRAW_OFPT13_PACKET_IN
) {
2856 pin
->cookie
= opi
->cookie
;
2859 ofputil_decode_packet_in_finish(pin
, &match
, &b
);
2860 } else if (raw
== OFPRAW_OFPT10_PACKET_IN
) {
2861 const struct ofp10_packet_in
*opi
;
2863 opi
= ofpbuf_pull(&b
, offsetof(struct ofp10_packet_in
, data
));
2865 pin
->packet
= opi
->data
;
2866 pin
->packet_len
= b
.size
;
2868 pin
->fmd
.in_port
= u16_to_ofp(ntohs(opi
->in_port
));
2869 pin
->reason
= opi
->reason
;
2870 pin
->buffer_id
= ntohl(opi
->buffer_id
);
2871 pin
->total_len
= ntohs(opi
->total_len
);
2872 } else if (raw
== OFPRAW_NXT_PACKET_IN
) {
2873 const struct nx_packet_in
*npi
;
2877 npi
= ofpbuf_pull(&b
, sizeof *npi
);
2878 error
= nx_pull_match_loose(&b
, ntohs(npi
->match_len
), &match
, NULL
,
2884 if (!ofpbuf_try_pull(&b
, 2)) {
2885 return OFPERR_OFPBRC_BAD_LEN
;
2888 pin
->reason
= npi
->reason
;
2889 pin
->table_id
= npi
->table_id
;
2890 pin
->cookie
= npi
->cookie
;
2892 pin
->buffer_id
= ntohl(npi
->buffer_id
);
2893 pin
->total_len
= ntohs(npi
->total_len
);
2895 ofputil_decode_packet_in_finish(pin
, &match
, &b
);
2904 ofputil_packet_in_to_match(const struct ofputil_packet_in
*pin
,
2905 struct match
*match
)
2909 match_init_catchall(match
);
2910 if (pin
->fmd
.tun_id
!= htonll(0)) {
2911 match_set_tun_id(match
, pin
->fmd
.tun_id
);
2913 if (pin
->fmd
.tun_src
!= htonl(0)) {
2914 match_set_tun_src(match
, pin
->fmd
.tun_src
);
2916 if (pin
->fmd
.tun_dst
!= htonl(0)) {
2917 match_set_tun_dst(match
, pin
->fmd
.tun_dst
);
2919 if (pin
->fmd
.metadata
!= htonll(0)) {
2920 match_set_metadata(match
, pin
->fmd
.metadata
);
2923 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
2924 if (pin
->fmd
.regs
[i
]) {
2925 match_set_reg(match
, i
, pin
->fmd
.regs
[i
]);
2929 if (pin
->fmd
.pkt_mark
!= 0) {
2930 match_set_pkt_mark(match
, pin
->fmd
.pkt_mark
);
2933 match_set_in_port(match
, pin
->fmd
.in_port
);
2936 /* Converts abstract ofputil_packet_in 'pin' into a PACKET_IN message
2937 * in the format specified by 'packet_in_format'. */
2939 ofputil_encode_packet_in(const struct ofputil_packet_in
*pin
,
2940 enum ofputil_protocol protocol
,
2941 enum nx_packet_in_format packet_in_format
)
2943 struct ofpbuf
*packet
;
2945 /* Add OFPT_PACKET_IN. */
2946 if (protocol
== OFPUTIL_P_OF13_OXM
|| protocol
== OFPUTIL_P_OF12_OXM
) {
2947 struct ofp13_packet_in
*opi
;
2949 enum ofpraw packet_in_raw
;
2950 enum ofp_version packet_in_version
;
2951 size_t packet_in_size
;
2953 if (protocol
== OFPUTIL_P_OF12_OXM
) {
2954 packet_in_raw
= OFPRAW_OFPT12_PACKET_IN
;
2955 packet_in_version
= OFP12_VERSION
;
2956 packet_in_size
= sizeof (struct ofp12_packet_in
);
2958 packet_in_raw
= OFPRAW_OFPT13_PACKET_IN
;
2959 packet_in_version
= OFP13_VERSION
;
2960 packet_in_size
= sizeof (struct ofp13_packet_in
);
2963 ofputil_packet_in_to_match(pin
, &match
);
2965 /* The final argument is just an estimate of the space required. */
2966 packet
= ofpraw_alloc_xid(packet_in_raw
, packet_in_version
,
2967 htonl(0), (sizeof(struct flow_metadata
) * 2
2968 + 2 + pin
->packet_len
));
2969 ofpbuf_put_zeros(packet
, packet_in_size
);
2970 oxm_put_match(packet
, &match
);
2971 ofpbuf_put_zeros(packet
, 2);
2972 ofpbuf_put(packet
, pin
->packet
, pin
->packet_len
);
2975 opi
->pi
.buffer_id
= htonl(pin
->buffer_id
);
2976 opi
->pi
.total_len
= htons(pin
->total_len
);
2977 opi
->pi
.reason
= pin
->reason
;
2978 opi
->pi
.table_id
= pin
->table_id
;
2979 if (protocol
== OFPUTIL_P_OF13_OXM
) {
2980 opi
->cookie
= pin
->cookie
;
2982 } else if (packet_in_format
== NXPIF_OPENFLOW10
) {
2983 struct ofp10_packet_in
*opi
;
2985 packet
= ofpraw_alloc_xid(OFPRAW_OFPT10_PACKET_IN
, OFP10_VERSION
,
2986 htonl(0), pin
->packet_len
);
2987 opi
= ofpbuf_put_zeros(packet
, offsetof(struct ofp10_packet_in
, data
));
2988 opi
->total_len
= htons(pin
->total_len
);
2989 opi
->in_port
= htons(ofp_to_u16(pin
->fmd
.in_port
));
2990 opi
->reason
= pin
->reason
;
2991 opi
->buffer_id
= htonl(pin
->buffer_id
);
2993 ofpbuf_put(packet
, pin
->packet
, pin
->packet_len
);
2994 } else if (packet_in_format
== NXPIF_NXM
) {
2995 struct nx_packet_in
*npi
;
2999 ofputil_packet_in_to_match(pin
, &match
);
3001 /* The final argument is just an estimate of the space required. */
3002 packet
= ofpraw_alloc_xid(OFPRAW_NXT_PACKET_IN
, OFP10_VERSION
,
3003 htonl(0), (sizeof(struct flow_metadata
) * 2
3004 + 2 + pin
->packet_len
));
3005 ofpbuf_put_zeros(packet
, sizeof *npi
);
3006 match_len
= nx_put_match(packet
, &match
, 0, 0);
3007 ofpbuf_put_zeros(packet
, 2);
3008 ofpbuf_put(packet
, pin
->packet
, pin
->packet_len
);
3011 npi
->buffer_id
= htonl(pin
->buffer_id
);
3012 npi
->total_len
= htons(pin
->total_len
);
3013 npi
->reason
= pin
->reason
;
3014 npi
->table_id
= pin
->table_id
;
3015 npi
->cookie
= pin
->cookie
;
3016 npi
->match_len
= htons(match_len
);
3020 ofpmsg_update_length(packet
);
3025 /* Returns a string form of 'reason'. The return value is either a statically
3026 * allocated constant string or the 'bufsize'-byte buffer 'reasonbuf'.
3027 * 'bufsize' should be at least OFPUTIL_PACKET_IN_REASON_BUFSIZE. */
3029 ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason reason
,
3030 char *reasonbuf
, size_t bufsize
)
3037 case OFPR_INVALID_TTL
:
3038 return "invalid_ttl";
3040 case OFPR_N_REASONS
:
3042 snprintf(reasonbuf
, bufsize
, "%d", (int) reason
);
3048 ofputil_packet_in_reason_from_string(const char *s
,
3049 enum ofp_packet_in_reason
*reason
)
3053 for (i
= 0; i
< OFPR_N_REASONS
; i
++) {
3054 char reasonbuf
[OFPUTIL_PACKET_IN_REASON_BUFSIZE
];
3055 const char *reason_s
;
3057 reason_s
= ofputil_packet_in_reason_to_string(i
, reasonbuf
,
3059 if (!strcasecmp(s
, reason_s
)) {
3067 /* Converts an OFPT_PACKET_OUT in 'opo' into an abstract ofputil_packet_out in
3070 * Uses 'ofpacts' to store the abstract OFPACT_* version of the packet out
3071 * message's actions. The caller must initialize 'ofpacts' and retains
3072 * ownership of it. 'po->ofpacts' will point into the 'ofpacts' buffer.
3074 * Returns 0 if successful, otherwise an OFPERR_* value. */
3076 ofputil_decode_packet_out(struct ofputil_packet_out
*po
,
3077 const struct ofp_header
*oh
,
3078 struct ofpbuf
*ofpacts
)
3083 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
3084 raw
= ofpraw_pull_assert(&b
);
3086 if (raw
== OFPRAW_OFPT11_PACKET_OUT
) {
3088 const struct ofp11_packet_out
*opo
= ofpbuf_pull(&b
, sizeof *opo
);
3090 po
->buffer_id
= ntohl(opo
->buffer_id
);
3091 error
= ofputil_port_from_ofp11(opo
->in_port
, &po
->in_port
);
3096 error
= ofpacts_pull_openflow11_actions(&b
, oh
->version
,
3097 ntohs(opo
->actions_len
),
3102 } else if (raw
== OFPRAW_OFPT10_PACKET_OUT
) {
3104 const struct ofp10_packet_out
*opo
= ofpbuf_pull(&b
, sizeof *opo
);
3106 po
->buffer_id
= ntohl(opo
->buffer_id
);
3107 po
->in_port
= u16_to_ofp(ntohs(opo
->in_port
));
3109 error
= ofpacts_pull_openflow10(&b
, ntohs(opo
->actions_len
), ofpacts
);
3117 if (ofp_to_u16(po
->in_port
) >= ofp_to_u16(OFPP_MAX
)
3118 && po
->in_port
!= OFPP_LOCAL
3119 && po
->in_port
!= OFPP_NONE
&& po
->in_port
!= OFPP_CONTROLLER
) {
3120 VLOG_WARN_RL(&bad_ofmsg_rl
, "packet-out has bad input port %#"PRIx16
,
3122 return OFPERR_OFPBRC_BAD_PORT
;
3125 po
->ofpacts
= ofpacts
->data
;
3126 po
->ofpacts_len
= ofpacts
->size
;
3128 if (po
->buffer_id
== UINT32_MAX
) {
3129 po
->packet
= b
.data
;
3130 po
->packet_len
= b
.size
;
3139 /* ofputil_phy_port */
3141 /* NETDEV_F_* to and from OFPPF_* and OFPPF10_*. */
3142 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_HD
== OFPPF_10MB_HD
); /* bit 0 */
3143 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_FD
== OFPPF_10MB_FD
); /* bit 1 */
3144 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_HD
== OFPPF_100MB_HD
); /* bit 2 */
3145 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_FD
== OFPPF_100MB_FD
); /* bit 3 */
3146 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_HD
== OFPPF_1GB_HD
); /* bit 4 */
3147 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_FD
== OFPPF_1GB_FD
); /* bit 5 */
3148 BUILD_ASSERT_DECL((int) NETDEV_F_10GB_FD
== OFPPF_10GB_FD
); /* bit 6 */
3150 /* NETDEV_F_ bits 11...15 are OFPPF10_ bits 7...11: */
3151 BUILD_ASSERT_DECL((int) NETDEV_F_COPPER
== (OFPPF10_COPPER
<< 4));
3152 BUILD_ASSERT_DECL((int) NETDEV_F_FIBER
== (OFPPF10_FIBER
<< 4));
3153 BUILD_ASSERT_DECL((int) NETDEV_F_AUTONEG
== (OFPPF10_AUTONEG
<< 4));
3154 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE
== (OFPPF10_PAUSE
<< 4));
3155 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE_ASYM
== (OFPPF10_PAUSE_ASYM
<< 4));
3157 static enum netdev_features
3158 netdev_port_features_from_ofp10(ovs_be32 ofp10_
)
3160 uint32_t ofp10
= ntohl(ofp10_
);
3161 return (ofp10
& 0x7f) | ((ofp10
& 0xf80) << 4);
3165 netdev_port_features_to_ofp10(enum netdev_features features
)
3167 return htonl((features
& 0x7f) | ((features
& 0xf800) >> 4));
3170 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_HD
== OFPPF_10MB_HD
); /* bit 0 */
3171 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_FD
== OFPPF_10MB_FD
); /* bit 1 */
3172 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_HD
== OFPPF_100MB_HD
); /* bit 2 */
3173 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_FD
== OFPPF_100MB_FD
); /* bit 3 */
3174 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_HD
== OFPPF_1GB_HD
); /* bit 4 */
3175 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_FD
== OFPPF_1GB_FD
); /* bit 5 */
3176 BUILD_ASSERT_DECL((int) NETDEV_F_10GB_FD
== OFPPF_10GB_FD
); /* bit 6 */
3177 BUILD_ASSERT_DECL((int) NETDEV_F_40GB_FD
== OFPPF11_40GB_FD
); /* bit 7 */
3178 BUILD_ASSERT_DECL((int) NETDEV_F_100GB_FD
== OFPPF11_100GB_FD
); /* bit 8 */
3179 BUILD_ASSERT_DECL((int) NETDEV_F_1TB_FD
== OFPPF11_1TB_FD
); /* bit 9 */
3180 BUILD_ASSERT_DECL((int) NETDEV_F_OTHER
== OFPPF11_OTHER
); /* bit 10 */
3181 BUILD_ASSERT_DECL((int) NETDEV_F_COPPER
== OFPPF11_COPPER
); /* bit 11 */
3182 BUILD_ASSERT_DECL((int) NETDEV_F_FIBER
== OFPPF11_FIBER
); /* bit 12 */
3183 BUILD_ASSERT_DECL((int) NETDEV_F_AUTONEG
== OFPPF11_AUTONEG
); /* bit 13 */
3184 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE
== OFPPF11_PAUSE
); /* bit 14 */
3185 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE_ASYM
== OFPPF11_PAUSE_ASYM
);/* bit 15 */
3187 static enum netdev_features
3188 netdev_port_features_from_ofp11(ovs_be32 ofp11
)
3190 return ntohl(ofp11
) & 0xffff;
3194 netdev_port_features_to_ofp11(enum netdev_features features
)
3196 return htonl(features
& 0xffff);
3200 ofputil_decode_ofp10_phy_port(struct ofputil_phy_port
*pp
,
3201 const struct ofp10_phy_port
*opp
)
3203 memset(pp
, 0, sizeof *pp
);
3205 pp
->port_no
= u16_to_ofp(ntohs(opp
->port_no
));
3206 memcpy(pp
->hw_addr
, opp
->hw_addr
, OFP_ETH_ALEN
);
3207 ovs_strlcpy(pp
->name
, opp
->name
, OFP_MAX_PORT_NAME_LEN
);
3209 pp
->config
= ntohl(opp
->config
) & OFPPC10_ALL
;
3210 pp
->state
= ntohl(opp
->state
) & OFPPS10_ALL
;
3212 pp
->curr
= netdev_port_features_from_ofp10(opp
->curr
);
3213 pp
->advertised
= netdev_port_features_from_ofp10(opp
->advertised
);
3214 pp
->supported
= netdev_port_features_from_ofp10(opp
->supported
);
3215 pp
->peer
= netdev_port_features_from_ofp10(opp
->peer
);
3217 pp
->curr_speed
= netdev_features_to_bps(pp
->curr
, 0) / 1000;
3218 pp
->max_speed
= netdev_features_to_bps(pp
->supported
, 0) / 1000;
3224 ofputil_decode_ofp11_port(struct ofputil_phy_port
*pp
,
3225 const struct ofp11_port
*op
)
3229 memset(pp
, 0, sizeof *pp
);
3231 error
= ofputil_port_from_ofp11(op
->port_no
, &pp
->port_no
);
3235 memcpy(pp
->hw_addr
, op
->hw_addr
, OFP_ETH_ALEN
);
3236 ovs_strlcpy(pp
->name
, op
->name
, OFP_MAX_PORT_NAME_LEN
);
3238 pp
->config
= ntohl(op
->config
) & OFPPC11_ALL
;
3239 pp
->state
= ntohl(op
->state
) & OFPPC11_ALL
;
3241 pp
->curr
= netdev_port_features_from_ofp11(op
->curr
);
3242 pp
->advertised
= netdev_port_features_from_ofp11(op
->advertised
);
3243 pp
->supported
= netdev_port_features_from_ofp11(op
->supported
);
3244 pp
->peer
= netdev_port_features_from_ofp11(op
->peer
);
3246 pp
->curr_speed
= ntohl(op
->curr_speed
);
3247 pp
->max_speed
= ntohl(op
->max_speed
);
3253 ofputil_get_phy_port_size(enum ofp_version ofp_version
)
3255 switch (ofp_version
) {
3257 return sizeof(struct ofp10_phy_port
);
3261 return sizeof(struct ofp11_port
);
3268 ofputil_encode_ofp10_phy_port(const struct ofputil_phy_port
*pp
,
3269 struct ofp10_phy_port
*opp
)
3271 memset(opp
, 0, sizeof *opp
);
3273 opp
->port_no
= htons(ofp_to_u16(pp
->port_no
));
3274 memcpy(opp
->hw_addr
, pp
->hw_addr
, ETH_ADDR_LEN
);
3275 ovs_strlcpy(opp
->name
, pp
->name
, OFP_MAX_PORT_NAME_LEN
);
3277 opp
->config
= htonl(pp
->config
& OFPPC10_ALL
);
3278 opp
->state
= htonl(pp
->state
& OFPPS10_ALL
);
3280 opp
->curr
= netdev_port_features_to_ofp10(pp
->curr
);
3281 opp
->advertised
= netdev_port_features_to_ofp10(pp
->advertised
);
3282 opp
->supported
= netdev_port_features_to_ofp10(pp
->supported
);
3283 opp
->peer
= netdev_port_features_to_ofp10(pp
->peer
);
3287 ofputil_encode_ofp11_port(const struct ofputil_phy_port
*pp
,
3288 struct ofp11_port
*op
)
3290 memset(op
, 0, sizeof *op
);
3292 op
->port_no
= ofputil_port_to_ofp11(pp
->port_no
);
3293 memcpy(op
->hw_addr
, pp
->hw_addr
, ETH_ADDR_LEN
);
3294 ovs_strlcpy(op
->name
, pp
->name
, OFP_MAX_PORT_NAME_LEN
);
3296 op
->config
= htonl(pp
->config
& OFPPC11_ALL
);
3297 op
->state
= htonl(pp
->state
& OFPPS11_ALL
);
3299 op
->curr
= netdev_port_features_to_ofp11(pp
->curr
);
3300 op
->advertised
= netdev_port_features_to_ofp11(pp
->advertised
);
3301 op
->supported
= netdev_port_features_to_ofp11(pp
->supported
);
3302 op
->peer
= netdev_port_features_to_ofp11(pp
->peer
);
3304 op
->curr_speed
= htonl(pp
->curr_speed
);
3305 op
->max_speed
= htonl(pp
->max_speed
);
3309 ofputil_put_phy_port(enum ofp_version ofp_version
,
3310 const struct ofputil_phy_port
*pp
, struct ofpbuf
*b
)
3312 switch (ofp_version
) {
3313 case OFP10_VERSION
: {
3314 struct ofp10_phy_port
*opp
;
3315 if (b
->size
+ sizeof *opp
<= UINT16_MAX
) {
3316 opp
= ofpbuf_put_uninit(b
, sizeof *opp
);
3317 ofputil_encode_ofp10_phy_port(pp
, opp
);
3324 case OFP13_VERSION
: {
3325 struct ofp11_port
*op
;
3326 if (b
->size
+ sizeof *op
<= UINT16_MAX
) {
3327 op
= ofpbuf_put_uninit(b
, sizeof *op
);
3328 ofputil_encode_ofp11_port(pp
, op
);
3339 ofputil_append_port_desc_stats_reply(enum ofp_version ofp_version
,
3340 const struct ofputil_phy_port
*pp
,
3341 struct list
*replies
)
3343 switch (ofp_version
) {
3344 case OFP10_VERSION
: {
3345 struct ofp10_phy_port
*opp
;
3347 opp
= ofpmp_append(replies
, sizeof *opp
);
3348 ofputil_encode_ofp10_phy_port(pp
, opp
);
3354 case OFP13_VERSION
: {
3355 struct ofp11_port
*op
;
3357 op
= ofpmp_append(replies
, sizeof *op
);
3358 ofputil_encode_ofp11_port(pp
, op
);
3367 /* ofputil_switch_features */
3369 #define OFPC_COMMON (OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \
3370 OFPC_IP_REASM | OFPC_QUEUE_STATS)
3371 BUILD_ASSERT_DECL((int) OFPUTIL_C_FLOW_STATS
== OFPC_FLOW_STATS
);
3372 BUILD_ASSERT_DECL((int) OFPUTIL_C_TABLE_STATS
== OFPC_TABLE_STATS
);
3373 BUILD_ASSERT_DECL((int) OFPUTIL_C_PORT_STATS
== OFPC_PORT_STATS
);
3374 BUILD_ASSERT_DECL((int) OFPUTIL_C_IP_REASM
== OFPC_IP_REASM
);
3375 BUILD_ASSERT_DECL((int) OFPUTIL_C_QUEUE_STATS
== OFPC_QUEUE_STATS
);
3376 BUILD_ASSERT_DECL((int) OFPUTIL_C_ARP_MATCH_IP
== OFPC_ARP_MATCH_IP
);
3378 struct ofputil_action_bit_translation
{
3379 enum ofputil_action_bitmap ofputil_bit
;
3383 static const struct ofputil_action_bit_translation of10_action_bits
[] = {
3384 { OFPUTIL_A_OUTPUT
, OFPAT10_OUTPUT
},
3385 { OFPUTIL_A_SET_VLAN_VID
, OFPAT10_SET_VLAN_VID
},
3386 { OFPUTIL_A_SET_VLAN_PCP
, OFPAT10_SET_VLAN_PCP
},
3387 { OFPUTIL_A_STRIP_VLAN
, OFPAT10_STRIP_VLAN
},
3388 { OFPUTIL_A_SET_DL_SRC
, OFPAT10_SET_DL_SRC
},
3389 { OFPUTIL_A_SET_DL_DST
, OFPAT10_SET_DL_DST
},
3390 { OFPUTIL_A_SET_NW_SRC
, OFPAT10_SET_NW_SRC
},
3391 { OFPUTIL_A_SET_NW_DST
, OFPAT10_SET_NW_DST
},
3392 { OFPUTIL_A_SET_NW_TOS
, OFPAT10_SET_NW_TOS
},
3393 { OFPUTIL_A_SET_TP_SRC
, OFPAT10_SET_TP_SRC
},
3394 { OFPUTIL_A_SET_TP_DST
, OFPAT10_SET_TP_DST
},
3395 { OFPUTIL_A_ENQUEUE
, OFPAT10_ENQUEUE
},
3399 static enum ofputil_action_bitmap
3400 decode_action_bits(ovs_be32 of_actions
,
3401 const struct ofputil_action_bit_translation
*x
)
3403 enum ofputil_action_bitmap ofputil_actions
;
3405 ofputil_actions
= 0;
3406 for (; x
->ofputil_bit
; x
++) {
3407 if (of_actions
& htonl(1u << x
->of_bit
)) {
3408 ofputil_actions
|= x
->ofputil_bit
;
3411 return ofputil_actions
;
3415 ofputil_capabilities_mask(enum ofp_version ofp_version
)
3417 /* Handle capabilities whose bit is unique for all Open Flow versions */
3418 switch (ofp_version
) {
3421 return OFPC_COMMON
| OFPC_ARP_MATCH_IP
;
3424 return OFPC_COMMON
| OFPC12_PORT_BLOCKED
;
3426 /* Caller needs to check osf->header.version itself */
3431 /* Decodes an OpenFlow 1.0 or 1.1 "switch_features" structure 'osf' into an
3432 * abstract representation in '*features'. Initializes '*b' to iterate over
3433 * the OpenFlow port structures following 'osf' with later calls to
3434 * ofputil_pull_phy_port(). Returns 0 if successful, otherwise an
3435 * OFPERR_* value. */
3437 ofputil_decode_switch_features(const struct ofp_header
*oh
,
3438 struct ofputil_switch_features
*features
,
3441 const struct ofp_switch_features
*osf
;
3444 ofpbuf_use_const(b
, oh
, ntohs(oh
->length
));
3445 raw
= ofpraw_pull_assert(b
);
3447 osf
= ofpbuf_pull(b
, sizeof *osf
);
3448 features
->datapath_id
= ntohll(osf
->datapath_id
);
3449 features
->n_buffers
= ntohl(osf
->n_buffers
);
3450 features
->n_tables
= osf
->n_tables
;
3451 features
->auxiliary_id
= 0;
3453 features
->capabilities
= ntohl(osf
->capabilities
) &
3454 ofputil_capabilities_mask(oh
->version
);
3456 if (b
->size
% ofputil_get_phy_port_size(oh
->version
)) {
3457 return OFPERR_OFPBRC_BAD_LEN
;
3460 if (raw
== OFPRAW_OFPT10_FEATURES_REPLY
) {
3461 if (osf
->capabilities
& htonl(OFPC10_STP
)) {
3462 features
->capabilities
|= OFPUTIL_C_STP
;
3464 features
->actions
= decode_action_bits(osf
->actions
, of10_action_bits
);
3465 } else if (raw
== OFPRAW_OFPT11_FEATURES_REPLY
3466 || raw
== OFPRAW_OFPT13_FEATURES_REPLY
) {
3467 if (osf
->capabilities
& htonl(OFPC11_GROUP_STATS
)) {
3468 features
->capabilities
|= OFPUTIL_C_GROUP_STATS
;
3470 features
->actions
= 0;
3471 if (raw
== OFPRAW_OFPT13_FEATURES_REPLY
) {
3472 features
->auxiliary_id
= osf
->auxiliary_id
;
3475 return OFPERR_OFPBRC_BAD_VERSION
;
3481 /* Returns true if the maximum number of ports are in 'oh'. */
3483 max_ports_in_features(const struct ofp_header
*oh
)
3485 size_t pp_size
= ofputil_get_phy_port_size(oh
->version
);
3486 return ntohs(oh
->length
) + pp_size
> UINT16_MAX
;
3489 /* Given a buffer 'b' that contains a Features Reply message, checks if
3490 * it contains the maximum number of ports that will fit. If so, it
3491 * returns true and removes the ports from the message. The caller
3492 * should then send an OFPST_PORT_DESC stats request to get the ports,
3493 * since the switch may have more ports than could be represented in the
3494 * Features Reply. Otherwise, returns false.
3497 ofputil_switch_features_ports_trunc(struct ofpbuf
*b
)
3499 struct ofp_header
*oh
= b
->data
;
3501 if (max_ports_in_features(oh
)) {
3502 /* Remove all the ports. */
3503 b
->size
= (sizeof(struct ofp_header
)
3504 + sizeof(struct ofp_switch_features
));
3505 ofpmsg_update_length(b
);
3514 encode_action_bits(enum ofputil_action_bitmap ofputil_actions
,
3515 const struct ofputil_action_bit_translation
*x
)
3517 uint32_t of_actions
;
3520 for (; x
->ofputil_bit
; x
++) {
3521 if (ofputil_actions
& x
->ofputil_bit
) {
3522 of_actions
|= 1 << x
->of_bit
;
3525 return htonl(of_actions
);
3528 /* Returns a buffer owned by the caller that encodes 'features' in the format
3529 * required by 'protocol' with the given 'xid'. The caller should append port
3530 * information to the buffer with subsequent calls to
3531 * ofputil_put_switch_features_port(). */
3533 ofputil_encode_switch_features(const struct ofputil_switch_features
*features
,
3534 enum ofputil_protocol protocol
, ovs_be32 xid
)
3536 struct ofp_switch_features
*osf
;
3538 enum ofp_version version
;
3541 version
= ofputil_protocol_to_ofp_version(protocol
);
3544 raw
= OFPRAW_OFPT10_FEATURES_REPLY
;
3548 raw
= OFPRAW_OFPT11_FEATURES_REPLY
;
3551 raw
= OFPRAW_OFPT13_FEATURES_REPLY
;
3556 b
= ofpraw_alloc_xid(raw
, version
, xid
, 0);
3557 osf
= ofpbuf_put_zeros(b
, sizeof *osf
);
3558 osf
->datapath_id
= htonll(features
->datapath_id
);
3559 osf
->n_buffers
= htonl(features
->n_buffers
);
3560 osf
->n_tables
= features
->n_tables
;
3562 osf
->capabilities
= htonl(features
->capabilities
& OFPC_COMMON
);
3563 osf
->capabilities
= htonl(features
->capabilities
&
3564 ofputil_capabilities_mask(version
));
3567 if (features
->capabilities
& OFPUTIL_C_STP
) {
3568 osf
->capabilities
|= htonl(OFPC10_STP
);
3570 osf
->actions
= encode_action_bits(features
->actions
, of10_action_bits
);
3573 osf
->auxiliary_id
= features
->auxiliary_id
;
3577 if (features
->capabilities
& OFPUTIL_C_GROUP_STATS
) {
3578 osf
->capabilities
|= htonl(OFPC11_GROUP_STATS
);
3588 /* Encodes 'pp' into the format required by the switch_features message already
3589 * in 'b', which should have been returned by ofputil_encode_switch_features(),
3590 * and appends the encoded version to 'b'. */
3592 ofputil_put_switch_features_port(const struct ofputil_phy_port
*pp
,
3595 const struct ofp_header
*oh
= b
->data
;
3597 if (oh
->version
< OFP13_VERSION
) {
3598 ofputil_put_phy_port(oh
->version
, pp
, b
);
3602 /* ofputil_port_status */
3604 /* Decodes the OpenFlow "port status" message in '*ops' into an abstract form
3605 * in '*ps'. Returns 0 if successful, otherwise an OFPERR_* value. */
3607 ofputil_decode_port_status(const struct ofp_header
*oh
,
3608 struct ofputil_port_status
*ps
)
3610 const struct ofp_port_status
*ops
;
3614 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
3615 ofpraw_pull_assert(&b
);
3616 ops
= ofpbuf_pull(&b
, sizeof *ops
);
3618 if (ops
->reason
!= OFPPR_ADD
&&
3619 ops
->reason
!= OFPPR_DELETE
&&
3620 ops
->reason
!= OFPPR_MODIFY
) {
3621 return OFPERR_NXBRC_BAD_REASON
;
3623 ps
->reason
= ops
->reason
;
3625 retval
= ofputil_pull_phy_port(oh
->version
, &b
, &ps
->desc
);
3626 ovs_assert(retval
!= EOF
);
3630 /* Converts the abstract form of a "port status" message in '*ps' into an
3631 * OpenFlow message suitable for 'protocol', and returns that encoded form in
3632 * a buffer owned by the caller. */
3634 ofputil_encode_port_status(const struct ofputil_port_status
*ps
,
3635 enum ofputil_protocol protocol
)
3637 struct ofp_port_status
*ops
;
3639 enum ofp_version version
;
3642 version
= ofputil_protocol_to_ofp_version(protocol
);
3645 raw
= OFPRAW_OFPT10_PORT_STATUS
;
3651 raw
= OFPRAW_OFPT11_PORT_STATUS
;
3658 b
= ofpraw_alloc_xid(raw
, version
, htonl(0), 0);
3659 ops
= ofpbuf_put_zeros(b
, sizeof *ops
);
3660 ops
->reason
= ps
->reason
;
3661 ofputil_put_phy_port(version
, &ps
->desc
, b
);
3662 ofpmsg_update_length(b
);
3666 /* ofputil_port_mod */
3668 /* Decodes the OpenFlow "port mod" message in '*oh' into an abstract form in
3669 * '*pm'. Returns 0 if successful, otherwise an OFPERR_* value. */
3671 ofputil_decode_port_mod(const struct ofp_header
*oh
,
3672 struct ofputil_port_mod
*pm
)
3677 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
3678 raw
= ofpraw_pull_assert(&b
);
3680 if (raw
== OFPRAW_OFPT10_PORT_MOD
) {
3681 const struct ofp10_port_mod
*opm
= b
.data
;
3683 pm
->port_no
= u16_to_ofp(ntohs(opm
->port_no
));
3684 memcpy(pm
->hw_addr
, opm
->hw_addr
, ETH_ADDR_LEN
);
3685 pm
->config
= ntohl(opm
->config
) & OFPPC10_ALL
;
3686 pm
->mask
= ntohl(opm
->mask
) & OFPPC10_ALL
;
3687 pm
->advertise
= netdev_port_features_from_ofp10(opm
->advertise
);
3688 } else if (raw
== OFPRAW_OFPT11_PORT_MOD
) {
3689 const struct ofp11_port_mod
*opm
= b
.data
;
3692 error
= ofputil_port_from_ofp11(opm
->port_no
, &pm
->port_no
);
3697 memcpy(pm
->hw_addr
, opm
->hw_addr
, ETH_ADDR_LEN
);
3698 pm
->config
= ntohl(opm
->config
) & OFPPC11_ALL
;
3699 pm
->mask
= ntohl(opm
->mask
) & OFPPC11_ALL
;
3700 pm
->advertise
= netdev_port_features_from_ofp11(opm
->advertise
);
3702 return OFPERR_OFPBRC_BAD_TYPE
;
3705 pm
->config
&= pm
->mask
;
3709 /* Converts the abstract form of a "port mod" message in '*pm' into an OpenFlow
3710 * message suitable for 'protocol', and returns that encoded form in a buffer
3711 * owned by the caller. */
3713 ofputil_encode_port_mod(const struct ofputil_port_mod
*pm
,
3714 enum ofputil_protocol protocol
)
3716 enum ofp_version ofp_version
= ofputil_protocol_to_ofp_version(protocol
);
3719 switch (ofp_version
) {
3720 case OFP10_VERSION
: {
3721 struct ofp10_port_mod
*opm
;
3723 b
= ofpraw_alloc(OFPRAW_OFPT10_PORT_MOD
, ofp_version
, 0);
3724 opm
= ofpbuf_put_zeros(b
, sizeof *opm
);
3725 opm
->port_no
= htons(ofp_to_u16(pm
->port_no
));
3726 memcpy(opm
->hw_addr
, pm
->hw_addr
, ETH_ADDR_LEN
);
3727 opm
->config
= htonl(pm
->config
& OFPPC10_ALL
);
3728 opm
->mask
= htonl(pm
->mask
& OFPPC10_ALL
);
3729 opm
->advertise
= netdev_port_features_to_ofp10(pm
->advertise
);
3735 case OFP13_VERSION
: {
3736 struct ofp11_port_mod
*opm
;
3738 b
= ofpraw_alloc(OFPRAW_OFPT11_PORT_MOD
, ofp_version
, 0);
3739 opm
= ofpbuf_put_zeros(b
, sizeof *opm
);
3740 opm
->port_no
= ofputil_port_to_ofp11(pm
->port_no
);
3741 memcpy(opm
->hw_addr
, pm
->hw_addr
, ETH_ADDR_LEN
);
3742 opm
->config
= htonl(pm
->config
& OFPPC11_ALL
);
3743 opm
->mask
= htonl(pm
->mask
& OFPPC11_ALL
);
3744 opm
->advertise
= netdev_port_features_to_ofp11(pm
->advertise
);
3754 /* ofputil_table_mod */
3756 /* Decodes the OpenFlow "table mod" message in '*oh' into an abstract form in
3757 * '*pm'. Returns 0 if successful, otherwise an OFPERR_* value. */
3759 ofputil_decode_table_mod(const struct ofp_header
*oh
,
3760 struct ofputil_table_mod
*pm
)
3765 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
3766 raw
= ofpraw_pull_assert(&b
);
3768 if (raw
== OFPRAW_OFPT11_TABLE_MOD
) {
3769 const struct ofp11_table_mod
*otm
= b
.data
;
3771 pm
->table_id
= otm
->table_id
;
3772 pm
->config
= ntohl(otm
->config
);
3774 return OFPERR_OFPBRC_BAD_TYPE
;
3780 /* Converts the abstract form of a "table mod" message in '*pm' into an OpenFlow
3781 * message suitable for 'protocol', and returns that encoded form in a buffer
3782 * owned by the caller. */
3784 ofputil_encode_table_mod(const struct ofputil_table_mod
*pm
,
3785 enum ofputil_protocol protocol
)
3787 enum ofp_version ofp_version
= ofputil_protocol_to_ofp_version(protocol
);
3790 switch (ofp_version
) {
3791 case OFP10_VERSION
: {
3792 ovs_fatal(0, "table mod needs OpenFlow 1.1 or later "
3793 "(\'-O OpenFlow11\')");
3798 case OFP13_VERSION
: {
3799 struct ofp11_table_mod
*otm
;
3801 b
= ofpraw_alloc(OFPRAW_OFPT11_TABLE_MOD
, ofp_version
, 0);
3802 otm
= ofpbuf_put_zeros(b
, sizeof *otm
);
3803 otm
->table_id
= pm
->table_id
;
3804 otm
->config
= htonl(pm
->config
);
3814 /* ofputil_role_request */
3816 /* Decodes the OpenFlow "role request" or "role reply" message in '*oh' into
3817 * an abstract form in '*rr'. Returns 0 if successful, otherwise an
3818 * OFPERR_* value. */
3820 ofputil_decode_role_message(const struct ofp_header
*oh
,
3821 struct ofputil_role_request
*rr
)
3826 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
3827 raw
= ofpraw_pull_assert(&b
);
3829 if (raw
== OFPRAW_OFPT12_ROLE_REQUEST
||
3830 raw
== OFPRAW_OFPT12_ROLE_REPLY
) {
3831 const struct ofp12_role_request
*orr
= b
.l3
;
3833 if (orr
->role
!= htonl(OFPCR12_ROLE_NOCHANGE
) &&
3834 orr
->role
!= htonl(OFPCR12_ROLE_EQUAL
) &&
3835 orr
->role
!= htonl(OFPCR12_ROLE_MASTER
) &&
3836 orr
->role
!= htonl(OFPCR12_ROLE_SLAVE
)) {
3837 return OFPERR_OFPRRFC_BAD_ROLE
;
3840 rr
->role
= ntohl(orr
->role
);
3841 if (raw
== OFPRAW_OFPT12_ROLE_REQUEST
3842 ? orr
->role
== htonl(OFPCR12_ROLE_NOCHANGE
)
3843 : orr
->generation_id
== OVS_BE64_MAX
) {
3844 rr
->have_generation_id
= false;
3845 rr
->generation_id
= 0;
3847 rr
->have_generation_id
= true;
3848 rr
->generation_id
= ntohll(orr
->generation_id
);
3850 } else if (raw
== OFPRAW_NXT_ROLE_REQUEST
||
3851 raw
== OFPRAW_NXT_ROLE_REPLY
) {
3852 const struct nx_role_request
*nrr
= b
.l3
;
3854 BUILD_ASSERT(NX_ROLE_OTHER
+ 1 == OFPCR12_ROLE_EQUAL
);
3855 BUILD_ASSERT(NX_ROLE_MASTER
+ 1 == OFPCR12_ROLE_MASTER
);
3856 BUILD_ASSERT(NX_ROLE_SLAVE
+ 1 == OFPCR12_ROLE_SLAVE
);
3858 if (nrr
->role
!= htonl(NX_ROLE_OTHER
) &&
3859 nrr
->role
!= htonl(NX_ROLE_MASTER
) &&
3860 nrr
->role
!= htonl(NX_ROLE_SLAVE
)) {
3861 return OFPERR_OFPRRFC_BAD_ROLE
;
3864 rr
->role
= ntohl(nrr
->role
) + 1;
3865 rr
->have_generation_id
= false;
3866 rr
->generation_id
= 0;
3874 /* Returns an encoded form of a role reply suitable for the "request" in a
3875 * buffer owned by the caller. */
3877 ofputil_encode_role_reply(const struct ofp_header
*request
,
3878 const struct ofputil_role_request
*rr
)
3883 raw
= ofpraw_decode_assert(request
);
3884 if (raw
== OFPRAW_OFPT12_ROLE_REQUEST
) {
3885 struct ofp12_role_request
*orr
;
3887 buf
= ofpraw_alloc_reply(OFPRAW_OFPT12_ROLE_REPLY
, request
, 0);
3888 orr
= ofpbuf_put_zeros(buf
, sizeof *orr
);
3890 orr
->role
= htonl(rr
->role
);
3891 orr
->generation_id
= htonll(rr
->have_generation_id
3894 } else if (raw
== OFPRAW_NXT_ROLE_REQUEST
) {
3895 struct nx_role_request
*nrr
;
3897 BUILD_ASSERT(NX_ROLE_OTHER
== OFPCR12_ROLE_EQUAL
- 1);
3898 BUILD_ASSERT(NX_ROLE_MASTER
== OFPCR12_ROLE_MASTER
- 1);
3899 BUILD_ASSERT(NX_ROLE_SLAVE
== OFPCR12_ROLE_SLAVE
- 1);
3901 buf
= ofpraw_alloc_reply(OFPRAW_NXT_ROLE_REPLY
, request
, 0);
3902 nrr
= ofpbuf_put_zeros(buf
, sizeof *nrr
);
3903 nrr
->role
= htonl(rr
->role
- 1);
3914 ofputil_put_ofp10_table_stats(const struct ofp12_table_stats
*in
,
3918 enum ofp10_flow_wildcards wc10
;
3919 enum oxm12_ofb_match_fields mf12
;
3922 static const struct wc_map wc_map
[] = {
3923 { OFPFW10_IN_PORT
, OFPXMT12_OFB_IN_PORT
},
3924 { OFPFW10_DL_VLAN
, OFPXMT12_OFB_VLAN_VID
},
3925 { OFPFW10_DL_SRC
, OFPXMT12_OFB_ETH_SRC
},
3926 { OFPFW10_DL_DST
, OFPXMT12_OFB_ETH_DST
},
3927 { OFPFW10_DL_TYPE
, OFPXMT12_OFB_ETH_TYPE
},
3928 { OFPFW10_NW_PROTO
, OFPXMT12_OFB_IP_PROTO
},
3929 { OFPFW10_TP_SRC
, OFPXMT12_OFB_TCP_SRC
},
3930 { OFPFW10_TP_DST
, OFPXMT12_OFB_TCP_DST
},
3931 { OFPFW10_NW_SRC_MASK
, OFPXMT12_OFB_IPV4_SRC
},
3932 { OFPFW10_NW_DST_MASK
, OFPXMT12_OFB_IPV4_DST
},
3933 { OFPFW10_DL_VLAN_PCP
, OFPXMT12_OFB_VLAN_PCP
},
3934 { OFPFW10_NW_TOS
, OFPXMT12_OFB_IP_DSCP
},
3937 struct ofp10_table_stats
*out
;
3938 const struct wc_map
*p
;
3940 out
= ofpbuf_put_zeros(buf
, sizeof *out
);
3941 out
->table_id
= in
->table_id
;
3942 ovs_strlcpy(out
->name
, in
->name
, sizeof out
->name
);
3944 for (p
= wc_map
; p
< &wc_map
[ARRAY_SIZE(wc_map
)]; p
++) {
3945 if (in
->wildcards
& htonll(1ULL << p
->mf12
)) {
3946 out
->wildcards
|= htonl(p
->wc10
);
3949 out
->max_entries
= in
->max_entries
;
3950 out
->active_count
= in
->active_count
;
3951 put_32aligned_be64(&out
->lookup_count
, in
->lookup_count
);
3952 put_32aligned_be64(&out
->matched_count
, in
->matched_count
);
3956 oxm12_to_ofp11_flow_match_fields(ovs_be64 oxm12
)
3959 enum ofp11_flow_match_fields fmf11
;
3960 enum oxm12_ofb_match_fields mf12
;
3963 static const struct map map
[] = {
3964 { OFPFMF11_IN_PORT
, OFPXMT12_OFB_IN_PORT
},
3965 { OFPFMF11_DL_VLAN
, OFPXMT12_OFB_VLAN_VID
},
3966 { OFPFMF11_DL_VLAN_PCP
, OFPXMT12_OFB_VLAN_PCP
},
3967 { OFPFMF11_DL_TYPE
, OFPXMT12_OFB_ETH_TYPE
},
3968 { OFPFMF11_NW_TOS
, OFPXMT12_OFB_IP_DSCP
},
3969 { OFPFMF11_NW_PROTO
, OFPXMT12_OFB_IP_PROTO
},
3970 { OFPFMF11_TP_SRC
, OFPXMT12_OFB_TCP_SRC
},
3971 { OFPFMF11_TP_DST
, OFPXMT12_OFB_TCP_DST
},
3972 { OFPFMF11_MPLS_LABEL
, OFPXMT12_OFB_MPLS_LABEL
},
3973 { OFPFMF11_MPLS_TC
, OFPXMT12_OFB_MPLS_TC
},
3974 /* I don't know what OFPFMF11_TYPE means. */
3975 { OFPFMF11_DL_SRC
, OFPXMT12_OFB_ETH_SRC
},
3976 { OFPFMF11_DL_DST
, OFPXMT12_OFB_ETH_DST
},
3977 { OFPFMF11_NW_SRC
, OFPXMT12_OFB_IPV4_SRC
},
3978 { OFPFMF11_NW_DST
, OFPXMT12_OFB_IPV4_DST
},
3979 { OFPFMF11_METADATA
, OFPXMT12_OFB_METADATA
},
3982 const struct map
*p
;
3986 for (p
= map
; p
< &map
[ARRAY_SIZE(map
)]; p
++) {
3987 if (oxm12
& htonll(1ULL << p
->mf12
)) {
3991 return htonl(fmf11
);
3995 ofputil_put_ofp11_table_stats(const struct ofp12_table_stats
*in
,
3998 struct ofp11_table_stats
*out
;
4000 out
= ofpbuf_put_zeros(buf
, sizeof *out
);
4001 out
->table_id
= in
->table_id
;
4002 ovs_strlcpy(out
->name
, in
->name
, sizeof out
->name
);
4003 out
->wildcards
= oxm12_to_ofp11_flow_match_fields(in
->wildcards
);
4004 out
->match
= oxm12_to_ofp11_flow_match_fields(in
->match
);
4005 out
->instructions
= in
->instructions
;
4006 out
->write_actions
= in
->write_actions
;
4007 out
->apply_actions
= in
->apply_actions
;
4008 out
->config
= in
->config
;
4009 out
->max_entries
= in
->max_entries
;
4010 out
->active_count
= in
->active_count
;
4011 out
->lookup_count
= in
->lookup_count
;
4012 out
->matched_count
= in
->matched_count
;
4016 ofputil_put_ofp12_table_stats(const struct ofp12_table_stats
*in
,
4019 struct ofp12_table_stats
*out
= ofpbuf_put(buf
, in
, sizeof *in
);
4021 /* Trim off OF1.3-only capabilities. */
4022 out
->match
&= htonll(OFPXMT12_MASK
);
4023 out
->wildcards
&= htonll(OFPXMT12_MASK
);
4024 out
->write_setfields
&= htonll(OFPXMT12_MASK
);
4025 out
->apply_setfields
&= htonll(OFPXMT12_MASK
);
4029 ofputil_put_ofp13_table_stats(const struct ofp12_table_stats
*in
,
4032 struct ofp13_table_stats
*out
;
4034 /* OF 1.3 splits table features off the ofp_table_stats,
4035 * so there is not much here. */
4037 out
= ofpbuf_put_uninit(buf
, sizeof *out
);
4038 out
->table_id
= in
->table_id
;
4039 out
->active_count
= in
->active_count
;
4040 out
->lookup_count
= in
->lookup_count
;
4041 out
->matched_count
= in
->matched_count
;
4045 ofputil_encode_table_stats_reply(const struct ofp12_table_stats stats
[], int n
,
4046 const struct ofp_header
*request
)
4048 struct ofpbuf
*reply
;
4051 reply
= ofpraw_alloc_stats_reply(request
, n
* sizeof *stats
);
4053 for (i
= 0; i
< n
; i
++) {
4054 switch ((enum ofp_version
) request
->version
) {
4056 ofputil_put_ofp10_table_stats(&stats
[i
], reply
);
4060 ofputil_put_ofp11_table_stats(&stats
[i
], reply
);
4064 ofputil_put_ofp12_table_stats(&stats
[i
], reply
);
4068 ofputil_put_ofp13_table_stats(&stats
[i
], reply
);
4079 /* ofputil_flow_monitor_request */
4081 /* Converts an NXST_FLOW_MONITOR request in 'msg' into an abstract
4082 * ofputil_flow_monitor_request in 'rq'.
4084 * Multiple NXST_FLOW_MONITOR requests can be packed into a single OpenFlow
4085 * message. Calling this function multiple times for a single 'msg' iterates
4086 * through the requests. The caller must initially leave 'msg''s layer
4087 * pointers null and not modify them between calls.
4089 * Returns 0 if successful, EOF if no requests were left in this 'msg',
4090 * otherwise an OFPERR_* value. */
4092 ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request
*rq
,
4095 struct nx_flow_monitor_request
*nfmr
;
4099 msg
->l2
= msg
->data
;
4100 ofpraw_pull_assert(msg
);
4107 nfmr
= ofpbuf_try_pull(msg
, sizeof *nfmr
);
4109 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW_MONITOR request has %zu "
4110 "leftover bytes at end", msg
->size
);
4111 return OFPERR_OFPBRC_BAD_LEN
;
4114 flags
= ntohs(nfmr
->flags
);
4115 if (!(flags
& (NXFMF_ADD
| NXFMF_DELETE
| NXFMF_MODIFY
))
4116 || flags
& ~(NXFMF_INITIAL
| NXFMF_ADD
| NXFMF_DELETE
4117 | NXFMF_MODIFY
| NXFMF_ACTIONS
| NXFMF_OWN
)) {
4118 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW_MONITOR has bad flags %#"PRIx16
,
4120 return OFPERR_NXBRC_FM_BAD_FLAGS
;
4123 if (!is_all_zeros(nfmr
->zeros
, sizeof nfmr
->zeros
)) {
4124 return OFPERR_NXBRC_MUST_BE_ZERO
;
4127 rq
->id
= ntohl(nfmr
->id
);
4129 rq
->out_port
= u16_to_ofp(ntohs(nfmr
->out_port
));
4130 rq
->table_id
= nfmr
->table_id
;
4132 return nx_pull_match(msg
, ntohs(nfmr
->match_len
), &rq
->match
, NULL
, NULL
);
4136 ofputil_append_flow_monitor_request(
4137 const struct ofputil_flow_monitor_request
*rq
, struct ofpbuf
*msg
)
4139 struct nx_flow_monitor_request
*nfmr
;
4144 ofpraw_put(OFPRAW_NXST_FLOW_MONITOR_REQUEST
, OFP10_VERSION
, msg
);
4147 start_ofs
= msg
->size
;
4148 ofpbuf_put_zeros(msg
, sizeof *nfmr
);
4149 match_len
= nx_put_match(msg
, &rq
->match
, htonll(0), htonll(0));
4151 nfmr
= ofpbuf_at_assert(msg
, start_ofs
, sizeof *nfmr
);
4152 nfmr
->id
= htonl(rq
->id
);
4153 nfmr
->flags
= htons(rq
->flags
);
4154 nfmr
->out_port
= htons(ofp_to_u16(rq
->out_port
));
4155 nfmr
->match_len
= htons(match_len
);
4156 nfmr
->table_id
= rq
->table_id
;
4159 /* Converts an NXST_FLOW_MONITOR reply (also known as a flow update) in 'msg'
4160 * into an abstract ofputil_flow_update in 'update'. The caller must have
4161 * initialized update->match to point to space allocated for a match.
4163 * Uses 'ofpacts' to store the abstract OFPACT_* version of the update's
4164 * actions (except for NXFME_ABBREV, which never includes actions). The caller
4165 * must initialize 'ofpacts' and retains ownership of it. 'update->ofpacts'
4166 * will point into the 'ofpacts' buffer.
4168 * Multiple flow updates can be packed into a single OpenFlow message. Calling
4169 * this function multiple times for a single 'msg' iterates through the
4170 * updates. The caller must initially leave 'msg''s layer pointers null and
4171 * not modify them between calls.
4173 * Returns 0 if successful, EOF if no updates were left in this 'msg',
4174 * otherwise an OFPERR_* value. */
4176 ofputil_decode_flow_update(struct ofputil_flow_update
*update
,
4177 struct ofpbuf
*msg
, struct ofpbuf
*ofpacts
)
4179 struct nx_flow_update_header
*nfuh
;
4180 unsigned int length
;
4183 msg
->l2
= msg
->data
;
4184 ofpraw_pull_assert(msg
);
4191 if (msg
->size
< sizeof(struct nx_flow_update_header
)) {
4196 update
->event
= ntohs(nfuh
->event
);
4197 length
= ntohs(nfuh
->length
);
4198 if (length
> msg
->size
|| length
% 8) {
4202 if (update
->event
== NXFME_ABBREV
) {
4203 struct nx_flow_update_abbrev
*nfua
;
4205 if (length
!= sizeof *nfua
) {
4209 nfua
= ofpbuf_pull(msg
, sizeof *nfua
);
4210 update
->xid
= nfua
->xid
;
4212 } else if (update
->event
== NXFME_ADDED
4213 || update
->event
== NXFME_DELETED
4214 || update
->event
== NXFME_MODIFIED
) {
4215 struct nx_flow_update_full
*nfuf
;
4216 unsigned int actions_len
;
4217 unsigned int match_len
;
4220 if (length
< sizeof *nfuf
) {
4224 nfuf
= ofpbuf_pull(msg
, sizeof *nfuf
);
4225 match_len
= ntohs(nfuf
->match_len
);
4226 if (sizeof *nfuf
+ match_len
> length
) {
4230 update
->reason
= ntohs(nfuf
->reason
);
4231 update
->idle_timeout
= ntohs(nfuf
->idle_timeout
);
4232 update
->hard_timeout
= ntohs(nfuf
->hard_timeout
);
4233 update
->table_id
= nfuf
->table_id
;
4234 update
->cookie
= nfuf
->cookie
;
4235 update
->priority
= ntohs(nfuf
->priority
);
4237 error
= nx_pull_match(msg
, match_len
, update
->match
, NULL
, NULL
);
4242 actions_len
= length
- sizeof *nfuf
- ROUND_UP(match_len
, 8);
4243 error
= ofpacts_pull_openflow10(msg
, actions_len
, ofpacts
);
4248 update
->ofpacts
= ofpacts
->data
;
4249 update
->ofpacts_len
= ofpacts
->size
;
4252 VLOG_WARN_RL(&bad_ofmsg_rl
,
4253 "NXST_FLOW_MONITOR reply has bad event %"PRIu16
,
4254 ntohs(nfuh
->event
));
4255 return OFPERR_NXBRC_FM_BAD_EVENT
;
4259 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW_MONITOR reply has %zu "
4260 "leftover bytes at end", msg
->size
);
4261 return OFPERR_OFPBRC_BAD_LEN
;
4265 ofputil_decode_flow_monitor_cancel(const struct ofp_header
*oh
)
4267 const struct nx_flow_monitor_cancel
*cancel
= ofpmsg_body(oh
);
4269 return ntohl(cancel
->id
);
4273 ofputil_encode_flow_monitor_cancel(uint32_t id
)
4275 struct nx_flow_monitor_cancel
*nfmc
;
4278 msg
= ofpraw_alloc(OFPRAW_NXT_FLOW_MONITOR_CANCEL
, OFP10_VERSION
, 0);
4279 nfmc
= ofpbuf_put_uninit(msg
, sizeof *nfmc
);
4280 nfmc
->id
= htonl(id
);
4285 ofputil_start_flow_update(struct list
*replies
)
4289 msg
= ofpraw_alloc_xid(OFPRAW_NXST_FLOW_MONITOR_REPLY
, OFP10_VERSION
,
4293 list_push_back(replies
, &msg
->list_node
);
4297 ofputil_append_flow_update(const struct ofputil_flow_update
*update
,
4298 struct list
*replies
)
4300 struct nx_flow_update_header
*nfuh
;
4304 msg
= ofpbuf_from_list(list_back(replies
));
4305 start_ofs
= msg
->size
;
4307 if (update
->event
== NXFME_ABBREV
) {
4308 struct nx_flow_update_abbrev
*nfua
;
4310 nfua
= ofpbuf_put_zeros(msg
, sizeof *nfua
);
4311 nfua
->xid
= update
->xid
;
4313 struct nx_flow_update_full
*nfuf
;
4316 ofpbuf_put_zeros(msg
, sizeof *nfuf
);
4317 match_len
= nx_put_match(msg
, update
->match
, htonll(0), htonll(0));
4318 ofpacts_put_openflow10(update
->ofpacts
, update
->ofpacts_len
, msg
);
4320 nfuf
= ofpbuf_at_assert(msg
, start_ofs
, sizeof *nfuf
);
4321 nfuf
->reason
= htons(update
->reason
);
4322 nfuf
->priority
= htons(update
->priority
);
4323 nfuf
->idle_timeout
= htons(update
->idle_timeout
);
4324 nfuf
->hard_timeout
= htons(update
->hard_timeout
);
4325 nfuf
->match_len
= htons(match_len
);
4326 nfuf
->table_id
= update
->table_id
;
4327 nfuf
->cookie
= update
->cookie
;
4330 nfuh
= ofpbuf_at_assert(msg
, start_ofs
, sizeof *nfuh
);
4331 nfuh
->length
= htons(msg
->size
- start_ofs
);
4332 nfuh
->event
= htons(update
->event
);
4334 ofpmp_postappend(replies
, start_ofs
);
4338 ofputil_encode_packet_out(const struct ofputil_packet_out
*po
,
4339 enum ofputil_protocol protocol
)
4341 enum ofp_version ofp_version
= ofputil_protocol_to_ofp_version(protocol
);
4345 size
= po
->ofpacts_len
;
4346 if (po
->buffer_id
== UINT32_MAX
) {
4347 size
+= po
->packet_len
;
4350 switch (ofp_version
) {
4351 case OFP10_VERSION
: {
4352 struct ofp10_packet_out
*opo
;
4355 msg
= ofpraw_alloc(OFPRAW_OFPT10_PACKET_OUT
, OFP10_VERSION
, size
);
4356 ofpbuf_put_zeros(msg
, sizeof *opo
);
4357 actions_ofs
= msg
->size
;
4358 ofpacts_put_openflow10(po
->ofpacts
, po
->ofpacts_len
, msg
);
4361 opo
->buffer_id
= htonl(po
->buffer_id
);
4362 opo
->in_port
= htons(ofp_to_u16(po
->in_port
));
4363 opo
->actions_len
= htons(msg
->size
- actions_ofs
);
4369 case OFP13_VERSION
: {
4370 struct ofp11_packet_out
*opo
;
4373 msg
= ofpraw_alloc(OFPRAW_OFPT11_PACKET_OUT
, ofp_version
, size
);
4374 ofpbuf_put_zeros(msg
, sizeof *opo
);
4375 len
= ofpacts_put_openflow11_actions(po
->ofpacts
, po
->ofpacts_len
, msg
);
4378 opo
->buffer_id
= htonl(po
->buffer_id
);
4379 opo
->in_port
= ofputil_port_to_ofp11(po
->in_port
);
4380 opo
->actions_len
= htons(len
);
4388 if (po
->buffer_id
== UINT32_MAX
) {
4389 ofpbuf_put(msg
, po
->packet
, po
->packet_len
);
4392 ofpmsg_update_length(msg
);
4397 /* Creates and returns an OFPT_ECHO_REQUEST message with an empty payload. */
4399 make_echo_request(enum ofp_version ofp_version
)
4401 return ofpraw_alloc_xid(OFPRAW_OFPT_ECHO_REQUEST
, ofp_version
,
4405 /* Creates and returns an OFPT_ECHO_REPLY message matching the
4406 * OFPT_ECHO_REQUEST message in 'rq'. */
4408 make_echo_reply(const struct ofp_header
*rq
)
4410 struct ofpbuf rq_buf
;
4411 struct ofpbuf
*reply
;
4413 ofpbuf_use_const(&rq_buf
, rq
, ntohs(rq
->length
));
4414 ofpraw_pull_assert(&rq_buf
);
4416 reply
= ofpraw_alloc_reply(OFPRAW_OFPT_ECHO_REPLY
, rq
, rq_buf
.size
);
4417 ofpbuf_put(reply
, rq_buf
.data
, rq_buf
.size
);
4422 ofputil_encode_barrier_request(enum ofp_version ofp_version
)
4426 switch (ofp_version
) {
4430 type
= OFPRAW_OFPT11_BARRIER_REQUEST
;
4434 type
= OFPRAW_OFPT10_BARRIER_REQUEST
;
4441 return ofpraw_alloc(type
, ofp_version
, 0);
4445 ofputil_frag_handling_to_string(enum ofp_config_flags flags
)
4447 switch (flags
& OFPC_FRAG_MASK
) {
4448 case OFPC_FRAG_NORMAL
: return "normal";
4449 case OFPC_FRAG_DROP
: return "drop";
4450 case OFPC_FRAG_REASM
: return "reassemble";
4451 case OFPC_FRAG_NX_MATCH
: return "nx-match";
4458 ofputil_frag_handling_from_string(const char *s
, enum ofp_config_flags
*flags
)
4460 if (!strcasecmp(s
, "normal")) {
4461 *flags
= OFPC_FRAG_NORMAL
;
4462 } else if (!strcasecmp(s
, "drop")) {
4463 *flags
= OFPC_FRAG_DROP
;
4464 } else if (!strcasecmp(s
, "reassemble")) {
4465 *flags
= OFPC_FRAG_REASM
;
4466 } else if (!strcasecmp(s
, "nx-match")) {
4467 *flags
= OFPC_FRAG_NX_MATCH
;
4474 /* Converts the OpenFlow 1.1+ port number 'ofp11_port' into an OpenFlow 1.0
4475 * port number and stores the latter in '*ofp10_port', for the purpose of
4476 * decoding OpenFlow 1.1+ protocol messages. Returns 0 if successful,
4477 * otherwise an OFPERR_* number. On error, stores OFPP_NONE in '*ofp10_port'.
4479 * See the definition of OFP11_MAX for an explanation of the mapping. */
4481 ofputil_port_from_ofp11(ovs_be32 ofp11_port
, ofp_port_t
*ofp10_port
)
4483 uint32_t ofp11_port_h
= ntohl(ofp11_port
);
4485 if (ofp11_port_h
< ofp_to_u16(OFPP_MAX
)) {
4486 *ofp10_port
= u16_to_ofp(ofp11_port_h
);
4488 } else if (ofp11_port_h
>= ofp11_to_u32(OFPP11_MAX
)) {
4489 *ofp10_port
= u16_to_ofp(ofp11_port_h
- OFPP11_OFFSET
);
4492 *ofp10_port
= OFPP_NONE
;
4493 VLOG_WARN_RL(&bad_ofmsg_rl
, "port %"PRIu32
" is outside the supported "
4494 "range 0 through %d or 0x%"PRIx32
" through 0x%"PRIx32
,
4495 ofp11_port_h
, ofp_to_u16(OFPP_MAX
) - 1,
4496 ofp11_to_u32(OFPP11_MAX
), UINT32_MAX
);
4497 return OFPERR_OFPBAC_BAD_OUT_PORT
;
4501 /* Returns the OpenFlow 1.1+ port number equivalent to the OpenFlow 1.0 port
4502 * number 'ofp10_port', for encoding OpenFlow 1.1+ protocol messages.
4504 * See the definition of OFP11_MAX for an explanation of the mapping. */
4506 ofputil_port_to_ofp11(ofp_port_t ofp10_port
)
4508 return htonl(ofp_to_u16(ofp10_port
) < ofp_to_u16(OFPP_MAX
)
4509 ? ofp_to_u16(ofp10_port
)
4510 : ofp_to_u16(ofp10_port
) + OFPP11_OFFSET
);
4513 /* Checks that 'port' is a valid output port for the OFPAT10_OUTPUT action, given
4514 * that the switch will never have more than 'max_ports' ports. Returns 0 if
4515 * 'port' is valid, otherwise an OpenFlow return code. */
4517 ofputil_check_output_port(ofp_port_t port
, ofp_port_t max_ports
)
4525 case OFPP_CONTROLLER
:
4531 if (ofp_to_u16(port
) < ofp_to_u16(max_ports
)) {
4534 return OFPERR_OFPBAC_BAD_OUT_PORT
;
4538 #define OFPUTIL_NAMED_PORTS \
4539 OFPUTIL_NAMED_PORT(IN_PORT) \
4540 OFPUTIL_NAMED_PORT(TABLE) \
4541 OFPUTIL_NAMED_PORT(NORMAL) \
4542 OFPUTIL_NAMED_PORT(FLOOD) \
4543 OFPUTIL_NAMED_PORT(ALL) \
4544 OFPUTIL_NAMED_PORT(CONTROLLER) \
4545 OFPUTIL_NAMED_PORT(LOCAL) \
4546 OFPUTIL_NAMED_PORT(ANY)
4548 /* For backwards compatibility, so that "none" is recognized as OFPP_ANY */
4549 #define OFPUTIL_NAMED_PORTS_WITH_NONE \
4550 OFPUTIL_NAMED_PORTS \
4551 OFPUTIL_NAMED_PORT(NONE)
4553 /* Stores the port number represented by 's' into '*portp'. 's' may be an
4554 * integer or, for reserved ports, the standard OpenFlow name for the port
4557 * Returns true if successful, false if 's' is not a valid OpenFlow port number
4558 * or name. The caller should issue an error message in this case, because
4559 * this function usually does not. (This gives the caller an opportunity to
4560 * look up the port name another way, e.g. by contacting the switch and listing
4561 * the names of all its ports).
4563 * This function accepts OpenFlow 1.0 port numbers. It also accepts a subset
4564 * of OpenFlow 1.1+ port numbers, mapping those port numbers into the 16-bit
4565 * range as described in include/openflow/openflow-1.1.h. */
4567 ofputil_port_from_string(const char *s
, ofp_port_t
*portp
)
4572 if (str_to_uint(s
, 10, &port32
)) {
4573 if (port32
< ofp_to_u16(OFPP_MAX
)) {
4575 } else if (port32
< ofp_to_u16(OFPP_FIRST_RESV
)) {
4576 VLOG_WARN("port %u is a reserved OF1.0 port number that will "
4577 "be translated to %u when talking to an OF1.1 or "
4578 "later controller", port32
, port32
+ OFPP11_OFFSET
);
4579 } else if (port32
<= ofp_to_u16(OFPP_LAST_RESV
)) {
4580 char name
[OFP_MAX_PORT_NAME_LEN
];
4582 ofputil_port_to_string(u16_to_ofp(port32
), name
, sizeof name
);
4583 VLOG_WARN_ONCE("referring to port %s as %"PRIu32
" is deprecated "
4584 "for compatibility with OpenFlow 1.1 and later",
4586 } else if (port32
< ofp11_to_u32(OFPP11_MAX
)) {
4587 VLOG_WARN("port %u is outside the supported range 0 through "
4588 "%"PRIx16
" or 0x%x through 0x%"PRIx32
, port32
,
4589 UINT16_MAX
, ofp11_to_u32(OFPP11_MAX
), UINT32_MAX
);
4592 port32
-= OFPP11_OFFSET
;
4595 *portp
= u16_to_ofp(port32
);
4602 static const struct pair pairs
[] = {
4603 #define OFPUTIL_NAMED_PORT(NAME) {#NAME, OFPP_##NAME},
4604 OFPUTIL_NAMED_PORTS_WITH_NONE
4605 #undef OFPUTIL_NAMED_PORT
4607 const struct pair
*p
;
4609 for (p
= pairs
; p
< &pairs
[ARRAY_SIZE(pairs
)]; p
++) {
4610 if (!strcasecmp(s
, p
->name
)) {
4619 /* Appends to 's' a string representation of the OpenFlow port number 'port'.
4620 * Most ports' string representation is just the port number, but for special
4621 * ports, e.g. OFPP_LOCAL, it is the name, e.g. "LOCAL". */
4623 ofputil_format_port(ofp_port_t port
, struct ds
*s
)
4625 char name
[OFP_MAX_PORT_NAME_LEN
];
4627 ofputil_port_to_string(port
, name
, sizeof name
);
4628 ds_put_cstr(s
, name
);
4631 /* Puts in the 'bufsize' byte in 'namebuf' a null-terminated string
4632 * representation of OpenFlow port number 'port'. Most ports are represented
4633 * as just the port number, but special ports, e.g. OFPP_LOCAL, are represented
4634 * by name, e.g. "LOCAL". */
4636 ofputil_port_to_string(ofp_port_t port
,
4637 char namebuf
[OFP_MAX_PORT_NAME_LEN
], size_t bufsize
)
4640 #define OFPUTIL_NAMED_PORT(NAME) \
4642 ovs_strlcpy(namebuf, #NAME, bufsize); \
4645 #undef OFPUTIL_NAMED_PORT
4648 snprintf(namebuf
, bufsize
, "%"PRIu16
, port
);
4653 /* Stores the group id represented by 's' into '*group_idp'. 's' may be an
4654 * integer or, for reserved group IDs, the standard OpenFlow name for the group
4655 * (either "ANY" or "ALL").
4657 * Returns true if successful, false if 's' is not a valid OpenFlow group ID or
4660 ofputil_group_from_string(const char *s
, uint32_t *group_idp
)
4662 if (!strcasecmp(s
, "any")) {
4663 *group_idp
= OFPG11_ANY
;
4664 } else if (!strcasecmp(s
, "all")) {
4665 *group_idp
= OFPG11_ALL
;
4666 } else if (!str_to_uint(s
, 10, group_idp
)) {
4667 VLOG_WARN("%s is not a valid group ID. (Valid group IDs are "
4668 "32-bit nonnegative integers or the keywords ANY or "
4676 /* Appends to 's' a string representation of the OpenFlow group ID 'group_id'.
4677 * Most groups' string representation is just the number, but for special
4678 * groups, e.g. OFPG11_ALL, it is the name, e.g. "ALL". */
4680 ofputil_format_group(uint32_t group_id
, struct ds
*s
)
4682 char name
[MAX_GROUP_NAME_LEN
];
4684 ofputil_group_to_string(group_id
, name
, sizeof name
);
4685 ds_put_cstr(s
, name
);
4689 /* Puts in the 'bufsize' byte in 'namebuf' a null-terminated string
4690 * representation of OpenFlow group ID 'group_id'. Most group are represented
4691 * as just their number, but special groups, e.g. OFPG11_ALL, are represented
4692 * by name, e.g. "ALL". */
4694 ofputil_group_to_string(uint32_t group_id
,
4695 char namebuf
[MAX_GROUP_NAME_LEN
+ 1], size_t bufsize
)
4699 ovs_strlcpy(namebuf
, "ALL", bufsize
);
4703 ovs_strlcpy(namebuf
, "ANY", bufsize
);
4707 snprintf(namebuf
, bufsize
, "%"PRIu32
, group_id
);
4712 /* Given a buffer 'b' that contains an array of OpenFlow ports of type
4713 * 'ofp_version', tries to pull the first element from the array. If
4714 * successful, initializes '*pp' with an abstract representation of the
4715 * port and returns 0. If no ports remain to be decoded, returns EOF.
4716 * On an error, returns a positive OFPERR_* value. */
4718 ofputil_pull_phy_port(enum ofp_version ofp_version
, struct ofpbuf
*b
,
4719 struct ofputil_phy_port
*pp
)
4721 switch (ofp_version
) {
4722 case OFP10_VERSION
: {
4723 const struct ofp10_phy_port
*opp
= ofpbuf_try_pull(b
, sizeof *opp
);
4724 return opp
? ofputil_decode_ofp10_phy_port(pp
, opp
) : EOF
;
4728 case OFP13_VERSION
: {
4729 const struct ofp11_port
*op
= ofpbuf_try_pull(b
, sizeof *op
);
4730 return op
? ofputil_decode_ofp11_port(pp
, op
) : EOF
;
4737 /* Given a buffer 'b' that contains an array of OpenFlow ports of type
4738 * 'ofp_version', returns the number of elements. */
4739 size_t ofputil_count_phy_ports(uint8_t ofp_version
, struct ofpbuf
*b
)
4741 return b
->size
/ ofputil_get_phy_port_size(ofp_version
);
4744 /* Returns the 'enum ofputil_action_code' corresponding to 'name' (e.g. if
4745 * 'name' is "output" then the return value is OFPUTIL_OFPAT10_OUTPUT), or -1 if
4746 * 'name' is not the name of any action.
4748 * ofp-util.def lists the mapping from names to action. */
4750 ofputil_action_code_from_name(const char *name
)
4752 static const char *const names
[OFPUTIL_N_ACTIONS
] = {
4754 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) NAME,
4755 #define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
4756 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
4757 #include "ofp-util.def"
4760 const char *const *p
;
4762 for (p
= names
; p
< &names
[ARRAY_SIZE(names
)]; p
++) {
4763 if (*p
&& !strcasecmp(name
, *p
)) {
4770 /* Appends an action of the type specified by 'code' to 'buf' and returns the
4771 * action. Initializes the parts of 'action' that identify it as having type
4772 * <ENUM> and length 'sizeof *action' and zeros the rest. For actions that
4773 * have variable length, the length used and cleared is that of struct
4776 ofputil_put_action(enum ofputil_action_code code
, struct ofpbuf
*buf
)
4779 case OFPUTIL_ACTION_INVALID
:
4782 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
4783 case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
4784 #define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
4785 case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
4786 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
4787 case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
4788 #include "ofp-util.def"
4793 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
4795 ofputil_init_##ENUM(struct STRUCT *s) \
4797 memset(s, 0, sizeof *s); \
4798 s->type = htons(ENUM); \
4799 s->len = htons(sizeof *s); \
4803 ofputil_put_##ENUM(struct ofpbuf *buf) \
4805 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
4806 ofputil_init_##ENUM(s); \
4809 #define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
4810 OFPAT10_ACTION(ENUM, STRUCT, NAME)
4811 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
4813 ofputil_init_##ENUM(struct STRUCT *s) \
4815 memset(s, 0, sizeof *s); \
4816 s->type = htons(OFPAT10_VENDOR); \
4817 s->len = htons(sizeof *s); \
4818 s->vendor = htonl(NX_VENDOR_ID); \
4819 s->subtype = htons(ENUM); \
4823 ofputil_put_##ENUM(struct ofpbuf *buf) \
4825 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
4826 ofputil_init_##ENUM(s); \
4829 #include "ofp-util.def"
4832 ofputil_normalize_match__(struct match
*match
, bool may_log
)
4835 MAY_NW_ADDR
= 1 << 0, /* nw_src, nw_dst */
4836 MAY_TP_ADDR
= 1 << 1, /* tp_src, tp_dst */
4837 MAY_NW_PROTO
= 1 << 2, /* nw_proto */
4838 MAY_IPVx
= 1 << 3, /* tos, frag, ttl */
4839 MAY_ARP_SHA
= 1 << 4, /* arp_sha */
4840 MAY_ARP_THA
= 1 << 5, /* arp_tha */
4841 MAY_IPV6
= 1 << 6, /* ipv6_src, ipv6_dst, ipv6_label */
4842 MAY_ND_TARGET
= 1 << 7, /* nd_target */
4843 MAY_MPLS
= 1 << 8, /* mpls label and tc */
4846 struct flow_wildcards wc
;
4848 /* Figure out what fields may be matched. */
4849 if (match
->flow
.dl_type
== htons(ETH_TYPE_IP
)) {
4850 may_match
= MAY_NW_PROTO
| MAY_IPVx
| MAY_NW_ADDR
;
4851 if (match
->flow
.nw_proto
== IPPROTO_TCP
||
4852 match
->flow
.nw_proto
== IPPROTO_UDP
||
4853 match
->flow
.nw_proto
== IPPROTO_SCTP
||
4854 match
->flow
.nw_proto
== IPPROTO_ICMP
) {
4855 may_match
|= MAY_TP_ADDR
;
4857 } else if (match
->flow
.dl_type
== htons(ETH_TYPE_IPV6
)) {
4858 may_match
= MAY_NW_PROTO
| MAY_IPVx
| MAY_IPV6
;
4859 if (match
->flow
.nw_proto
== IPPROTO_TCP
||
4860 match
->flow
.nw_proto
== IPPROTO_UDP
||
4861 match
->flow
.nw_proto
== IPPROTO_SCTP
) {
4862 may_match
|= MAY_TP_ADDR
;
4863 } else if (match
->flow
.nw_proto
== IPPROTO_ICMPV6
) {
4864 may_match
|= MAY_TP_ADDR
;
4865 if (match
->flow
.tp_src
== htons(ND_NEIGHBOR_SOLICIT
)) {
4866 may_match
|= MAY_ND_TARGET
| MAY_ARP_SHA
;
4867 } else if (match
->flow
.tp_src
== htons(ND_NEIGHBOR_ADVERT
)) {
4868 may_match
|= MAY_ND_TARGET
| MAY_ARP_THA
;
4871 } else if (match
->flow
.dl_type
== htons(ETH_TYPE_ARP
) ||
4872 match
->flow
.dl_type
== htons(ETH_TYPE_RARP
)) {
4873 may_match
= MAY_NW_PROTO
| MAY_NW_ADDR
| MAY_ARP_SHA
| MAY_ARP_THA
;
4874 } else if (eth_type_mpls(match
->flow
.dl_type
)) {
4875 may_match
= MAY_MPLS
;
4880 /* Clear the fields that may not be matched. */
4882 if (!(may_match
& MAY_NW_ADDR
)) {
4883 wc
.masks
.nw_src
= wc
.masks
.nw_dst
= htonl(0);
4885 if (!(may_match
& MAY_TP_ADDR
)) {
4886 wc
.masks
.tp_src
= wc
.masks
.tp_dst
= htons(0);
4888 if (!(may_match
& MAY_NW_PROTO
)) {
4889 wc
.masks
.nw_proto
= 0;
4891 if (!(may_match
& MAY_IPVx
)) {
4892 wc
.masks
.nw_tos
= 0;
4893 wc
.masks
.nw_ttl
= 0;
4895 if (!(may_match
& MAY_ARP_SHA
)) {
4896 memset(wc
.masks
.arp_sha
, 0, ETH_ADDR_LEN
);
4898 if (!(may_match
& MAY_ARP_THA
)) {
4899 memset(wc
.masks
.arp_tha
, 0, ETH_ADDR_LEN
);
4901 if (!(may_match
& MAY_IPV6
)) {
4902 wc
.masks
.ipv6_src
= wc
.masks
.ipv6_dst
= in6addr_any
;
4903 wc
.masks
.ipv6_label
= htonl(0);
4905 if (!(may_match
& MAY_ND_TARGET
)) {
4906 wc
.masks
.nd_target
= in6addr_any
;
4908 if (!(may_match
& MAY_MPLS
)) {
4909 wc
.masks
.mpls_lse
= htonl(0);
4912 /* Log any changes. */
4913 if (!flow_wildcards_equal(&wc
, &match
->wc
)) {
4914 bool log
= may_log
&& !VLOG_DROP_INFO(&bad_ofmsg_rl
);
4915 char *pre
= log
? match_to_string(match
, OFP_DEFAULT_PRIORITY
) : NULL
;
4918 match_zero_wildcarded_fields(match
);
4921 char *post
= match_to_string(match
, OFP_DEFAULT_PRIORITY
);
4922 VLOG_INFO("normalization changed ofp_match, details:");
4923 VLOG_INFO(" pre: %s", pre
);
4924 VLOG_INFO("post: %s", post
);
4931 /* "Normalizes" the wildcards in 'match'. That means:
4933 * 1. If the type of level N is known, then only the valid fields for that
4934 * level may be specified. For example, ARP does not have a TOS field,
4935 * so nw_tos must be wildcarded if 'match' specifies an ARP flow.
4936 * Similarly, IPv4 does not have any IPv6 addresses, so ipv6_src and
4937 * ipv6_dst (and other fields) must be wildcarded if 'match' specifies an
4940 * 2. If the type of level N is not known (or not understood by Open
4941 * vSwitch), then no fields at all for that level may be specified. For
4942 * example, Open vSwitch does not understand SCTP, an L4 protocol, so the
4943 * L4 fields tp_src and tp_dst must be wildcarded if 'match' specifies an
4946 * If this function changes 'match', it logs a rate-limited informational
4949 ofputil_normalize_match(struct match
*match
)
4951 ofputil_normalize_match__(match
, true);
4954 /* Same as ofputil_normalize_match() without the logging. Thus, this function
4955 * is suitable for a program's internal use, whereas ofputil_normalize_match()
4956 * sense for use on flows received from elsewhere (so that a bug in the program
4957 * that sent them can be reported and corrected). */
4959 ofputil_normalize_match_quiet(struct match
*match
)
4961 ofputil_normalize_match__(match
, false);
4964 /* Parses a key or a key-value pair from '*stringp'.
4966 * On success: Stores the key into '*keyp'. Stores the value, if present, into
4967 * '*valuep', otherwise an empty string. Advances '*stringp' past the end of
4968 * the key-value pair, preparing it for another call. '*keyp' and '*valuep'
4969 * are substrings of '*stringp' created by replacing some of its bytes by null
4970 * terminators. Returns true.
4972 * If '*stringp' is just white space or commas, sets '*keyp' and '*valuep' to
4973 * NULL and returns false. */
4975 ofputil_parse_key_value(char **stringp
, char **keyp
, char **valuep
)
4977 char *pos
, *key
, *value
;
4981 pos
+= strspn(pos
, ", \t\r\n");
4983 *keyp
= *valuep
= NULL
;
4988 key_len
= strcspn(pos
, ":=(, \t\r\n");
4989 if (key
[key_len
] == ':' || key
[key_len
] == '=') {
4990 /* The value can be separated by a colon. */
4993 value
= key
+ key_len
+ 1;
4994 value_len
= strcspn(value
, ", \t\r\n");
4995 pos
= value
+ value_len
+ (value
[value_len
] != '\0');
4996 value
[value_len
] = '\0';
4997 } else if (key
[key_len
] == '(') {
4998 /* The value can be surrounded by balanced parentheses. The outermost
4999 * set of parentheses is removed. */
5003 value
= key
+ key_len
+ 1;
5004 for (value_len
= 0; level
> 0; value_len
++) {
5005 switch (value
[value_len
]) {
5019 value
[value_len
- 1] = '\0';
5020 pos
= value
+ value_len
;
5022 /* There might be no value at all. */
5023 value
= key
+ key_len
; /* Will become the empty string below. */
5024 pos
= key
+ key_len
+ (key
[key_len
] != '\0');
5026 key
[key_len
] = '\0';
5034 /* Encode a dump ports request for 'port', the encoded message
5035 * will be for Open Flow version 'ofp_version'. Returns message
5036 * as a struct ofpbuf. Returns encoded message on success, NULL on error */
5038 ofputil_encode_dump_ports_request(enum ofp_version ofp_version
, ofp_port_t port
)
5040 struct ofpbuf
*request
;
5042 switch (ofp_version
) {
5043 case OFP10_VERSION
: {
5044 struct ofp10_port_stats_request
*req
;
5045 request
= ofpraw_alloc(OFPRAW_OFPST10_PORT_REQUEST
, ofp_version
, 0);
5046 req
= ofpbuf_put_zeros(request
, sizeof *req
);
5047 req
->port_no
= htons(ofp_to_u16(port
));
5052 case OFP13_VERSION
: {
5053 struct ofp11_port_stats_request
*req
;
5054 request
= ofpraw_alloc(OFPRAW_OFPST11_PORT_REQUEST
, ofp_version
, 0);
5055 req
= ofpbuf_put_zeros(request
, sizeof *req
);
5056 req
->port_no
= ofputil_port_to_ofp11(port
);
5067 ofputil_port_stats_to_ofp10(const struct ofputil_port_stats
*ops
,
5068 struct ofp10_port_stats
*ps10
)
5070 ps10
->port_no
= htons(ofp_to_u16(ops
->port_no
));
5071 memset(ps10
->pad
, 0, sizeof ps10
->pad
);
5072 put_32aligned_be64(&ps10
->rx_packets
, htonll(ops
->stats
.rx_packets
));
5073 put_32aligned_be64(&ps10
->tx_packets
, htonll(ops
->stats
.tx_packets
));
5074 put_32aligned_be64(&ps10
->rx_bytes
, htonll(ops
->stats
.rx_bytes
));
5075 put_32aligned_be64(&ps10
->tx_bytes
, htonll(ops
->stats
.tx_bytes
));
5076 put_32aligned_be64(&ps10
->rx_dropped
, htonll(ops
->stats
.rx_dropped
));
5077 put_32aligned_be64(&ps10
->tx_dropped
, htonll(ops
->stats
.tx_dropped
));
5078 put_32aligned_be64(&ps10
->rx_errors
, htonll(ops
->stats
.rx_errors
));
5079 put_32aligned_be64(&ps10
->tx_errors
, htonll(ops
->stats
.tx_errors
));
5080 put_32aligned_be64(&ps10
->rx_frame_err
, htonll(ops
->stats
.rx_frame_errors
));
5081 put_32aligned_be64(&ps10
->rx_over_err
, htonll(ops
->stats
.rx_over_errors
));
5082 put_32aligned_be64(&ps10
->rx_crc_err
, htonll(ops
->stats
.rx_crc_errors
));
5083 put_32aligned_be64(&ps10
->collisions
, htonll(ops
->stats
.collisions
));
5087 ofputil_port_stats_to_ofp11(const struct ofputil_port_stats
*ops
,
5088 struct ofp11_port_stats
*ps11
)
5090 ps11
->port_no
= ofputil_port_to_ofp11(ops
->port_no
);
5091 memset(ps11
->pad
, 0, sizeof ps11
->pad
);
5092 ps11
->rx_packets
= htonll(ops
->stats
.rx_packets
);
5093 ps11
->tx_packets
= htonll(ops
->stats
.tx_packets
);
5094 ps11
->rx_bytes
= htonll(ops
->stats
.rx_bytes
);
5095 ps11
->tx_bytes
= htonll(ops
->stats
.tx_bytes
);
5096 ps11
->rx_dropped
= htonll(ops
->stats
.rx_dropped
);
5097 ps11
->tx_dropped
= htonll(ops
->stats
.tx_dropped
);
5098 ps11
->rx_errors
= htonll(ops
->stats
.rx_errors
);
5099 ps11
->tx_errors
= htonll(ops
->stats
.tx_errors
);
5100 ps11
->rx_frame_err
= htonll(ops
->stats
.rx_frame_errors
);
5101 ps11
->rx_over_err
= htonll(ops
->stats
.rx_over_errors
);
5102 ps11
->rx_crc_err
= htonll(ops
->stats
.rx_crc_errors
);
5103 ps11
->collisions
= htonll(ops
->stats
.collisions
);
5107 ofputil_port_stats_to_ofp13(const struct ofputil_port_stats
*ops
,
5108 struct ofp13_port_stats
*ps13
)
5110 ofputil_port_stats_to_ofp11(ops
, &ps13
->ps
);
5111 ps13
->duration_sec
= htonl(ops
->duration_sec
);
5112 ps13
->duration_nsec
= htonl(ops
->duration_nsec
);
5116 /* Encode a ports stat for 'ops' and append it to 'replies'. */
5118 ofputil_append_port_stat(struct list
*replies
,
5119 const struct ofputil_port_stats
*ops
)
5121 struct ofpbuf
*msg
= ofpbuf_from_list(list_back(replies
));
5122 struct ofp_header
*oh
= msg
->data
;
5124 switch ((enum ofp_version
)oh
->version
) {
5125 case OFP13_VERSION
: {
5126 struct ofp13_port_stats
*reply
= ofpmp_append(replies
, sizeof *reply
);
5127 ofputil_port_stats_to_ofp13(ops
, reply
);
5131 case OFP11_VERSION
: {
5132 struct ofp11_port_stats
*reply
= ofpmp_append(replies
, sizeof *reply
);
5133 ofputil_port_stats_to_ofp11(ops
, reply
);
5137 case OFP10_VERSION
: {
5138 struct ofp10_port_stats
*reply
= ofpmp_append(replies
, sizeof *reply
);
5139 ofputil_port_stats_to_ofp10(ops
, reply
);
5149 ofputil_port_stats_from_ofp10(struct ofputil_port_stats
*ops
,
5150 const struct ofp10_port_stats
*ps10
)
5152 memset(ops
, 0, sizeof *ops
);
5154 ops
->port_no
= u16_to_ofp(ntohs(ps10
->port_no
));
5155 ops
->stats
.rx_packets
= ntohll(get_32aligned_be64(&ps10
->rx_packets
));
5156 ops
->stats
.tx_packets
= ntohll(get_32aligned_be64(&ps10
->tx_packets
));
5157 ops
->stats
.rx_bytes
= ntohll(get_32aligned_be64(&ps10
->rx_bytes
));
5158 ops
->stats
.tx_bytes
= ntohll(get_32aligned_be64(&ps10
->tx_bytes
));
5159 ops
->stats
.rx_dropped
= ntohll(get_32aligned_be64(&ps10
->rx_dropped
));
5160 ops
->stats
.tx_dropped
= ntohll(get_32aligned_be64(&ps10
->tx_dropped
));
5161 ops
->stats
.rx_errors
= ntohll(get_32aligned_be64(&ps10
->rx_errors
));
5162 ops
->stats
.tx_errors
= ntohll(get_32aligned_be64(&ps10
->tx_errors
));
5163 ops
->stats
.rx_frame_errors
=
5164 ntohll(get_32aligned_be64(&ps10
->rx_frame_err
));
5165 ops
->stats
.rx_over_errors
= ntohll(get_32aligned_be64(&ps10
->rx_over_err
));
5166 ops
->stats
.rx_crc_errors
= ntohll(get_32aligned_be64(&ps10
->rx_crc_err
));
5167 ops
->stats
.collisions
= ntohll(get_32aligned_be64(&ps10
->collisions
));
5168 ops
->duration_sec
= ops
->duration_nsec
= UINT32_MAX
;
5174 ofputil_port_stats_from_ofp11(struct ofputil_port_stats
*ops
,
5175 const struct ofp11_port_stats
*ps11
)
5179 memset(ops
, 0, sizeof *ops
);
5180 error
= ofputil_port_from_ofp11(ps11
->port_no
, &ops
->port_no
);
5185 ops
->stats
.rx_packets
= ntohll(ps11
->rx_packets
);
5186 ops
->stats
.tx_packets
= ntohll(ps11
->tx_packets
);
5187 ops
->stats
.rx_bytes
= ntohll(ps11
->rx_bytes
);
5188 ops
->stats
.tx_bytes
= ntohll(ps11
->tx_bytes
);
5189 ops
->stats
.rx_dropped
= ntohll(ps11
->rx_dropped
);
5190 ops
->stats
.tx_dropped
= ntohll(ps11
->tx_dropped
);
5191 ops
->stats
.rx_errors
= ntohll(ps11
->rx_errors
);
5192 ops
->stats
.tx_errors
= ntohll(ps11
->tx_errors
);
5193 ops
->stats
.rx_frame_errors
= ntohll(ps11
->rx_frame_err
);
5194 ops
->stats
.rx_over_errors
= ntohll(ps11
->rx_over_err
);
5195 ops
->stats
.rx_crc_errors
= ntohll(ps11
->rx_crc_err
);
5196 ops
->stats
.collisions
= ntohll(ps11
->collisions
);
5197 ops
->duration_sec
= ops
->duration_nsec
= UINT32_MAX
;
5203 ofputil_port_stats_from_ofp13(struct ofputil_port_stats
*ops
,
5204 const struct ofp13_port_stats
*ps13
)
5206 enum ofperr error
= ofputil_port_stats_from_ofp11(ops
, &ps13
->ps
);
5208 ops
->duration_sec
= ntohl(ps13
->duration_sec
);
5209 ops
->duration_nsec
= ntohl(ps13
->duration_nsec
);
5215 ofputil_get_port_stats_size(enum ofp_version ofp_version
)
5217 switch (ofp_version
) {
5219 return sizeof(struct ofp10_port_stats
);
5222 return sizeof(struct ofp11_port_stats
);
5224 return sizeof(struct ofp13_port_stats
);
5230 /* Returns the number of port stats elements in OFPTYPE_PORT_STATS_REPLY
5233 ofputil_count_port_stats(const struct ofp_header
*oh
)
5237 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
5238 ofpraw_pull_assert(&b
);
5240 return b
.size
/ ofputil_get_port_stats_size(oh
->version
);
5243 /* Converts an OFPST_PORT_STATS reply in 'msg' into an abstract
5244 * ofputil_port_stats in 'ps'.
5246 * Multiple OFPST_PORT_STATS replies can be packed into a single OpenFlow
5247 * message. Calling this function multiple times for a single 'msg' iterates
5248 * through the replies. The caller must initially leave 'msg''s layer pointers
5249 * null and not modify them between calls.
5251 * Returns 0 if successful, EOF if no replies were left in this 'msg',
5252 * otherwise a positive errno value. */
5254 ofputil_decode_port_stats(struct ofputil_port_stats
*ps
, struct ofpbuf
*msg
)
5260 ? ofpraw_decode(&raw
, msg
->l2
)
5261 : ofpraw_pull(&raw
, msg
));
5268 } else if (raw
== OFPRAW_OFPST13_PORT_REPLY
) {
5269 const struct ofp13_port_stats
*ps13
;
5271 ps13
= ofpbuf_try_pull(msg
, sizeof *ps13
);
5275 return ofputil_port_stats_from_ofp13(ps
, ps13
);
5276 } else if (raw
== OFPRAW_OFPST11_PORT_REPLY
) {
5277 const struct ofp11_port_stats
*ps11
;
5279 ps11
= ofpbuf_try_pull(msg
, sizeof *ps11
);
5283 return ofputil_port_stats_from_ofp11(ps
, ps11
);
5284 } else if (raw
== OFPRAW_OFPST10_PORT_REPLY
) {
5285 const struct ofp10_port_stats
*ps10
;
5287 ps10
= ofpbuf_try_pull(msg
, sizeof *ps10
);
5291 return ofputil_port_stats_from_ofp10(ps
, ps10
);
5297 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_PORT reply has %zu leftover "
5298 "bytes at end", msg
->size
);
5299 return OFPERR_OFPBRC_BAD_LEN
;
5302 /* Parse a port status request message into a 16 bit OpenFlow 1.0
5303 * port number and stores the latter in '*ofp10_port'.
5304 * Returns 0 if successful, otherwise an OFPERR_* number. */
5306 ofputil_decode_port_stats_request(const struct ofp_header
*request
,
5307 ofp_port_t
*ofp10_port
)
5309 switch ((enum ofp_version
)request
->version
) {
5312 case OFP11_VERSION
: {
5313 const struct ofp11_port_stats_request
*psr11
= ofpmsg_body(request
);
5314 return ofputil_port_from_ofp11(psr11
->port_no
, ofp10_port
);
5317 case OFP10_VERSION
: {
5318 const struct ofp10_port_stats_request
*psr10
= ofpmsg_body(request
);
5319 *ofp10_port
= u16_to_ofp(ntohs(psr10
->port_no
));
5328 /* Frees all of the "struct ofputil_bucket"s in the 'buckets' list. */
5330 ofputil_bucket_list_destroy(struct list
*buckets
)
5332 struct ofputil_bucket
*bucket
, *next_bucket
;
5334 LIST_FOR_EACH_SAFE (bucket
, next_bucket
, list_node
, buckets
) {
5335 list_remove(&bucket
->list_node
);
5336 free(bucket
->ofpacts
);
5341 /* Returns an OpenFlow group stats request for OpenFlow version 'ofp_version',
5342 * that requests stats for group 'group_id'. (Use OFPG_ALL to request stats
5345 * Group statistics include packet and byte counts for each group. */
5347 ofputil_encode_group_stats_request(enum ofp_version ofp_version
,
5350 struct ofpbuf
*request
;
5352 switch (ofp_version
) {
5354 ovs_fatal(0, "dump-group-stats needs OpenFlow 1.1 or later "
5355 "(\'-O OpenFlow11\')");
5358 case OFP13_VERSION
: {
5359 struct ofp11_group_stats_request
*req
;
5360 request
= ofpraw_alloc(OFPRAW_OFPST11_GROUP_REQUEST
, ofp_version
, 0);
5361 req
= ofpbuf_put_zeros(request
, sizeof *req
);
5362 req
->group_id
= htonl(group_id
);
5372 /* Returns an OpenFlow group description request for OpenFlow version
5373 * 'ofp_version', that requests stats for group 'group_id'. (Use OFPG_ALL to
5374 * request stats for all groups.)
5376 * Group descriptions include the bucket and action configuration for each
5379 ofputil_encode_group_desc_request(enum ofp_version ofp_version
)
5381 struct ofpbuf
*request
;
5383 switch (ofp_version
) {
5385 ovs_fatal(0, "dump-groups needs OpenFlow 1.1 or later "
5386 "(\'-O OpenFlow11\')");
5389 case OFP13_VERSION
: {
5390 request
= ofpraw_alloc(OFPRAW_OFPST11_GROUP_DESC_REQUEST
, ofp_version
, 0);
5401 ofputil_group_stats_to_ofp11(const struct ofputil_group_stats
*ogs
,
5402 size_t base_len
, struct list
*replies
)
5404 struct ofp11_bucket_counter
*bc11
;
5405 struct ofp11_group_stats
*gs11
;
5409 length
= base_len
+ sizeof(struct ofp11_bucket_counter
) * ogs
->n_buckets
;
5411 gs11
= ofpmp_append(replies
, length
);
5412 memset(gs11
, 0, base_len
);
5413 gs11
->length
= htons(length
);
5414 gs11
->group_id
= htonl(ogs
->group_id
);
5415 gs11
->ref_count
= htonl(ogs
->ref_count
);
5416 gs11
->packet_count
= htonll(ogs
->packet_count
);
5417 gs11
->byte_count
= htonll(ogs
->byte_count
);
5419 bc11
= (void *) (((uint8_t *) gs11
) + base_len
);
5420 for (i
= 0; i
< ogs
->n_buckets
; i
++) {
5421 const struct bucket_counter
*obc
= &ogs
->bucket_stats
[i
];
5423 bc11
[i
].packet_count
= htonll(obc
->packet_count
);
5424 bc11
[i
].byte_count
= htonll(obc
->byte_count
);
5431 ofputil_append_of13_group_stats(const struct ofputil_group_stats
*ogs
,
5432 struct list
*replies
)
5434 struct ofp13_group_stats
*gs13
;
5436 gs13
= ofputil_group_stats_to_ofp11(ogs
, sizeof *gs13
, replies
);
5437 gs13
->duration_sec
= htonl(ogs
->duration_sec
);
5438 gs13
->duration_nsec
= htonl(ogs
->duration_nsec
);
5441 /* Encodes 'ogs' properly for the format of the list of group statistics
5442 * replies already begun in 'replies' and appends it to the list. 'replies'
5443 * must have originally been initialized with ofpmp_init(). */
5445 ofputil_append_group_stats(struct list
*replies
,
5446 const struct ofputil_group_stats
*ogs
)
5448 struct ofpbuf
*msg
= ofpbuf_from_list(list_back(replies
));
5449 struct ofp_header
*oh
= msg
->data
;
5451 switch ((enum ofp_version
)oh
->version
) {
5454 ofputil_group_stats_to_ofp11(ogs
, sizeof(struct ofp11_group_stats
),
5459 ofputil_append_of13_group_stats(ogs
, replies
);
5468 /* Returns an OpenFlow group features request for OpenFlow version
5471 ofputil_encode_group_features_request(enum ofp_version ofp_version
)
5473 struct ofpbuf
*request
= NULL
;
5475 switch (ofp_version
) {
5478 ovs_fatal(0, "dump-group-features needs OpenFlow 1.2 or later "
5479 "(\'-O OpenFlow12\')");
5481 case OFP13_VERSION
: {
5482 request
= ofpraw_alloc(OFPRAW_OFPST12_GROUP_FEATURES_REQUEST
,
5493 /* Returns a OpenFlow message that encodes 'features' properly as a reply to
5494 * group features request 'request'. */
5496 ofputil_encode_group_features_reply(
5497 const struct ofputil_group_features
*features
,
5498 const struct ofp_header
*request
)
5500 struct ofp12_group_features_stats
*ogf
;
5501 struct ofpbuf
*reply
;
5503 reply
= ofpraw_alloc_xid(OFPRAW_OFPST12_GROUP_FEATURES_REPLY
,
5504 request
->version
, request
->xid
, 0);
5505 ogf
= ofpbuf_put_zeros(reply
, sizeof *ogf
);
5506 ogf
->types
= htonl(features
->types
);
5507 ogf
->capabilities
= htonl(features
->capabilities
);
5508 ogf
->max_groups
[0] = htonl(features
->max_groups
[0]);
5509 ogf
->max_groups
[1] = htonl(features
->max_groups
[1]);
5510 ogf
->max_groups
[2] = htonl(features
->max_groups
[2]);
5511 ogf
->max_groups
[3] = htonl(features
->max_groups
[3]);
5512 ogf
->actions
[0] = htonl(features
->actions
[0]);
5513 ogf
->actions
[1] = htonl(features
->actions
[1]);
5514 ogf
->actions
[2] = htonl(features
->actions
[2]);
5515 ogf
->actions
[3] = htonl(features
->actions
[3]);
5520 /* Decodes group features reply 'oh' into 'features'. */
5522 ofputil_decode_group_features_reply(const struct ofp_header
*oh
,
5523 struct ofputil_group_features
*features
)
5525 const struct ofp12_group_features_stats
*ogf
= ofpmsg_body(oh
);
5527 features
->types
= ntohl(ogf
->types
);
5528 features
->capabilities
= ntohl(ogf
->capabilities
);
5529 features
->max_groups
[0] = ntohl(ogf
->max_groups
[0]);
5530 features
->max_groups
[1] = ntohl(ogf
->max_groups
[1]);
5531 features
->max_groups
[2] = ntohl(ogf
->max_groups
[2]);
5532 features
->max_groups
[3] = ntohl(ogf
->max_groups
[3]);
5533 features
->actions
[0] = ntohl(ogf
->actions
[0]);
5534 features
->actions
[1] = ntohl(ogf
->actions
[1]);
5535 features
->actions
[2] = ntohl(ogf
->actions
[2]);
5536 features
->actions
[3] = ntohl(ogf
->actions
[3]);
5539 /* Parse a group status request message into a 32 bit OpenFlow 1.1
5540 * group ID and stores the latter in '*group_id'.
5541 * Returns 0 if successful, otherwise an OFPERR_* number. */
5543 ofputil_decode_group_stats_request(const struct ofp_header
*request
,
5546 const struct ofp11_group_stats_request
*gsr11
= ofpmsg_body(request
);
5547 *group_id
= ntohl(gsr11
->group_id
);
5551 /* Converts a group stats reply in 'msg' into an abstract ofputil_group_stats
5552 * in 'gs'. Assigns freshly allocated memory to gs->bucket_stats for the
5553 * caller to eventually free.
5555 * Multiple group stats replies can be packed into a single OpenFlow message.
5556 * Calling this function multiple times for a single 'msg' iterates through the
5557 * replies. The caller must initially leave 'msg''s layer pointers null and
5558 * not modify them between calls.
5560 * Returns 0 if successful, EOF if no replies were left in this 'msg',
5561 * otherwise a positive errno value. */
5563 ofputil_decode_group_stats_reply(struct ofpbuf
*msg
,
5564 struct ofputil_group_stats
*gs
)
5566 struct ofp11_bucket_counter
*obc
;
5567 struct ofp11_group_stats
*ogs11
;
5574 gs
->bucket_stats
= NULL
;
5576 ? ofpraw_decode(&raw
, msg
->l2
)
5577 : ofpraw_pull(&raw
, msg
));
5586 if (raw
== OFPRAW_OFPST11_GROUP_REPLY
) {
5587 base_len
= sizeof *ogs11
;
5588 ogs11
= ofpbuf_try_pull(msg
, sizeof *ogs11
);
5589 gs
->duration_sec
= gs
->duration_nsec
= UINT32_MAX
;
5590 } else if (raw
== OFPRAW_OFPST13_GROUP_REPLY
) {
5591 struct ofp13_group_stats
*ogs13
;
5593 base_len
= sizeof *ogs13
;
5594 ogs13
= ofpbuf_try_pull(msg
, sizeof *ogs13
);
5597 gs
->duration_sec
= ntohl(ogs13
->duration_sec
);
5598 gs
->duration_nsec
= ntohl(ogs13
->duration_nsec
);
5607 VLOG_WARN_RL(&bad_ofmsg_rl
, "%s reply has %zu leftover bytes at end",
5608 ofpraw_get_name(raw
), msg
->size
);
5609 return OFPERR_OFPBRC_BAD_LEN
;
5611 length
= ntohs(ogs11
->length
);
5612 if (length
< sizeof base_len
) {
5613 VLOG_WARN_RL(&bad_ofmsg_rl
, "%s reply claims invalid length %zu",
5614 ofpraw_get_name(raw
), length
);
5615 return OFPERR_OFPBRC_BAD_LEN
;
5618 gs
->group_id
= ntohl(ogs11
->group_id
);
5619 gs
->ref_count
= ntohl(ogs11
->ref_count
);
5620 gs
->packet_count
= ntohll(ogs11
->packet_count
);
5621 gs
->byte_count
= ntohll(ogs11
->byte_count
);
5623 gs
->n_buckets
= (length
- base_len
) / sizeof *obc
;
5624 obc
= ofpbuf_try_pull(msg
, gs
->n_buckets
* sizeof *obc
);
5626 VLOG_WARN_RL(&bad_ofmsg_rl
, "%s reply has %zu leftover bytes at end",
5627 ofpraw_get_name(raw
), msg
->size
);
5628 return OFPERR_OFPBRC_BAD_LEN
;
5631 gs
->bucket_stats
= xmalloc(gs
->n_buckets
* sizeof *gs
->bucket_stats
);
5632 for (i
= 0; i
< gs
->n_buckets
; i
++) {
5633 gs
->bucket_stats
[i
].packet_count
= ntohll(obc
[i
].packet_count
);
5634 gs
->bucket_stats
[i
].byte_count
= ntohll(obc
[i
].byte_count
);
5640 /* Appends a group stats reply that contains the data in 'gds' to those already
5641 * present in the list of ofpbufs in 'replies'. 'replies' should have been
5642 * initialized with ofpmp_init(). */
5644 ofputil_append_group_desc_reply(const struct ofputil_group_desc
*gds
,
5645 struct list
*buckets
,
5646 struct list
*replies
)
5648 struct ofpbuf
*reply
= ofpbuf_from_list(list_back(replies
));
5649 struct ofp11_group_desc_stats
*ogds
;
5650 struct ofputil_bucket
*bucket
;
5653 start_ogds
= reply
->size
;
5654 ofpbuf_put_zeros(reply
, sizeof *ogds
);
5655 LIST_FOR_EACH (bucket
, list_node
, buckets
) {
5656 struct ofp11_bucket
*ob
;
5659 start_ob
= reply
->size
;
5660 ofpbuf_put_zeros(reply
, sizeof *ob
);
5661 ofpacts_put_openflow11_actions(bucket
->ofpacts
,
5662 bucket
->ofpacts_len
, reply
);
5664 ob
= ofpbuf_at_assert(reply
, start_ob
, sizeof *ob
);
5665 ob
->len
= htons(reply
->size
- start_ob
);
5666 ob
->weight
= htons(bucket
->weight
);
5667 ob
->watch_port
= ofputil_port_to_ofp11(bucket
->watch_port
);
5668 ob
->watch_group
= htonl(bucket
->watch_group
);
5670 ogds
= ofpbuf_at_assert(reply
, start_ogds
, sizeof *ogds
);
5671 ogds
->length
= htons(reply
->size
- start_ogds
);
5672 ogds
->type
= gds
->type
;
5673 ogds
->group_id
= htonl(gds
->group_id
);
5675 ofpmp_postappend(replies
, start_ogds
);
5679 ofputil_pull_buckets(struct ofpbuf
*msg
, enum ofp_version version
,
5680 size_t buckets_length
, struct list
*buckets
)
5682 struct ofp11_bucket
*ob
;
5685 while (buckets_length
> 0) {
5686 struct ofputil_bucket
*bucket
;
5687 struct ofpbuf ofpacts
;
5691 ob
= (buckets_length
>= sizeof *ob
5692 ? ofpbuf_try_pull(msg
, sizeof *ob
)
5695 VLOG_WARN_RL(&bad_ofmsg_rl
, "buckets end with %zu leftover bytes",
5699 ob_len
= ntohs(ob
->len
);
5700 if (ob_len
< sizeof *ob
) {
5701 VLOG_WARN_RL(&bad_ofmsg_rl
, "OpenFlow message bucket length "
5702 "%zu is not valid", ob_len
);
5703 return OFPERR_OFPGMFC_BAD_BUCKET
;
5704 } else if (ob_len
> buckets_length
) {
5705 VLOG_WARN_RL(&bad_ofmsg_rl
, "OpenFlow message bucket length "
5706 "%zu exceeds remaining buckets data size %zu",
5707 ob_len
, buckets_length
);
5708 return OFPERR_OFPGMFC_BAD_BUCKET
;
5710 buckets_length
-= ob_len
;
5712 ofpbuf_init(&ofpacts
, 0);
5713 error
= ofpacts_pull_openflow11_actions(msg
, version
,
5714 ob_len
- sizeof *ob
, &ofpacts
);
5716 ofpbuf_uninit(&ofpacts
);
5717 ofputil_bucket_list_destroy(buckets
);
5721 bucket
= xzalloc(sizeof *bucket
);
5722 bucket
->weight
= ntohs(ob
->weight
);
5723 error
= ofputil_port_from_ofp11(ob
->watch_port
, &bucket
->watch_port
);
5725 ofpbuf_uninit(&ofpacts
);
5726 ofputil_bucket_list_destroy(buckets
);
5727 return OFPERR_OFPGMFC_BAD_WATCH
;
5729 bucket
->watch_group
= ntohl(ob
->watch_group
);
5730 bucket
->ofpacts
= ofpbuf_steal_data(&ofpacts
);
5731 bucket
->ofpacts_len
= ofpacts
.size
;
5732 list_push_back(buckets
, &bucket
->list_node
);
5738 /* Converts a group description reply in 'msg' into an abstract
5739 * ofputil_group_desc in 'gd'.
5741 * Multiple group description replies can be packed into a single OpenFlow
5742 * message. Calling this function multiple times for a single 'msg' iterates
5743 * through the replies. The caller must initially leave 'msg''s layer pointers
5744 * null and not modify them between calls.
5746 * Returns 0 if successful, EOF if no replies were left in this 'msg',
5747 * otherwise a positive errno value. */
5749 ofputil_decode_group_desc_reply(struct ofputil_group_desc
*gd
,
5750 struct ofpbuf
*msg
, enum ofp_version version
)
5752 struct ofp11_group_desc_stats
*ogds
;
5756 ofpraw_pull_assert(msg
);
5763 ogds
= ofpbuf_try_pull(msg
, sizeof *ogds
);
5765 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST11_GROUP_DESC reply has %zu "
5766 "leftover bytes at end", msg
->size
);
5767 return OFPERR_OFPBRC_BAD_LEN
;
5769 gd
->type
= ogds
->type
;
5770 gd
->group_id
= ntohl(ogds
->group_id
);
5772 length
= ntohs(ogds
->length
);
5773 if (length
< sizeof *ogds
|| length
- sizeof *ogds
> msg
->size
) {
5774 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST11_GROUP_DESC reply claims invalid "
5775 "length %zu", length
);
5776 return OFPERR_OFPBRC_BAD_LEN
;
5779 return ofputil_pull_buckets(msg
, version
, length
- sizeof *ogds
,
5783 /* Converts abstract group mod 'gm' into a message for OpenFlow version
5784 * 'ofp_version' and returns the message. */
5786 ofputil_encode_group_mod(enum ofp_version ofp_version
,
5787 const struct ofputil_group_mod
*gm
)
5790 struct ofp11_group_mod
*ogm
;
5792 size_t start_bucket
;
5793 struct ofputil_bucket
*bucket
;
5794 struct ofp11_bucket
*ob
;
5796 switch (ofp_version
) {
5797 case OFP10_VERSION
: {
5798 if (gm
->command
== OFPGC11_ADD
) {
5799 ovs_fatal(0, "add-group needs OpenFlow 1.1 or later "
5800 "(\'-O OpenFlow11\')");
5801 } else if (gm
->command
== OFPGC11_MODIFY
) {
5802 ovs_fatal(0, "mod-group needs OpenFlow 1.1 or later "
5803 "(\'-O OpenFlow11\')");
5805 ovs_fatal(0, "del-groups needs OpenFlow 1.1 or later "
5806 "(\'-O OpenFlow11\')");
5812 case OFP13_VERSION
: {
5813 b
= ofpraw_alloc(OFPRAW_OFPT11_GROUP_MOD
, ofp_version
, 0);
5814 start_ogm
= b
->size
;
5815 ofpbuf_put_uninit(b
, sizeof *ogm
);
5817 LIST_FOR_EACH (bucket
, list_node
, &gm
->buckets
) {
5818 start_bucket
= b
->size
;
5819 ofpbuf_put_uninit(b
, sizeof *ob
);
5820 if (bucket
->ofpacts
&& bucket
->ofpacts_len
) {
5821 ofpacts_put_openflow11_actions(bucket
->ofpacts
,
5822 bucket
->ofpacts_len
, b
);
5824 ob
= ofpbuf_at_assert(b
, start_bucket
, sizeof *ob
);
5825 ob
->len
= htons(b
->size
- start_bucket
);;
5826 ob
->weight
= htons(bucket
->weight
);
5827 ob
->watch_port
= ofputil_port_to_ofp11(bucket
->watch_port
);
5828 ob
->watch_group
= htonl(bucket
->watch_group
);
5830 ogm
= ofpbuf_at_assert(b
, start_ogm
, sizeof *ogm
);
5831 ogm
->command
= htons(gm
->command
);
5832 ogm
->type
= gm
->type
;
5834 ogm
->group_id
= htonl(gm
->group_id
);
5846 /* Converts OpenFlow group mod message 'oh' into an abstract group mod in
5847 * 'gm'. Returns 0 if successful, otherwise an OpenFlow error code. */
5849 ofputil_decode_group_mod(const struct ofp_header
*oh
,
5850 struct ofputil_group_mod
*gm
)
5852 const struct ofp11_group_mod
*ogm
;
5855 ofpbuf_use_const(&msg
, oh
, ntohs(oh
->length
));
5856 ofpraw_pull_assert(&msg
);
5858 ogm
= ofpbuf_pull(&msg
, sizeof *ogm
);
5859 gm
->command
= ntohs(ogm
->command
);
5860 gm
->type
= ogm
->type
;
5861 gm
->group_id
= ntohl(ogm
->group_id
);
5863 return ofputil_pull_buckets(&msg
, oh
->version
, msg
.size
, &gm
->buckets
);
5866 /* Parse a queue status request message into 'oqsr'.
5867 * Returns 0 if successful, otherwise an OFPERR_* number. */
5869 ofputil_decode_queue_stats_request(const struct ofp_header
*request
,
5870 struct ofputil_queue_stats_request
*oqsr
)
5872 switch ((enum ofp_version
)request
->version
) {
5875 case OFP11_VERSION
: {
5876 const struct ofp11_queue_stats_request
*qsr11
= ofpmsg_body(request
);
5877 oqsr
->queue_id
= ntohl(qsr11
->queue_id
);
5878 return ofputil_port_from_ofp11(qsr11
->port_no
, &oqsr
->port_no
);
5881 case OFP10_VERSION
: {
5882 const struct ofp10_queue_stats_request
*qsr10
= ofpmsg_body(request
);
5883 oqsr
->queue_id
= ntohl(qsr10
->queue_id
);
5884 oqsr
->port_no
= u16_to_ofp(ntohs(qsr10
->port_no
));
5885 /* OF 1.0 uses OFPP_ALL for OFPP_ANY */
5886 if (oqsr
->port_no
== OFPP_ALL
) {
5887 oqsr
->port_no
= OFPP_ANY
;
5897 /* Encode a queue statsrequest for 'oqsr', the encoded message
5898 * will be fore Open Flow version 'ofp_version'. Returns message
5899 * as a struct ofpbuf. Returns encoded message on success, NULL on error */
5901 ofputil_encode_queue_stats_request(enum ofp_version ofp_version
,
5902 const struct ofputil_queue_stats_request
*oqsr
)
5904 struct ofpbuf
*request
;
5906 switch (ofp_version
) {
5909 case OFP13_VERSION
: {
5910 struct ofp11_queue_stats_request
*req
;
5911 request
= ofpraw_alloc(OFPRAW_OFPST11_QUEUE_REQUEST
, ofp_version
, 0);
5912 req
= ofpbuf_put_zeros(request
, sizeof *req
);
5913 req
->port_no
= ofputil_port_to_ofp11(oqsr
->port_no
);
5914 req
->queue_id
= htonl(oqsr
->queue_id
);
5917 case OFP10_VERSION
: {
5918 struct ofp10_queue_stats_request
*req
;
5919 request
= ofpraw_alloc(OFPRAW_OFPST10_QUEUE_REQUEST
, ofp_version
, 0);
5920 req
= ofpbuf_put_zeros(request
, sizeof *req
);
5921 /* OpenFlow 1.0 needs OFPP_ALL instead of OFPP_ANY */
5922 req
->port_no
= htons(ofp_to_u16(oqsr
->port_no
== OFPP_ANY
5923 ? OFPP_ALL
: oqsr
->port_no
));
5924 req
->queue_id
= htonl(oqsr
->queue_id
);
5935 ofputil_get_queue_stats_size(enum ofp_version ofp_version
)
5937 switch (ofp_version
) {
5939 return sizeof(struct ofp10_queue_stats
);
5942 return sizeof(struct ofp11_queue_stats
);
5944 return sizeof(struct ofp13_queue_stats
);
5950 /* Returns the number of queue stats elements in OFPTYPE_QUEUE_STATS_REPLY
5953 ofputil_count_queue_stats(const struct ofp_header
*oh
)
5957 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
5958 ofpraw_pull_assert(&b
);
5960 return b
.size
/ ofputil_get_queue_stats_size(oh
->version
);
5964 ofputil_queue_stats_from_ofp10(struct ofputil_queue_stats
*oqs
,
5965 const struct ofp10_queue_stats
*qs10
)
5967 oqs
->port_no
= u16_to_ofp(ntohs(qs10
->port_no
));
5968 oqs
->queue_id
= ntohl(qs10
->queue_id
);
5969 oqs
->tx_bytes
= ntohll(get_32aligned_be64(&qs10
->tx_bytes
));
5970 oqs
->tx_packets
= ntohll(get_32aligned_be64(&qs10
->tx_packets
));
5971 oqs
->tx_errors
= ntohll(get_32aligned_be64(&qs10
->tx_errors
));
5972 oqs
->duration_sec
= oqs
->duration_nsec
= UINT32_MAX
;
5978 ofputil_queue_stats_from_ofp11(struct ofputil_queue_stats
*oqs
,
5979 const struct ofp11_queue_stats
*qs11
)
5983 error
= ofputil_port_from_ofp11(qs11
->port_no
, &oqs
->port_no
);
5988 oqs
->queue_id
= ntohl(qs11
->queue_id
);
5989 oqs
->tx_bytes
= ntohll(qs11
->tx_bytes
);
5990 oqs
->tx_packets
= ntohll(qs11
->tx_packets
);
5991 oqs
->tx_errors
= ntohll(qs11
->tx_errors
);
5992 oqs
->duration_sec
= oqs
->duration_nsec
= UINT32_MAX
;
5998 ofputil_queue_stats_from_ofp13(struct ofputil_queue_stats
*oqs
,
5999 const struct ofp13_queue_stats
*qs13
)
6001 enum ofperr error
= ofputil_queue_stats_from_ofp11(oqs
, &qs13
->qs
);
6003 oqs
->duration_sec
= ntohl(qs13
->duration_sec
);
6004 oqs
->duration_nsec
= ntohl(qs13
->duration_nsec
);
6010 /* Converts an OFPST_QUEUE_STATS reply in 'msg' into an abstract
6011 * ofputil_queue_stats in 'qs'.
6013 * Multiple OFPST_QUEUE_STATS replies can be packed into a single OpenFlow
6014 * message. Calling this function multiple times for a single 'msg' iterates
6015 * through the replies. The caller must initially leave 'msg''s layer pointers
6016 * null and not modify them between calls.
6018 * Returns 0 if successful, EOF if no replies were left in this 'msg',
6019 * otherwise a positive errno value. */
6021 ofputil_decode_queue_stats(struct ofputil_queue_stats
*qs
, struct ofpbuf
*msg
)
6027 ? ofpraw_decode(&raw
, msg
->l2
)
6028 : ofpraw_pull(&raw
, msg
));
6035 } else if (raw
== OFPRAW_OFPST13_QUEUE_REPLY
) {
6036 const struct ofp13_queue_stats
*qs13
;
6038 qs13
= ofpbuf_try_pull(msg
, sizeof *qs13
);
6042 return ofputil_queue_stats_from_ofp13(qs
, qs13
);
6043 } else if (raw
== OFPRAW_OFPST11_QUEUE_REPLY
) {
6044 const struct ofp11_queue_stats
*qs11
;
6046 qs11
= ofpbuf_try_pull(msg
, sizeof *qs11
);
6050 return ofputil_queue_stats_from_ofp11(qs
, qs11
);
6051 } else if (raw
== OFPRAW_OFPST10_QUEUE_REPLY
) {
6052 const struct ofp10_queue_stats
*qs10
;
6054 qs10
= ofpbuf_try_pull(msg
, sizeof *qs10
);
6058 return ofputil_queue_stats_from_ofp10(qs
, qs10
);
6064 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_QUEUE reply has %zu leftover "
6065 "bytes at end", msg
->size
);
6066 return OFPERR_OFPBRC_BAD_LEN
;
6070 ofputil_queue_stats_to_ofp10(const struct ofputil_queue_stats
*oqs
,
6071 struct ofp10_queue_stats
*qs10
)
6073 qs10
->port_no
= htons(ofp_to_u16(oqs
->port_no
));
6074 memset(qs10
->pad
, 0, sizeof qs10
->pad
);
6075 qs10
->queue_id
= htonl(oqs
->queue_id
);
6076 put_32aligned_be64(&qs10
->tx_bytes
, htonll(oqs
->tx_bytes
));
6077 put_32aligned_be64(&qs10
->tx_packets
, htonll(oqs
->tx_packets
));
6078 put_32aligned_be64(&qs10
->tx_errors
, htonll(oqs
->tx_errors
));
6082 ofputil_queue_stats_to_ofp11(const struct ofputil_queue_stats
*oqs
,
6083 struct ofp11_queue_stats
*qs11
)
6085 qs11
->port_no
= ofputil_port_to_ofp11(oqs
->port_no
);
6086 qs11
->queue_id
= htonl(oqs
->queue_id
);
6087 qs11
->tx_bytes
= htonll(oqs
->tx_bytes
);
6088 qs11
->tx_packets
= htonll(oqs
->tx_packets
);
6089 qs11
->tx_errors
= htonll(oqs
->tx_errors
);
6093 ofputil_queue_stats_to_ofp13(const struct ofputil_queue_stats
*oqs
,
6094 struct ofp13_queue_stats
*qs13
)
6096 ofputil_queue_stats_to_ofp11(oqs
, &qs13
->qs
);
6097 if (oqs
->duration_sec
!= UINT32_MAX
) {
6098 qs13
->duration_sec
= htonl(oqs
->duration_sec
);
6099 qs13
->duration_nsec
= htonl(oqs
->duration_nsec
);
6101 qs13
->duration_sec
= OVS_BE32_MAX
;
6102 qs13
->duration_nsec
= OVS_BE32_MAX
;
6106 /* Encode a queue stat for 'oqs' and append it to 'replies'. */
6108 ofputil_append_queue_stat(struct list
*replies
,
6109 const struct ofputil_queue_stats
*oqs
)
6111 struct ofpbuf
*msg
= ofpbuf_from_list(list_back(replies
));
6112 struct ofp_header
*oh
= msg
->data
;
6114 switch ((enum ofp_version
)oh
->version
) {
6115 case OFP13_VERSION
: {
6116 struct ofp13_queue_stats
*reply
= ofpmp_append(replies
, sizeof *reply
);
6117 ofputil_queue_stats_to_ofp13(oqs
, reply
);
6122 case OFP11_VERSION
: {
6123 struct ofp11_queue_stats
*reply
= ofpmp_append(replies
, sizeof *reply
);
6124 ofputil_queue_stats_to_ofp11(oqs
, reply
);
6128 case OFP10_VERSION
: {
6129 struct ofp10_queue_stats
*reply
= ofpmp_append(replies
, sizeof *reply
);
6130 ofputil_queue_stats_to_ofp10(oqs
, reply
);