2 * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
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"
21 #include <netinet/icmp6.h>
24 #include "byte-order.h"
25 #include "classifier.h"
26 #include "dynamic-string.h"
27 #include "multipath.h"
29 #include "ofp-errors.h"
34 #include "unaligned.h"
35 #include "type-props.h"
38 VLOG_DEFINE_THIS_MODULE(ofp_util
);
40 /* Rate limit for OpenFlow message parse errors. These always indicate a bug
41 * in the peer and so there's not much point in showing a lot of them. */
42 static struct vlog_rate_limit bad_ofmsg_rl
= VLOG_RATE_LIMIT_INIT(1, 5);
44 /* Given the wildcard bit count in the least-significant 6 of 'wcbits', returns
45 * an IP netmask with a 1 in each bit that must match and a 0 in each bit that
48 * The bits in 'wcbits' are in the format used in enum ofp_flow_wildcards: 0
49 * is exact match, 1 ignores the LSB, 2 ignores the 2 least-significant bits,
50 * ..., 32 and higher wildcard the entire field. This is the *opposite* of the
51 * usual convention where e.g. /24 indicates that 8 bits (not 24 bits) are
54 ofputil_wcbits_to_netmask(int wcbits
)
57 return wcbits
< 32 ? htonl(~((1u << wcbits
) - 1)) : 0;
60 /* Given the IP netmask 'netmask', returns the number of bits of the IP address
61 * that it wildcards. 'netmask' must be a CIDR netmask (see ip_is_cidr()). */
63 ofputil_netmask_to_wcbits(ovs_be32 netmask
)
65 assert(ip_is_cidr(netmask
));
67 return netmask
== htonl(0) ? 32 : __builtin_ctz(ntohl(netmask
));
71 for (wcbits
= 32; netmask
; wcbits
--) {
72 netmask
&= netmask
- 1;
79 /* A list of the FWW_* and OFPFW_ bits that have the same value, meaning, and
81 #define WC_INVARIANT_LIST \
82 WC_INVARIANT_BIT(IN_PORT) \
83 WC_INVARIANT_BIT(DL_SRC) \
84 WC_INVARIANT_BIT(DL_DST) \
85 WC_INVARIANT_BIT(DL_TYPE) \
86 WC_INVARIANT_BIT(NW_PROTO) \
87 WC_INVARIANT_BIT(TP_SRC) \
88 WC_INVARIANT_BIT(TP_DST)
90 /* Verify that all of the invariant bits (as defined on WC_INVARIANT_LIST)
91 * actually have the same names and values. */
92 #define WC_INVARIANT_BIT(NAME) BUILD_ASSERT_DECL(FWW_##NAME == OFPFW_##NAME);
94 #undef WC_INVARIANT_BIT
96 /* WC_INVARIANTS is the invariant bits (as defined on WC_INVARIANT_LIST) all
98 static const flow_wildcards_t WC_INVARIANTS
= 0
99 #define WC_INVARIANT_BIT(NAME) | FWW_##NAME
101 #undef WC_INVARIANT_BIT
104 /* Converts the wildcard in 'ofpfw' into a flow_wildcards in 'wc' for use in
105 * struct cls_rule. It is the caller's responsibility to handle the special
106 * case where the flow match's dl_vlan is set to OFP_VLAN_NONE. */
108 ofputil_wildcard_from_openflow(uint32_t ofpfw
, struct flow_wildcards
*wc
)
110 /* Initialize most of rule->wc. */
111 flow_wildcards_init_catchall(wc
);
112 wc
->wildcards
= (OVS_FORCE flow_wildcards_t
) ofpfw
& WC_INVARIANTS
;
114 /* Wildcard fields that aren't defined by ofp_match or tun_id. */
115 wc
->wildcards
|= (FWW_ARP_SHA
| FWW_ARP_THA
| FWW_ND_TARGET
);
117 if (ofpfw
& OFPFW_NW_TOS
) {
118 wc
->wildcards
|= FWW_NW_TOS
;
120 wc
->nw_src_mask
= ofputil_wcbits_to_netmask(ofpfw
>> OFPFW_NW_SRC_SHIFT
);
121 wc
->nw_dst_mask
= ofputil_wcbits_to_netmask(ofpfw
>> OFPFW_NW_DST_SHIFT
);
123 if (ofpfw
& OFPFW_DL_DST
) {
124 /* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but
125 * Open vSwitch breaks the Ethernet destination into bits as FWW_DL_DST
126 * and FWW_ETH_MCAST. */
127 wc
->wildcards
|= FWW_ETH_MCAST
;
131 if (!(ofpfw
& OFPFW_DL_VLAN_PCP
)) {
132 wc
->vlan_tci_mask
|= htons(VLAN_PCP_MASK
| VLAN_CFI
);
134 if (!(ofpfw
& OFPFW_DL_VLAN
)) {
135 wc
->vlan_tci_mask
|= htons(VLAN_VID_MASK
| VLAN_CFI
);
139 /* Converts the ofp_match in 'match' into a cls_rule in 'rule', with the given
142 ofputil_cls_rule_from_match(const struct ofp_match
*match
,
143 unsigned int priority
, struct cls_rule
*rule
)
145 uint32_t ofpfw
= ntohl(match
->wildcards
) & OFPFW_ALL
;
147 /* Initialize rule->priority, rule->wc. */
148 rule
->priority
= !ofpfw
? UINT16_MAX
: priority
;
149 ofputil_wildcard_from_openflow(ofpfw
, &rule
->wc
);
151 /* Initialize most of rule->flow. */
152 rule
->flow
.nw_src
= match
->nw_src
;
153 rule
->flow
.nw_dst
= match
->nw_dst
;
154 rule
->flow
.in_port
= ntohs(match
->in_port
);
155 rule
->flow
.dl_type
= ofputil_dl_type_from_openflow(match
->dl_type
);
156 rule
->flow
.tp_src
= match
->tp_src
;
157 rule
->flow
.tp_dst
= match
->tp_dst
;
158 memcpy(rule
->flow
.dl_src
, match
->dl_src
, ETH_ADDR_LEN
);
159 memcpy(rule
->flow
.dl_dst
, match
->dl_dst
, ETH_ADDR_LEN
);
160 rule
->flow
.nw_tos
= match
->nw_tos
;
161 rule
->flow
.nw_proto
= match
->nw_proto
;
163 /* Translate VLANs. */
164 if (!(ofpfw
& OFPFW_DL_VLAN
) && match
->dl_vlan
== htons(OFP_VLAN_NONE
)) {
165 /* Match only packets without 802.1Q header.
167 * When OFPFW_DL_VLAN_PCP is wildcarded, this is obviously correct.
169 * If OFPFW_DL_VLAN_PCP is matched, the flow match is contradictory,
170 * because we can't have a specific PCP without an 802.1Q header.
171 * However, older versions of OVS treated this as matching packets
172 * withut an 802.1Q header, so we do here too. */
173 rule
->flow
.vlan_tci
= htons(0);
174 rule
->wc
.vlan_tci_mask
= htons(0xffff);
176 ovs_be16 vid
, pcp
, tci
;
178 vid
= match
->dl_vlan
& htons(VLAN_VID_MASK
);
179 pcp
= htons((match
->dl_vlan_pcp
<< VLAN_PCP_SHIFT
) & VLAN_PCP_MASK
);
180 tci
= vid
| pcp
| htons(VLAN_CFI
);
181 rule
->flow
.vlan_tci
= tci
& rule
->wc
.vlan_tci_mask
;
185 cls_rule_zero_wildcarded_fields(rule
);
188 /* Convert 'rule' into the OpenFlow match structure 'match'. */
190 ofputil_cls_rule_to_match(const struct cls_rule
*rule
, struct ofp_match
*match
)
192 const struct flow_wildcards
*wc
= &rule
->wc
;
195 /* Figure out most OpenFlow wildcards. */
196 ofpfw
= (OVS_FORCE
uint32_t) (wc
->wildcards
& WC_INVARIANTS
);
197 ofpfw
|= ofputil_netmask_to_wcbits(wc
->nw_src_mask
) << OFPFW_NW_SRC_SHIFT
;
198 ofpfw
|= ofputil_netmask_to_wcbits(wc
->nw_dst_mask
) << OFPFW_NW_DST_SHIFT
;
199 if (wc
->wildcards
& FWW_NW_TOS
) {
200 ofpfw
|= OFPFW_NW_TOS
;
203 /* Translate VLANs. */
204 match
->dl_vlan
= htons(0);
205 match
->dl_vlan_pcp
= 0;
206 if (rule
->wc
.vlan_tci_mask
== htons(0)) {
207 ofpfw
|= OFPFW_DL_VLAN
| OFPFW_DL_VLAN_PCP
;
208 } else if (rule
->wc
.vlan_tci_mask
& htons(VLAN_CFI
)
209 && !(rule
->flow
.vlan_tci
& htons(VLAN_CFI
))) {
210 match
->dl_vlan
= htons(OFP_VLAN_NONE
);
212 if (!(rule
->wc
.vlan_tci_mask
& htons(VLAN_VID_MASK
))) {
213 ofpfw
|= OFPFW_DL_VLAN
;
215 match
->dl_vlan
= htons(vlan_tci_to_vid(rule
->flow
.vlan_tci
));
218 if (!(rule
->wc
.vlan_tci_mask
& htons(VLAN_PCP_MASK
))) {
219 ofpfw
|= OFPFW_DL_VLAN_PCP
;
221 match
->dl_vlan_pcp
= vlan_tci_to_pcp(rule
->flow
.vlan_tci
);
225 /* Compose most of the match structure. */
226 match
->wildcards
= htonl(ofpfw
);
227 match
->in_port
= htons(rule
->flow
.in_port
);
228 memcpy(match
->dl_src
, rule
->flow
.dl_src
, ETH_ADDR_LEN
);
229 memcpy(match
->dl_dst
, rule
->flow
.dl_dst
, ETH_ADDR_LEN
);
230 match
->dl_type
= ofputil_dl_type_to_openflow(rule
->flow
.dl_type
);
231 match
->nw_src
= rule
->flow
.nw_src
;
232 match
->nw_dst
= rule
->flow
.nw_dst
;
233 match
->nw_tos
= rule
->flow
.nw_tos
;
234 match
->nw_proto
= rule
->flow
.nw_proto
;
235 match
->tp_src
= rule
->flow
.tp_src
;
236 match
->tp_dst
= rule
->flow
.tp_dst
;
237 memset(match
->pad1
, '\0', sizeof match
->pad1
);
238 memset(match
->pad2
, '\0', sizeof match
->pad2
);
241 /* Given a 'dl_type' value in the format used in struct flow, returns the
242 * corresponding 'dl_type' value for use in an OpenFlow ofp_match structure. */
244 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type
)
246 return (flow_dl_type
== htons(FLOW_DL_TYPE_NONE
)
247 ? htons(OFP_DL_TYPE_NOT_ETH_TYPE
)
251 /* Given a 'dl_type' value in the format used in an OpenFlow ofp_match
252 * structure, returns the corresponding 'dl_type' value for use in struct
255 ofputil_dl_type_from_openflow(ovs_be16 ofp_dl_type
)
257 return (ofp_dl_type
== htons(OFP_DL_TYPE_NOT_ETH_TYPE
)
258 ? htons(FLOW_DL_TYPE_NONE
)
262 /* Returns a transaction ID to use for an outgoing OpenFlow message. */
266 static uint32_t next_xid
= 1;
267 return htonl(next_xid
++);
270 /* Basic parsing of OpenFlow messages. */
272 struct ofputil_msg_type
{
273 enum ofputil_msg_code code
; /* OFPUTIL_*. */
274 uint32_t value
; /* OFPT_*, OFPST_*, NXT_*, or NXST_*. */
275 const char *name
; /* e.g. "OFPT_FLOW_REMOVED". */
276 unsigned int min_size
; /* Minimum total message size in bytes. */
277 /* 0 if 'min_size' is the exact size that the message must be. Otherwise,
278 * the message may exceed 'min_size' by an even multiple of this value. */
279 unsigned int extra_multiple
;
282 struct ofputil_msg_category
{
283 const char *name
; /* e.g. "OpenFlow message" */
284 const struct ofputil_msg_type
*types
;
286 int missing_error
; /* ofp_mkerr() value for missing type. */
290 ofputil_length_ok(const struct ofputil_msg_category
*cat
,
291 const struct ofputil_msg_type
*type
,
294 switch (type
->extra_multiple
) {
296 if (size
!= type
->min_size
) {
297 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s %s with incorrect "
298 "length %u (expected length %u)",
299 cat
->name
, type
->name
, size
, type
->min_size
);
305 if (size
< type
->min_size
) {
306 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s %s with incorrect "
307 "length %u (expected length at least %u bytes)",
308 cat
->name
, type
->name
, size
, type
->min_size
);
314 if (size
< type
->min_size
315 || (size
- type
->min_size
) % type
->extra_multiple
) {
316 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s %s with incorrect "
317 "length %u (must be exactly %u bytes or longer "
318 "by an integer multiple of %u bytes)",
319 cat
->name
, type
->name
, size
,
320 type
->min_size
, type
->extra_multiple
);
328 ofputil_lookup_openflow_message(const struct ofputil_msg_category
*cat
,
329 uint32_t value
, unsigned int size
,
330 const struct ofputil_msg_type
**typep
)
332 const struct ofputil_msg_type
*type
;
334 for (type
= cat
->types
; type
< &cat
->types
[cat
->n_types
]; type
++) {
335 if (type
->value
== value
) {
336 if (!ofputil_length_ok(cat
, type
, size
)) {
337 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_LEN
);
344 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s of unknown type %"PRIu32
,
346 return cat
->missing_error
;
350 ofputil_decode_vendor(const struct ofp_header
*oh
,
351 const struct ofputil_msg_type
**typep
)
353 BUILD_ASSERT_DECL(sizeof(struct nxt_set_flow_format
)
354 != sizeof(struct nxt_flow_mod_table_id
));
356 static const struct ofputil_msg_type nxt_messages
[] = {
357 { OFPUTIL_NXT_ROLE_REQUEST
,
358 NXT_ROLE_REQUEST
, "NXT_ROLE_REQUEST",
359 sizeof(struct nx_role_request
), 0 },
361 { OFPUTIL_NXT_ROLE_REPLY
,
362 NXT_ROLE_REPLY
, "NXT_ROLE_REPLY",
363 sizeof(struct nx_role_request
), 0 },
365 { OFPUTIL_NXT_SET_FLOW_FORMAT
,
366 NXT_SET_FLOW_FORMAT
, "NXT_SET_FLOW_FORMAT",
367 sizeof(struct nxt_set_flow_format
), 0 },
369 { OFPUTIL_NXT_FLOW_MOD
,
370 NXT_FLOW_MOD
, "NXT_FLOW_MOD",
371 sizeof(struct nx_flow_mod
), 8 },
373 { OFPUTIL_NXT_FLOW_REMOVED
,
374 NXT_FLOW_REMOVED
, "NXT_FLOW_REMOVED",
375 sizeof(struct nx_flow_removed
), 8 },
377 { OFPUTIL_NXT_FLOW_MOD_TABLE_ID
,
378 NXT_FLOW_MOD_TABLE_ID
, "NXT_FLOW_MOD_TABLE_ID",
379 sizeof(struct nxt_flow_mod_table_id
), 0 },
382 static const struct ofputil_msg_category nxt_category
= {
383 "Nicira extension message",
384 nxt_messages
, ARRAY_SIZE(nxt_messages
),
385 OFP_MKERR(OFPET_BAD_REQUEST
, OFPBRC_BAD_SUBTYPE
)
388 const struct ofp_vendor_header
*ovh
;
389 const struct nicira_header
*nh
;
391 ovh
= (const struct ofp_vendor_header
*) oh
;
392 if (ovh
->vendor
!= htonl(NX_VENDOR_ID
)) {
393 VLOG_WARN_RL(&bad_ofmsg_rl
, "received vendor message for unknown "
394 "vendor %"PRIx32
, ntohl(ovh
->vendor
));
395 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_VENDOR
);
398 if (ntohs(ovh
->header
.length
) < sizeof(struct nicira_header
)) {
399 VLOG_WARN_RL(&bad_ofmsg_rl
, "received Nicira vendor message of "
400 "length %u (expected at least %zu)",
401 ntohs(ovh
->header
.length
), sizeof(struct nicira_header
));
402 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_LEN
);
405 nh
= (const struct nicira_header
*) oh
;
406 return ofputil_lookup_openflow_message(&nxt_category
, ntohl(nh
->subtype
),
407 ntohs(oh
->length
), typep
);
411 check_nxstats_msg(const struct ofp_header
*oh
)
413 const struct ofp_stats_msg
*osm
= (const struct ofp_stats_msg
*) oh
;
416 memcpy(&vendor
, osm
+ 1, sizeof vendor
);
417 if (vendor
!= htonl(NX_VENDOR_ID
)) {
418 VLOG_WARN_RL(&bad_ofmsg_rl
, "received vendor stats message for "
419 "unknown vendor %"PRIx32
, ntohl(vendor
));
420 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_VENDOR
);
423 if (ntohs(osm
->header
.length
) < sizeof(struct nicira_stats_msg
)) {
424 VLOG_WARN_RL(&bad_ofmsg_rl
, "truncated Nicira stats message");
425 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_LEN
);
432 ofputil_decode_nxst_request(const struct ofp_header
*oh
,
433 const struct ofputil_msg_type
**typep
)
435 static const struct ofputil_msg_type nxst_requests
[] = {
436 { OFPUTIL_NXST_FLOW_REQUEST
,
437 NXST_FLOW
, "NXST_FLOW request",
438 sizeof(struct nx_flow_stats_request
), 8 },
440 { OFPUTIL_NXST_AGGREGATE_REQUEST
,
441 NXST_AGGREGATE
, "NXST_AGGREGATE request",
442 sizeof(struct nx_aggregate_stats_request
), 8 },
445 static const struct ofputil_msg_category nxst_request_category
= {
446 "Nicira extension statistics request",
447 nxst_requests
, ARRAY_SIZE(nxst_requests
),
448 OFP_MKERR(OFPET_BAD_REQUEST
, OFPBRC_BAD_SUBTYPE
)
451 const struct nicira_stats_msg
*nsm
;
454 error
= check_nxstats_msg(oh
);
459 nsm
= (struct nicira_stats_msg
*) oh
;
460 return ofputil_lookup_openflow_message(&nxst_request_category
,
462 ntohs(oh
->length
), typep
);
466 ofputil_decode_nxst_reply(const struct ofp_header
*oh
,
467 const struct ofputil_msg_type
**typep
)
469 static const struct ofputil_msg_type nxst_replies
[] = {
470 { OFPUTIL_NXST_FLOW_REPLY
,
471 NXST_FLOW
, "NXST_FLOW reply",
472 sizeof(struct nicira_stats_msg
), 8 },
474 { OFPUTIL_NXST_AGGREGATE_REPLY
,
475 NXST_AGGREGATE
, "NXST_AGGREGATE reply",
476 sizeof(struct nx_aggregate_stats_reply
), 0 },
479 static const struct ofputil_msg_category nxst_reply_category
= {
480 "Nicira extension statistics reply",
481 nxst_replies
, ARRAY_SIZE(nxst_replies
),
482 OFP_MKERR(OFPET_BAD_REQUEST
, OFPBRC_BAD_SUBTYPE
)
485 const struct nicira_stats_msg
*nsm
;
488 error
= check_nxstats_msg(oh
);
493 nsm
= (struct nicira_stats_msg
*) oh
;
494 return ofputil_lookup_openflow_message(&nxst_reply_category
,
496 ntohs(oh
->length
), typep
);
500 ofputil_decode_ofpst_request(const struct ofp_header
*oh
,
501 const struct ofputil_msg_type
**typep
)
503 static const struct ofputil_msg_type ofpst_requests
[] = {
504 { OFPUTIL_OFPST_DESC_REQUEST
,
505 OFPST_DESC
, "OFPST_DESC request",
506 sizeof(struct ofp_stats_msg
), 0 },
508 { OFPUTIL_OFPST_FLOW_REQUEST
,
509 OFPST_FLOW
, "OFPST_FLOW request",
510 sizeof(struct ofp_flow_stats_request
), 0 },
512 { OFPUTIL_OFPST_AGGREGATE_REQUEST
,
513 OFPST_AGGREGATE
, "OFPST_AGGREGATE request",
514 sizeof(struct ofp_flow_stats_request
), 0 },
516 { OFPUTIL_OFPST_TABLE_REQUEST
,
517 OFPST_TABLE
, "OFPST_TABLE request",
518 sizeof(struct ofp_stats_msg
), 0 },
520 { OFPUTIL_OFPST_PORT_REQUEST
,
521 OFPST_PORT
, "OFPST_PORT request",
522 sizeof(struct ofp_port_stats_request
), 0 },
524 { OFPUTIL_OFPST_QUEUE_REQUEST
,
525 OFPST_QUEUE
, "OFPST_QUEUE request",
526 sizeof(struct ofp_queue_stats_request
), 0 },
529 OFPST_VENDOR
, "OFPST_VENDOR request",
530 sizeof(struct ofp_vendor_stats_msg
), 1 },
533 static const struct ofputil_msg_category ofpst_request_category
= {
534 "OpenFlow statistics",
535 ofpst_requests
, ARRAY_SIZE(ofpst_requests
),
536 OFP_MKERR(OFPET_BAD_REQUEST
, OFPBRC_BAD_STAT
)
539 const struct ofp_stats_msg
*request
= (const struct ofp_stats_msg
*) oh
;
542 error
= ofputil_lookup_openflow_message(&ofpst_request_category
,
543 ntohs(request
->type
),
544 ntohs(oh
->length
), typep
);
545 if (!error
&& request
->type
== htons(OFPST_VENDOR
)) {
546 error
= ofputil_decode_nxst_request(oh
, typep
);
552 ofputil_decode_ofpst_reply(const struct ofp_header
*oh
,
553 const struct ofputil_msg_type
**typep
)
555 static const struct ofputil_msg_type ofpst_replies
[] = {
556 { OFPUTIL_OFPST_DESC_REPLY
,
557 OFPST_DESC
, "OFPST_DESC reply",
558 sizeof(struct ofp_desc_stats
), 0 },
560 { OFPUTIL_OFPST_FLOW_REPLY
,
561 OFPST_FLOW
, "OFPST_FLOW reply",
562 sizeof(struct ofp_stats_msg
), 1 },
564 { OFPUTIL_OFPST_AGGREGATE_REPLY
,
565 OFPST_AGGREGATE
, "OFPST_AGGREGATE reply",
566 sizeof(struct ofp_aggregate_stats_reply
), 0 },
568 { OFPUTIL_OFPST_TABLE_REPLY
,
569 OFPST_TABLE
, "OFPST_TABLE reply",
570 sizeof(struct ofp_stats_msg
), sizeof(struct ofp_table_stats
) },
572 { OFPUTIL_OFPST_PORT_REPLY
,
573 OFPST_PORT
, "OFPST_PORT reply",
574 sizeof(struct ofp_stats_msg
), sizeof(struct ofp_port_stats
) },
576 { OFPUTIL_OFPST_QUEUE_REPLY
,
577 OFPST_QUEUE
, "OFPST_QUEUE reply",
578 sizeof(struct ofp_stats_msg
), sizeof(struct ofp_queue_stats
) },
581 OFPST_VENDOR
, "OFPST_VENDOR reply",
582 sizeof(struct ofp_vendor_stats_msg
), 1 },
585 static const struct ofputil_msg_category ofpst_reply_category
= {
586 "OpenFlow statistics",
587 ofpst_replies
, ARRAY_SIZE(ofpst_replies
),
588 OFP_MKERR(OFPET_BAD_REQUEST
, OFPBRC_BAD_STAT
)
591 const struct ofp_stats_msg
*reply
= (const struct ofp_stats_msg
*) oh
;
594 error
= ofputil_lookup_openflow_message(&ofpst_reply_category
,
596 ntohs(oh
->length
), typep
);
597 if (!error
&& reply
->type
== htons(OFPST_VENDOR
)) {
598 error
= ofputil_decode_nxst_reply(oh
, typep
);
603 /* Decodes the message type represented by 'oh'. Returns 0 if successful or
604 * an OpenFlow error code constructed with ofp_mkerr() on failure. Either
605 * way, stores in '*typep' a type structure that can be inspected with the
606 * ofputil_msg_type_*() functions.
608 * oh->length must indicate the correct length of the message (and must be at
609 * least sizeof(struct ofp_header)).
611 * Success indicates that 'oh' is at least as long as the minimum-length
612 * message of its type. */
614 ofputil_decode_msg_type(const struct ofp_header
*oh
,
615 const struct ofputil_msg_type
**typep
)
617 static const struct ofputil_msg_type ofpt_messages
[] = {
618 { OFPUTIL_OFPT_HELLO
,
619 OFPT_HELLO
, "OFPT_HELLO",
620 sizeof(struct ofp_hello
), 1 },
622 { OFPUTIL_OFPT_ERROR
,
623 OFPT_ERROR
, "OFPT_ERROR",
624 sizeof(struct ofp_error_msg
), 1 },
626 { OFPUTIL_OFPT_ECHO_REQUEST
,
627 OFPT_ECHO_REQUEST
, "OFPT_ECHO_REQUEST",
628 sizeof(struct ofp_header
), 1 },
630 { OFPUTIL_OFPT_ECHO_REPLY
,
631 OFPT_ECHO_REPLY
, "OFPT_ECHO_REPLY",
632 sizeof(struct ofp_header
), 1 },
634 { OFPUTIL_OFPT_FEATURES_REQUEST
,
635 OFPT_FEATURES_REQUEST
, "OFPT_FEATURES_REQUEST",
636 sizeof(struct ofp_header
), 0 },
638 { OFPUTIL_OFPT_FEATURES_REPLY
,
639 OFPT_FEATURES_REPLY
, "OFPT_FEATURES_REPLY",
640 sizeof(struct ofp_switch_features
), sizeof(struct ofp_phy_port
) },
642 { OFPUTIL_OFPT_GET_CONFIG_REQUEST
,
643 OFPT_GET_CONFIG_REQUEST
, "OFPT_GET_CONFIG_REQUEST",
644 sizeof(struct ofp_header
), 0 },
646 { OFPUTIL_OFPT_GET_CONFIG_REPLY
,
647 OFPT_GET_CONFIG_REPLY
, "OFPT_GET_CONFIG_REPLY",
648 sizeof(struct ofp_switch_config
), 0 },
650 { OFPUTIL_OFPT_SET_CONFIG
,
651 OFPT_SET_CONFIG
, "OFPT_SET_CONFIG",
652 sizeof(struct ofp_switch_config
), 0 },
654 { OFPUTIL_OFPT_PACKET_IN
,
655 OFPT_PACKET_IN
, "OFPT_PACKET_IN",
656 offsetof(struct ofp_packet_in
, data
), 1 },
658 { OFPUTIL_OFPT_FLOW_REMOVED
,
659 OFPT_FLOW_REMOVED
, "OFPT_FLOW_REMOVED",
660 sizeof(struct ofp_flow_removed
), 0 },
662 { OFPUTIL_OFPT_PORT_STATUS
,
663 OFPT_PORT_STATUS
, "OFPT_PORT_STATUS",
664 sizeof(struct ofp_port_status
), 0 },
666 { OFPUTIL_OFPT_PACKET_OUT
,
667 OFPT_PACKET_OUT
, "OFPT_PACKET_OUT",
668 sizeof(struct ofp_packet_out
), 1 },
670 { OFPUTIL_OFPT_FLOW_MOD
,
671 OFPT_FLOW_MOD
, "OFPT_FLOW_MOD",
672 sizeof(struct ofp_flow_mod
), 1 },
674 { OFPUTIL_OFPT_PORT_MOD
,
675 OFPT_PORT_MOD
, "OFPT_PORT_MOD",
676 sizeof(struct ofp_port_mod
), 0 },
679 OFPT_STATS_REQUEST
, "OFPT_STATS_REQUEST",
680 sizeof(struct ofp_stats_msg
), 1 },
683 OFPT_STATS_REPLY
, "OFPT_STATS_REPLY",
684 sizeof(struct ofp_stats_msg
), 1 },
686 { OFPUTIL_OFPT_BARRIER_REQUEST
,
687 OFPT_BARRIER_REQUEST
, "OFPT_BARRIER_REQUEST",
688 sizeof(struct ofp_header
), 0 },
690 { OFPUTIL_OFPT_BARRIER_REPLY
,
691 OFPT_BARRIER_REPLY
, "OFPT_BARRIER_REPLY",
692 sizeof(struct ofp_header
), 0 },
695 OFPT_VENDOR
, "OFPT_VENDOR",
696 sizeof(struct ofp_vendor_header
), 1 },
699 static const struct ofputil_msg_category ofpt_category
= {
701 ofpt_messages
, ARRAY_SIZE(ofpt_messages
),
702 OFP_MKERR(OFPET_BAD_REQUEST
, OFPBRC_BAD_TYPE
)
707 error
= ofputil_lookup_openflow_message(&ofpt_category
, oh
->type
,
708 ntohs(oh
->length
), typep
);
712 error
= ofputil_decode_vendor(oh
, typep
);
715 case OFPT_STATS_REQUEST
:
716 error
= ofputil_decode_ofpst_request(oh
, typep
);
719 case OFPT_STATS_REPLY
:
720 error
= ofputil_decode_ofpst_reply(oh
, typep
);
727 static const struct ofputil_msg_type ofputil_invalid_type
= {
729 0, "OFPUTIL_MSG_INVALID",
733 *typep
= &ofputil_invalid_type
;
738 /* Returns an OFPUTIL_* message type code for 'type'. */
739 enum ofputil_msg_code
740 ofputil_msg_type_code(const struct ofputil_msg_type
*type
)
748 ofputil_flow_format_is_valid(enum nx_flow_format flow_format
)
750 switch (flow_format
) {
751 case NXFF_OPENFLOW10
:
760 ofputil_flow_format_to_string(enum nx_flow_format flow_format
)
762 switch (flow_format
) {
763 case NXFF_OPENFLOW10
:
773 ofputil_flow_format_from_string(const char *s
)
775 return (!strcmp(s
, "openflow10") ? NXFF_OPENFLOW10
776 : !strcmp(s
, "nxm") ? NXFF_NXM
781 regs_fully_wildcarded(const struct flow_wildcards
*wc
)
785 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
786 if (wc
->reg_masks
[i
] != 0) {
793 /* Returns the minimum nx_flow_format to use for sending 'rule' to a switch
794 * (e.g. to add or remove a flow). Only NXM can handle tunnel IDs, registers,
795 * or fixing the Ethernet multicast bit. Otherwise, it's better to use
796 * NXFF_OPENFLOW10 for backward compatibility. */
798 ofputil_min_flow_format(const struct cls_rule
*rule
)
800 const struct flow_wildcards
*wc
= &rule
->wc
;
802 /* Only NXM supports separately wildcards the Ethernet multicast bit. */
803 if (!(wc
->wildcards
& FWW_DL_DST
) != !(wc
->wildcards
& FWW_ETH_MCAST
)) {
807 /* Only NXM supports matching ARP hardware addresses. */
808 if (!(wc
->wildcards
& FWW_ARP_SHA
) || !(wc
->wildcards
& FWW_ARP_THA
)) {
812 /* Only NXM supports matching IPv6 traffic. */
813 if (!(wc
->wildcards
& FWW_DL_TYPE
)
814 && (rule
->flow
.dl_type
== htons(ETH_TYPE_IPV6
))) {
818 /* Only NXM supports matching registers. */
819 if (!regs_fully_wildcarded(wc
)) {
823 /* Only NXM supports matching tun_id. */
824 if (wc
->tun_id_mask
!= htonll(0)) {
828 /* Other formats can express this rule. */
829 return NXFF_OPENFLOW10
;
832 /* Returns an OpenFlow message that can be used to set the flow format to
835 ofputil_make_set_flow_format(enum nx_flow_format flow_format
)
837 struct nxt_set_flow_format
*sff
;
840 sff
= make_nxmsg(sizeof *sff
, NXT_SET_FLOW_FORMAT
, &msg
);
841 sff
->format
= htonl(flow_format
);
846 /* Returns an OpenFlow message that can be used to turn the flow_mod_table_id
847 * extension on or off (according to 'flow_mod_table_id'). */
849 ofputil_make_flow_mod_table_id(bool flow_mod_table_id
)
851 struct nxt_flow_mod_table_id
*nfmti
;
854 nfmti
= make_nxmsg(sizeof *nfmti
, NXT_FLOW_MOD_TABLE_ID
, &msg
);
855 nfmti
->set
= flow_mod_table_id
;
859 /* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
860 * flow_mod in 'fm'. Returns 0 if successful, otherwise an OpenFlow error
863 * 'flow_mod_table_id' should be true if the NXT_FLOW_MOD_TABLE_ID extension is
864 * enabled, false otherwise.
866 * Does not validate the flow_mod actions. */
868 ofputil_decode_flow_mod(struct flow_mod
*fm
, const struct ofp_header
*oh
,
869 bool flow_mod_table_id
)
871 const struct ofputil_msg_type
*type
;
875 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
877 ofputil_decode_msg_type(oh
, &type
);
878 if (ofputil_msg_type_code(type
) == OFPUTIL_OFPT_FLOW_MOD
) {
879 /* Standard OpenFlow flow_mod. */
880 const struct ofp_flow_mod
*ofm
;
884 /* Dissect the message. */
885 ofm
= ofpbuf_pull(&b
, sizeof *ofm
);
886 error
= ofputil_pull_actions(&b
, b
.size
, &fm
->actions
, &fm
->n_actions
);
891 /* Set priority based on original wildcards. Normally we'd allow
892 * ofputil_cls_rule_from_match() to do this for us, but
893 * ofputil_normalize_rule() can put wildcards where the original flow
894 * didn't have them. */
895 priority
= ntohs(ofm
->priority
);
896 if (!(ofm
->match
.wildcards
& htonl(OFPFW_ALL
))) {
897 priority
= UINT16_MAX
;
900 /* Translate the rule. */
901 ofputil_cls_rule_from_match(&ofm
->match
, priority
, &fm
->cr
);
902 ofputil_normalize_rule(&fm
->cr
, NXFF_OPENFLOW10
);
904 /* Translate the message. */
905 fm
->cookie
= ofm
->cookie
;
906 command
= ntohs(ofm
->command
);
907 fm
->idle_timeout
= ntohs(ofm
->idle_timeout
);
908 fm
->hard_timeout
= ntohs(ofm
->hard_timeout
);
909 fm
->buffer_id
= ntohl(ofm
->buffer_id
);
910 fm
->out_port
= ntohs(ofm
->out_port
);
911 fm
->flags
= ntohs(ofm
->flags
);
912 } else if (ofputil_msg_type_code(type
) == OFPUTIL_NXT_FLOW_MOD
) {
913 /* Nicira extended flow_mod. */
914 const struct nx_flow_mod
*nfm
;
917 /* Dissect the message. */
918 nfm
= ofpbuf_pull(&b
, sizeof *nfm
);
919 error
= nx_pull_match(&b
, ntohs(nfm
->match_len
), ntohs(nfm
->priority
),
924 error
= ofputil_pull_actions(&b
, b
.size
, &fm
->actions
, &fm
->n_actions
);
929 /* Translate the message. */
930 fm
->cookie
= nfm
->cookie
;
931 command
= ntohs(nfm
->command
);
932 fm
->idle_timeout
= ntohs(nfm
->idle_timeout
);
933 fm
->hard_timeout
= ntohs(nfm
->hard_timeout
);
934 fm
->buffer_id
= ntohl(nfm
->buffer_id
);
935 fm
->out_port
= ntohs(nfm
->out_port
);
936 fm
->flags
= ntohs(nfm
->flags
);
941 if (flow_mod_table_id
) {
942 fm
->command
= command
& 0xff;
943 fm
->table_id
= command
>> 8;
945 fm
->command
= command
;
952 /* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to
953 * 'flow_format' and returns the message.
955 * 'flow_mod_table_id' should be true if the NXT_FLOW_MOD_TABLE_ID extension is
956 * enabled, false otherwise. */
958 ofputil_encode_flow_mod(const struct flow_mod
*fm
,
959 enum nx_flow_format flow_format
,
960 bool flow_mod_table_id
)
962 size_t actions_len
= fm
->n_actions
* sizeof *fm
->actions
;
966 command
= (flow_mod_table_id
967 ? (fm
->command
& 0xff) | (fm
->table_id
<< 8)
970 if (flow_format
== NXFF_OPENFLOW10
) {
971 struct ofp_flow_mod
*ofm
;
973 msg
= ofpbuf_new(sizeof *ofm
+ actions_len
);
974 ofm
= put_openflow(sizeof *ofm
, OFPT_FLOW_MOD
, msg
);
975 ofputil_cls_rule_to_match(&fm
->cr
, &ofm
->match
);
976 ofm
->cookie
= fm
->cookie
;
977 ofm
->command
= htons(command
);
978 ofm
->idle_timeout
= htons(fm
->idle_timeout
);
979 ofm
->hard_timeout
= htons(fm
->hard_timeout
);
980 ofm
->priority
= htons(fm
->cr
.priority
);
981 ofm
->buffer_id
= htonl(fm
->buffer_id
);
982 ofm
->out_port
= htons(fm
->out_port
);
983 ofm
->flags
= htons(fm
->flags
);
984 } else if (flow_format
== NXFF_NXM
) {
985 struct nx_flow_mod
*nfm
;
988 msg
= ofpbuf_new(sizeof *nfm
+ NXM_TYPICAL_LEN
+ actions_len
);
989 put_nxmsg(sizeof *nfm
, NXT_FLOW_MOD
, msg
);
990 match_len
= nx_put_match(msg
, &fm
->cr
);
993 nfm
->cookie
= fm
->cookie
;
994 nfm
->command
= htons(command
);
995 nfm
->idle_timeout
= htons(fm
->idle_timeout
);
996 nfm
->hard_timeout
= htons(fm
->hard_timeout
);
997 nfm
->priority
= htons(fm
->cr
.priority
);
998 nfm
->buffer_id
= htonl(fm
->buffer_id
);
999 nfm
->out_port
= htons(fm
->out_port
);
1000 nfm
->flags
= htons(fm
->flags
);
1001 nfm
->match_len
= htons(match_len
);
1006 ofpbuf_put(msg
, fm
->actions
, actions_len
);
1007 update_openflow_length(msg
);
1012 ofputil_decode_ofpst_flow_request(struct flow_stats_request
*fsr
,
1013 const struct ofp_header
*oh
,
1016 const struct ofp_flow_stats_request
*ofsr
=
1017 (const struct ofp_flow_stats_request
*) oh
;
1019 fsr
->aggregate
= aggregate
;
1020 ofputil_cls_rule_from_match(&ofsr
->match
, 0, &fsr
->match
);
1021 fsr
->out_port
= ntohs(ofsr
->out_port
);
1022 fsr
->table_id
= ofsr
->table_id
;
1028 ofputil_decode_nxst_flow_request(struct flow_stats_request
*fsr
,
1029 const struct ofp_header
*oh
,
1032 const struct nx_flow_stats_request
*nfsr
;
1036 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1038 nfsr
= ofpbuf_pull(&b
, sizeof *nfsr
);
1039 error
= nx_pull_match(&b
, ntohs(nfsr
->match_len
), 0, &fsr
->match
);
1044 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_LEN
);
1047 fsr
->aggregate
= aggregate
;
1048 fsr
->out_port
= ntohs(nfsr
->out_port
);
1049 fsr
->table_id
= nfsr
->table_id
;
1054 /* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
1055 * request 'oh', into an abstract flow_stats_request in 'fsr'. Returns 0 if
1056 * successful, otherwise an OpenFlow error code. */
1058 ofputil_decode_flow_stats_request(struct flow_stats_request
*fsr
,
1059 const struct ofp_header
*oh
)
1061 const struct ofputil_msg_type
*type
;
1065 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1067 ofputil_decode_msg_type(oh
, &type
);
1068 code
= ofputil_msg_type_code(type
);
1070 case OFPUTIL_OFPST_FLOW_REQUEST
:
1071 return ofputil_decode_ofpst_flow_request(fsr
, oh
, false);
1073 case OFPUTIL_OFPST_AGGREGATE_REQUEST
:
1074 return ofputil_decode_ofpst_flow_request(fsr
, oh
, true);
1076 case OFPUTIL_NXST_FLOW_REQUEST
:
1077 return ofputil_decode_nxst_flow_request(fsr
, oh
, false);
1079 case OFPUTIL_NXST_AGGREGATE_REQUEST
:
1080 return ofputil_decode_nxst_flow_request(fsr
, oh
, true);
1083 /* Hey, the caller lied. */
1088 /* Converts abstract flow_stats_request 'fsr' into an OFPST_FLOW,
1089 * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
1090 * 'flow_format', and returns the message. */
1092 ofputil_encode_flow_stats_request(const struct flow_stats_request
*fsr
,
1093 enum nx_flow_format flow_format
)
1097 if (flow_format
== NXFF_OPENFLOW10
) {
1098 struct ofp_flow_stats_request
*ofsr
;
1101 type
= fsr
->aggregate
? OFPST_AGGREGATE
: OFPST_FLOW
;
1102 ofsr
= ofputil_make_stats_request(sizeof *ofsr
, type
, 0, &msg
);
1103 ofputil_cls_rule_to_match(&fsr
->match
, &ofsr
->match
);
1104 ofsr
->table_id
= fsr
->table_id
;
1105 ofsr
->out_port
= htons(fsr
->out_port
);
1106 } else if (flow_format
== NXFF_NXM
) {
1107 struct nx_flow_stats_request
*nfsr
;
1111 subtype
= fsr
->aggregate
? NXST_AGGREGATE
: NXST_FLOW
;
1112 ofputil_make_stats_request(sizeof *nfsr
, OFPST_VENDOR
, subtype
, &msg
);
1113 match_len
= nx_put_match(msg
, &fsr
->match
);
1116 nfsr
->out_port
= htons(fsr
->out_port
);
1117 nfsr
->match_len
= htons(match_len
);
1118 nfsr
->table_id
= fsr
->table_id
;
1126 /* Converts an OFPST_FLOW or NXST_FLOW reply in 'msg' into an abstract
1127 * ofputil_flow_stats in 'fs'.
1129 * Multiple OFPST_FLOW or NXST_FLOW replies can be packed into a single
1130 * OpenFlow message. Calling this function multiple times for a single 'msg'
1131 * iterates through the replies. The caller must initially leave 'msg''s layer
1132 * pointers null and not modify them between calls.
1134 * Returns 0 if successful, EOF if no replies were left in this 'msg',
1135 * otherwise a positive errno value. */
1137 ofputil_decode_flow_stats_reply(struct ofputil_flow_stats
*fs
,
1140 const struct ofputil_msg_type
*type
;
1143 ofputil_decode_msg_type(msg
->l2
? msg
->l2
: msg
->data
, &type
);
1144 code
= ofputil_msg_type_code(type
);
1146 msg
->l2
= msg
->data
;
1147 if (code
== OFPUTIL_OFPST_FLOW_REPLY
) {
1148 ofpbuf_pull(msg
, sizeof(struct ofp_stats_msg
));
1149 } else if (code
== OFPUTIL_NXST_FLOW_REPLY
) {
1150 ofpbuf_pull(msg
, sizeof(struct nicira_stats_msg
));
1158 } else if (code
== OFPUTIL_OFPST_FLOW_REPLY
) {
1159 const struct ofp_flow_stats
*ofs
;
1162 ofs
= ofpbuf_try_pull(msg
, sizeof *ofs
);
1164 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply has %zu leftover "
1165 "bytes at end", msg
->size
);
1169 length
= ntohs(ofs
->length
);
1170 if (length
< sizeof *ofs
) {
1171 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply claims invalid "
1172 "length %zu", length
);
1176 if (ofputil_pull_actions(msg
, length
- sizeof *ofs
,
1177 &fs
->actions
, &fs
->n_actions
)) {
1181 fs
->cookie
= get_32aligned_be64(&ofs
->cookie
);
1182 ofputil_cls_rule_from_match(&ofs
->match
, ntohs(ofs
->priority
),
1184 fs
->table_id
= ofs
->table_id
;
1185 fs
->duration_sec
= ntohl(ofs
->duration_sec
);
1186 fs
->duration_nsec
= ntohl(ofs
->duration_nsec
);
1187 fs
->idle_timeout
= ntohs(ofs
->idle_timeout
);
1188 fs
->hard_timeout
= ntohs(ofs
->hard_timeout
);
1189 fs
->packet_count
= ntohll(get_32aligned_be64(&ofs
->packet_count
));
1190 fs
->byte_count
= ntohll(get_32aligned_be64(&ofs
->byte_count
));
1191 } else if (code
== OFPUTIL_NXST_FLOW_REPLY
) {
1192 const struct nx_flow_stats
*nfs
;
1193 size_t match_len
, length
;
1195 nfs
= ofpbuf_try_pull(msg
, sizeof *nfs
);
1197 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW reply has %zu leftover "
1198 "bytes at end", msg
->size
);
1202 length
= ntohs(nfs
->length
);
1203 match_len
= ntohs(nfs
->match_len
);
1204 if (length
< sizeof *nfs
+ ROUND_UP(match_len
, 8)) {
1205 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW reply with match_len=%zu "
1206 "claims invalid length %zu", match_len
, length
);
1209 if (nx_pull_match(msg
, match_len
, ntohs(nfs
->priority
), &fs
->rule
)) {
1213 if (ofputil_pull_actions(msg
,
1214 length
- sizeof *nfs
- ROUND_UP(match_len
, 8),
1215 &fs
->actions
, &fs
->n_actions
)) {
1219 fs
->cookie
= nfs
->cookie
;
1220 fs
->table_id
= nfs
->table_id
;
1221 fs
->duration_sec
= ntohl(nfs
->duration_sec
);
1222 fs
->duration_nsec
= ntohl(nfs
->duration_nsec
);
1223 fs
->idle_timeout
= ntohs(nfs
->idle_timeout
);
1224 fs
->hard_timeout
= ntohs(nfs
->hard_timeout
);
1225 fs
->packet_count
= ntohll(nfs
->packet_count
);
1226 fs
->byte_count
= ntohll(nfs
->byte_count
);
1234 /* Returns 'count' unchanged except that UINT64_MAX becomes 0.
1236 * We use this in situations where OVS internally uses UINT64_MAX to mean
1237 * "value unknown" but OpenFlow 1.0 does not define any unknown value. */
1239 unknown_to_zero(uint64_t count
)
1241 return count
!= UINT64_MAX
? count
: 0;
1244 /* Appends an OFPST_FLOW or NXST_FLOW reply that contains the data in 'fs' to
1245 * those already present in the list of ofpbufs in 'replies'. 'replies' should
1246 * have been initialized with ofputil_start_stats_reply(). */
1248 ofputil_append_flow_stats_reply(const struct ofputil_flow_stats
*fs
,
1249 struct list
*replies
)
1251 size_t act_len
= fs
->n_actions
* sizeof *fs
->actions
;
1252 const struct ofp_stats_msg
*osm
;
1254 osm
= ofpbuf_from_list(list_back(replies
))->data
;
1255 if (osm
->type
== htons(OFPST_FLOW
)) {
1256 size_t len
= offsetof(struct ofp_flow_stats
, actions
) + act_len
;
1257 struct ofp_flow_stats
*ofs
;
1259 ofs
= ofputil_append_stats_reply(len
, replies
);
1260 ofs
->length
= htons(len
);
1261 ofs
->table_id
= fs
->table_id
;
1263 ofputil_cls_rule_to_match(&fs
->rule
, &ofs
->match
);
1264 ofs
->duration_sec
= htonl(fs
->duration_sec
);
1265 ofs
->duration_nsec
= htonl(fs
->duration_nsec
);
1266 ofs
->priority
= htons(fs
->rule
.priority
);
1267 ofs
->idle_timeout
= htons(fs
->idle_timeout
);
1268 ofs
->hard_timeout
= htons(fs
->hard_timeout
);
1269 memset(ofs
->pad2
, 0, sizeof ofs
->pad2
);
1270 put_32aligned_be64(&ofs
->cookie
, fs
->cookie
);
1271 put_32aligned_be64(&ofs
->packet_count
,
1272 htonll(unknown_to_zero(fs
->packet_count
)));
1273 put_32aligned_be64(&ofs
->byte_count
,
1274 htonll(unknown_to_zero(fs
->byte_count
)));
1275 memcpy(ofs
->actions
, fs
->actions
, act_len
);
1276 } else if (osm
->type
== htons(OFPST_VENDOR
)) {
1277 struct nx_flow_stats
*nfs
;
1281 msg
= ofputil_reserve_stats_reply(
1282 sizeof *nfs
+ NXM_MAX_LEN
+ act_len
, replies
);
1283 start_len
= msg
->size
;
1285 nfs
= ofpbuf_put_uninit(msg
, sizeof *nfs
);
1286 nfs
->table_id
= fs
->table_id
;
1288 nfs
->duration_sec
= htonl(fs
->duration_sec
);
1289 nfs
->duration_nsec
= htonl(fs
->duration_nsec
);
1290 nfs
->priority
= htons(fs
->rule
.priority
);
1291 nfs
->idle_timeout
= htons(fs
->idle_timeout
);
1292 nfs
->hard_timeout
= htons(fs
->hard_timeout
);
1293 nfs
->match_len
= htons(nx_put_match(msg
, &fs
->rule
));
1294 memset(nfs
->pad2
, 0, sizeof nfs
->pad2
);
1295 nfs
->cookie
= fs
->cookie
;
1296 nfs
->packet_count
= htonll(fs
->packet_count
);
1297 nfs
->byte_count
= htonll(fs
->byte_count
);
1298 ofpbuf_put(msg
, fs
->actions
, act_len
);
1299 nfs
->length
= htons(msg
->size
- start_len
);
1305 /* Converts abstract ofputil_aggregate_stats 'stats' into an OFPST_AGGREGATE or
1306 * NXST_AGGREGATE reply according to 'flow_format', and returns the message. */
1308 ofputil_encode_aggregate_stats_reply(
1309 const struct ofputil_aggregate_stats
*stats
,
1310 const struct ofp_stats_msg
*request
)
1314 if (request
->type
== htons(OFPST_AGGREGATE
)) {
1315 struct ofp_aggregate_stats_reply
*asr
;
1317 asr
= ofputil_make_stats_reply(sizeof *asr
, request
, &msg
);
1318 put_32aligned_be64(&asr
->packet_count
,
1319 htonll(unknown_to_zero(stats
->packet_count
)));
1320 put_32aligned_be64(&asr
->byte_count
,
1321 htonll(unknown_to_zero(stats
->byte_count
)));
1322 asr
->flow_count
= htonl(stats
->flow_count
);
1323 } else if (request
->type
== htons(OFPST_VENDOR
)) {
1324 struct nx_aggregate_stats_reply
*nasr
;
1326 nasr
= ofputil_make_stats_reply(sizeof *nasr
, request
, &msg
);
1327 assert(nasr
->nsm
.subtype
== htonl(NXST_AGGREGATE
));
1328 nasr
->packet_count
= htonll(stats
->packet_count
);
1329 nasr
->byte_count
= htonll(stats
->byte_count
);
1330 nasr
->flow_count
= htonl(stats
->flow_count
);
1338 /* Converts an OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED message 'oh' into an
1339 * abstract ofputil_flow_removed in 'fr'. Returns 0 if successful, otherwise
1340 * an OpenFlow error code. */
1342 ofputil_decode_flow_removed(struct ofputil_flow_removed
*fr
,
1343 const struct ofp_header
*oh
)
1345 const struct ofputil_msg_type
*type
;
1346 enum ofputil_msg_code code
;
1348 ofputil_decode_msg_type(oh
, &type
);
1349 code
= ofputil_msg_type_code(type
);
1350 if (code
== OFPUTIL_OFPT_FLOW_REMOVED
) {
1351 const struct ofp_flow_removed
*ofr
;
1353 ofr
= (const struct ofp_flow_removed
*) oh
;
1354 ofputil_cls_rule_from_match(&ofr
->match
, ntohs(ofr
->priority
),
1356 fr
->cookie
= ofr
->cookie
;
1357 fr
->reason
= ofr
->reason
;
1358 fr
->duration_sec
= ntohl(ofr
->duration_sec
);
1359 fr
->duration_nsec
= ntohl(ofr
->duration_nsec
);
1360 fr
->idle_timeout
= ntohs(ofr
->idle_timeout
);
1361 fr
->packet_count
= ntohll(ofr
->packet_count
);
1362 fr
->byte_count
= ntohll(ofr
->byte_count
);
1363 } else if (code
== OFPUTIL_NXT_FLOW_REMOVED
) {
1364 struct nx_flow_removed
*nfr
;
1368 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1370 nfr
= ofpbuf_pull(&b
, sizeof *nfr
);
1371 error
= nx_pull_match(&b
, ntohs(nfr
->match_len
), ntohs(nfr
->priority
),
1377 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_LEN
);
1380 fr
->cookie
= nfr
->cookie
;
1381 fr
->reason
= nfr
->reason
;
1382 fr
->duration_sec
= ntohl(nfr
->duration_sec
);
1383 fr
->duration_nsec
= ntohl(nfr
->duration_nsec
);
1384 fr
->idle_timeout
= ntohs(nfr
->idle_timeout
);
1385 fr
->packet_count
= ntohll(nfr
->packet_count
);
1386 fr
->byte_count
= ntohll(nfr
->byte_count
);
1394 /* Converts abstract ofputil_flow_removed 'fr' into an OFPT_FLOW_REMOVED or
1395 * NXT_FLOW_REMOVED message 'oh' according to 'flow_format', and returns the
1398 ofputil_encode_flow_removed(const struct ofputil_flow_removed
*fr
,
1399 enum nx_flow_format flow_format
)
1403 if (flow_format
== NXFF_OPENFLOW10
) {
1404 struct ofp_flow_removed
*ofr
;
1406 ofr
= make_openflow_xid(sizeof *ofr
, OFPT_FLOW_REMOVED
, htonl(0),
1408 ofputil_cls_rule_to_match(&fr
->rule
, &ofr
->match
);
1409 ofr
->cookie
= fr
->cookie
;
1410 ofr
->priority
= htons(fr
->rule
.priority
);
1411 ofr
->reason
= fr
->reason
;
1412 ofr
->duration_sec
= htonl(fr
->duration_sec
);
1413 ofr
->duration_nsec
= htonl(fr
->duration_nsec
);
1414 ofr
->idle_timeout
= htons(fr
->idle_timeout
);
1415 ofr
->packet_count
= htonll(unknown_to_zero(fr
->packet_count
));
1416 ofr
->byte_count
= htonll(unknown_to_zero(fr
->byte_count
));
1417 } else if (flow_format
== NXFF_NXM
) {
1418 struct nx_flow_removed
*nfr
;
1421 make_nxmsg_xid(sizeof *nfr
, NXT_FLOW_REMOVED
, htonl(0), &msg
);
1422 match_len
= nx_put_match(msg
, &fr
->rule
);
1425 nfr
->cookie
= fr
->cookie
;
1426 nfr
->priority
= htons(fr
->rule
.priority
);
1427 nfr
->reason
= fr
->reason
;
1428 nfr
->duration_sec
= htonl(fr
->duration_sec
);
1429 nfr
->duration_nsec
= htonl(fr
->duration_nsec
);
1430 nfr
->idle_timeout
= htons(fr
->idle_timeout
);
1431 nfr
->match_len
= htons(match_len
);
1432 nfr
->packet_count
= htonll(fr
->packet_count
);
1433 nfr
->byte_count
= htonll(fr
->byte_count
);
1441 /* Converts abstract ofputil_packet_in 'pin' into an OFPT_PACKET_IN message
1442 * and returns the message.
1444 * If 'rw_packet' is NULL, the caller takes ownership of the newly allocated
1447 * If 'rw_packet' is nonnull, then it must contain the same data as
1448 * pin->packet. 'rw_packet' is allowed to be the same ofpbuf as pin->packet.
1449 * It is modified in-place into an OFPT_PACKET_IN message according to 'pin',
1450 * and then ofputil_encode_packet_in() returns 'rw_packet'. If 'rw_packet' has
1451 * enough headroom to insert a "struct ofp_packet_in", this is more efficient
1452 * than ofputil_encode_packet_in() because it does not copy the packet
1455 ofputil_encode_packet_in(const struct ofputil_packet_in
*pin
,
1456 struct ofpbuf
*rw_packet
)
1458 int total_len
= pin
->packet
->size
;
1459 struct ofp_packet_in
*opi
;
1462 if (pin
->send_len
< rw_packet
->size
) {
1463 rw_packet
->size
= pin
->send_len
;
1466 rw_packet
= ofpbuf_clone_data_with_headroom(
1467 pin
->packet
->data
, MIN(pin
->send_len
, pin
->packet
->size
),
1468 offsetof(struct ofp_packet_in
, data
));
1471 /* Add OFPT_PACKET_IN. */
1472 opi
= ofpbuf_push_zeros(rw_packet
, offsetof(struct ofp_packet_in
, data
));
1473 opi
->header
.version
= OFP_VERSION
;
1474 opi
->header
.type
= OFPT_PACKET_IN
;
1475 opi
->total_len
= htons(total_len
);
1476 opi
->in_port
= htons(pin
->in_port
);
1477 opi
->reason
= pin
->reason
;
1478 opi
->buffer_id
= htonl(pin
->buffer_id
);
1479 update_openflow_length(rw_packet
);
1484 /* Returns a string representing the message type of 'type'. The string is the
1485 * enumeration constant for the type, e.g. "OFPT_HELLO". For statistics
1486 * messages, the constant is followed by "request" or "reply",
1487 * e.g. "OFPST_AGGREGATE reply". */
1489 ofputil_msg_type_name(const struct ofputil_msg_type
*type
)
1494 /* Allocates and stores in '*bufferp' a new ofpbuf with a size of
1495 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
1496 * an arbitrary transaction id. Allocated bytes beyond the header, if any, are
1499 * The caller is responsible for freeing '*bufferp' when it is no longer
1502 * The OpenFlow header length is initially set to 'openflow_len'; if the
1503 * message is later extended, the length should be updated with
1504 * update_openflow_length() before sending.
1506 * Returns the header. */
1508 make_openflow(size_t openflow_len
, uint8_t type
, struct ofpbuf
**bufferp
)
1510 *bufferp
= ofpbuf_new(openflow_len
);
1511 return put_openflow_xid(openflow_len
, type
, alloc_xid(), *bufferp
);
1514 /* Similar to make_openflow() but creates a Nicira vendor extension message
1515 * with the specific 'subtype'. 'subtype' should be in host byte order. */
1517 make_nxmsg(size_t openflow_len
, uint32_t subtype
, struct ofpbuf
**bufferp
)
1519 return make_nxmsg_xid(openflow_len
, subtype
, alloc_xid(), bufferp
);
1522 /* Allocates and stores in '*bufferp' a new ofpbuf with a size of
1523 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
1524 * transaction id 'xid'. Allocated bytes beyond the header, if any, are
1527 * The caller is responsible for freeing '*bufferp' when it is no longer
1530 * The OpenFlow header length is initially set to 'openflow_len'; if the
1531 * message is later extended, the length should be updated with
1532 * update_openflow_length() before sending.
1534 * Returns the header. */
1536 make_openflow_xid(size_t openflow_len
, uint8_t type
, ovs_be32 xid
,
1537 struct ofpbuf
**bufferp
)
1539 *bufferp
= ofpbuf_new(openflow_len
);
1540 return put_openflow_xid(openflow_len
, type
, xid
, *bufferp
);
1543 /* Similar to make_openflow_xid() but creates a Nicira vendor extension message
1544 * with the specific 'subtype'. 'subtype' should be in host byte order. */
1546 make_nxmsg_xid(size_t openflow_len
, uint32_t subtype
, ovs_be32 xid
,
1547 struct ofpbuf
**bufferp
)
1549 *bufferp
= ofpbuf_new(openflow_len
);
1550 return put_nxmsg_xid(openflow_len
, subtype
, xid
, *bufferp
);
1553 /* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
1554 * with the given 'type' and an arbitrary transaction id. Allocated bytes
1555 * beyond the header, if any, are zeroed.
1557 * The OpenFlow header length is initially set to 'openflow_len'; if the
1558 * message is later extended, the length should be updated with
1559 * update_openflow_length() before sending.
1561 * Returns the header. */
1563 put_openflow(size_t openflow_len
, uint8_t type
, struct ofpbuf
*buffer
)
1565 return put_openflow_xid(openflow_len
, type
, alloc_xid(), buffer
);
1568 /* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
1569 * with the given 'type' and an transaction id 'xid'. Allocated bytes beyond
1570 * the header, if any, are zeroed.
1572 * The OpenFlow header length is initially set to 'openflow_len'; if the
1573 * message is later extended, the length should be updated with
1574 * update_openflow_length() before sending.
1576 * Returns the header. */
1578 put_openflow_xid(size_t openflow_len
, uint8_t type
, ovs_be32 xid
,
1579 struct ofpbuf
*buffer
)
1581 struct ofp_header
*oh
;
1583 assert(openflow_len
>= sizeof *oh
);
1584 assert(openflow_len
<= UINT16_MAX
);
1586 oh
= ofpbuf_put_uninit(buffer
, openflow_len
);
1587 oh
->version
= OFP_VERSION
;
1589 oh
->length
= htons(openflow_len
);
1591 memset(oh
+ 1, 0, openflow_len
- sizeof *oh
);
1595 /* Similar to put_openflow() but append a Nicira vendor extension message with
1596 * the specific 'subtype'. 'subtype' should be in host byte order. */
1598 put_nxmsg(size_t openflow_len
, uint32_t subtype
, struct ofpbuf
*buffer
)
1600 return put_nxmsg_xid(openflow_len
, subtype
, alloc_xid(), buffer
);
1603 /* Similar to put_openflow_xid() but append a Nicira vendor extension message
1604 * with the specific 'subtype'. 'subtype' should be in host byte order. */
1606 put_nxmsg_xid(size_t openflow_len
, uint32_t subtype
, ovs_be32 xid
,
1607 struct ofpbuf
*buffer
)
1609 struct nicira_header
*nxh
;
1611 nxh
= put_openflow_xid(openflow_len
, OFPT_VENDOR
, xid
, buffer
);
1612 nxh
->vendor
= htonl(NX_VENDOR_ID
);
1613 nxh
->subtype
= htonl(subtype
);
1617 /* Updates the 'length' field of the OpenFlow message in 'buffer' to
1618 * 'buffer->size'. */
1620 update_openflow_length(struct ofpbuf
*buffer
)
1622 struct ofp_header
*oh
= ofpbuf_at_assert(buffer
, 0, sizeof *oh
);
1623 oh
->length
= htons(buffer
->size
);
1627 put_stats__(ovs_be32 xid
, uint8_t ofp_type
,
1628 ovs_be16 ofpst_type
, ovs_be32 nxst_subtype
,
1631 if (ofpst_type
== htons(OFPST_VENDOR
)) {
1632 struct nicira_stats_msg
*nsm
;
1634 nsm
= put_openflow_xid(sizeof *nsm
, ofp_type
, xid
, msg
);
1635 nsm
->vsm
.osm
.type
= ofpst_type
;
1636 nsm
->vsm
.vendor
= htonl(NX_VENDOR_ID
);
1637 nsm
->subtype
= nxst_subtype
;
1639 struct ofp_stats_msg
*osm
;
1641 osm
= put_openflow_xid(sizeof *osm
, ofp_type
, xid
, msg
);
1642 osm
->type
= ofpst_type
;
1646 /* Creates a statistics request message with total length 'openflow_len'
1647 * (including all headers) and the given 'ofpst_type', and stores the buffer
1648 * containing the new message in '*bufferp'. If 'ofpst_type' is OFPST_VENDOR
1649 * then 'nxst_subtype' is used as the Nicira vendor extension statistics
1650 * subtype (otherwise 'nxst_subtype' is ignored).
1652 * Initializes bytes following the headers to all-bits-zero.
1654 * Returns the first byte of the new message. */
1656 ofputil_make_stats_request(size_t openflow_len
, uint16_t ofpst_type
,
1657 uint32_t nxst_subtype
, struct ofpbuf
**bufferp
)
1661 msg
= *bufferp
= ofpbuf_new(openflow_len
);
1662 put_stats__(alloc_xid(), OFPT_STATS_REQUEST
,
1663 htons(ofpst_type
), htonl(nxst_subtype
), msg
);
1664 ofpbuf_padto(msg
, openflow_len
);
1670 put_stats_reply__(const struct ofp_stats_msg
*request
, struct ofpbuf
*msg
)
1672 assert(request
->header
.type
== OFPT_STATS_REQUEST
||
1673 request
->header
.type
== OFPT_STATS_REPLY
);
1674 put_stats__(request
->header
.xid
, OFPT_STATS_REPLY
, request
->type
,
1675 (request
->type
!= htons(OFPST_VENDOR
)
1677 : ((const struct nicira_stats_msg
*) request
)->subtype
),
1681 /* Creates a statistics reply message with total length 'openflow_len'
1682 * (including all headers) and the same type (either a standard OpenFlow
1683 * statistics type or a Nicira extension type and subtype) as 'request', and
1684 * stores the buffer containing the new message in '*bufferp'.
1686 * Initializes bytes following the headers to all-bits-zero.
1688 * Returns the first byte of the new message. */
1690 ofputil_make_stats_reply(size_t openflow_len
,
1691 const struct ofp_stats_msg
*request
,
1692 struct ofpbuf
**bufferp
)
1696 msg
= *bufferp
= ofpbuf_new(openflow_len
);
1697 put_stats_reply__(request
, msg
);
1698 ofpbuf_padto(msg
, openflow_len
);
1703 /* Initializes 'replies' as a list of ofpbufs that will contain a series of
1704 * replies to 'request', which should be an OpenFlow or Nicira extension
1705 * statistics request. Initially 'replies' will have a single reply message
1706 * that has only a header. The functions ofputil_reserve_stats_reply() and
1707 * ofputil_append_stats_reply() may be used to add to the reply. */
1709 ofputil_start_stats_reply(const struct ofp_stats_msg
*request
,
1710 struct list
*replies
)
1714 msg
= ofpbuf_new(1024);
1715 put_stats_reply__(request
, msg
);
1718 list_push_back(replies
, &msg
->list_node
);
1721 /* Prepares to append up to 'len' bytes to the series of statistics replies in
1722 * 'replies', which should have been initialized with
1723 * ofputil_start_stats_reply(). Returns an ofpbuf with at least 'len' bytes of
1724 * tailroom. (The 'len' bytes have not actually be allocated; the caller must
1725 * do so with e.g. ofpbuf_put_uninit().) */
1727 ofputil_reserve_stats_reply(size_t len
, struct list
*replies
)
1729 struct ofpbuf
*msg
= ofpbuf_from_list(list_back(replies
));
1730 struct ofp_stats_msg
*osm
= msg
->data
;
1732 if (msg
->size
+ len
<= UINT16_MAX
) {
1733 ofpbuf_prealloc_tailroom(msg
, len
);
1735 osm
->flags
|= htons(OFPSF_REPLY_MORE
);
1737 msg
= ofpbuf_new(MAX(1024, sizeof(struct nicira_stats_msg
) + len
));
1738 put_stats_reply__(osm
, msg
);
1739 list_push_back(replies
, &msg
->list_node
);
1744 /* Appends 'len' bytes to the series of statistics replies in 'replies', and
1745 * returns the first byte. */
1747 ofputil_append_stats_reply(size_t len
, struct list
*replies
)
1749 return ofpbuf_put_uninit(ofputil_reserve_stats_reply(len
, replies
), len
);
1752 /* Returns the first byte past the ofp_stats_msg header in 'oh'. */
1754 ofputil_stats_body(const struct ofp_header
*oh
)
1756 assert(oh
->type
== OFPT_STATS_REQUEST
|| oh
->type
== OFPT_STATS_REPLY
);
1757 return (const struct ofp_stats_msg
*) oh
+ 1;
1760 /* Returns the number of bytes past the ofp_stats_msg header in 'oh'. */
1762 ofputil_stats_body_len(const struct ofp_header
*oh
)
1764 assert(oh
->type
== OFPT_STATS_REQUEST
|| oh
->type
== OFPT_STATS_REPLY
);
1765 return ntohs(oh
->length
) - sizeof(struct ofp_stats_msg
);
1768 /* Returns the first byte past the nicira_stats_msg header in 'oh'. */
1770 ofputil_nxstats_body(const struct ofp_header
*oh
)
1772 assert(oh
->type
== OFPT_STATS_REQUEST
|| oh
->type
== OFPT_STATS_REPLY
);
1773 return ((const struct nicira_stats_msg
*) oh
) + 1;
1776 /* Returns the number of bytes past the nicira_stats_msg header in 'oh'. */
1778 ofputil_nxstats_body_len(const struct ofp_header
*oh
)
1780 assert(oh
->type
== OFPT_STATS_REQUEST
|| oh
->type
== OFPT_STATS_REPLY
);
1781 return ntohs(oh
->length
) - sizeof(struct nicira_stats_msg
);
1785 make_flow_mod(uint16_t command
, const struct cls_rule
*rule
,
1788 struct ofp_flow_mod
*ofm
;
1789 size_t size
= sizeof *ofm
+ actions_len
;
1790 struct ofpbuf
*out
= ofpbuf_new(size
);
1791 ofm
= ofpbuf_put_zeros(out
, sizeof *ofm
);
1792 ofm
->header
.version
= OFP_VERSION
;
1793 ofm
->header
.type
= OFPT_FLOW_MOD
;
1794 ofm
->header
.length
= htons(size
);
1796 ofm
->priority
= htons(MIN(rule
->priority
, UINT16_MAX
));
1797 ofputil_cls_rule_to_match(rule
, &ofm
->match
);
1798 ofm
->command
= htons(command
);
1803 make_add_flow(const struct cls_rule
*rule
, uint32_t buffer_id
,
1804 uint16_t idle_timeout
, size_t actions_len
)
1806 struct ofpbuf
*out
= make_flow_mod(OFPFC_ADD
, rule
, actions_len
);
1807 struct ofp_flow_mod
*ofm
= out
->data
;
1808 ofm
->idle_timeout
= htons(idle_timeout
);
1809 ofm
->hard_timeout
= htons(OFP_FLOW_PERMANENT
);
1810 ofm
->buffer_id
= htonl(buffer_id
);
1815 make_del_flow(const struct cls_rule
*rule
)
1817 struct ofpbuf
*out
= make_flow_mod(OFPFC_DELETE_STRICT
, rule
, 0);
1818 struct ofp_flow_mod
*ofm
= out
->data
;
1819 ofm
->out_port
= htons(OFPP_NONE
);
1824 make_add_simple_flow(const struct cls_rule
*rule
,
1825 uint32_t buffer_id
, uint16_t out_port
,
1826 uint16_t idle_timeout
)
1828 if (out_port
!= OFPP_NONE
) {
1829 struct ofp_action_output
*oao
;
1830 struct ofpbuf
*buffer
;
1832 buffer
= make_add_flow(rule
, buffer_id
, idle_timeout
, sizeof *oao
);
1833 oao
= ofpbuf_put_zeros(buffer
, sizeof *oao
);
1834 oao
->type
= htons(OFPAT_OUTPUT
);
1835 oao
->len
= htons(sizeof *oao
);
1836 oao
->port
= htons(out_port
);
1839 return make_add_flow(rule
, buffer_id
, idle_timeout
, 0);
1844 make_packet_in(uint32_t buffer_id
, uint16_t in_port
, uint8_t reason
,
1845 const struct ofpbuf
*payload
, int max_send_len
)
1847 struct ofp_packet_in
*opi
;
1851 send_len
= MIN(max_send_len
, payload
->size
);
1852 buf
= ofpbuf_new(sizeof *opi
+ send_len
);
1853 opi
= put_openflow_xid(offsetof(struct ofp_packet_in
, data
),
1854 OFPT_PACKET_IN
, 0, buf
);
1855 opi
->buffer_id
= htonl(buffer_id
);
1856 opi
->total_len
= htons(payload
->size
);
1857 opi
->in_port
= htons(in_port
);
1858 opi
->reason
= reason
;
1859 ofpbuf_put(buf
, payload
->data
, send_len
);
1860 update_openflow_length(buf
);
1866 make_packet_out(const struct ofpbuf
*packet
, uint32_t buffer_id
,
1868 const struct ofp_action_header
*actions
, size_t n_actions
)
1870 size_t actions_len
= n_actions
* sizeof *actions
;
1871 struct ofp_packet_out
*opo
;
1872 size_t size
= sizeof *opo
+ actions_len
+ (packet
? packet
->size
: 0);
1873 struct ofpbuf
*out
= ofpbuf_new(size
);
1875 opo
= ofpbuf_put_uninit(out
, sizeof *opo
);
1876 opo
->header
.version
= OFP_VERSION
;
1877 opo
->header
.type
= OFPT_PACKET_OUT
;
1878 opo
->header
.length
= htons(size
);
1879 opo
->header
.xid
= htonl(0);
1880 opo
->buffer_id
= htonl(buffer_id
);
1881 opo
->in_port
= htons(in_port
== ODPP_LOCAL
? OFPP_LOCAL
: in_port
);
1882 opo
->actions_len
= htons(actions_len
);
1883 ofpbuf_put(out
, actions
, actions_len
);
1885 ofpbuf_put(out
, packet
->data
, packet
->size
);
1891 make_unbuffered_packet_out(const struct ofpbuf
*packet
,
1892 uint16_t in_port
, uint16_t out_port
)
1894 struct ofp_action_output action
;
1895 action
.type
= htons(OFPAT_OUTPUT
);
1896 action
.len
= htons(sizeof action
);
1897 action
.port
= htons(out_port
);
1898 return make_packet_out(packet
, UINT32_MAX
, in_port
,
1899 (struct ofp_action_header
*) &action
, 1);
1903 make_buffered_packet_out(uint32_t buffer_id
,
1904 uint16_t in_port
, uint16_t out_port
)
1906 if (out_port
!= OFPP_NONE
) {
1907 struct ofp_action_output action
;
1908 action
.type
= htons(OFPAT_OUTPUT
);
1909 action
.len
= htons(sizeof action
);
1910 action
.port
= htons(out_port
);
1911 return make_packet_out(NULL
, buffer_id
, in_port
,
1912 (struct ofp_action_header
*) &action
, 1);
1914 return make_packet_out(NULL
, buffer_id
, in_port
, NULL
, 0);
1918 /* Creates and returns an OFPT_ECHO_REQUEST message with an empty payload. */
1920 make_echo_request(void)
1922 struct ofp_header
*rq
;
1923 struct ofpbuf
*out
= ofpbuf_new(sizeof *rq
);
1924 rq
= ofpbuf_put_uninit(out
, sizeof *rq
);
1925 rq
->version
= OFP_VERSION
;
1926 rq
->type
= OFPT_ECHO_REQUEST
;
1927 rq
->length
= htons(sizeof *rq
);
1932 /* Creates and returns an OFPT_ECHO_REPLY message matching the
1933 * OFPT_ECHO_REQUEST message in 'rq'. */
1935 make_echo_reply(const struct ofp_header
*rq
)
1937 size_t size
= ntohs(rq
->length
);
1938 struct ofpbuf
*out
= ofpbuf_new(size
);
1939 struct ofp_header
*reply
= ofpbuf_put(out
, rq
, size
);
1940 reply
->type
= OFPT_ECHO_REPLY
;
1944 /* Checks that 'port' is a valid output port for the OFPAT_OUTPUT action, given
1945 * that the switch will never have more than 'max_ports' ports. Returns 0 if
1946 * 'port' is valid, otherwise an ofp_mkerr() return code. */
1948 check_output_port(uint16_t port
, int max_ports
)
1956 case OFPP_CONTROLLER
:
1961 if (port
< max_ports
) {
1964 return ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_OUT_PORT
);
1969 validate_actions(const union ofp_action
*actions
, size_t n_actions
,
1970 const struct flow
*flow
, int max_ports
)
1972 const union ofp_action
*a
;
1975 OFPUTIL_ACTION_FOR_EACH (a
, left
, actions
, n_actions
) {
1980 code
= ofputil_decode_action(a
);
1985 msg
= ofputil_error_to_string(error
);
1986 VLOG_WARN_RL(&bad_ofmsg_rl
,
1987 "action decoding error at offset %td (%s)",
1988 (a
- actions
) * sizeof *a
, msg
);
1995 switch ((enum ofputil_action_code
) code
) {
1996 case OFPUTIL_OFPAT_OUTPUT
:
1997 error
= check_output_port(ntohs(a
->output
.port
), max_ports
);
2000 case OFPUTIL_OFPAT_SET_VLAN_VID
:
2001 if (a
->vlan_vid
.vlan_vid
& ~htons(0xfff)) {
2002 error
= ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_ARGUMENT
);
2006 case OFPUTIL_OFPAT_SET_VLAN_PCP
:
2007 if (a
->vlan_pcp
.vlan_pcp
& ~7) {
2008 error
= ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_ARGUMENT
);
2012 case OFPUTIL_OFPAT_ENQUEUE
:
2013 port
= ntohs(((const struct ofp_action_enqueue
*) a
)->port
);
2014 if (port
>= max_ports
&& port
!= OFPP_IN_PORT
) {
2015 error
= ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_OUT_PORT
);
2019 case OFPUTIL_NXAST_REG_MOVE
:
2020 error
= nxm_check_reg_move((const struct nx_action_reg_move
*) a
,
2024 case OFPUTIL_NXAST_REG_LOAD
:
2025 error
= nxm_check_reg_load((const struct nx_action_reg_load
*) a
,
2029 case OFPUTIL_NXAST_MULTIPATH
:
2030 error
= multipath_check((const struct nx_action_multipath
*) a
);
2033 case OFPUTIL_NXAST_AUTOPATH
:
2034 error
= autopath_check((const struct nx_action_autopath
*) a
);
2037 case OFPUTIL_OFPAT_STRIP_VLAN
:
2038 case OFPUTIL_OFPAT_SET_NW_SRC
:
2039 case OFPUTIL_OFPAT_SET_NW_DST
:
2040 case OFPUTIL_OFPAT_SET_NW_TOS
:
2041 case OFPUTIL_OFPAT_SET_TP_SRC
:
2042 case OFPUTIL_OFPAT_SET_TP_DST
:
2043 case OFPUTIL_OFPAT_SET_DL_SRC
:
2044 case OFPUTIL_OFPAT_SET_DL_DST
:
2045 case OFPUTIL_NXAST_RESUBMIT
:
2046 case OFPUTIL_NXAST_SET_TUNNEL
:
2047 case OFPUTIL_NXAST_SET_QUEUE
:
2048 case OFPUTIL_NXAST_POP_QUEUE
:
2049 case OFPUTIL_NXAST_NOTE
:
2050 case OFPUTIL_NXAST_SET_TUNNEL64
:
2055 char *msg
= ofputil_error_to_string(error
);
2056 VLOG_WARN_RL(&bad_ofmsg_rl
, "bad action at offset %td (%s)",
2057 (a
- actions
) * sizeof *a
, msg
);
2063 VLOG_WARN_RL(&bad_ofmsg_rl
, "bad action format at offset %zu",
2064 (n_actions
- left
) * sizeof *a
);
2065 return ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_LEN
);
2070 struct ofputil_ofpat_action
{
2071 enum ofputil_action_code code
;
2075 static const struct ofputil_ofpat_action ofpat_actions
[] = {
2076 { OFPUTIL_OFPAT_OUTPUT
, 8 },
2077 { OFPUTIL_OFPAT_SET_VLAN_VID
, 8 },
2078 { OFPUTIL_OFPAT_SET_VLAN_PCP
, 8 },
2079 { OFPUTIL_OFPAT_STRIP_VLAN
, 8 },
2080 { OFPUTIL_OFPAT_SET_DL_SRC
, 16 },
2081 { OFPUTIL_OFPAT_SET_DL_DST
, 16 },
2082 { OFPUTIL_OFPAT_SET_NW_SRC
, 8 },
2083 { OFPUTIL_OFPAT_SET_NW_DST
, 8 },
2084 { OFPUTIL_OFPAT_SET_NW_TOS
, 8 },
2085 { OFPUTIL_OFPAT_SET_TP_SRC
, 8 },
2086 { OFPUTIL_OFPAT_SET_TP_DST
, 8 },
2087 { OFPUTIL_OFPAT_ENQUEUE
, 16 },
2090 struct ofputil_nxast_action
{
2091 enum ofputil_action_code code
;
2092 unsigned int min_len
;
2093 unsigned int max_len
;
2096 static const struct ofputil_nxast_action nxast_actions
[] = {
2097 { 0, UINT_MAX
, UINT_MAX
}, /* NXAST_SNAT__OBSOLETE */
2098 { OFPUTIL_NXAST_RESUBMIT
, 16, 16 },
2099 { OFPUTIL_NXAST_SET_TUNNEL
, 16, 16 },
2100 { 0, UINT_MAX
, UINT_MAX
}, /* NXAST_DROP_SPOOFED_ARP__OBSOLETE */
2101 { OFPUTIL_NXAST_SET_QUEUE
, 16, 16 },
2102 { OFPUTIL_NXAST_POP_QUEUE
, 16, 16 },
2103 { OFPUTIL_NXAST_REG_MOVE
, 24, 24 },
2104 { OFPUTIL_NXAST_REG_LOAD
, 24, 24 },
2105 { OFPUTIL_NXAST_NOTE
, 16, UINT_MAX
},
2106 { OFPUTIL_NXAST_SET_TUNNEL64
, 24, 24 },
2107 { OFPUTIL_NXAST_MULTIPATH
, 32, 32 },
2108 { OFPUTIL_NXAST_AUTOPATH
, 24, 24 },
2112 ofputil_decode_ofpat_action(const union ofp_action
*a
)
2114 int type
= ntohs(a
->type
);
2116 if (type
< ARRAY_SIZE(ofpat_actions
)) {
2117 const struct ofputil_ofpat_action
*ooa
= &ofpat_actions
[type
];
2118 unsigned int len
= ntohs(a
->header
.len
);
2120 return (len
== ooa
->len
2122 : -ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_LEN
));
2124 return -ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_TYPE
);
2129 ofputil_decode_nxast_action(const union ofp_action
*a
)
2131 unsigned int len
= ntohs(a
->header
.len
);
2133 if (len
< sizeof(struct nx_action_header
)) {
2134 return -ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_LEN
);
2136 const struct nx_action_header
*nah
= (const void *) a
;
2137 int subtype
= ntohs(nah
->subtype
);
2139 if (subtype
<= ARRAY_SIZE(nxast_actions
)) {
2140 const struct ofputil_nxast_action
*ona
= &nxast_actions
[subtype
];
2141 if (len
>= ona
->min_len
&& len
<= ona
->max_len
) {
2143 } else if (ona
->min_len
== UINT_MAX
) {
2144 return -ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_TYPE
);
2146 return -ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_LEN
);
2149 return -ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_TYPE
);
2154 /* Parses 'a' to determine its type. Returns a nonnegative OFPUTIL_OFPAT_* or
2155 * OFPUTIL_NXAST_* constant if successful, otherwise a negative OpenFlow error
2156 * code (as returned by ofp_mkerr()).
2158 * The caller must have already verified that 'a''s length is correct (that is,
2159 * a->header.len is nonzero and a multiple of sizeof(union ofp_action) and no
2160 * longer than the amount of space allocated to 'a').
2162 * This function verifies that 'a''s length is correct for the type of action
2163 * that it represents. */
2165 ofputil_decode_action(const union ofp_action
*a
)
2167 if (a
->type
!= htons(OFPAT_VENDOR
)) {
2168 return ofputil_decode_ofpat_action(a
);
2169 } else if (a
->vendor
.vendor
== htonl(NX_VENDOR_ID
)) {
2170 return ofputil_decode_nxast_action(a
);
2172 return -ofp_mkerr(OFPET_BAD_ACTION
, OFPBAC_BAD_VENDOR
);
2176 /* Parses 'a' and returns its type as an OFPUTIL_OFPAT_* or OFPUTIL_NXAST_*
2177 * constant. The caller must have already validated that 'a' is a valid action
2178 * understood by Open vSwitch (e.g. by a previous successful call to
2179 * ofputil_decode_action()). */
2180 enum ofputil_action_code
2181 ofputil_decode_action_unsafe(const union ofp_action
*a
)
2183 if (a
->type
!= htons(OFPAT_VENDOR
)) {
2184 return ofpat_actions
[ntohs(a
->type
)].code
;
2186 const struct nx_action_header
*nah
= (const void *) a
;
2188 return nxast_actions
[ntohs(nah
->subtype
)].code
;
2192 /* Returns true if 'action' outputs to 'port', false otherwise. */
2194 action_outputs_to_port(const union ofp_action
*action
, ovs_be16 port
)
2196 switch (ntohs(action
->type
)) {
2198 return action
->output
.port
== port
;
2200 return ((const struct ofp_action_enqueue
*) action
)->port
== port
;
2206 /* "Normalizes" the wildcards in 'rule'. That means:
2208 * 1. If the type of level N is known, then only the valid fields for that
2209 * level may be specified. For example, ARP does not have a TOS field,
2210 * so nw_tos must be wildcarded if 'rule' specifies an ARP flow.
2211 * Similarly, IPv4 does not have any IPv6 addresses, so ipv6_src and
2212 * ipv6_dst (and other fields) must be wildcarded if 'rule' specifies an
2215 * 2. If the type of level N is not known (or not understood by Open
2216 * vSwitch), then no fields at all for that level may be specified. For
2217 * example, Open vSwitch does not understand SCTP, an L4 protocol, so the
2218 * L4 fields tp_src and tp_dst must be wildcarded if 'rule' specifies an
2221 * 'flow_format' specifies the format of the flow as received or as intended to
2222 * be sent. This is important for IPv6 and ARP, for which NXM supports more
2223 * detailed matching. */
2225 ofputil_normalize_rule(struct cls_rule
*rule
, enum nx_flow_format flow_format
)
2228 MAY_NW_ADDR
= 1 << 0, /* nw_src, nw_dst */
2229 MAY_TP_ADDR
= 1 << 1, /* tp_src, tp_dst */
2230 MAY_NW_PROTO
= 1 << 2, /* nw_proto */
2231 MAY_NW_TOS
= 1 << 3, /* nw_tos */
2232 MAY_ARP_SHA
= 1 << 4, /* arp_sha */
2233 MAY_ARP_THA
= 1 << 5, /* arp_tha */
2234 MAY_IPV6_ADDR
= 1 << 6, /* ipv6_src, ipv6_dst */
2235 MAY_ND_TARGET
= 1 << 7 /* nd_target */
2238 struct flow_wildcards wc
;
2240 /* Figure out what fields may be matched. */
2241 if (rule
->flow
.dl_type
== htons(ETH_TYPE_IP
)) {
2242 may_match
= MAY_NW_PROTO
| MAY_NW_TOS
| MAY_NW_ADDR
;
2243 if (rule
->flow
.nw_proto
== IPPROTO_TCP
||
2244 rule
->flow
.nw_proto
== IPPROTO_UDP
||
2245 rule
->flow
.nw_proto
== IPPROTO_ICMP
) {
2246 may_match
|= MAY_TP_ADDR
;
2248 } else if (rule
->flow
.dl_type
== htons(ETH_TYPE_IPV6
)
2249 && flow_format
== NXFF_NXM
) {
2250 may_match
= MAY_NW_PROTO
| MAY_NW_TOS
| MAY_IPV6_ADDR
;
2251 if (rule
->flow
.nw_proto
== IPPROTO_TCP
||
2252 rule
->flow
.nw_proto
== IPPROTO_UDP
) {
2253 may_match
|= MAY_TP_ADDR
;
2254 } else if (rule
->flow
.nw_proto
== IPPROTO_ICMPV6
) {
2255 may_match
|= MAY_TP_ADDR
;
2256 if (rule
->flow
.tp_src
== htons(ND_NEIGHBOR_SOLICIT
)) {
2257 may_match
|= MAY_ND_TARGET
| MAY_ARP_SHA
;
2258 } else if (rule
->flow
.tp_src
== htons(ND_NEIGHBOR_ADVERT
)) {
2259 may_match
|= MAY_ND_TARGET
| MAY_ARP_THA
;
2262 } else if (rule
->flow
.dl_type
== htons(ETH_TYPE_ARP
)) {
2263 may_match
= MAY_NW_PROTO
| MAY_NW_ADDR
;
2264 if (flow_format
== NXFF_NXM
) {
2265 may_match
|= MAY_ARP_SHA
| MAY_ARP_THA
;
2271 /* Clear the fields that may not be matched. */
2273 if (!(may_match
& MAY_NW_ADDR
)) {
2274 wc
.nw_src_mask
= wc
.nw_dst_mask
= htonl(0);
2276 if (!(may_match
& MAY_TP_ADDR
)) {
2277 wc
.wildcards
|= FWW_TP_SRC
| FWW_TP_DST
;
2279 if (!(may_match
& MAY_NW_PROTO
)) {
2280 wc
.wildcards
|= FWW_NW_PROTO
;
2282 if (!(may_match
& MAY_NW_TOS
)) {
2283 wc
.wildcards
|= FWW_NW_TOS
;
2285 if (!(may_match
& MAY_ARP_SHA
)) {
2286 wc
.wildcards
|= FWW_ARP_SHA
;
2288 if (!(may_match
& MAY_ARP_THA
)) {
2289 wc
.wildcards
|= FWW_ARP_THA
;
2291 if (!(may_match
& MAY_IPV6_ADDR
)) {
2292 wc
.ipv6_src_mask
= wc
.ipv6_dst_mask
= in6addr_any
;
2294 if (!(may_match
& MAY_ND_TARGET
)) {
2295 wc
.wildcards
|= FWW_ND_TARGET
;
2298 /* Log any changes. */
2299 if (!flow_wildcards_equal(&wc
, &rule
->wc
)) {
2300 bool log
= !VLOG_DROP_INFO(&bad_ofmsg_rl
);
2301 char *pre
= log
? cls_rule_to_string(rule
) : NULL
;
2304 cls_rule_zero_wildcarded_fields(rule
);
2307 char *post
= cls_rule_to_string(rule
);
2308 VLOG_INFO("normalization changed ofp_match, details:");
2309 VLOG_INFO(" pre: %s", pre
);
2310 VLOG_INFO("post: %s", post
);
2318 vendor_code_to_id(uint8_t code
)
2321 #define OFPUTIL_VENDOR(NAME, VENDOR_ID) case NAME: return VENDOR_ID;
2323 #undef OFPUTIL_VENDOR
2330 vendor_id_to_code(uint32_t id
)
2333 #define OFPUTIL_VENDOR(NAME, VENDOR_ID) case VENDOR_ID: return NAME;
2335 #undef OFPUTIL_VENDOR
2341 /* Creates and returns an OpenFlow message of type OFPT_ERROR with the error
2342 * information taken from 'error', whose encoding must be as described in the
2343 * large comment in ofp-util.h. If 'oh' is nonnull, then the error will use
2344 * oh->xid as its transaction ID, and it will include up to the first 64 bytes
2347 * Returns NULL if 'error' is not an OpenFlow error code. */
2349 ofputil_encode_error_msg(int error
, const struct ofp_header
*oh
)
2351 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
2361 if (!is_ofp_error(error
)) {
2362 /* We format 'error' with strerror() here since it seems likely to be
2363 * a system errno value. */
2364 VLOG_WARN_RL(&rl
, "invalid OpenFlow error code %d (%s)",
2365 error
, strerror(error
));
2372 len
= ntohs(oh
->length
);
2382 vendor
= get_ofp_err_vendor(error
);
2383 type
= get_ofp_err_type(error
);
2384 code
= get_ofp_err_code(error
);
2385 if (vendor
== OFPUTIL_VENDOR_OPENFLOW
) {
2386 struct ofp_error_msg
*oem
;
2388 oem
= make_openflow_xid(len
+ sizeof *oem
, OFPT_ERROR
, xid
, &buf
);
2389 oem
->type
= htons(type
);
2390 oem
->code
= htons(code
);
2392 struct ofp_error_msg
*oem
;
2393 struct nx_vendor_error
*nve
;
2396 vendor_id
= vendor_code_to_id(vendor
);
2397 if (vendor_id
== UINT32_MAX
) {
2398 VLOG_WARN_RL(&rl
, "error %x contains invalid vendor code %d",
2403 oem
= make_openflow_xid(len
+ sizeof *oem
+ sizeof *nve
,
2404 OFPT_ERROR
, xid
, &buf
);
2405 oem
->type
= htons(NXET_VENDOR
);
2406 oem
->code
= htons(NXVC_VENDOR_ERROR
);
2408 nve
= (struct nx_vendor_error
*)oem
->data
;
2409 nve
->vendor
= htonl(vendor_id
);
2410 nve
->type
= htons(type
);
2411 nve
->code
= htons(code
);
2416 ofpbuf_put(buf
, data
, len
);
2422 /* Decodes 'oh', which should be an OpenFlow OFPT_ERROR message, and returns an
2423 * Open vSwitch internal error code in the format described in the large
2424 * comment in ofp-util.h.
2426 * If 'payload_ofs' is nonnull, on success '*payload_ofs' is set to the offset
2427 * to the payload starting from 'oh' and on failure it is set to 0. */
2429 ofputil_decode_error_msg(const struct ofp_header
*oh
, size_t *payload_ofs
)
2431 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
2433 const struct ofp_error_msg
*oem
;
2434 uint16_t type
, code
;
2441 if (oh
->type
!= OFPT_ERROR
) {
2445 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2446 oem
= ofpbuf_try_pull(&b
, sizeof *oem
);
2451 type
= ntohs(oem
->type
);
2452 code
= ntohs(oem
->code
);
2453 if (type
== NXET_VENDOR
&& code
== NXVC_VENDOR_ERROR
) {
2454 const struct nx_vendor_error
*nve
= ofpbuf_try_pull(&b
, sizeof *nve
);
2459 vendor
= vendor_id_to_code(ntohl(nve
->vendor
));
2461 VLOG_WARN_RL(&rl
, "error contains unknown vendor ID %#"PRIx32
,
2462 ntohl(nve
->vendor
));
2465 type
= ntohs(nve
->type
);
2466 code
= ntohs(nve
->code
);
2468 vendor
= OFPUTIL_VENDOR_OPENFLOW
;
2472 VLOG_WARN_RL(&rl
, "error contains type %"PRIu16
" greater than "
2473 "supported maximum value 1023", type
);
2478 *payload_ofs
= (uint8_t *) b
.data
- (uint8_t *) oh
;
2480 return ofp_mkerr_vendor(vendor
, type
, code
);
2484 ofputil_format_error(struct ds
*s
, int error
)
2486 if (is_errno(error
)) {
2487 ds_put_cstr(s
, strerror(error
));
2489 uint16_t type
= get_ofp_err_type(error
);
2490 uint16_t code
= get_ofp_err_code(error
);
2491 const char *type_s
= ofp_error_type_to_string(type
);
2492 const char *code_s
= ofp_error_code_to_string(type
, code
);
2494 ds_put_format(s
, "type ");
2496 ds_put_cstr(s
, type_s
);
2498 ds_put_format(s
, "%"PRIu16
, type
);
2501 ds_put_cstr(s
, ", code ");
2503 ds_put_cstr(s
, code_s
);
2505 ds_put_format(s
, "%"PRIu16
, code
);
2511 ofputil_error_to_string(int error
)
2513 struct ds s
= DS_EMPTY_INITIALIZER
;
2514 ofputil_format_error(&s
, error
);
2515 return ds_steal_cstr(&s
);
2518 /* Attempts to pull 'actions_len' bytes from the front of 'b'. Returns 0 if
2519 * successful, otherwise an OpenFlow error.
2521 * If successful, the first action is stored in '*actionsp' and the number of
2522 * "union ofp_action" size elements into '*n_actionsp'. Otherwise NULL and 0
2523 * are stored, respectively.
2525 * This function does not check that the actions are valid (the caller should
2526 * do so, with validate_actions()). The caller is also responsible for making
2527 * sure that 'b->data' is initially aligned appropriately for "union
2530 ofputil_pull_actions(struct ofpbuf
*b
, unsigned int actions_len
,
2531 union ofp_action
**actionsp
, size_t *n_actionsp
)
2533 if (actions_len
% OFP_ACTION_ALIGN
!= 0) {
2534 VLOG_WARN_RL(&bad_ofmsg_rl
, "OpenFlow message actions length %u "
2535 "is not a multiple of %d", actions_len
, OFP_ACTION_ALIGN
);
2539 *actionsp
= ofpbuf_try_pull(b
, actions_len
);
2540 if (*actionsp
== NULL
) {
2541 VLOG_WARN_RL(&bad_ofmsg_rl
, "OpenFlow message actions length %u "
2542 "exceeds remaining message length (%zu)",
2543 actions_len
, b
->size
);
2547 *n_actionsp
= actions_len
/ OFP_ACTION_ALIGN
;
2553 return ofp_mkerr(OFPET_BAD_REQUEST
, OFPBRC_BAD_LEN
);
2557 ofputil_actions_equal(const union ofp_action
*a
, size_t n_a
,
2558 const union ofp_action
*b
, size_t n_b
)
2560 return n_a
== n_b
&& (!n_a
|| !memcmp(a
, b
, n_a
* sizeof *a
));
2564 ofputil_actions_clone(const union ofp_action
*actions
, size_t n
)
2566 return n
? xmemdup(actions
, n
* sizeof *actions
) : NULL
;