2 * Copyright (c) 2008, 2009, 2010, 2011, 2012 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"
21 #include <sys/types.h>
22 #include <netinet/in.h>
23 #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"
41 #include "unaligned.h"
42 #include "type-props.h"
45 VLOG_DEFINE_THIS_MODULE(ofp_util
);
47 /* Rate limit for OpenFlow message parse errors. These always indicate a bug
48 * in the peer and so there's not much point in showing a lot of them. */
49 static struct vlog_rate_limit bad_ofmsg_rl
= VLOG_RATE_LIMIT_INIT(1, 5);
51 /* Given the wildcard bit count in the least-significant 6 of 'wcbits', returns
52 * an IP netmask with a 1 in each bit that must match and a 0 in each bit that
55 * The bits in 'wcbits' are in the format used in enum ofp_flow_wildcards: 0
56 * is exact match, 1 ignores the LSB, 2 ignores the 2 least-significant bits,
57 * ..., 32 and higher wildcard the entire field. This is the *opposite* of the
58 * usual convention where e.g. /24 indicates that 8 bits (not 24 bits) are
61 ofputil_wcbits_to_netmask(int wcbits
)
64 return wcbits
< 32 ? htonl(~((1u << wcbits
) - 1)) : 0;
67 /* Given the IP netmask 'netmask', returns the number of bits of the IP address
68 * that it wildcards, that is, the number of 0-bits in 'netmask', a number
69 * between 0 and 32 inclusive.
71 * If 'netmask' is not a CIDR netmask (see ip_is_cidr()), the return value will
72 * still be in the valid range but isn't otherwise meaningful. */
74 ofputil_netmask_to_wcbits(ovs_be32 netmask
)
76 return 32 - ip_count_cidr_bits(netmask
);
79 /* A list of the FWW_* and OFPFW10_ bits that have the same value, meaning, and
81 #define WC_INVARIANT_LIST \
82 WC_INVARIANT_BIT(IN_PORT) \
83 WC_INVARIANT_BIT(DL_TYPE) \
84 WC_INVARIANT_BIT(NW_PROTO)
86 /* Verify that all of the invariant bits (as defined on WC_INVARIANT_LIST)
87 * actually have the same names and values. */
88 #define WC_INVARIANT_BIT(NAME) BUILD_ASSERT_DECL(FWW_##NAME == OFPFW10_##NAME);
90 #undef WC_INVARIANT_BIT
92 /* WC_INVARIANTS is the invariant bits (as defined on WC_INVARIANT_LIST) all
94 static const flow_wildcards_t WC_INVARIANTS
= 0
95 #define WC_INVARIANT_BIT(NAME) | FWW_##NAME
97 #undef WC_INVARIANT_BIT
100 /* Converts the OpenFlow 1.0 wildcards in 'ofpfw' (OFPFW10_*) into a
101 * flow_wildcards in 'wc' for use in struct cls_rule. It is the caller's
102 * responsibility to handle the special case where the flow match's dl_vlan is
103 * set to OFP_VLAN_NONE. */
105 ofputil_wildcard_from_ofpfw10(uint32_t ofpfw
, struct flow_wildcards
*wc
)
107 BUILD_ASSERT_DECL(FLOW_WC_SEQ
== 12);
109 /* Initialize most of rule->wc. */
110 flow_wildcards_init_catchall(wc
);
111 wc
->wildcards
= (OVS_FORCE flow_wildcards_t
) ofpfw
& WC_INVARIANTS
;
113 /* Wildcard fields that aren't defined by ofp10_match or tun_id. */
114 wc
->wildcards
|= (FWW_ARP_SHA
| FWW_ARP_THA
| FWW_NW_ECN
| FWW_NW_TTL
117 if (ofpfw
& OFPFW10_NW_TOS
) {
118 /* OpenFlow 1.0 defines a TOS wildcard, but it's much later in
119 * the enum than we can use. */
120 wc
->wildcards
|= FWW_NW_DSCP
;
123 wc
->nw_src_mask
= ofputil_wcbits_to_netmask(ofpfw
>> OFPFW10_NW_SRC_SHIFT
);
124 wc
->nw_dst_mask
= ofputil_wcbits_to_netmask(ofpfw
>> OFPFW10_NW_DST_SHIFT
);
126 if (!(ofpfw
& OFPFW10_TP_SRC
)) {
127 wc
->tp_src_mask
= htons(UINT16_MAX
);
129 if (!(ofpfw
& OFPFW10_TP_DST
)) {
130 wc
->tp_dst_mask
= htons(UINT16_MAX
);
133 if (!(ofpfw
& OFPFW10_DL_SRC
)) {
134 memset(wc
->dl_src_mask
, 0xff, ETH_ADDR_LEN
);
136 if (!(ofpfw
& OFPFW10_DL_DST
)) {
137 memset(wc
->dl_dst_mask
, 0xff, ETH_ADDR_LEN
);
141 if (!(ofpfw
& OFPFW10_DL_VLAN_PCP
)) {
142 wc
->vlan_tci_mask
|= htons(VLAN_PCP_MASK
| VLAN_CFI
);
144 if (!(ofpfw
& OFPFW10_DL_VLAN
)) {
145 wc
->vlan_tci_mask
|= htons(VLAN_VID_MASK
| VLAN_CFI
);
149 /* Converts the ofp10_match in 'match' into a cls_rule in 'rule', with the
150 * given 'priority'. */
152 ofputil_cls_rule_from_ofp10_match(const struct ofp10_match
*match
,
153 unsigned int priority
, struct cls_rule
*rule
)
155 uint32_t ofpfw
= ntohl(match
->wildcards
) & OFPFW10_ALL
;
157 /* Initialize rule->priority, rule->wc. */
158 rule
->priority
= !ofpfw
? UINT16_MAX
: priority
;
159 ofputil_wildcard_from_ofpfw10(ofpfw
, &rule
->wc
);
161 /* Initialize most of rule->flow. */
162 rule
->flow
.nw_src
= match
->nw_src
;
163 rule
->flow
.nw_dst
= match
->nw_dst
;
164 rule
->flow
.in_port
= ntohs(match
->in_port
);
165 rule
->flow
.dl_type
= ofputil_dl_type_from_openflow(match
->dl_type
);
166 rule
->flow
.tp_src
= match
->tp_src
;
167 rule
->flow
.tp_dst
= match
->tp_dst
;
168 memcpy(rule
->flow
.dl_src
, match
->dl_src
, ETH_ADDR_LEN
);
169 memcpy(rule
->flow
.dl_dst
, match
->dl_dst
, ETH_ADDR_LEN
);
170 rule
->flow
.nw_tos
= match
->nw_tos
& IP_DSCP_MASK
;
171 rule
->flow
.nw_proto
= match
->nw_proto
;
173 /* Translate VLANs. */
174 if (!(ofpfw
& OFPFW10_DL_VLAN
) &&
175 match
->dl_vlan
== htons(OFP10_VLAN_NONE
)) {
176 /* Match only packets without 802.1Q header.
178 * When OFPFW10_DL_VLAN_PCP is wildcarded, this is obviously correct.
180 * If OFPFW10_DL_VLAN_PCP is matched, the flow match is contradictory,
181 * because we can't have a specific PCP without an 802.1Q header.
182 * However, older versions of OVS treated this as matching packets
183 * withut an 802.1Q header, so we do here too. */
184 rule
->flow
.vlan_tci
= htons(0);
185 rule
->wc
.vlan_tci_mask
= htons(0xffff);
187 ovs_be16 vid
, pcp
, tci
;
189 vid
= match
->dl_vlan
& htons(VLAN_VID_MASK
);
190 pcp
= htons((match
->dl_vlan_pcp
<< VLAN_PCP_SHIFT
) & VLAN_PCP_MASK
);
191 tci
= vid
| pcp
| htons(VLAN_CFI
);
192 rule
->flow
.vlan_tci
= tci
& rule
->wc
.vlan_tci_mask
;
196 cls_rule_zero_wildcarded_fields(rule
);
199 /* Convert 'rule' into the OpenFlow 1.0 match structure 'match'. */
201 ofputil_cls_rule_to_ofp10_match(const struct cls_rule
*rule
,
202 struct ofp10_match
*match
)
204 const struct flow_wildcards
*wc
= &rule
->wc
;
207 /* Figure out most OpenFlow wildcards. */
208 ofpfw
= (OVS_FORCE
uint32_t) (wc
->wildcards
& WC_INVARIANTS
);
209 ofpfw
|= (ofputil_netmask_to_wcbits(wc
->nw_src_mask
)
210 << OFPFW10_NW_SRC_SHIFT
);
211 ofpfw
|= (ofputil_netmask_to_wcbits(wc
->nw_dst_mask
)
212 << OFPFW10_NW_DST_SHIFT
);
213 if (wc
->wildcards
& FWW_NW_DSCP
) {
214 ofpfw
|= OFPFW10_NW_TOS
;
216 if (!wc
->tp_src_mask
) {
217 ofpfw
|= OFPFW10_TP_SRC
;
219 if (!wc
->tp_dst_mask
) {
220 ofpfw
|= OFPFW10_TP_DST
;
222 if (eth_addr_is_zero(wc
->dl_src_mask
)) {
223 ofpfw
|= OFPFW10_DL_SRC
;
225 if (eth_addr_is_zero(wc
->dl_dst_mask
)) {
226 ofpfw
|= OFPFW10_DL_DST
;
229 /* Translate VLANs. */
230 match
->dl_vlan
= htons(0);
231 match
->dl_vlan_pcp
= 0;
232 if (rule
->wc
.vlan_tci_mask
== htons(0)) {
233 ofpfw
|= OFPFW10_DL_VLAN
| OFPFW10_DL_VLAN_PCP
;
234 } else if (rule
->wc
.vlan_tci_mask
& htons(VLAN_CFI
)
235 && !(rule
->flow
.vlan_tci
& htons(VLAN_CFI
))) {
236 match
->dl_vlan
= htons(OFP10_VLAN_NONE
);
237 ofpfw
|= OFPFW10_DL_VLAN_PCP
;
239 if (!(rule
->wc
.vlan_tci_mask
& htons(VLAN_VID_MASK
))) {
240 ofpfw
|= OFPFW10_DL_VLAN
;
242 match
->dl_vlan
= htons(vlan_tci_to_vid(rule
->flow
.vlan_tci
));
245 if (!(rule
->wc
.vlan_tci_mask
& htons(VLAN_PCP_MASK
))) {
246 ofpfw
|= OFPFW10_DL_VLAN_PCP
;
248 match
->dl_vlan_pcp
= vlan_tci_to_pcp(rule
->flow
.vlan_tci
);
252 /* Compose most of the match structure. */
253 match
->wildcards
= htonl(ofpfw
);
254 match
->in_port
= htons(rule
->flow
.in_port
);
255 memcpy(match
->dl_src
, rule
->flow
.dl_src
, ETH_ADDR_LEN
);
256 memcpy(match
->dl_dst
, rule
->flow
.dl_dst
, ETH_ADDR_LEN
);
257 match
->dl_type
= ofputil_dl_type_to_openflow(rule
->flow
.dl_type
);
258 match
->nw_src
= rule
->flow
.nw_src
;
259 match
->nw_dst
= rule
->flow
.nw_dst
;
260 match
->nw_tos
= rule
->flow
.nw_tos
& IP_DSCP_MASK
;
261 match
->nw_proto
= rule
->flow
.nw_proto
;
262 match
->tp_src
= rule
->flow
.tp_src
;
263 match
->tp_dst
= rule
->flow
.tp_dst
;
264 memset(match
->pad1
, '\0', sizeof match
->pad1
);
265 memset(match
->pad2
, '\0', sizeof match
->pad2
);
268 /* Converts the ofp11_match in 'match' into a cls_rule in 'rule', with the
269 * given 'priority'. Returns 0 if successful, otherwise an OFPERR_* value. */
271 ofputil_cls_rule_from_ofp11_match(const struct ofp11_match
*match
,
272 unsigned int priority
,
273 struct cls_rule
*rule
)
275 uint16_t wc
= ntohl(match
->wildcards
);
276 uint8_t dl_src_mask
[ETH_ADDR_LEN
];
277 uint8_t dl_dst_mask
[ETH_ADDR_LEN
];
281 cls_rule_init_catchall(rule
, priority
);
283 if (!(wc
& OFPFW11_IN_PORT
)) {
287 error
= ofputil_port_from_ofp11(match
->in_port
, &ofp_port
);
289 return OFPERR_OFPBMC_BAD_VALUE
;
291 cls_rule_set_in_port(rule
, ofp_port
);
294 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
295 dl_src_mask
[i
] = ~match
->dl_src_mask
[i
];
297 cls_rule_set_dl_src_masked(rule
, match
->dl_src
, dl_src_mask
);
299 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
300 dl_dst_mask
[i
] = ~match
->dl_dst_mask
[i
];
302 cls_rule_set_dl_dst_masked(rule
, match
->dl_dst
, dl_dst_mask
);
304 if (!(wc
& OFPFW11_DL_VLAN
)) {
305 if (match
->dl_vlan
== htons(OFPVID11_NONE
)) {
306 /* Match only packets without a VLAN tag. */
307 rule
->flow
.vlan_tci
= htons(0);
308 rule
->wc
.vlan_tci_mask
= htons(UINT16_MAX
);
310 if (match
->dl_vlan
== htons(OFPVID11_ANY
)) {
311 /* Match any packet with a VLAN tag regardless of VID. */
312 rule
->flow
.vlan_tci
= htons(VLAN_CFI
);
313 rule
->wc
.vlan_tci_mask
= htons(VLAN_CFI
);
314 } else if (ntohs(match
->dl_vlan
) < 4096) {
315 /* Match only packets with the specified VLAN VID. */
316 rule
->flow
.vlan_tci
= htons(VLAN_CFI
) | match
->dl_vlan
;
317 rule
->wc
.vlan_tci_mask
= htons(VLAN_CFI
| VLAN_VID_MASK
);
320 return OFPERR_OFPBMC_BAD_VALUE
;
323 if (!(wc
& OFPFW11_DL_VLAN_PCP
)) {
324 if (match
->dl_vlan_pcp
<= 7) {
325 rule
->flow
.vlan_tci
|= htons(match
->dl_vlan_pcp
327 rule
->wc
.vlan_tci_mask
|= htons(VLAN_PCP_MASK
);
330 return OFPERR_OFPBMC_BAD_VALUE
;
336 if (!(wc
& OFPFW11_DL_TYPE
)) {
337 cls_rule_set_dl_type(rule
,
338 ofputil_dl_type_from_openflow(match
->dl_type
));
341 ipv4
= rule
->flow
.dl_type
== htons(ETH_TYPE_IP
);
342 arp
= rule
->flow
.dl_type
== htons(ETH_TYPE_ARP
);
344 if (ipv4
&& !(wc
& OFPFW11_NW_TOS
)) {
345 if (match
->nw_tos
& ~IP_DSCP_MASK
) {
347 return OFPERR_OFPBMC_BAD_VALUE
;
350 cls_rule_set_nw_dscp(rule
, match
->nw_tos
);
354 if (!(wc
& OFPFW11_NW_PROTO
)) {
355 cls_rule_set_nw_proto(rule
, match
->nw_proto
);
357 cls_rule_set_nw_src_masked(rule
, match
->nw_src
, ~match
->nw_src_mask
);
358 cls_rule_set_nw_dst_masked(rule
, match
->nw_dst
, ~match
->nw_dst_mask
);
361 #define OFPFW11_TP_ALL (OFPFW11_TP_SRC | OFPFW11_TP_DST)
362 if (ipv4
&& (wc
& OFPFW11_TP_ALL
) != OFPFW11_TP_ALL
) {
363 switch (rule
->flow
.nw_proto
) {
365 /* "A.2.3 Flow Match Structures" in OF1.1 says:
367 * The tp_src and tp_dst fields will be ignored unless the
368 * network protocol specified is as TCP, UDP or SCTP.
370 * but I'm pretty sure we should support ICMP too, otherwise
371 * that's a regression from OF1.0. */
372 if (!(wc
& OFPFW11_TP_SRC
)) {
373 uint16_t icmp_type
= ntohs(match
->tp_src
);
374 if (icmp_type
< 0x100) {
375 cls_rule_set_icmp_type(rule
, icmp_type
);
377 return OFPERR_OFPBMC_BAD_FIELD
;
380 if (!(wc
& OFPFW11_TP_DST
)) {
381 uint16_t icmp_code
= ntohs(match
->tp_dst
);
382 if (icmp_code
< 0x100) {
383 cls_rule_set_icmp_code(rule
, icmp_code
);
385 return OFPERR_OFPBMC_BAD_FIELD
;
392 if (!(wc
& (OFPFW11_TP_SRC
))) {
393 cls_rule_set_tp_src(rule
, match
->tp_src
);
395 if (!(wc
& (OFPFW11_TP_DST
))) {
396 cls_rule_set_tp_dst(rule
, match
->tp_dst
);
401 /* We don't support SCTP and it seems that we should tell the
402 * controller, since OF1.1 implementations are supposed to. */
403 return OFPERR_OFPBMC_BAD_FIELD
;
406 /* OF1.1 says explicitly to ignore this. */
411 if (rule
->flow
.dl_type
== htons(ETH_TYPE_MPLS
) ||
412 rule
->flow
.dl_type
== htons(ETH_TYPE_MPLS_MCAST
)) {
413 enum { OFPFW11_MPLS_ALL
= OFPFW11_MPLS_LABEL
| OFPFW11_MPLS_TC
};
415 if ((wc
& OFPFW11_MPLS_ALL
) != OFPFW11_MPLS_ALL
) {
416 /* MPLS not supported. */
417 return OFPERR_OFPBMC_BAD_TAG
;
421 if (match
->metadata_mask
!= htonll(UINT64_MAX
)) {
422 cls_rule_set_metadata_masked(rule
, match
->metadata
,
423 ~match
->metadata_mask
);
429 /* Convert 'rule' into the OpenFlow 1.1 match structure 'match'. */
431 ofputil_cls_rule_to_ofp11_match(const struct cls_rule
*rule
,
432 struct ofp11_match
*match
)
437 memset(match
, 0, sizeof *match
);
438 match
->omh
.type
= htons(OFPMT_STANDARD
);
439 match
->omh
.length
= htons(OFPMT11_STANDARD_LENGTH
);
441 if (rule
->wc
.wildcards
& FWW_IN_PORT
) {
442 wc
|= OFPFW11_IN_PORT
;
444 match
->in_port
= ofputil_port_to_ofp11(rule
->flow
.in_port
);
448 memcpy(match
->dl_src
, rule
->flow
.dl_src
, ETH_ADDR_LEN
);
449 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
450 match
->dl_src_mask
[i
] = ~rule
->wc
.dl_src_mask
[i
];
453 memcpy(match
->dl_dst
, rule
->flow
.dl_dst
, ETH_ADDR_LEN
);
454 for (i
= 0; i
< ETH_ADDR_LEN
; i
++) {
455 match
->dl_dst_mask
[i
] = ~rule
->wc
.dl_dst_mask
[i
];
458 if (rule
->wc
.vlan_tci_mask
== htons(0)) {
459 wc
|= OFPFW11_DL_VLAN
| OFPFW11_DL_VLAN_PCP
;
460 } else if (rule
->wc
.vlan_tci_mask
& htons(VLAN_CFI
)
461 && !(rule
->flow
.vlan_tci
& htons(VLAN_CFI
))) {
462 match
->dl_vlan
= htons(OFPVID11_NONE
);
463 wc
|= OFPFW11_DL_VLAN_PCP
;
465 if (!(rule
->wc
.vlan_tci_mask
& htons(VLAN_VID_MASK
))) {
466 match
->dl_vlan
= htons(OFPVID11_ANY
);
468 match
->dl_vlan
= htons(vlan_tci_to_vid(rule
->flow
.vlan_tci
));
471 if (!(rule
->wc
.vlan_tci_mask
& htons(VLAN_PCP_MASK
))) {
472 wc
|= OFPFW11_DL_VLAN_PCP
;
474 match
->dl_vlan_pcp
= vlan_tci_to_pcp(rule
->flow
.vlan_tci
);
478 if (rule
->wc
.wildcards
& FWW_DL_TYPE
) {
479 wc
|= OFPFW11_DL_TYPE
;
481 match
->dl_type
= ofputil_dl_type_to_openflow(rule
->flow
.dl_type
);
484 if (rule
->wc
.wildcards
& FWW_NW_DSCP
) {
485 wc
|= OFPFW11_NW_TOS
;
487 match
->nw_tos
= rule
->flow
.nw_tos
& IP_DSCP_MASK
;
490 if (rule
->wc
.wildcards
& FWW_NW_PROTO
) {
491 wc
|= OFPFW11_NW_PROTO
;
493 match
->nw_proto
= rule
->flow
.nw_proto
;
496 match
->nw_src
= rule
->flow
.nw_src
;
497 match
->nw_src_mask
= ~rule
->wc
.nw_src_mask
;
498 match
->nw_dst
= rule
->flow
.nw_dst
;
499 match
->nw_dst_mask
= ~rule
->wc
.nw_dst_mask
;
501 if (!rule
->wc
.tp_src_mask
) {
502 wc
|= OFPFW11_TP_SRC
;
504 match
->tp_src
= rule
->flow
.tp_src
;
507 if (!rule
->wc
.tp_dst_mask
) {
508 wc
|= OFPFW11_TP_DST
;
510 match
->tp_dst
= rule
->flow
.tp_dst
;
513 /* MPLS not supported. */
514 wc
|= OFPFW11_MPLS_LABEL
;
515 wc
|= OFPFW11_MPLS_TC
;
517 match
->metadata
= rule
->flow
.metadata
;
518 match
->metadata_mask
= ~rule
->wc
.metadata_mask
;
520 match
->wildcards
= htonl(wc
);
523 /* Given a 'dl_type' value in the format used in struct flow, returns the
524 * corresponding 'dl_type' value for use in an ofp10_match or ofp11_match
527 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type
)
529 return (flow_dl_type
== htons(FLOW_DL_TYPE_NONE
)
530 ? htons(OFP_DL_TYPE_NOT_ETH_TYPE
)
534 /* Given a 'dl_type' value in the format used in an ofp10_match or ofp11_match
535 * structure, returns the corresponding 'dl_type' value for use in struct
538 ofputil_dl_type_from_openflow(ovs_be16 ofp_dl_type
)
540 return (ofp_dl_type
== htons(OFP_DL_TYPE_NOT_ETH_TYPE
)
541 ? htons(FLOW_DL_TYPE_NONE
)
545 /* Returns a transaction ID to use for an outgoing OpenFlow message. */
549 static uint32_t next_xid
= 1;
550 return htonl(next_xid
++);
553 /* Basic parsing of OpenFlow messages. */
555 struct ofputil_msg_type
{
556 enum ofputil_msg_code code
; /* OFPUTIL_*. */
557 uint8_t ofp_version
; /* An OpenFlow version or 0 for "any". */
558 uint32_t value
; /* OFPT_*, OFPST_*, NXT_*, or NXST_*. */
559 const char *name
; /* e.g. "OFPT_FLOW_REMOVED". */
560 unsigned int min_size
; /* Minimum total message size in bytes. */
561 /* 0 if 'min_size' is the exact size that the message must be. Otherwise,
562 * the message may exceed 'min_size' by an even multiple of this value. */
563 unsigned int extra_multiple
;
566 /* Represents a malformed OpenFlow message. */
567 static const struct ofputil_msg_type ofputil_invalid_type
= {
568 OFPUTIL_MSG_INVALID
, 0, 0, "OFPUTIL_MSG_INVALID", 0, 0
571 struct ofputil_msg_category
{
572 const char *name
; /* e.g. "OpenFlow message" */
573 const struct ofputil_msg_type
*types
;
575 enum ofperr missing_error
; /* Error value for missing type. */
579 ofputil_check_length(const struct ofputil_msg_type
*type
, unsigned int size
)
581 switch (type
->extra_multiple
) {
583 if (size
!= type
->min_size
) {
584 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s with incorrect "
585 "length %u (expected length %u)",
586 type
->name
, size
, type
->min_size
);
587 return OFPERR_OFPBRC_BAD_LEN
;
592 if (size
< type
->min_size
) {
593 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s with incorrect "
594 "length %u (expected length at least %u bytes)",
595 type
->name
, size
, type
->min_size
);
596 return OFPERR_OFPBRC_BAD_LEN
;
601 if (size
< type
->min_size
602 || (size
- type
->min_size
) % type
->extra_multiple
) {
603 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s with incorrect "
604 "length %u (must be exactly %u bytes or longer "
605 "by an integer multiple of %u bytes)",
607 type
->min_size
, type
->extra_multiple
);
608 return OFPERR_OFPBRC_BAD_LEN
;
615 ofputil_lookup_openflow_message(const struct ofputil_msg_category
*cat
,
616 uint8_t version
, uint32_t value
,
617 const struct ofputil_msg_type
**typep
)
619 const struct ofputil_msg_type
*type
;
621 for (type
= cat
->types
; type
< &cat
->types
[cat
->n_types
]; type
++) {
622 if (type
->value
== value
623 && (!type
->ofp_version
|| version
== type
->ofp_version
)) {
629 VLOG_WARN_RL(&bad_ofmsg_rl
, "received %s of unknown type %"PRIu32
,
631 return cat
->missing_error
;
635 ofputil_decode_vendor(const struct ofp_header
*oh
, size_t length
,
636 const struct ofputil_msg_type
**typep
)
638 static const struct ofputil_msg_type nxt_messages
[] = {
639 { OFPUTIL_NXT_ROLE_REQUEST
, OFP10_VERSION
,
640 NXT_ROLE_REQUEST
, "NXT_ROLE_REQUEST",
641 sizeof(struct nx_role_request
), 0 },
643 { OFPUTIL_NXT_ROLE_REPLY
, OFP10_VERSION
,
644 NXT_ROLE_REPLY
, "NXT_ROLE_REPLY",
645 sizeof(struct nx_role_request
), 0 },
647 { OFPUTIL_NXT_SET_FLOW_FORMAT
, OFP10_VERSION
,
648 NXT_SET_FLOW_FORMAT
, "NXT_SET_FLOW_FORMAT",
649 sizeof(struct nx_set_flow_format
), 0 },
651 { OFPUTIL_NXT_SET_PACKET_IN_FORMAT
, OFP10_VERSION
,
652 NXT_SET_PACKET_IN_FORMAT
, "NXT_SET_PACKET_IN_FORMAT",
653 sizeof(struct nx_set_packet_in_format
), 0 },
655 { OFPUTIL_NXT_PACKET_IN
, OFP10_VERSION
,
656 NXT_PACKET_IN
, "NXT_PACKET_IN",
657 sizeof(struct nx_packet_in
), 1 },
659 { OFPUTIL_NXT_FLOW_MOD
, OFP10_VERSION
,
660 NXT_FLOW_MOD
, "NXT_FLOW_MOD",
661 sizeof(struct nx_flow_mod
), 8 },
663 { OFPUTIL_NXT_FLOW_REMOVED
, OFP10_VERSION
,
664 NXT_FLOW_REMOVED
, "NXT_FLOW_REMOVED",
665 sizeof(struct nx_flow_removed
), 8 },
667 { OFPUTIL_NXT_FLOW_MOD_TABLE_ID
, OFP10_VERSION
,
668 NXT_FLOW_MOD_TABLE_ID
, "NXT_FLOW_MOD_TABLE_ID",
669 sizeof(struct nx_flow_mod_table_id
), 0 },
671 { OFPUTIL_NXT_FLOW_AGE
, OFP10_VERSION
,
672 NXT_FLOW_AGE
, "NXT_FLOW_AGE",
673 sizeof(struct nicira_header
), 0 },
675 { OFPUTIL_NXT_SET_ASYNC_CONFIG
, OFP10_VERSION
,
676 NXT_SET_ASYNC_CONFIG
, "NXT_SET_ASYNC_CONFIG",
677 sizeof(struct nx_async_config
), 0 },
679 { OFPUTIL_NXT_SET_CONTROLLER_ID
, OFP10_VERSION
,
680 NXT_SET_CONTROLLER_ID
, "NXT_SET_CONTROLLER_ID",
681 sizeof(struct nx_controller_id
), 0 },
683 { OFPUTIL_NXT_FLOW_MONITOR_CANCEL
, OFP10_VERSION
,
684 NXT_FLOW_MONITOR_CANCEL
, "NXT_FLOW_MONITOR_CANCEL",
685 sizeof(struct nx_flow_monitor_cancel
), 0 },
687 { OFPUTIL_NXT_FLOW_MONITOR_PAUSED
, OFP10_VERSION
,
688 NXT_FLOW_MONITOR_PAUSED
, "NXT_FLOW_MONITOR_PAUSED",
689 sizeof(struct nicira_header
), 0 },
691 { OFPUTIL_NXT_FLOW_MONITOR_RESUMED
, OFP10_VERSION
,
692 NXT_FLOW_MONITOR_RESUMED
, "NXT_FLOW_MONITOR_RESUMED",
693 sizeof(struct nicira_header
), 0 },
696 static const struct ofputil_msg_category nxt_category
= {
697 "Nicira extension message",
698 nxt_messages
, ARRAY_SIZE(nxt_messages
),
699 OFPERR_OFPBRC_BAD_SUBTYPE
702 const struct ofp_vendor_header
*ovh
;
703 const struct nicira_header
*nh
;
705 if (length
< sizeof(struct ofp_vendor_header
)) {
706 if (length
== ntohs(oh
->length
)) {
707 VLOG_WARN_RL(&bad_ofmsg_rl
, "truncated vendor message");
709 return OFPERR_OFPBRC_BAD_LEN
;
712 ovh
= (const struct ofp_vendor_header
*) oh
;
713 if (ovh
->vendor
!= htonl(NX_VENDOR_ID
)) {
714 VLOG_WARN_RL(&bad_ofmsg_rl
, "received vendor message for unknown "
715 "vendor %"PRIx32
, ntohl(ovh
->vendor
));
716 return OFPERR_OFPBRC_BAD_VENDOR
;
719 if (length
< sizeof(struct nicira_header
)) {
720 if (length
== ntohs(oh
->length
)) {
721 VLOG_WARN_RL(&bad_ofmsg_rl
, "received Nicira vendor message of "
722 "length %u (expected at least %zu)",
723 ntohs(ovh
->header
.length
),
724 sizeof(struct nicira_header
));
726 return OFPERR_OFPBRC_BAD_LEN
;
729 nh
= (const struct nicira_header
*) oh
;
730 return ofputil_lookup_openflow_message(&nxt_category
, oh
->version
,
731 ntohl(nh
->subtype
), typep
);
735 check_nxstats_msg(const struct ofp_header
*oh
, size_t length
)
737 const struct ofp_stats_msg
*osm
= (const struct ofp_stats_msg
*) oh
;
740 if (length
< sizeof(struct ofp_vendor_stats_msg
)) {
741 if (length
== ntohs(oh
->length
)) {
742 VLOG_WARN_RL(&bad_ofmsg_rl
, "truncated vendor stats message");
744 return OFPERR_OFPBRC_BAD_LEN
;
747 memcpy(&vendor
, osm
+ 1, sizeof vendor
);
748 if (vendor
!= htonl(NX_VENDOR_ID
)) {
749 VLOG_WARN_RL(&bad_ofmsg_rl
, "received vendor stats message for "
750 "unknown vendor %"PRIx32
, ntohl(vendor
));
751 return OFPERR_OFPBRC_BAD_VENDOR
;
754 if (length
< sizeof(struct nicira_stats_msg
)) {
755 if (length
== ntohs(osm
->header
.length
)) {
756 VLOG_WARN_RL(&bad_ofmsg_rl
, "truncated Nicira stats message");
758 return OFPERR_OFPBRC_BAD_LEN
;
765 ofputil_decode_nxst_request(const struct ofp_header
*oh
, size_t length
,
766 const struct ofputil_msg_type
**typep
)
768 static const struct ofputil_msg_type nxst_requests
[] = {
769 { OFPUTIL_NXST_FLOW_REQUEST
, OFP10_VERSION
,
770 NXST_FLOW
, "NXST_FLOW request",
771 sizeof(struct nx_flow_stats_request
), 8 },
773 { OFPUTIL_NXST_AGGREGATE_REQUEST
, OFP10_VERSION
,
774 NXST_AGGREGATE
, "NXST_AGGREGATE request",
775 sizeof(struct nx_aggregate_stats_request
), 8 },
777 { OFPUTIL_NXST_FLOW_MONITOR_REQUEST
, OFP10_VERSION
,
778 NXST_FLOW_MONITOR
, "NXST_FLOW_MONITOR request",
779 sizeof(struct nicira_stats_msg
), 8 },
782 static const struct ofputil_msg_category nxst_request_category
= {
783 "Nicira extension statistics request",
784 nxst_requests
, ARRAY_SIZE(nxst_requests
),
785 OFPERR_OFPBRC_BAD_SUBTYPE
788 const struct nicira_stats_msg
*nsm
;
791 error
= check_nxstats_msg(oh
, length
);
796 nsm
= (struct nicira_stats_msg
*) oh
;
797 return ofputil_lookup_openflow_message(&nxst_request_category
, oh
->version
,
798 ntohl(nsm
->subtype
), typep
);
802 ofputil_decode_nxst_reply(const struct ofp_header
*oh
, size_t length
,
803 const struct ofputil_msg_type
**typep
)
805 static const struct ofputil_msg_type nxst_replies
[] = {
806 { OFPUTIL_NXST_FLOW_REPLY
, OFP10_VERSION
,
807 NXST_FLOW
, "NXST_FLOW reply",
808 sizeof(struct nicira_stats_msg
), 8 },
810 { OFPUTIL_NXST_AGGREGATE_REPLY
, OFP10_VERSION
,
811 NXST_AGGREGATE
, "NXST_AGGREGATE reply",
812 sizeof(struct nx_aggregate_stats_reply
), 0 },
814 { OFPUTIL_NXST_FLOW_MONITOR_REPLY
, OFP10_VERSION
,
815 NXST_FLOW_MONITOR
, "NXST_FLOW_MONITOR reply",
816 sizeof(struct nicira_stats_msg
), 8 },
819 static const struct ofputil_msg_category nxst_reply_category
= {
820 "Nicira extension statistics reply",
821 nxst_replies
, ARRAY_SIZE(nxst_replies
),
822 OFPERR_OFPBRC_BAD_SUBTYPE
825 const struct nicira_stats_msg
*nsm
;
828 error
= check_nxstats_msg(oh
, length
);
833 nsm
= (struct nicira_stats_msg
*) oh
;
834 return ofputil_lookup_openflow_message(&nxst_reply_category
, oh
->version
,
835 ntohl(nsm
->subtype
), typep
);
839 check_stats_msg(const struct ofp_header
*oh
, size_t length
)
841 if (length
< sizeof(struct ofp_stats_msg
)) {
842 if (length
== ntohs(oh
->length
)) {
843 VLOG_WARN_RL(&bad_ofmsg_rl
, "truncated stats message");
845 return OFPERR_OFPBRC_BAD_LEN
;
852 ofputil_decode_ofpst_request(const struct ofp_header
*oh
, size_t length
,
853 const struct ofputil_msg_type
**typep
)
855 static const struct ofputil_msg_type ofpst_requests
[] = {
856 { OFPUTIL_OFPST_DESC_REQUEST
, OFP10_VERSION
,
857 OFPST_DESC
, "OFPST_DESC request",
858 sizeof(struct ofp_stats_msg
), 0 },
860 { OFPUTIL_OFPST_FLOW_REQUEST
, OFP10_VERSION
,
861 OFPST_FLOW
, "OFPST_FLOW request",
862 sizeof(struct ofp_flow_stats_request
), 0 },
864 { OFPUTIL_OFPST_AGGREGATE_REQUEST
, OFP10_VERSION
,
865 OFPST_AGGREGATE
, "OFPST_AGGREGATE request",
866 sizeof(struct ofp_flow_stats_request
), 0 },
868 { OFPUTIL_OFPST_TABLE_REQUEST
, OFP10_VERSION
,
869 OFPST_TABLE
, "OFPST_TABLE request",
870 sizeof(struct ofp_stats_msg
), 0 },
872 { OFPUTIL_OFPST_PORT_REQUEST
, OFP10_VERSION
,
873 OFPST_PORT
, "OFPST_PORT request",
874 sizeof(struct ofp_port_stats_request
), 0 },
876 { OFPUTIL_OFPST_QUEUE_REQUEST
, OFP10_VERSION
,
877 OFPST_QUEUE
, "OFPST_QUEUE request",
878 sizeof(struct ofp_queue_stats_request
), 0 },
880 { OFPUTIL_OFPST_PORT_DESC_REQUEST
, OFP10_VERSION
,
881 OFPST_PORT_DESC
, "OFPST_PORT_DESC request",
882 sizeof(struct ofp_stats_msg
), 0 },
885 OFPST_VENDOR
, "OFPST_VENDOR request",
886 sizeof(struct ofp_vendor_stats_msg
), 1 },
889 static const struct ofputil_msg_category ofpst_request_category
= {
890 "OpenFlow statistics",
891 ofpst_requests
, ARRAY_SIZE(ofpst_requests
),
892 OFPERR_OFPBRC_BAD_STAT
895 const struct ofp_stats_msg
*request
= (const struct ofp_stats_msg
*) oh
;
898 error
= check_stats_msg(oh
, length
);
903 error
= ofputil_lookup_openflow_message(&ofpst_request_category
,
904 oh
->version
, ntohs(request
->type
),
906 if (!error
&& request
->type
== htons(OFPST_VENDOR
)) {
907 error
= ofputil_decode_nxst_request(oh
, length
, typep
);
913 ofputil_decode_ofpst_reply(const struct ofp_header
*oh
, size_t length
,
914 const struct ofputil_msg_type
**typep
)
916 static const struct ofputil_msg_type ofpst_replies
[] = {
917 { OFPUTIL_OFPST_DESC_REPLY
, OFP10_VERSION
,
918 OFPST_DESC
, "OFPST_DESC reply",
919 sizeof(struct ofp_desc_stats
), 0 },
921 { OFPUTIL_OFPST_FLOW_REPLY
, OFP10_VERSION
,
922 OFPST_FLOW
, "OFPST_FLOW reply",
923 sizeof(struct ofp_stats_msg
), 1 },
925 { OFPUTIL_OFPST_AGGREGATE_REPLY
, OFP10_VERSION
,
926 OFPST_AGGREGATE
, "OFPST_AGGREGATE reply",
927 sizeof(struct ofp_aggregate_stats_reply
), 0 },
929 { OFPUTIL_OFPST_TABLE_REPLY
, OFP10_VERSION
,
930 OFPST_TABLE
, "OFPST_TABLE reply",
931 sizeof(struct ofp_stats_msg
), sizeof(struct ofp_table_stats
) },
933 { OFPUTIL_OFPST_PORT_REPLY
, OFP10_VERSION
,
934 OFPST_PORT
, "OFPST_PORT reply",
935 sizeof(struct ofp_stats_msg
), sizeof(struct ofp_port_stats
) },
937 { OFPUTIL_OFPST_QUEUE_REPLY
, OFP10_VERSION
,
938 OFPST_QUEUE
, "OFPST_QUEUE reply",
939 sizeof(struct ofp_stats_msg
), sizeof(struct ofp_queue_stats
) },
941 { OFPUTIL_OFPST_PORT_DESC_REPLY
, OFP10_VERSION
,
942 OFPST_PORT_DESC
, "OFPST_PORT_DESC reply",
943 sizeof(struct ofp_stats_msg
), sizeof(struct ofp10_phy_port
) },
946 OFPST_VENDOR
, "OFPST_VENDOR reply",
947 sizeof(struct ofp_vendor_stats_msg
), 1 },
950 static const struct ofputil_msg_category ofpst_reply_category
= {
951 "OpenFlow statistics",
952 ofpst_replies
, ARRAY_SIZE(ofpst_replies
),
953 OFPERR_OFPBRC_BAD_STAT
956 const struct ofp_stats_msg
*reply
= (const struct ofp_stats_msg
*) oh
;
959 error
= check_stats_msg(oh
, length
);
964 error
= ofputil_lookup_openflow_message(&ofpst_reply_category
, oh
->version
,
965 ntohs(reply
->type
), typep
);
966 if (!error
&& reply
->type
== htons(OFPST_VENDOR
)) {
967 error
= ofputil_decode_nxst_reply(oh
, length
, typep
);
973 ofputil_decode_msg_type__(const struct ofp_header
*oh
, size_t length
,
974 const struct ofputil_msg_type
**typep
)
976 static const struct ofputil_msg_type ofpt_messages
[] = {
977 { OFPUTIL_OFPT_HELLO
, OFP10_VERSION
,
978 OFPT_HELLO
, "OFPT_HELLO",
979 sizeof(struct ofp_hello
), 1 },
981 { OFPUTIL_OFPT_ERROR
, 0,
982 OFPT_ERROR
, "OFPT_ERROR",
983 sizeof(struct ofp_error_msg
), 1 },
985 { OFPUTIL_OFPT_ECHO_REQUEST
, OFP10_VERSION
,
986 OFPT_ECHO_REQUEST
, "OFPT_ECHO_REQUEST",
987 sizeof(struct ofp_header
), 1 },
989 { OFPUTIL_OFPT_ECHO_REPLY
, OFP10_VERSION
,
990 OFPT_ECHO_REPLY
, "OFPT_ECHO_REPLY",
991 sizeof(struct ofp_header
), 1 },
993 { OFPUTIL_OFPT_FEATURES_REQUEST
, OFP10_VERSION
,
994 OFPT_FEATURES_REQUEST
, "OFPT_FEATURES_REQUEST",
995 sizeof(struct ofp_header
), 0 },
997 { OFPUTIL_OFPT_FEATURES_REPLY
, OFP10_VERSION
,
998 OFPT_FEATURES_REPLY
, "OFPT_FEATURES_REPLY",
999 sizeof(struct ofp_switch_features
), sizeof(struct ofp10_phy_port
) },
1000 { OFPUTIL_OFPT_FEATURES_REPLY
, OFP11_VERSION
,
1001 OFPT_FEATURES_REPLY
, "OFPT_FEATURES_REPLY",
1002 sizeof(struct ofp_switch_features
), sizeof(struct ofp11_port
) },
1004 { OFPUTIL_OFPT_GET_CONFIG_REQUEST
, OFP10_VERSION
,
1005 OFPT_GET_CONFIG_REQUEST
, "OFPT_GET_CONFIG_REQUEST",
1006 sizeof(struct ofp_header
), 0 },
1008 { OFPUTIL_OFPT_GET_CONFIG_REPLY
, OFP10_VERSION
,
1009 OFPT_GET_CONFIG_REPLY
, "OFPT_GET_CONFIG_REPLY",
1010 sizeof(struct ofp_switch_config
), 0 },
1012 { OFPUTIL_OFPT_SET_CONFIG
, OFP10_VERSION
,
1013 OFPT_SET_CONFIG
, "OFPT_SET_CONFIG",
1014 sizeof(struct ofp_switch_config
), 0 },
1016 { OFPUTIL_OFPT_PACKET_IN
, OFP10_VERSION
,
1017 OFPT_PACKET_IN
, "OFPT_PACKET_IN",
1018 offsetof(struct ofp_packet_in
, data
), 1 },
1020 { OFPUTIL_OFPT_FLOW_REMOVED
, OFP10_VERSION
,
1021 OFPT_FLOW_REMOVED
, "OFPT_FLOW_REMOVED",
1022 sizeof(struct ofp_flow_removed
), 0 },
1024 { OFPUTIL_OFPT_PORT_STATUS
, OFP10_VERSION
,
1025 OFPT_PORT_STATUS
, "OFPT_PORT_STATUS",
1026 sizeof(struct ofp_port_status
) + sizeof(struct ofp10_phy_port
), 0 },
1027 { OFPUTIL_OFPT_PORT_STATUS
, OFP11_VERSION
,
1028 OFPT_PORT_STATUS
, "OFPT_PORT_STATUS",
1029 sizeof(struct ofp_port_status
) + sizeof(struct ofp11_port
), 0 },
1031 { OFPUTIL_OFPT_PACKET_OUT
, OFP10_VERSION
,
1032 OFPT_PACKET_OUT
, "OFPT_PACKET_OUT",
1033 sizeof(struct ofp_packet_out
), 1 },
1035 { OFPUTIL_OFPT_FLOW_MOD
, OFP10_VERSION
,
1036 OFPT_FLOW_MOD
, "OFPT_FLOW_MOD",
1037 sizeof(struct ofp_flow_mod
), 1 },
1039 { OFPUTIL_OFPT_PORT_MOD
, OFP10_VERSION
,
1040 OFPT10_PORT_MOD
, "OFPT_PORT_MOD",
1041 sizeof(struct ofp10_port_mod
), 0 },
1042 { OFPUTIL_OFPT_PORT_MOD
, OFP11_VERSION
,
1043 OFPT11_PORT_MOD
, "OFPT_PORT_MOD",
1044 sizeof(struct ofp11_port_mod
), 0 },
1047 OFPT10_STATS_REQUEST
, "OFPT_STATS_REQUEST",
1048 sizeof(struct ofp_stats_msg
), 1 },
1051 OFPT10_STATS_REPLY
, "OFPT_STATS_REPLY",
1052 sizeof(struct ofp_stats_msg
), 1 },
1054 { OFPUTIL_OFPT_BARRIER_REQUEST
, OFP10_VERSION
,
1055 OFPT10_BARRIER_REQUEST
, "OFPT_BARRIER_REQUEST",
1056 sizeof(struct ofp_header
), 0 },
1058 { OFPUTIL_OFPT_BARRIER_REPLY
, OFP10_VERSION
,
1059 OFPT10_BARRIER_REPLY
, "OFPT_BARRIER_REPLY",
1060 sizeof(struct ofp_header
), 0 },
1063 OFPT_VENDOR
, "OFPT_VENDOR",
1064 sizeof(struct ofp_vendor_header
), 1 },
1067 static const struct ofputil_msg_category ofpt_category
= {
1069 ofpt_messages
, ARRAY_SIZE(ofpt_messages
),
1070 OFPERR_OFPBRC_BAD_TYPE
1075 error
= ofputil_lookup_openflow_message(&ofpt_category
, oh
->version
,
1078 switch ((oh
->version
<< 8) | oh
->type
) {
1079 case (OFP10_VERSION
<< 8) | OFPT_VENDOR
:
1080 case (OFP11_VERSION
<< 8) | OFPT_VENDOR
:
1081 error
= ofputil_decode_vendor(oh
, length
, typep
);
1084 case (OFP10_VERSION
<< 8) | OFPT10_STATS_REQUEST
:
1085 case (OFP11_VERSION
<< 8) | OFPT11_STATS_REQUEST
:
1086 error
= ofputil_decode_ofpst_request(oh
, length
, typep
);
1089 case (OFP10_VERSION
<< 8) | OFPT10_STATS_REPLY
:
1090 case (OFP11_VERSION
<< 8) | OFPT11_STATS_REPLY
:
1091 error
= ofputil_decode_ofpst_reply(oh
, length
, typep
);
1100 /* Decodes the message type represented by 'oh'. Returns 0 if successful or an
1101 * OpenFlow error code on failure. Either way, stores in '*typep' a type
1102 * structure that can be inspected with the ofputil_msg_type_*() functions.
1104 * oh->length must indicate the correct length of the message (and must be at
1105 * least sizeof(struct ofp_header)).
1107 * Success indicates that 'oh' is at least as long as the minimum-length
1108 * message of its type. */
1110 ofputil_decode_msg_type(const struct ofp_header
*oh
,
1111 const struct ofputil_msg_type
**typep
)
1113 size_t length
= ntohs(oh
->length
);
1116 error
= ofputil_decode_msg_type__(oh
, length
, typep
);
1118 error
= ofputil_check_length(*typep
, length
);
1121 *typep
= &ofputil_invalid_type
;
1126 /* Decodes the message type represented by 'oh', of which only the first
1127 * 'length' bytes are available. Returns 0 if successful or an OpenFlow error
1128 * code on failure. Either way, stores in '*typep' a type structure that can
1129 * be inspected with the ofputil_msg_type_*() functions. */
1131 ofputil_decode_msg_type_partial(const struct ofp_header
*oh
, size_t length
,
1132 const struct ofputil_msg_type
**typep
)
1136 error
= (length
>= sizeof *oh
1137 ? ofputil_decode_msg_type__(oh
, length
, typep
)
1138 : OFPERR_OFPBRC_BAD_LEN
);
1140 *typep
= &ofputil_invalid_type
;
1145 /* Returns an OFPUTIL_* message type code for 'type'. */
1146 enum ofputil_msg_code
1147 ofputil_msg_type_code(const struct ofputil_msg_type
*type
)
1154 struct proto_abbrev
{
1155 enum ofputil_protocol protocol
;
1159 /* Most users really don't care about some of the differences between
1160 * protocols. These abbreviations help with that. */
1161 static const struct proto_abbrev proto_abbrevs
[] = {
1162 { OFPUTIL_P_ANY
, "any" },
1163 { OFPUTIL_P_OF10_ANY
, "OpenFlow10" },
1164 { OFPUTIL_P_NXM_ANY
, "NXM" },
1166 #define N_PROTO_ABBREVS ARRAY_SIZE(proto_abbrevs)
1168 enum ofputil_protocol ofputil_flow_dump_protocols
[] = {
1172 size_t ofputil_n_flow_dump_protocols
= ARRAY_SIZE(ofputil_flow_dump_protocols
);
1174 /* Returns the ofputil_protocol that is initially in effect on an OpenFlow
1175 * connection that has negotiated the given 'version'. 'version' should
1176 * normally be an 8-bit OpenFlow version identifier (e.g. 0x01 for OpenFlow
1177 * 1.0, 0x02 for OpenFlow 1.1). Returns 0 if 'version' is not supported or
1178 * outside the valid range. */
1179 enum ofputil_protocol
1180 ofputil_protocol_from_ofp_version(int version
)
1183 case OFP10_VERSION
: return OFPUTIL_P_OF10
;
1188 /* Returns the OpenFlow protocol version number (e.g. OFP10_VERSION or
1189 * OFP11_VERSION) that corresponds to 'protocol'. */
1191 ofputil_protocol_to_ofp_version(enum ofputil_protocol protocol
)
1194 case OFPUTIL_P_OF10
:
1195 case OFPUTIL_P_OF10_TID
:
1197 case OFPUTIL_P_NXM_TID
:
1198 return OFP10_VERSION
;
1204 /* Returns true if 'protocol' is a single OFPUTIL_P_* value, false
1207 ofputil_protocol_is_valid(enum ofputil_protocol protocol
)
1209 return protocol
& OFPUTIL_P_ANY
&& is_pow2(protocol
);
1212 /* Returns the equivalent of 'protocol' with the Nicira flow_mod_table_id
1213 * extension turned on or off if 'enable' is true or false, respectively.
1215 * This extension is only useful for protocols whose "standard" version does
1216 * not allow specific tables to be modified. In particular, this is true of
1217 * OpenFlow 1.0. In later versions of OpenFlow, a flow_mod request always
1218 * specifies a table ID and so there is no need for such an extension. When
1219 * 'protocol' is such a protocol that doesn't need a flow_mod_table_id
1220 * extension, this function just returns its 'protocol' argument unchanged
1221 * regardless of the value of 'enable'. */
1222 enum ofputil_protocol
1223 ofputil_protocol_set_tid(enum ofputil_protocol protocol
, bool enable
)
1226 case OFPUTIL_P_OF10
:
1227 case OFPUTIL_P_OF10_TID
:
1228 return enable
? OFPUTIL_P_OF10_TID
: OFPUTIL_P_OF10
;
1231 case OFPUTIL_P_NXM_TID
:
1232 return enable
? OFPUTIL_P_NXM_TID
: OFPUTIL_P_NXM
;
1239 /* Returns the "base" version of 'protocol'. That is, if 'protocol' includes
1240 * some extension to a standard protocol version, the return value is the
1241 * standard version of that protocol without any extension. If 'protocol' is a
1242 * standard protocol version, returns 'protocol' unchanged. */
1243 enum ofputil_protocol
1244 ofputil_protocol_to_base(enum ofputil_protocol protocol
)
1246 return ofputil_protocol_set_tid(protocol
, false);
1249 /* Returns 'new_base' with any extensions taken from 'cur'. */
1250 enum ofputil_protocol
1251 ofputil_protocol_set_base(enum ofputil_protocol cur
,
1252 enum ofputil_protocol new_base
)
1254 bool tid
= (cur
& OFPUTIL_P_TID
) != 0;
1257 case OFPUTIL_P_OF10
:
1258 case OFPUTIL_P_OF10_TID
:
1259 return ofputil_protocol_set_tid(OFPUTIL_P_OF10
, tid
);
1262 case OFPUTIL_P_NXM_TID
:
1263 return ofputil_protocol_set_tid(OFPUTIL_P_NXM
, tid
);
1270 /* Returns a string form of 'protocol', if a simple form exists (that is, if
1271 * 'protocol' is either a single protocol or it is a combination of protocols
1272 * that have a single abbreviation). Otherwise, returns NULL. */
1274 ofputil_protocol_to_string(enum ofputil_protocol protocol
)
1276 const struct proto_abbrev
*p
;
1278 /* Use a "switch" statement for single-bit names so that we get a compiler
1279 * warning if we forget any. */
1282 return "NXM-table_id";
1284 case OFPUTIL_P_NXM_TID
:
1285 return "NXM+table_id";
1287 case OFPUTIL_P_OF10
:
1288 return "OpenFlow10-table_id";
1290 case OFPUTIL_P_OF10_TID
:
1291 return "OpenFlow10+table_id";
1294 /* Check abbreviations. */
1295 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
1296 if (protocol
== p
->protocol
) {
1304 /* Returns a string that represents 'protocols'. The return value might be a
1305 * comma-separated list if 'protocols' doesn't have a simple name. The return
1306 * value is "none" if 'protocols' is 0.
1308 * The caller must free the returned string (with free()). */
1310 ofputil_protocols_to_string(enum ofputil_protocol protocols
)
1314 assert(!(protocols
& ~OFPUTIL_P_ANY
));
1315 if (protocols
== 0) {
1316 return xstrdup("none");
1321 const struct proto_abbrev
*p
;
1325 ds_put_char(&s
, ',');
1328 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
1329 if ((protocols
& p
->protocol
) == p
->protocol
) {
1330 ds_put_cstr(&s
, p
->name
);
1331 protocols
&= ~p
->protocol
;
1336 for (i
= 0; i
< CHAR_BIT
* sizeof(enum ofputil_protocol
); i
++) {
1337 enum ofputil_protocol bit
= 1u << i
;
1339 if (protocols
& bit
) {
1340 ds_put_cstr(&s
, ofputil_protocol_to_string(bit
));
1349 return ds_steal_cstr(&s
);
1352 static enum ofputil_protocol
1353 ofputil_protocol_from_string__(const char *s
, size_t n
)
1355 const struct proto_abbrev
*p
;
1358 for (i
= 0; i
< CHAR_BIT
* sizeof(enum ofputil_protocol
); i
++) {
1359 enum ofputil_protocol bit
= 1u << i
;
1360 const char *name
= ofputil_protocol_to_string(bit
);
1362 if (name
&& n
== strlen(name
) && !strncasecmp(s
, name
, n
)) {
1367 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
1368 if (n
== strlen(p
->name
) && !strncasecmp(s
, p
->name
, n
)) {
1376 /* Returns the nonempty set of protocols represented by 's', which can be a
1377 * single protocol name or abbreviation or a comma-separated list of them.
1379 * Aborts the program with an error message if 's' is invalid. */
1380 enum ofputil_protocol
1381 ofputil_protocols_from_string(const char *s
)
1383 const char *orig_s
= s
;
1384 enum ofputil_protocol protocols
;
1388 enum ofputil_protocol p
;
1391 n
= strcspn(s
, ",");
1397 p
= ofputil_protocol_from_string__(s
, n
);
1399 ovs_fatal(0, "%.*s: unknown flow protocol", (int) n
, s
);
1407 ovs_fatal(0, "%s: no flow protocol specified", orig_s
);
1413 ofputil_packet_in_format_is_valid(enum nx_packet_in_format packet_in_format
)
1415 switch (packet_in_format
) {
1416 case NXPIF_OPENFLOW10
:
1425 ofputil_packet_in_format_to_string(enum nx_packet_in_format packet_in_format
)
1427 switch (packet_in_format
) {
1428 case NXPIF_OPENFLOW10
:
1429 return "openflow10";
1438 ofputil_packet_in_format_from_string(const char *s
)
1440 return (!strcmp(s
, "openflow10") ? NXPIF_OPENFLOW10
1441 : !strcmp(s
, "nxm") ? NXPIF_NXM
1446 regs_fully_wildcarded(const struct flow_wildcards
*wc
)
1450 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
1451 if (wc
->reg_masks
[i
] != 0) {
1458 /* Returns a bit-mask of ofputil_protocols that can be used for sending 'rule'
1459 * to a switch (e.g. to add or remove a flow). Only NXM can handle tunnel IDs,
1460 * registers, or fixing the Ethernet multicast bit. Otherwise, it's better to
1461 * use OpenFlow 1.0 protocol for backward compatibility. */
1462 enum ofputil_protocol
1463 ofputil_usable_protocols(const struct cls_rule
*rule
)
1465 const struct flow_wildcards
*wc
= &rule
->wc
;
1467 BUILD_ASSERT_DECL(FLOW_WC_SEQ
== 12);
1469 /* NXM and OF1.1+ supports bitwise matching on ethernet addresses. */
1470 if (!eth_mask_is_exact(wc
->dl_src_mask
)
1471 && !eth_addr_is_zero(wc
->dl_src_mask
)) {
1472 return OFPUTIL_P_NXM_ANY
;
1474 if (!eth_mask_is_exact(wc
->dl_dst_mask
)
1475 && !eth_addr_is_zero(wc
->dl_dst_mask
)) {
1476 return OFPUTIL_P_NXM_ANY
;
1479 /* NXM and OF1.1+ support matching metadata. */
1480 if (wc
->metadata_mask
!= htonll(0)) {
1481 return OFPUTIL_P_NXM_ANY
;
1484 /* Only NXM supports matching ARP hardware addresses. */
1485 if (!(wc
->wildcards
& FWW_ARP_SHA
) || !(wc
->wildcards
& FWW_ARP_THA
)) {
1486 return OFPUTIL_P_NXM_ANY
;
1489 /* Only NXM supports matching IPv6 traffic. */
1490 if (!(wc
->wildcards
& FWW_DL_TYPE
)
1491 && (rule
->flow
.dl_type
== htons(ETH_TYPE_IPV6
))) {
1492 return OFPUTIL_P_NXM_ANY
;
1495 /* Only NXM supports matching registers. */
1496 if (!regs_fully_wildcarded(wc
)) {
1497 return OFPUTIL_P_NXM_ANY
;
1500 /* Only NXM supports matching tun_id. */
1501 if (wc
->tun_id_mask
!= htonll(0)) {
1502 return OFPUTIL_P_NXM_ANY
;
1505 /* Only NXM supports matching fragments. */
1506 if (wc
->nw_frag_mask
) {
1507 return OFPUTIL_P_NXM_ANY
;
1510 /* Only NXM supports matching IPv6 flow label. */
1511 if (!(wc
->wildcards
& FWW_IPV6_LABEL
)) {
1512 return OFPUTIL_P_NXM_ANY
;
1515 /* Only NXM supports matching IP ECN bits. */
1516 if (!(wc
->wildcards
& FWW_NW_ECN
)) {
1517 return OFPUTIL_P_NXM_ANY
;
1520 /* Only NXM supports matching IP TTL/hop limit. */
1521 if (!(wc
->wildcards
& FWW_NW_TTL
)) {
1522 return OFPUTIL_P_NXM_ANY
;
1525 /* Only NXM supports non-CIDR IPv4 address masks. */
1526 if (!ip_is_cidr(wc
->nw_src_mask
) || !ip_is_cidr(wc
->nw_dst_mask
)) {
1527 return OFPUTIL_P_NXM_ANY
;
1530 /* Only NXM supports bitwise matching on transport port. */
1531 if ((wc
->tp_src_mask
&& wc
->tp_src_mask
!= htons(UINT16_MAX
)) ||
1532 (wc
->tp_dst_mask
&& wc
->tp_dst_mask
!= htons(UINT16_MAX
))) {
1533 return OFPUTIL_P_NXM_ANY
;
1536 /* Other formats can express this rule. */
1537 return OFPUTIL_P_ANY
;
1540 /* Returns an OpenFlow message that, sent on an OpenFlow connection whose
1541 * protocol is 'current', at least partly transitions the protocol to 'want'.
1542 * Stores in '*next' the protocol that will be in effect on the OpenFlow
1543 * connection if the switch processes the returned message correctly. (If
1544 * '*next != want' then the caller will have to iterate.)
1546 * If 'current == want', returns NULL and stores 'current' in '*next'. */
1548 ofputil_encode_set_protocol(enum ofputil_protocol current
,
1549 enum ofputil_protocol want
,
1550 enum ofputil_protocol
*next
)
1552 enum ofputil_protocol cur_base
, want_base
;
1553 bool cur_tid
, want_tid
;
1555 cur_base
= ofputil_protocol_to_base(current
);
1556 want_base
= ofputil_protocol_to_base(want
);
1557 if (cur_base
!= want_base
) {
1558 *next
= ofputil_protocol_set_base(current
, want_base
);
1560 switch (want_base
) {
1562 return ofputil_encode_nx_set_flow_format(NXFF_NXM
);
1564 case OFPUTIL_P_OF10
:
1565 return ofputil_encode_nx_set_flow_format(NXFF_OPENFLOW10
);
1567 case OFPUTIL_P_OF10_TID
:
1568 case OFPUTIL_P_NXM_TID
:
1573 cur_tid
= (current
& OFPUTIL_P_TID
) != 0;
1574 want_tid
= (want
& OFPUTIL_P_TID
) != 0;
1575 if (cur_tid
!= want_tid
) {
1576 *next
= ofputil_protocol_set_tid(current
, want_tid
);
1577 return ofputil_make_flow_mod_table_id(want_tid
);
1580 assert(current
== want
);
1586 /* Returns an NXT_SET_FLOW_FORMAT message that can be used to set the flow
1587 * format to 'nxff'. */
1589 ofputil_encode_nx_set_flow_format(enum nx_flow_format nxff
)
1591 struct nx_set_flow_format
*sff
;
1594 assert(ofputil_nx_flow_format_is_valid(nxff
));
1596 sff
= make_nxmsg(sizeof *sff
, NXT_SET_FLOW_FORMAT
, &msg
);
1597 sff
->format
= htonl(nxff
);
1602 /* Returns the base protocol if 'flow_format' is a valid NXFF_* value, false
1604 enum ofputil_protocol
1605 ofputil_nx_flow_format_to_protocol(enum nx_flow_format flow_format
)
1607 switch (flow_format
) {
1608 case NXFF_OPENFLOW10
:
1609 return OFPUTIL_P_OF10
;
1612 return OFPUTIL_P_NXM
;
1619 /* Returns true if 'flow_format' is a valid NXFF_* value, false otherwise. */
1621 ofputil_nx_flow_format_is_valid(enum nx_flow_format flow_format
)
1623 return ofputil_nx_flow_format_to_protocol(flow_format
) != 0;
1626 /* Returns a string version of 'flow_format', which must be a valid NXFF_*
1629 ofputil_nx_flow_format_to_string(enum nx_flow_format flow_format
)
1631 switch (flow_format
) {
1632 case NXFF_OPENFLOW10
:
1633 return "openflow10";
1642 ofputil_make_set_packet_in_format(enum nx_packet_in_format packet_in_format
)
1644 struct nx_set_packet_in_format
*spif
;
1647 spif
= make_nxmsg(sizeof *spif
, NXT_SET_PACKET_IN_FORMAT
, &msg
);
1648 spif
->format
= htonl(packet_in_format
);
1653 /* Returns an OpenFlow message that can be used to turn the flow_mod_table_id
1654 * extension on or off (according to 'flow_mod_table_id'). */
1656 ofputil_make_flow_mod_table_id(bool flow_mod_table_id
)
1658 struct nx_flow_mod_table_id
*nfmti
;
1661 nfmti
= make_nxmsg(sizeof *nfmti
, NXT_FLOW_MOD_TABLE_ID
, &msg
);
1662 nfmti
->set
= flow_mod_table_id
;
1666 /* Converts an OFPT_FLOW_MOD or NXT_FLOW_MOD message 'oh' into an abstract
1667 * flow_mod in 'fm'. Returns 0 if successful, otherwise an OpenFlow error
1670 * Uses 'ofpacts' to store the abstract OFPACT_* version of 'oh''s actions.
1671 * The caller must initialize 'ofpacts' and retains ownership of it.
1672 * 'fm->ofpacts' will point into the 'ofpacts' buffer.
1674 * Does not validate the flow_mod actions. The caller should do that, with
1675 * ofpacts_check(). */
1677 ofputil_decode_flow_mod(struct ofputil_flow_mod
*fm
,
1678 const struct ofp_header
*oh
,
1679 enum ofputil_protocol protocol
,
1680 struct ofpbuf
*ofpacts
)
1682 const struct ofputil_msg_type
*type
;
1686 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1688 ofputil_decode_msg_type(oh
, &type
);
1689 if (ofputil_msg_type_code(type
) == OFPUTIL_OFPT_FLOW_MOD
) {
1690 /* Standard OpenFlow flow_mod. */
1691 const struct ofp_flow_mod
*ofm
;
1695 /* Get the ofp_flow_mod. */
1696 ofm
= ofpbuf_pull(&b
, sizeof *ofm
);
1698 /* Set priority based on original wildcards. Normally we'd allow
1699 * ofputil_cls_rule_from_match() to do this for us, but
1700 * ofputil_normalize_rule() can put wildcards where the original flow
1701 * didn't have them. */
1702 priority
= ntohs(ofm
->priority
);
1703 if (!(ofm
->match
.wildcards
& htonl(OFPFW10_ALL
))) {
1704 priority
= UINT16_MAX
;
1707 /* Translate the rule. */
1708 ofputil_cls_rule_from_ofp10_match(&ofm
->match
, priority
, &fm
->cr
);
1709 ofputil_normalize_rule(&fm
->cr
);
1711 /* Now get the actions. */
1712 error
= ofpacts_pull_openflow10(&b
, b
.size
, ofpacts
);
1717 /* Translate the message. */
1718 command
= ntohs(ofm
->command
);
1719 fm
->cookie
= htonll(0);
1720 fm
->cookie_mask
= htonll(0);
1721 fm
->new_cookie
= ofm
->cookie
;
1722 fm
->idle_timeout
= ntohs(ofm
->idle_timeout
);
1723 fm
->hard_timeout
= ntohs(ofm
->hard_timeout
);
1724 fm
->buffer_id
= ntohl(ofm
->buffer_id
);
1725 fm
->out_port
= ntohs(ofm
->out_port
);
1726 fm
->flags
= ntohs(ofm
->flags
);
1727 } else if (ofputil_msg_type_code(type
) == OFPUTIL_NXT_FLOW_MOD
) {
1728 /* Nicira extended flow_mod. */
1729 const struct nx_flow_mod
*nfm
;
1732 /* Dissect the message. */
1733 nfm
= ofpbuf_pull(&b
, sizeof *nfm
);
1734 error
= nx_pull_match(&b
, ntohs(nfm
->match_len
), ntohs(nfm
->priority
),
1735 &fm
->cr
, &fm
->cookie
, &fm
->cookie_mask
);
1739 error
= ofpacts_pull_openflow10(&b
, b
.size
, ofpacts
);
1744 /* Translate the message. */
1745 command
= ntohs(nfm
->command
);
1746 if ((command
& 0xff) == OFPFC_ADD
&& fm
->cookie_mask
) {
1747 /* Flow additions may only set a new cookie, not match an
1748 * existing cookie. */
1749 return OFPERR_NXBRC_NXM_INVALID
;
1751 fm
->new_cookie
= nfm
->cookie
;
1752 fm
->idle_timeout
= ntohs(nfm
->idle_timeout
);
1753 fm
->hard_timeout
= ntohs(nfm
->hard_timeout
);
1754 fm
->buffer_id
= ntohl(nfm
->buffer_id
);
1755 fm
->out_port
= ntohs(nfm
->out_port
);
1756 fm
->flags
= ntohs(nfm
->flags
);
1761 fm
->ofpacts
= ofpacts
->data
;
1762 fm
->ofpacts_len
= ofpacts
->size
;
1763 if (protocol
& OFPUTIL_P_TID
) {
1764 fm
->command
= command
& 0xff;
1765 fm
->table_id
= command
>> 8;
1767 fm
->command
= command
;
1768 fm
->table_id
= 0xff;
1774 /* Converts 'fm' into an OFPT_FLOW_MOD or NXT_FLOW_MOD message according to
1775 * 'protocol' and returns the message. */
1777 ofputil_encode_flow_mod(const struct ofputil_flow_mod
*fm
,
1778 enum ofputil_protocol protocol
)
1780 struct ofp_flow_mod
*ofm
;
1781 struct nx_flow_mod
*nfm
;
1786 command
= (protocol
& OFPUTIL_P_TID
1787 ? (fm
->command
& 0xff) | (fm
->table_id
<< 8)
1791 case OFPUTIL_P_OF10
:
1792 case OFPUTIL_P_OF10_TID
:
1793 msg
= ofpbuf_new(sizeof *ofm
+ fm
->ofpacts_len
);
1794 ofm
= put_openflow(sizeof *ofm
, OFPT_FLOW_MOD
, msg
);
1795 ofputil_cls_rule_to_ofp10_match(&fm
->cr
, &ofm
->match
);
1796 ofm
->cookie
= fm
->new_cookie
;
1797 ofm
->command
= htons(command
);
1798 ofm
->idle_timeout
= htons(fm
->idle_timeout
);
1799 ofm
->hard_timeout
= htons(fm
->hard_timeout
);
1800 ofm
->priority
= htons(fm
->cr
.priority
);
1801 ofm
->buffer_id
= htonl(fm
->buffer_id
);
1802 ofm
->out_port
= htons(fm
->out_port
);
1803 ofm
->flags
= htons(fm
->flags
);
1807 case OFPUTIL_P_NXM_TID
:
1808 msg
= ofpbuf_new(sizeof *nfm
+ NXM_TYPICAL_LEN
+ fm
->ofpacts_len
);
1809 put_nxmsg(sizeof *nfm
, NXT_FLOW_MOD
, msg
);
1811 nfm
->command
= htons(command
);
1812 nfm
->cookie
= fm
->new_cookie
;
1813 match_len
= nx_put_match(msg
, false, &fm
->cr
,
1814 fm
->cookie
, fm
->cookie_mask
);
1816 nfm
->idle_timeout
= htons(fm
->idle_timeout
);
1817 nfm
->hard_timeout
= htons(fm
->hard_timeout
);
1818 nfm
->priority
= htons(fm
->cr
.priority
);
1819 nfm
->buffer_id
= htonl(fm
->buffer_id
);
1820 nfm
->out_port
= htons(fm
->out_port
);
1821 nfm
->flags
= htons(fm
->flags
);
1822 nfm
->match_len
= htons(match_len
);
1830 ofpacts_put_openflow10(fm
->ofpacts
, fm
->ofpacts_len
, msg
);
1832 update_openflow_length(msg
);
1836 /* Returns a bitmask with a 1-bit for each protocol that could be used to
1837 * send all of the 'n_fm's flow table modification requests in 'fms', and a
1838 * 0-bit for each protocol that is inadequate.
1840 * (The return value will have at least one 1-bit.) */
1841 enum ofputil_protocol
1842 ofputil_flow_mod_usable_protocols(const struct ofputil_flow_mod
*fms
,
1845 enum ofputil_protocol usable_protocols
;
1848 usable_protocols
= OFPUTIL_P_ANY
;
1849 for (i
= 0; i
< n_fms
; i
++) {
1850 const struct ofputil_flow_mod
*fm
= &fms
[i
];
1852 usable_protocols
&= ofputil_usable_protocols(&fm
->cr
);
1853 if (fm
->table_id
!= 0xff) {
1854 usable_protocols
&= OFPUTIL_P_TID
;
1857 /* Matching of the cookie is only supported through NXM. */
1858 if (fm
->cookie_mask
!= htonll(0)) {
1859 usable_protocols
&= OFPUTIL_P_NXM_ANY
;
1862 assert(usable_protocols
);
1864 return usable_protocols
;
1868 ofputil_decode_ofpst_flow_request(struct ofputil_flow_stats_request
*fsr
,
1869 const struct ofp_header
*oh
,
1872 const struct ofp_flow_stats_request
*ofsr
=
1873 (const struct ofp_flow_stats_request
*) oh
;
1875 fsr
->aggregate
= aggregate
;
1876 ofputil_cls_rule_from_ofp10_match(&ofsr
->match
, 0, &fsr
->match
);
1877 fsr
->out_port
= ntohs(ofsr
->out_port
);
1878 fsr
->table_id
= ofsr
->table_id
;
1879 fsr
->cookie
= fsr
->cookie_mask
= htonll(0);
1885 ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request
*fsr
,
1886 const struct ofp_header
*oh
,
1889 const struct nx_flow_stats_request
*nfsr
;
1893 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1895 nfsr
= ofpbuf_pull(&b
, sizeof *nfsr
);
1896 error
= nx_pull_match(&b
, ntohs(nfsr
->match_len
), 0, &fsr
->match
,
1897 &fsr
->cookie
, &fsr
->cookie_mask
);
1902 return OFPERR_OFPBRC_BAD_LEN
;
1905 fsr
->aggregate
= aggregate
;
1906 fsr
->out_port
= ntohs(nfsr
->out_port
);
1907 fsr
->table_id
= nfsr
->table_id
;
1912 /* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
1913 * request 'oh', into an abstract flow_stats_request in 'fsr'. Returns 0 if
1914 * successful, otherwise an OpenFlow error code. */
1916 ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request
*fsr
,
1917 const struct ofp_header
*oh
)
1919 const struct ofputil_msg_type
*type
;
1923 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
1925 ofputil_decode_msg_type(oh
, &type
);
1926 code
= ofputil_msg_type_code(type
);
1928 case OFPUTIL_OFPST_FLOW_REQUEST
:
1929 return ofputil_decode_ofpst_flow_request(fsr
, oh
, false);
1931 case OFPUTIL_OFPST_AGGREGATE_REQUEST
:
1932 return ofputil_decode_ofpst_flow_request(fsr
, oh
, true);
1934 case OFPUTIL_NXST_FLOW_REQUEST
:
1935 return ofputil_decode_nxst_flow_request(fsr
, oh
, false);
1937 case OFPUTIL_NXST_AGGREGATE_REQUEST
:
1938 return ofputil_decode_nxst_flow_request(fsr
, oh
, true);
1941 /* Hey, the caller lied. */
1946 /* Converts abstract flow_stats_request 'fsr' into an OFPST_FLOW,
1947 * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
1948 * 'protocol', and returns the message. */
1950 ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request
*fsr
,
1951 enum ofputil_protocol protocol
)
1956 case OFPUTIL_P_OF10
:
1957 case OFPUTIL_P_OF10_TID
: {
1958 struct ofp_flow_stats_request
*ofsr
;
1961 type
= fsr
->aggregate
? OFPST_AGGREGATE
: OFPST_FLOW
;
1962 ofsr
= ofputil_make_stats_request(sizeof *ofsr
, type
, 0, &msg
);
1963 ofputil_cls_rule_to_ofp10_match(&fsr
->match
, &ofsr
->match
);
1964 ofsr
->table_id
= fsr
->table_id
;
1965 ofsr
->out_port
= htons(fsr
->out_port
);
1970 case OFPUTIL_P_NXM_TID
: {
1971 struct nx_flow_stats_request
*nfsr
;
1975 subtype
= fsr
->aggregate
? NXST_AGGREGATE
: NXST_FLOW
;
1976 ofputil_make_stats_request(sizeof *nfsr
, OFPST_VENDOR
, subtype
, &msg
);
1977 match_len
= nx_put_match(msg
, false, &fsr
->match
,
1978 fsr
->cookie
, fsr
->cookie_mask
);
1981 nfsr
->out_port
= htons(fsr
->out_port
);
1982 nfsr
->match_len
= htons(match_len
);
1983 nfsr
->table_id
= fsr
->table_id
;
1994 /* Returns a bitmask with a 1-bit for each protocol that could be used to
1995 * accurately encode 'fsr', and a 0-bit for each protocol that is inadequate.
1997 * (The return value will have at least one 1-bit.) */
1998 enum ofputil_protocol
1999 ofputil_flow_stats_request_usable_protocols(
2000 const struct ofputil_flow_stats_request
*fsr
)
2002 enum ofputil_protocol usable_protocols
;
2004 usable_protocols
= ofputil_usable_protocols(&fsr
->match
);
2005 if (fsr
->cookie_mask
!= htonll(0)) {
2006 usable_protocols
&= OFPUTIL_P_NXM_ANY
;
2008 return usable_protocols
;
2011 /* Converts an OFPST_FLOW or NXST_FLOW reply in 'msg' into an abstract
2012 * ofputil_flow_stats in 'fs'.
2014 * Multiple OFPST_FLOW or NXST_FLOW replies can be packed into a single
2015 * OpenFlow message. Calling this function multiple times for a single 'msg'
2016 * iterates through the replies. The caller must initially leave 'msg''s layer
2017 * pointers null and not modify them between calls.
2019 * Most switches don't send the values needed to populate fs->idle_age and
2020 * fs->hard_age, so those members will usually be set to 0. If the switch from
2021 * which 'msg' originated is known to implement NXT_FLOW_AGE, then pass
2022 * 'flow_age_extension' as true so that the contents of 'msg' determine the
2023 * 'idle_age' and 'hard_age' members in 'fs'.
2025 * Uses 'ofpacts' to store the abstract OFPACT_* version of the flow stats
2026 * reply's actions. The caller must initialize 'ofpacts' and retains ownership
2027 * of it. 'fs->ofpacts' will point into the 'ofpacts' buffer.
2029 * Returns 0 if successful, EOF if no replies were left in this 'msg',
2030 * otherwise a positive errno value. */
2032 ofputil_decode_flow_stats_reply(struct ofputil_flow_stats
*fs
,
2034 bool flow_age_extension
,
2035 struct ofpbuf
*ofpacts
)
2037 const struct ofputil_msg_type
*type
;
2040 ofputil_decode_msg_type(msg
->l2
? msg
->l2
: msg
->data
, &type
);
2041 code
= ofputil_msg_type_code(type
);
2043 msg
->l2
= msg
->data
;
2044 if (code
== OFPUTIL_OFPST_FLOW_REPLY
) {
2045 ofpbuf_pull(msg
, sizeof(struct ofp_stats_msg
));
2046 } else if (code
== OFPUTIL_NXST_FLOW_REPLY
) {
2047 ofpbuf_pull(msg
, sizeof(struct nicira_stats_msg
));
2055 } else if (code
== OFPUTIL_OFPST_FLOW_REPLY
) {
2056 const struct ofp_flow_stats
*ofs
;
2059 ofs
= ofpbuf_try_pull(msg
, sizeof *ofs
);
2061 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply has %zu leftover "
2062 "bytes at end", msg
->size
);
2066 length
= ntohs(ofs
->length
);
2067 if (length
< sizeof *ofs
) {
2068 VLOG_WARN_RL(&bad_ofmsg_rl
, "OFPST_FLOW reply claims invalid "
2069 "length %zu", length
);
2073 if (ofpacts_pull_openflow10(msg
, length
- sizeof *ofs
, ofpacts
)) {
2077 fs
->cookie
= get_32aligned_be64(&ofs
->cookie
);
2078 ofputil_cls_rule_from_ofp10_match(&ofs
->match
, ntohs(ofs
->priority
),
2080 fs
->table_id
= ofs
->table_id
;
2081 fs
->duration_sec
= ntohl(ofs
->duration_sec
);
2082 fs
->duration_nsec
= ntohl(ofs
->duration_nsec
);
2083 fs
->idle_timeout
= ntohs(ofs
->idle_timeout
);
2084 fs
->hard_timeout
= ntohs(ofs
->hard_timeout
);
2087 fs
->packet_count
= ntohll(get_32aligned_be64(&ofs
->packet_count
));
2088 fs
->byte_count
= ntohll(get_32aligned_be64(&ofs
->byte_count
));
2089 } else if (code
== OFPUTIL_NXST_FLOW_REPLY
) {
2090 const struct nx_flow_stats
*nfs
;
2091 size_t match_len
, actions_len
, length
;
2093 nfs
= ofpbuf_try_pull(msg
, sizeof *nfs
);
2095 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW reply has %zu leftover "
2096 "bytes at end", msg
->size
);
2100 length
= ntohs(nfs
->length
);
2101 match_len
= ntohs(nfs
->match_len
);
2102 if (length
< sizeof *nfs
+ ROUND_UP(match_len
, 8)) {
2103 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW reply with match_len=%zu "
2104 "claims invalid length %zu", match_len
, length
);
2107 if (nx_pull_match(msg
, match_len
, ntohs(nfs
->priority
), &fs
->rule
,
2112 actions_len
= length
- sizeof *nfs
- ROUND_UP(match_len
, 8);
2113 if (ofpacts_pull_openflow10(msg
, actions_len
, ofpacts
)) {
2117 fs
->cookie
= nfs
->cookie
;
2118 fs
->table_id
= nfs
->table_id
;
2119 fs
->duration_sec
= ntohl(nfs
->duration_sec
);
2120 fs
->duration_nsec
= ntohl(nfs
->duration_nsec
);
2121 fs
->idle_timeout
= ntohs(nfs
->idle_timeout
);
2122 fs
->hard_timeout
= ntohs(nfs
->hard_timeout
);
2125 if (flow_age_extension
) {
2126 if (nfs
->idle_age
) {
2127 fs
->idle_age
= ntohs(nfs
->idle_age
) - 1;
2129 if (nfs
->hard_age
) {
2130 fs
->hard_age
= ntohs(nfs
->hard_age
) - 1;
2133 fs
->packet_count
= ntohll(nfs
->packet_count
);
2134 fs
->byte_count
= ntohll(nfs
->byte_count
);
2139 fs
->ofpacts
= ofpacts
->data
;
2140 fs
->ofpacts_len
= ofpacts
->size
;
2145 /* Returns 'count' unchanged except that UINT64_MAX becomes 0.
2147 * We use this in situations where OVS internally uses UINT64_MAX to mean
2148 * "value unknown" but OpenFlow 1.0 does not define any unknown value. */
2150 unknown_to_zero(uint64_t count
)
2152 return count
!= UINT64_MAX
? count
: 0;
2155 /* Appends an OFPST_FLOW or NXST_FLOW reply that contains the data in 'fs' to
2156 * those already present in the list of ofpbufs in 'replies'. 'replies' should
2157 * have been initialized with ofputil_start_stats_reply(). */
2159 ofputil_append_flow_stats_reply(const struct ofputil_flow_stats
*fs
,
2160 struct list
*replies
)
2162 struct ofpbuf
*reply
= ofpbuf_from_list(list_back(replies
));
2163 const struct ofp_stats_msg
*osm
= reply
->data
;
2164 size_t start_ofs
= reply
->size
;
2166 if (osm
->type
== htons(OFPST_FLOW
)) {
2167 struct ofp_flow_stats
*ofs
;
2169 ofpbuf_put_uninit(reply
, sizeof *ofs
);
2170 ofpacts_put_openflow10(fs
->ofpacts
, fs
->ofpacts_len
, reply
);
2172 ofs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *ofs
);
2173 ofs
->length
= htons(reply
->size
- start_ofs
);
2174 ofs
->table_id
= fs
->table_id
;
2176 ofputil_cls_rule_to_ofp10_match(&fs
->rule
, &ofs
->match
);
2177 ofs
->duration_sec
= htonl(fs
->duration_sec
);
2178 ofs
->duration_nsec
= htonl(fs
->duration_nsec
);
2179 ofs
->priority
= htons(fs
->rule
.priority
);
2180 ofs
->idle_timeout
= htons(fs
->idle_timeout
);
2181 ofs
->hard_timeout
= htons(fs
->hard_timeout
);
2182 memset(ofs
->pad2
, 0, sizeof ofs
->pad2
);
2183 put_32aligned_be64(&ofs
->cookie
, fs
->cookie
);
2184 put_32aligned_be64(&ofs
->packet_count
,
2185 htonll(unknown_to_zero(fs
->packet_count
)));
2186 put_32aligned_be64(&ofs
->byte_count
,
2187 htonll(unknown_to_zero(fs
->byte_count
)));
2188 } else if (osm
->type
== htons(OFPST_VENDOR
)) {
2189 struct nx_flow_stats
*nfs
;
2192 ofpbuf_put_uninit(reply
, sizeof *nfs
);
2193 match_len
= nx_put_match(reply
, false, &fs
->rule
, 0, 0);
2194 ofpacts_put_openflow10(fs
->ofpacts
, fs
->ofpacts_len
, reply
);
2196 nfs
= ofpbuf_at_assert(reply
, start_ofs
, sizeof *nfs
);
2197 nfs
->length
= htons(reply
->size
- start_ofs
);
2198 nfs
->table_id
= fs
->table_id
;
2200 nfs
->duration_sec
= htonl(fs
->duration_sec
);
2201 nfs
->duration_nsec
= htonl(fs
->duration_nsec
);
2202 nfs
->priority
= htons(fs
->rule
.priority
);
2203 nfs
->idle_timeout
= htons(fs
->idle_timeout
);
2204 nfs
->hard_timeout
= htons(fs
->hard_timeout
);
2205 nfs
->idle_age
= htons(fs
->idle_age
< 0 ? 0
2206 : fs
->idle_age
< UINT16_MAX
? fs
->idle_age
+ 1
2208 nfs
->hard_age
= htons(fs
->hard_age
< 0 ? 0
2209 : fs
->hard_age
< UINT16_MAX
? fs
->hard_age
+ 1
2211 nfs
->match_len
= htons(match_len
);
2212 nfs
->cookie
= fs
->cookie
;
2213 nfs
->packet_count
= htonll(fs
->packet_count
);
2214 nfs
->byte_count
= htonll(fs
->byte_count
);
2219 ofputil_postappend_stats_reply(start_ofs
, replies
);
2222 /* Converts abstract ofputil_aggregate_stats 'stats' into an OFPST_AGGREGATE or
2223 * NXST_AGGREGATE reply according to 'protocol', and returns the message. */
2225 ofputil_encode_aggregate_stats_reply(
2226 const struct ofputil_aggregate_stats
*stats
,
2227 const struct ofp_stats_msg
*request
)
2231 if (request
->type
== htons(OFPST_AGGREGATE
)) {
2232 struct ofp_aggregate_stats_reply
*asr
;
2234 asr
= ofputil_make_stats_reply(sizeof *asr
, request
, &msg
);
2235 put_32aligned_be64(&asr
->packet_count
,
2236 htonll(unknown_to_zero(stats
->packet_count
)));
2237 put_32aligned_be64(&asr
->byte_count
,
2238 htonll(unknown_to_zero(stats
->byte_count
)));
2239 asr
->flow_count
= htonl(stats
->flow_count
);
2240 } else if (request
->type
== htons(OFPST_VENDOR
)) {
2241 struct nx_aggregate_stats_reply
*nasr
;
2243 nasr
= ofputil_make_stats_reply(sizeof *nasr
, request
, &msg
);
2244 assert(nasr
->nsm
.subtype
== htonl(NXST_AGGREGATE
));
2245 nasr
->packet_count
= htonll(stats
->packet_count
);
2246 nasr
->byte_count
= htonll(stats
->byte_count
);
2247 nasr
->flow_count
= htonl(stats
->flow_count
);
2255 /* Converts an OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED message 'oh' into an
2256 * abstract ofputil_flow_removed in 'fr'. Returns 0 if successful, otherwise
2257 * an OpenFlow error code. */
2259 ofputil_decode_flow_removed(struct ofputil_flow_removed
*fr
,
2260 const struct ofp_header
*oh
)
2262 const struct ofputil_msg_type
*type
;
2263 enum ofputil_msg_code code
;
2265 ofputil_decode_msg_type(oh
, &type
);
2266 code
= ofputil_msg_type_code(type
);
2267 if (code
== OFPUTIL_OFPT_FLOW_REMOVED
) {
2268 const struct ofp_flow_removed
*ofr
;
2270 ofr
= (const struct ofp_flow_removed
*) oh
;
2271 ofputil_cls_rule_from_ofp10_match(&ofr
->match
, ntohs(ofr
->priority
),
2273 fr
->cookie
= ofr
->cookie
;
2274 fr
->reason
= ofr
->reason
;
2275 fr
->duration_sec
= ntohl(ofr
->duration_sec
);
2276 fr
->duration_nsec
= ntohl(ofr
->duration_nsec
);
2277 fr
->idle_timeout
= ntohs(ofr
->idle_timeout
);
2278 fr
->packet_count
= ntohll(ofr
->packet_count
);
2279 fr
->byte_count
= ntohll(ofr
->byte_count
);
2280 } else if (code
== OFPUTIL_NXT_FLOW_REMOVED
) {
2281 struct nx_flow_removed
*nfr
;
2285 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2287 nfr
= ofpbuf_pull(&b
, sizeof *nfr
);
2288 error
= nx_pull_match(&b
, ntohs(nfr
->match_len
), ntohs(nfr
->priority
),
2289 &fr
->rule
, NULL
, NULL
);
2294 return OFPERR_OFPBRC_BAD_LEN
;
2297 fr
->cookie
= nfr
->cookie
;
2298 fr
->reason
= nfr
->reason
;
2299 fr
->duration_sec
= ntohl(nfr
->duration_sec
);
2300 fr
->duration_nsec
= ntohl(nfr
->duration_nsec
);
2301 fr
->idle_timeout
= ntohs(nfr
->idle_timeout
);
2302 fr
->packet_count
= ntohll(nfr
->packet_count
);
2303 fr
->byte_count
= ntohll(nfr
->byte_count
);
2311 /* Converts abstract ofputil_flow_removed 'fr' into an OFPT_FLOW_REMOVED or
2312 * NXT_FLOW_REMOVED message 'oh' according to 'protocol', and returns the
2315 ofputil_encode_flow_removed(const struct ofputil_flow_removed
*fr
,
2316 enum ofputil_protocol protocol
)
2321 case OFPUTIL_P_OF10
:
2322 case OFPUTIL_P_OF10_TID
: {
2323 struct ofp_flow_removed
*ofr
;
2325 ofr
= make_openflow_xid(sizeof *ofr
, OFPT_FLOW_REMOVED
, htonl(0),
2327 ofputil_cls_rule_to_ofp10_match(&fr
->rule
, &ofr
->match
);
2328 ofr
->cookie
= fr
->cookie
;
2329 ofr
->priority
= htons(fr
->rule
.priority
);
2330 ofr
->reason
= fr
->reason
;
2331 ofr
->duration_sec
= htonl(fr
->duration_sec
);
2332 ofr
->duration_nsec
= htonl(fr
->duration_nsec
);
2333 ofr
->idle_timeout
= htons(fr
->idle_timeout
);
2334 ofr
->packet_count
= htonll(unknown_to_zero(fr
->packet_count
));
2335 ofr
->byte_count
= htonll(unknown_to_zero(fr
->byte_count
));
2340 case OFPUTIL_P_NXM_TID
: {
2341 struct nx_flow_removed
*nfr
;
2344 make_nxmsg_xid(sizeof *nfr
, NXT_FLOW_REMOVED
, htonl(0), &msg
);
2345 match_len
= nx_put_match(msg
, false, &fr
->rule
, 0, 0);
2348 nfr
->cookie
= fr
->cookie
;
2349 nfr
->priority
= htons(fr
->rule
.priority
);
2350 nfr
->reason
= fr
->reason
;
2351 nfr
->duration_sec
= htonl(fr
->duration_sec
);
2352 nfr
->duration_nsec
= htonl(fr
->duration_nsec
);
2353 nfr
->idle_timeout
= htons(fr
->idle_timeout
);
2354 nfr
->match_len
= htons(match_len
);
2355 nfr
->packet_count
= htonll(fr
->packet_count
);
2356 nfr
->byte_count
= htonll(fr
->byte_count
);
2368 ofputil_decode_packet_in(struct ofputil_packet_in
*pin
,
2369 const struct ofp_header
*oh
)
2371 const struct ofputil_msg_type
*type
;
2372 enum ofputil_msg_code code
;
2374 ofputil_decode_msg_type(oh
, &type
);
2375 code
= ofputil_msg_type_code(type
);
2376 memset(pin
, 0, sizeof *pin
);
2378 if (code
== OFPUTIL_OFPT_PACKET_IN
) {
2379 const struct ofp_packet_in
*opi
= (const struct ofp_packet_in
*) oh
;
2381 pin
->packet
= opi
->data
;
2382 pin
->packet_len
= ntohs(opi
->header
.length
)
2383 - offsetof(struct ofp_packet_in
, data
);
2385 pin
->fmd
.in_port
= ntohs(opi
->in_port
);
2386 pin
->reason
= opi
->reason
;
2387 pin
->buffer_id
= ntohl(opi
->buffer_id
);
2388 pin
->total_len
= ntohs(opi
->total_len
);
2389 } else if (code
== OFPUTIL_NXT_PACKET_IN
) {
2390 const struct nx_packet_in
*npi
;
2391 struct cls_rule rule
;
2395 ofpbuf_use_const(&b
, oh
, ntohs(oh
->length
));
2397 npi
= ofpbuf_pull(&b
, sizeof *npi
);
2398 error
= nx_pull_match_loose(&b
, ntohs(npi
->match_len
), 0, &rule
, NULL
,
2404 if (!ofpbuf_try_pull(&b
, 2)) {
2405 return OFPERR_OFPBRC_BAD_LEN
;
2408 pin
->packet
= b
.data
;
2409 pin
->packet_len
= b
.size
;
2410 pin
->reason
= npi
->reason
;
2411 pin
->table_id
= npi
->table_id
;
2412 pin
->cookie
= npi
->cookie
;
2414 pin
->fmd
.in_port
= rule
.flow
.in_port
;
2416 pin
->fmd
.tun_id
= rule
.flow
.tun_id
;
2417 pin
->fmd
.tun_id_mask
= rule
.wc
.tun_id_mask
;
2419 pin
->fmd
.metadata
= rule
.flow
.metadata
;
2420 pin
->fmd
.metadata_mask
= rule
.wc
.metadata_mask
;
2422 memcpy(pin
->fmd
.regs
, rule
.flow
.regs
, sizeof pin
->fmd
.regs
);
2423 memcpy(pin
->fmd
.reg_masks
, rule
.wc
.reg_masks
,
2424 sizeof pin
->fmd
.reg_masks
);
2426 pin
->buffer_id
= ntohl(npi
->buffer_id
);
2427 pin
->total_len
= ntohs(npi
->total_len
);
2435 /* Converts abstract ofputil_packet_in 'pin' into a PACKET_IN message
2436 * in the format specified by 'packet_in_format'. */
2438 ofputil_encode_packet_in(const struct ofputil_packet_in
*pin
,
2439 enum nx_packet_in_format packet_in_format
)
2441 size_t send_len
= MIN(pin
->send_len
, pin
->packet_len
);
2442 struct ofpbuf
*packet
;
2444 /* Add OFPT_PACKET_IN. */
2445 if (packet_in_format
== NXPIF_OPENFLOW10
) {
2446 size_t header_len
= offsetof(struct ofp_packet_in
, data
);
2447 struct ofp_packet_in
*opi
;
2449 packet
= ofpbuf_new(send_len
+ header_len
);
2450 opi
= ofpbuf_put_zeros(packet
, header_len
);
2451 opi
->header
.version
= OFP10_VERSION
;
2452 opi
->header
.type
= OFPT_PACKET_IN
;
2453 opi
->total_len
= htons(pin
->total_len
);
2454 opi
->in_port
= htons(pin
->fmd
.in_port
);
2455 opi
->reason
= pin
->reason
;
2456 opi
->buffer_id
= htonl(pin
->buffer_id
);
2458 ofpbuf_put(packet
, pin
->packet
, send_len
);
2459 } else if (packet_in_format
== NXPIF_NXM
) {
2460 struct nx_packet_in
*npi
;
2461 struct cls_rule rule
;
2465 /* Estimate of required PACKET_IN length includes the NPI header, space
2466 * for the match (2 times sizeof the metadata seems like enough), 2
2467 * bytes for padding, and the packet length. */
2468 packet
= ofpbuf_new(sizeof *npi
+ sizeof(struct flow_metadata
) * 2
2471 cls_rule_init_catchall(&rule
, 0);
2472 cls_rule_set_tun_id_masked(&rule
, pin
->fmd
.tun_id
,
2473 pin
->fmd
.tun_id_mask
);
2474 cls_rule_set_metadata_masked(&rule
, pin
->fmd
.metadata
,
2475 pin
->fmd
.metadata_mask
);
2478 for (i
= 0; i
< FLOW_N_REGS
; i
++) {
2479 cls_rule_set_reg_masked(&rule
, i
, pin
->fmd
.regs
[i
],
2480 pin
->fmd
.reg_masks
[i
]);
2483 cls_rule_set_in_port(&rule
, pin
->fmd
.in_port
);
2485 ofpbuf_put_zeros(packet
, sizeof *npi
);
2486 match_len
= nx_put_match(packet
, false, &rule
, 0, 0);
2487 ofpbuf_put_zeros(packet
, 2);
2488 ofpbuf_put(packet
, pin
->packet
, send_len
);
2491 npi
->nxh
.header
.version
= OFP10_VERSION
;
2492 npi
->nxh
.header
.type
= OFPT_VENDOR
;
2493 npi
->nxh
.vendor
= htonl(NX_VENDOR_ID
);
2494 npi
->nxh
.subtype
= htonl(NXT_PACKET_IN
);
2496 npi
->buffer_id
= htonl(pin
->buffer_id
);
2497 npi
->total_len
= htons(pin
->total_len
);
2498 npi
->reason
= pin
->reason
;
2499 npi
->table_id
= pin
->table_id
;
2500 npi
->cookie
= pin
->cookie
;
2501 npi
->match_len
= htons(match_len
);
2505 update_openflow_length(packet
);
2511 ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason reason
)
2513 static char s
[INT_STRLEN(int) + 1];
2520 case OFPR_INVALID_TTL
:
2521 return "invalid_ttl";
2523 case OFPR_N_REASONS
:
2525 sprintf(s
, "%d", (int) reason
);
2531 ofputil_packet_in_reason_from_string(const char *s
,
2532 enum ofp_packet_in_reason
*reason
)
2536 for (i
= 0; i
< OFPR_N_REASONS
; i
++) {
2537 if (!strcasecmp(s
, ofputil_packet_in_reason_to_string(i
))) {
2545 /* Converts an OFPT_PACKET_OUT in 'opo' into an abstract ofputil_packet_out in
2548 * Uses 'ofpacts' to store the abstract OFPACT_* version of the packet out
2549 * message's actions. The caller must initialize 'ofpacts' and retains
2550 * ownership of it. 'po->ofpacts' will point into the 'ofpacts' buffer.
2552 * Returns 0 if successful, otherwise an OFPERR_* value. */
2554 ofputil_decode_packet_out(struct ofputil_packet_out
*po
,
2555 const struct ofp_packet_out
*opo
,
2556 struct ofpbuf
*ofpacts
)
2561 po
->buffer_id
= ntohl(opo
->buffer_id
);
2562 po
->in_port
= ntohs(opo
->in_port
);
2563 if (po
->in_port
>= OFPP_MAX
&& po
->in_port
!= OFPP_LOCAL
2564 && po
->in_port
!= OFPP_NONE
&& po
->in_port
!= OFPP_CONTROLLER
) {
2565 VLOG_WARN_RL(&bad_ofmsg_rl
, "packet-out has bad input port %#"PRIx16
,
2567 return OFPERR_NXBRC_BAD_IN_PORT
;
2570 ofpbuf_use_const(&b
, opo
, ntohs(opo
->header
.length
));
2571 ofpbuf_pull(&b
, sizeof *opo
);
2573 error
= ofpacts_pull_openflow10(&b
, ntohs(opo
->actions_len
), ofpacts
);
2577 po
->ofpacts
= ofpacts
->data
;
2578 po
->ofpacts_len
= ofpacts
->size
;
2580 if (po
->buffer_id
== UINT32_MAX
) {
2581 po
->packet
= b
.data
;
2582 po
->packet_len
= b
.size
;
2591 /* ofputil_phy_port */
2593 /* NETDEV_F_* to and from OFPPF_* and OFPPF10_*. */
2594 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_HD
== OFPPF_10MB_HD
); /* bit 0 */
2595 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_FD
== OFPPF_10MB_FD
); /* bit 1 */
2596 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_HD
== OFPPF_100MB_HD
); /* bit 2 */
2597 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_FD
== OFPPF_100MB_FD
); /* bit 3 */
2598 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_HD
== OFPPF_1GB_HD
); /* bit 4 */
2599 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_FD
== OFPPF_1GB_FD
); /* bit 5 */
2600 BUILD_ASSERT_DECL((int) NETDEV_F_10GB_FD
== OFPPF_10GB_FD
); /* bit 6 */
2602 /* NETDEV_F_ bits 11...15 are OFPPF10_ bits 7...11: */
2603 BUILD_ASSERT_DECL((int) NETDEV_F_COPPER
== (OFPPF10_COPPER
<< 4));
2604 BUILD_ASSERT_DECL((int) NETDEV_F_FIBER
== (OFPPF10_FIBER
<< 4));
2605 BUILD_ASSERT_DECL((int) NETDEV_F_AUTONEG
== (OFPPF10_AUTONEG
<< 4));
2606 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE
== (OFPPF10_PAUSE
<< 4));
2607 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE_ASYM
== (OFPPF10_PAUSE_ASYM
<< 4));
2609 static enum netdev_features
2610 netdev_port_features_from_ofp10(ovs_be32 ofp10_
)
2612 uint32_t ofp10
= ntohl(ofp10_
);
2613 return (ofp10
& 0x7f) | ((ofp10
& 0xf80) << 4);
2617 netdev_port_features_to_ofp10(enum netdev_features features
)
2619 return htonl((features
& 0x7f) | ((features
& 0xf800) >> 4));
2622 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_HD
== OFPPF_10MB_HD
); /* bit 0 */
2623 BUILD_ASSERT_DECL((int) NETDEV_F_10MB_FD
== OFPPF_10MB_FD
); /* bit 1 */
2624 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_HD
== OFPPF_100MB_HD
); /* bit 2 */
2625 BUILD_ASSERT_DECL((int) NETDEV_F_100MB_FD
== OFPPF_100MB_FD
); /* bit 3 */
2626 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_HD
== OFPPF_1GB_HD
); /* bit 4 */
2627 BUILD_ASSERT_DECL((int) NETDEV_F_1GB_FD
== OFPPF_1GB_FD
); /* bit 5 */
2628 BUILD_ASSERT_DECL((int) NETDEV_F_10GB_FD
== OFPPF_10GB_FD
); /* bit 6 */
2629 BUILD_ASSERT_DECL((int) NETDEV_F_40GB_FD
== OFPPF11_40GB_FD
); /* bit 7 */
2630 BUILD_ASSERT_DECL((int) NETDEV_F_100GB_FD
== OFPPF11_100GB_FD
); /* bit 8 */
2631 BUILD_ASSERT_DECL((int) NETDEV_F_1TB_FD
== OFPPF11_1TB_FD
); /* bit 9 */
2632 BUILD_ASSERT_DECL((int) NETDEV_F_OTHER
== OFPPF11_OTHER
); /* bit 10 */
2633 BUILD_ASSERT_DECL((int) NETDEV_F_COPPER
== OFPPF11_COPPER
); /* bit 11 */
2634 BUILD_ASSERT_DECL((int) NETDEV_F_FIBER
== OFPPF11_FIBER
); /* bit 12 */
2635 BUILD_ASSERT_DECL((int) NETDEV_F_AUTONEG
== OFPPF11_AUTONEG
); /* bit 13 */
2636 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE
== OFPPF11_PAUSE
); /* bit 14 */
2637 BUILD_ASSERT_DECL((int) NETDEV_F_PAUSE_ASYM
== OFPPF11_PAUSE_ASYM
);/* bit 15 */
2639 static enum netdev_features
2640 netdev_port_features_from_ofp11(ovs_be32 ofp11
)
2642 return ntohl(ofp11
) & 0xffff;
2646 netdev_port_features_to_ofp11(enum netdev_features features
)
2648 return htonl(features
& 0xffff);
2652 ofputil_decode_ofp10_phy_port(struct ofputil_phy_port
*pp
,
2653 const struct ofp10_phy_port
*opp
)
2655 memset(pp
, 0, sizeof *pp
);
2657 pp
->port_no
= ntohs(opp
->port_no
);
2658 memcpy(pp
->hw_addr
, opp
->hw_addr
, OFP_ETH_ALEN
);
2659 ovs_strlcpy(pp
->name
, opp
->name
, OFP_MAX_PORT_NAME_LEN
);
2661 pp
->config
= ntohl(opp
->config
) & OFPPC10_ALL
;
2662 pp
->state
= ntohl(opp
->state
) & OFPPS10_ALL
;
2664 pp
->curr
= netdev_port_features_from_ofp10(opp
->curr
);
2665 pp
->advertised
= netdev_port_features_from_ofp10(opp
->advertised
);
2666 pp
->supported
= netdev_port_features_from_ofp10(opp
->supported
);
2667 pp
->peer
= netdev_port_features_from_ofp10(opp
->peer
);
2669 pp
->curr_speed
= netdev_features_to_bps(pp
->curr
) / 1000;
2670 pp
->max_speed
= netdev_features_to_bps(pp
->supported
) / 1000;
2676 ofputil_decode_ofp11_port(struct ofputil_phy_port
*pp
,
2677 const struct ofp11_port
*op
)
2681 memset(pp
, 0, sizeof *pp
);
2683 error
= ofputil_port_from_ofp11(op
->port_no
, &pp
->port_no
);
2687 memcpy(pp
->hw_addr
, op
->hw_addr
, OFP_ETH_ALEN
);
2688 ovs_strlcpy(pp
->name
, op
->name
, OFP_MAX_PORT_NAME_LEN
);
2690 pp
->config
= ntohl(op
->config
) & OFPPC11_ALL
;
2691 pp
->state
= ntohl(op
->state
) & OFPPC11_ALL
;
2693 pp
->curr
= netdev_port_features_from_ofp11(op
->curr
);
2694 pp
->advertised
= netdev_port_features_from_ofp11(op
->advertised
);
2695 pp
->supported
= netdev_port_features_from_ofp11(op
->supported
);
2696 pp
->peer
= netdev_port_features_from_ofp11(op
->peer
);
2698 pp
->curr_speed
= ntohl(op
->curr_speed
);
2699 pp
->max_speed
= ntohl(op
->max_speed
);
2705 ofputil_get_phy_port_size(uint8_t ofp_version
)
2707 return ofp_version
== OFP10_VERSION
? sizeof(struct ofp10_phy_port
)
2708 : sizeof(struct ofp11_port
);
2712 ofputil_encode_ofp10_phy_port(const struct ofputil_phy_port
*pp
,
2713 struct ofp10_phy_port
*opp
)
2715 memset(opp
, 0, sizeof *opp
);
2717 opp
->port_no
= htons(pp
->port_no
);
2718 memcpy(opp
->hw_addr
, pp
->hw_addr
, ETH_ADDR_LEN
);
2719 ovs_strlcpy(opp
->name
, pp
->name
, OFP_MAX_PORT_NAME_LEN
);
2721 opp
->config
= htonl(pp
->config
& OFPPC10_ALL
);
2722 opp
->state
= htonl(pp
->state
& OFPPS10_ALL
);
2724 opp
->curr
= netdev_port_features_to_ofp10(pp
->curr
);
2725 opp
->advertised
= netdev_port_features_to_ofp10(pp
->advertised
);
2726 opp
->supported
= netdev_port_features_to_ofp10(pp
->supported
);
2727 opp
->peer
= netdev_port_features_to_ofp10(pp
->peer
);
2731 ofputil_encode_ofp11_port(const struct ofputil_phy_port
*pp
,
2732 struct ofp11_port
*op
)
2734 memset(op
, 0, sizeof *op
);
2736 op
->port_no
= ofputil_port_to_ofp11(pp
->port_no
);
2737 memcpy(op
->hw_addr
, pp
->hw_addr
, ETH_ADDR_LEN
);
2738 ovs_strlcpy(op
->name
, pp
->name
, OFP_MAX_PORT_NAME_LEN
);
2740 op
->config
= htonl(pp
->config
& OFPPC11_ALL
);
2741 op
->state
= htonl(pp
->state
& OFPPS11_ALL
);
2743 op
->curr
= netdev_port_features_to_ofp11(pp
->curr
);
2744 op
->advertised
= netdev_port_features_to_ofp11(pp
->advertised
);
2745 op
->supported
= netdev_port_features_to_ofp11(pp
->supported
);
2746 op
->peer
= netdev_port_features_to_ofp11(pp
->peer
);
2748 op
->curr_speed
= htonl(pp
->curr_speed
);
2749 op
->max_speed
= htonl(pp
->max_speed
);
2753 ofputil_put_phy_port(uint8_t ofp_version
, const struct ofputil_phy_port
*pp
,
2756 if (ofp_version
== OFP10_VERSION
) {
2757 struct ofp10_phy_port
*opp
;
2758 if (b
->size
+ sizeof *opp
<= UINT16_MAX
) {
2759 opp
= ofpbuf_put_uninit(b
, sizeof *opp
);
2760 ofputil_encode_ofp10_phy_port(pp
, opp
);
2763 struct ofp11_port
*op
;
2764 if (b
->size
+ sizeof *op
<= UINT16_MAX
) {
2765 op
= ofpbuf_put_uninit(b
, sizeof *op
);
2766 ofputil_encode_ofp11_port(pp
, op
);
2772 ofputil_append_port_desc_stats_reply(uint8_t ofp_version
,
2773 const struct ofputil_phy_port
*pp
,
2774 struct list
*replies
)
2776 if (ofp_version
== OFP10_VERSION
) {
2777 struct ofp10_phy_port
*opp
;
2779 opp
= ofputil_append_stats_reply(sizeof *opp
, replies
);
2780 ofputil_encode_ofp10_phy_port(pp
, opp
);
2782 struct ofp11_port
*op
;
2784 op
= ofputil_append_stats_reply(sizeof *op
, replies
);
2785 ofputil_encode_ofp11_port(pp
, op
);
2789 /* ofputil_switch_features */
2791 #define OFPC_COMMON (OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \
2792 OFPC_IP_REASM | OFPC_QUEUE_STATS | OFPC_ARP_MATCH_IP)
2793 BUILD_ASSERT_DECL((int) OFPUTIL_C_FLOW_STATS
== OFPC_FLOW_STATS
);
2794 BUILD_ASSERT_DECL((int) OFPUTIL_C_TABLE_STATS
== OFPC_TABLE_STATS
);
2795 BUILD_ASSERT_DECL((int) OFPUTIL_C_PORT_STATS
== OFPC_PORT_STATS
);
2796 BUILD_ASSERT_DECL((int) OFPUTIL_C_IP_REASM
== OFPC_IP_REASM
);
2797 BUILD_ASSERT_DECL((int) OFPUTIL_C_QUEUE_STATS
== OFPC_QUEUE_STATS
);
2798 BUILD_ASSERT_DECL((int) OFPUTIL_C_ARP_MATCH_IP
== OFPC_ARP_MATCH_IP
);
2800 struct ofputil_action_bit_translation
{
2801 enum ofputil_action_bitmap ofputil_bit
;
2805 static const struct ofputil_action_bit_translation of10_action_bits
[] = {
2806 { OFPUTIL_A_OUTPUT
, OFPAT10_OUTPUT
},
2807 { OFPUTIL_A_SET_VLAN_VID
, OFPAT10_SET_VLAN_VID
},
2808 { OFPUTIL_A_SET_VLAN_PCP
, OFPAT10_SET_VLAN_PCP
},
2809 { OFPUTIL_A_STRIP_VLAN
, OFPAT10_STRIP_VLAN
},
2810 { OFPUTIL_A_SET_DL_SRC
, OFPAT10_SET_DL_SRC
},
2811 { OFPUTIL_A_SET_DL_DST
, OFPAT10_SET_DL_DST
},
2812 { OFPUTIL_A_SET_NW_SRC
, OFPAT10_SET_NW_SRC
},
2813 { OFPUTIL_A_SET_NW_DST
, OFPAT10_SET_NW_DST
},
2814 { OFPUTIL_A_SET_NW_TOS
, OFPAT10_SET_NW_TOS
},
2815 { OFPUTIL_A_SET_TP_SRC
, OFPAT10_SET_TP_SRC
},
2816 { OFPUTIL_A_SET_TP_DST
, OFPAT10_SET_TP_DST
},
2817 { OFPUTIL_A_ENQUEUE
, OFPAT10_ENQUEUE
},
2821 static const struct ofputil_action_bit_translation of11_action_bits
[] = {
2822 { OFPUTIL_A_OUTPUT
, OFPAT11_OUTPUT
},
2823 { OFPUTIL_A_SET_VLAN_VID
, OFPAT11_SET_VLAN_VID
},
2824 { OFPUTIL_A_SET_VLAN_PCP
, OFPAT11_SET_VLAN_PCP
},
2825 { OFPUTIL_A_SET_DL_SRC
, OFPAT11_SET_DL_SRC
},
2826 { OFPUTIL_A_SET_DL_DST
, OFPAT11_SET_DL_DST
},
2827 { OFPUTIL_A_SET_NW_SRC
, OFPAT11_SET_NW_SRC
},
2828 { OFPUTIL_A_SET_NW_DST
, OFPAT11_SET_NW_DST
},
2829 { OFPUTIL_A_SET_NW_TOS
, OFPAT11_SET_NW_TOS
},
2830 { OFPUTIL_A_SET_NW_ECN
, OFPAT11_SET_NW_ECN
},
2831 { OFPUTIL_A_SET_TP_SRC
, OFPAT11_SET_TP_SRC
},
2832 { OFPUTIL_A_SET_TP_DST
, OFPAT11_SET_TP_DST
},
2833 { OFPUTIL_A_COPY_TTL_OUT
, OFPAT11_COPY_TTL_OUT
},
2834 { OFPUTIL_A_COPY_TTL_IN
, OFPAT11_COPY_TTL_IN
},
2835 { OFPUTIL_A_SET_MPLS_LABEL
, OFPAT11_SET_MPLS_LABEL
},
2836 { OFPUTIL_A_SET_MPLS_TC
, OFPAT11_SET_MPLS_TC
},
2837 { OFPUTIL_A_SET_MPLS_TTL
, OFPAT11_SET_MPLS_TTL
},
2838 { OFPUTIL_A_DEC_MPLS_TTL
, OFPAT11_DEC_MPLS_TTL
},
2839 { OFPUTIL_A_PUSH_VLAN
, OFPAT11_PUSH_VLAN
},
2840 { OFPUTIL_A_POP_VLAN
, OFPAT11_POP_VLAN
},
2841 { OFPUTIL_A_PUSH_MPLS
, OFPAT11_PUSH_MPLS
},
2842 { OFPUTIL_A_POP_MPLS
, OFPAT11_POP_MPLS
},
2843 { OFPUTIL_A_SET_QUEUE
, OFPAT11_SET_QUEUE
},
2844 { OFPUTIL_A_GROUP
, OFPAT11_GROUP
},
2845 { OFPUTIL_A_SET_NW_TTL
, OFPAT11_SET_NW_TTL
},
2846 { OFPUTIL_A_DEC_NW_TTL
, OFPAT11_DEC_NW_TTL
},
2850 static enum ofputil_action_bitmap
2851 decode_action_bits(ovs_be32 of_actions
,
2852 const struct ofputil_action_bit_translation
*x
)
2854 enum ofputil_action_bitmap ofputil_actions
;
2856 ofputil_actions
= 0;
2857 for (; x
->ofputil_bit
; x
++) {
2858 if (of_actions
& htonl(1u << x
->of_bit
)) {
2859 ofputil_actions
|= x
->ofputil_bit
;
2862 return ofputil_actions
;
2865 /* Decodes an OpenFlow 1.0 or 1.1 "switch_features" structure 'osf' into an
2866 * abstract representation in '*features'. Initializes '*b' to iterate over
2867 * the OpenFlow port structures following 'osf' with later calls to
2868 * ofputil_pull_phy_port(). Returns 0 if successful, otherwise an
2869 * OFPERR_* value. */
2871 ofputil_decode_switch_features(const struct ofp_switch_features
*osf
,
2872 struct ofputil_switch_features
*features
,
2875 ofpbuf_use_const(b
, osf
, ntohs(osf
->header
.length
));
2876 ofpbuf_pull(b
, sizeof *osf
);
2878 features
->datapath_id
= ntohll(osf
->datapath_id
);
2879 features
->n_buffers
= ntohl(osf
->n_buffers
);
2880 features
->n_tables
= osf
->n_tables
;
2882 features
->capabilities
= ntohl(osf
->capabilities
) & OFPC_COMMON
;
2884 if (b
->size
% ofputil_get_phy_port_size(osf
->header
.version
)) {
2885 return OFPERR_OFPBRC_BAD_LEN
;
2888 if (osf
->header
.version
== OFP10_VERSION
) {
2889 if (osf
->capabilities
& htonl(OFPC10_STP
)) {
2890 features
->capabilities
|= OFPUTIL_C_STP
;
2892 features
->actions
= decode_action_bits(osf
->actions
, of10_action_bits
);
2893 } else if (osf
->header
.version
== OFP11_VERSION
) {
2894 if (osf
->capabilities
& htonl(OFPC11_GROUP_STATS
)) {
2895 features
->capabilities
|= OFPUTIL_C_GROUP_STATS
;
2897 features
->actions
= decode_action_bits(osf
->actions
, of11_action_bits
);
2899 return OFPERR_OFPBRC_BAD_VERSION
;
2905 /* Returns true if the maximum number of ports are in 'osf'. */
2907 max_ports_in_features(const struct ofp_switch_features
*osf
)
2909 size_t pp_size
= ofputil_get_phy_port_size(osf
->header
.version
);
2910 return ntohs(osf
->header
.length
) + pp_size
> UINT16_MAX
;
2913 /* Given a buffer 'b' that contains a Features Reply message, checks if
2914 * it contains the maximum number of ports that will fit. If so, it
2915 * returns true and removes the ports from the message. The caller
2916 * should then send an OFPST_PORT_DESC stats request to get the ports,
2917 * since the switch may have more ports than could be represented in the
2918 * Features Reply. Otherwise, returns false.
2921 ofputil_switch_features_ports_trunc(struct ofpbuf
*b
)
2923 struct ofp_switch_features
*osf
= b
->data
;
2925 if (max_ports_in_features(osf
)) {
2926 /* Remove all the ports. */
2927 b
->size
= sizeof(*osf
);
2928 update_openflow_length(b
);
2937 encode_action_bits(enum ofputil_action_bitmap ofputil_actions
,
2938 const struct ofputil_action_bit_translation
*x
)
2940 uint32_t of_actions
;
2943 for (; x
->ofputil_bit
; x
++) {
2944 if (ofputil_actions
& x
->ofputil_bit
) {
2945 of_actions
|= 1 << x
->of_bit
;
2948 return htonl(of_actions
);
2951 /* Returns a buffer owned by the caller that encodes 'features' in the format
2952 * required by 'protocol' with the given 'xid'. The caller should append port
2953 * information to the buffer with subsequent calls to
2954 * ofputil_put_switch_features_port(). */
2956 ofputil_encode_switch_features(const struct ofputil_switch_features
*features
,
2957 enum ofputil_protocol protocol
, ovs_be32 xid
)
2959 struct ofp_switch_features
*osf
;
2962 osf
= make_openflow_xid(sizeof *osf
, OFPT_FEATURES_REPLY
, xid
, &b
);
2963 osf
->header
.version
= ofputil_protocol_to_ofp_version(protocol
);
2964 osf
->datapath_id
= htonll(features
->datapath_id
);
2965 osf
->n_buffers
= htonl(features
->n_buffers
);
2966 osf
->n_tables
= features
->n_tables
;
2968 osf
->capabilities
= htonl(features
->capabilities
& OFPC_COMMON
);
2969 if (osf
->header
.version
== OFP10_VERSION
) {
2970 if (features
->capabilities
& OFPUTIL_C_STP
) {
2971 osf
->capabilities
|= htonl(OFPC10_STP
);
2973 osf
->actions
= encode_action_bits(features
->actions
, of10_action_bits
);
2975 if (features
->capabilities
& OFPUTIL_C_GROUP_STATS
) {
2976 osf
->capabilities
|= htonl(OFPC11_GROUP_STATS
);
2978 osf
->actions
= encode_action_bits(features
->actions
, of11_action_bits
);
2984 /* Encodes 'pp' into the format required by the switch_features message already
2985 * in 'b', which should have been returned by ofputil_encode_switch_features(),
2986 * and appends the encoded version to 'b'. */
2988 ofputil_put_switch_features_port(const struct ofputil_phy_port
*pp
,
2991 const struct ofp_switch_features
*osf
= b
->data
;
2993 ofputil_put_phy_port(osf
->header
.version
, pp
, b
);
2996 /* ofputil_port_status */
2998 /* Decodes the OpenFlow "port status" message in '*ops' into an abstract form
2999 * in '*ps'. Returns 0 if successful, otherwise an OFPERR_* value. */
3001 ofputil_decode_port_status(const struct ofp_port_status
*ops
,
3002 struct ofputil_port_status
*ps
)
3007 if (ops
->reason
!= OFPPR_ADD
&&
3008 ops
->reason
!= OFPPR_DELETE
&&
3009 ops
->reason
!= OFPPR_MODIFY
) {
3010 return OFPERR_NXBRC_BAD_REASON
;
3012 ps
->reason
= ops
->reason
;
3014 ofpbuf_use_const(&b
, ops
, ntohs(ops
->header
.length
));
3015 ofpbuf_pull(&b
, sizeof *ops
);
3016 retval
= ofputil_pull_phy_port(ops
->header
.version
, &b
, &ps
->desc
);
3017 assert(retval
!= EOF
);
3021 /* Converts the abstract form of a "port status" message in '*ps' into an
3022 * OpenFlow message suitable for 'protocol', and returns that encoded form in
3023 * a buffer owned by the caller. */
3025 ofputil_encode_port_status(const struct ofputil_port_status
*ps
,
3026 enum ofputil_protocol protocol
)
3028 struct ofp_port_status
*ops
;
3031 b
= ofpbuf_new(sizeof *ops
+ sizeof(struct ofp11_port
));
3032 ops
= put_openflow_xid(sizeof *ops
, OFPT_PORT_STATUS
, htonl(0), b
);
3033 ops
->header
.version
= ofputil_protocol_to_ofp_version(protocol
);
3034 ops
->reason
= ps
->reason
;
3035 ofputil_put_phy_port(ops
->header
.version
, &ps
->desc
, b
);
3036 update_openflow_length(b
);
3040 /* ofputil_port_mod */
3042 /* Decodes the OpenFlow "port mod" message in '*oh' into an abstract form in
3043 * '*pm'. Returns 0 if successful, otherwise an OFPERR_* value. */
3045 ofputil_decode_port_mod(const struct ofp_header
*oh
,
3046 struct ofputil_port_mod
*pm
)
3048 if (oh
->version
== OFP10_VERSION
) {
3049 const struct ofp10_port_mod
*opm
= (const struct ofp10_port_mod
*) oh
;
3051 if (oh
->length
!= htons(sizeof *opm
)) {
3052 return OFPERR_OFPBRC_BAD_LEN
;
3055 pm
->port_no
= ntohs(opm
->port_no
);
3056 memcpy(pm
->hw_addr
, opm
->hw_addr
, ETH_ADDR_LEN
);
3057 pm
->config
= ntohl(opm
->config
) & OFPPC10_ALL
;
3058 pm
->mask
= ntohl(opm
->mask
) & OFPPC10_ALL
;
3059 pm
->advertise
= netdev_port_features_from_ofp10(opm
->advertise
);
3060 } else if (oh
->version
== OFP11_VERSION
) {
3061 const struct ofp11_port_mod
*opm
= (const struct ofp11_port_mod
*) oh
;
3064 if (oh
->length
!= htons(sizeof *opm
)) {
3065 return OFPERR_OFPBRC_BAD_LEN
;
3068 error
= ofputil_port_from_ofp11(opm
->port_no
, &pm
->port_no
);
3073 memcpy(pm
->hw_addr
, opm
->hw_addr
, ETH_ADDR_LEN
);
3074 pm
->config
= ntohl(opm
->config
) & OFPPC11_ALL
;
3075 pm
->mask
= ntohl(opm
->mask
) & OFPPC11_ALL
;
3076 pm
->advertise
= netdev_port_features_from_ofp11(opm
->advertise
);
3078 return OFPERR_OFPBRC_BAD_VERSION
;
3081 pm
->config
&= pm
->mask
;
3085 /* Converts the abstract form of a "port mod" message in '*pm' into an OpenFlow
3086 * message suitable for 'protocol', and returns that encoded form in a buffer
3087 * owned by the caller. */
3089 ofputil_encode_port_mod(const struct ofputil_port_mod
*pm
,
3090 enum ofputil_protocol protocol
)
3092 uint8_t ofp_version
= ofputil_protocol_to_ofp_version(protocol
);
3095 if (ofp_version
== OFP10_VERSION
) {
3096 struct ofp10_port_mod
*opm
;
3098 opm
= make_openflow(sizeof *opm
, OFPT10_PORT_MOD
, &b
);
3099 opm
->port_no
= htons(pm
->port_no
);
3100 memcpy(opm
->hw_addr
, pm
->hw_addr
, ETH_ADDR_LEN
);
3101 opm
->config
= htonl(pm
->config
& OFPPC10_ALL
);
3102 opm
->mask
= htonl(pm
->mask
& OFPPC10_ALL
);
3103 opm
->advertise
= netdev_port_features_to_ofp10(pm
->advertise
);
3104 } else if (ofp_version
== OFP11_VERSION
) {
3105 struct ofp11_port_mod
*opm
;
3107 opm
= make_openflow(sizeof *opm
, OFPT11_PORT_MOD
, &b
);
3108 opm
->port_no
= htonl(pm
->port_no
);
3109 memcpy(opm
->hw_addr
, pm
->hw_addr
, ETH_ADDR_LEN
);
3110 opm
->config
= htonl(pm
->config
& OFPPC11_ALL
);
3111 opm
->mask
= htonl(pm
->mask
& OFPPC11_ALL
);
3112 opm
->advertise
= netdev_port_features_to_ofp11(pm
->advertise
);
3120 /* ofputil_flow_monitor_request */
3122 /* Converts an NXST_FLOW_MONITOR request in 'msg' into an abstract
3123 * ofputil_flow_monitor_request in 'rq'.
3125 * Multiple NXST_FLOW_MONITOR requests can be packed into a single OpenFlow
3126 * message. Calling this function multiple times for a single 'msg' iterates
3127 * through the requests. The caller must initially leave 'msg''s layer
3128 * pointers null and not modify them between calls.
3130 * Returns 0 if successful, EOF if no requests were left in this 'msg',
3131 * otherwise an OFPERR_* value. */
3133 ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request
*rq
,
3136 struct nx_flow_monitor_request
*nfmr
;
3140 msg
->l2
= msg
->data
;
3141 ofpbuf_pull(msg
, sizeof(struct nicira_stats_msg
));
3148 nfmr
= ofpbuf_try_pull(msg
, sizeof *nfmr
);
3150 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW_MONITOR request has %zu "
3151 "leftover bytes at end", msg
->size
);
3152 return OFPERR_OFPBRC_BAD_LEN
;
3155 flags
= ntohs(nfmr
->flags
);
3156 if (!(flags
& (NXFMF_ADD
| NXFMF_DELETE
| NXFMF_MODIFY
))
3157 || flags
& ~(NXFMF_INITIAL
| NXFMF_ADD
| NXFMF_DELETE
3158 | NXFMF_MODIFY
| NXFMF_ACTIONS
| NXFMF_OWN
)) {
3159 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW_MONITOR has bad flags %#"PRIx16
,
3161 return OFPERR_NXBRC_FM_BAD_FLAGS
;
3164 if (!is_all_zeros(nfmr
->zeros
, sizeof nfmr
->zeros
)) {
3165 return OFPERR_NXBRC_MUST_BE_ZERO
;
3168 rq
->id
= ntohl(nfmr
->id
);
3170 rq
->out_port
= ntohs(nfmr
->out_port
);
3171 rq
->table_id
= nfmr
->table_id
;
3173 return nx_pull_match(msg
, ntohs(nfmr
->match_len
), OFP_DEFAULT_PRIORITY
,
3174 &rq
->match
, NULL
, NULL
);
3178 ofputil_append_flow_monitor_request(
3179 const struct ofputil_flow_monitor_request
*rq
, struct ofpbuf
*msg
)
3181 struct nx_flow_monitor_request
*nfmr
;
3186 ofputil_put_stats_header(alloc_xid(), OFPT10_STATS_REQUEST
,
3187 htons(OFPST_VENDOR
),
3188 htonl(NXST_FLOW_MONITOR
), msg
);
3191 start_ofs
= msg
->size
;
3192 ofpbuf_put_zeros(msg
, sizeof *nfmr
);
3193 match_len
= nx_put_match(msg
, false, &rq
->match
, htonll(0), htonll(0));
3195 nfmr
= ofpbuf_at_assert(msg
, start_ofs
, sizeof *nfmr
);
3196 nfmr
->id
= htonl(rq
->id
);
3197 nfmr
->flags
= htons(rq
->flags
);
3198 nfmr
->out_port
= htons(rq
->out_port
);
3199 nfmr
->match_len
= htons(match_len
);
3200 nfmr
->table_id
= rq
->table_id
;
3203 /* Converts an NXST_FLOW_MONITOR reply (also known as a flow update) in 'msg'
3204 * into an abstract ofputil_flow_update in 'update'. The caller must have
3205 * initialized update->match to point to space allocated for a cls_rule.
3207 * Uses 'ofpacts' to store the abstract OFPACT_* version of the update's
3208 * actions (except for NXFME_ABBREV, which never includes actions). The caller
3209 * must initialize 'ofpacts' and retains ownership of it. 'update->ofpacts'
3210 * will point into the 'ofpacts' buffer.
3212 * Multiple flow updates can be packed into a single OpenFlow message. Calling
3213 * this function multiple times for a single 'msg' iterates through the
3214 * updates. The caller must initially leave 'msg''s layer pointers null and
3215 * not modify them between calls.
3217 * Returns 0 if successful, EOF if no updates were left in this 'msg',
3218 * otherwise an OFPERR_* value. */
3220 ofputil_decode_flow_update(struct ofputil_flow_update
*update
,
3221 struct ofpbuf
*msg
, struct ofpbuf
*ofpacts
)
3223 struct nx_flow_update_header
*nfuh
;
3224 unsigned int length
;
3227 msg
->l2
= msg
->data
;
3228 ofpbuf_pull(msg
, sizeof(struct nicira_stats_msg
));
3235 if (msg
->size
< sizeof(struct nx_flow_update_header
)) {
3240 update
->event
= ntohs(nfuh
->event
);
3241 length
= ntohs(nfuh
->length
);
3242 if (length
> msg
->size
|| length
% 8) {
3246 if (update
->event
== NXFME_ABBREV
) {
3247 struct nx_flow_update_abbrev
*nfua
;
3249 if (length
!= sizeof *nfua
) {
3253 nfua
= ofpbuf_pull(msg
, sizeof *nfua
);
3254 update
->xid
= nfua
->xid
;
3256 } else if (update
->event
== NXFME_ADDED
3257 || update
->event
== NXFME_DELETED
3258 || update
->event
== NXFME_MODIFIED
) {
3259 struct nx_flow_update_full
*nfuf
;
3260 unsigned int actions_len
;
3261 unsigned int match_len
;
3264 if (length
< sizeof *nfuf
) {
3268 nfuf
= ofpbuf_pull(msg
, sizeof *nfuf
);
3269 match_len
= ntohs(nfuf
->match_len
);
3270 if (sizeof *nfuf
+ match_len
> length
) {
3274 update
->reason
= ntohs(nfuf
->reason
);
3275 update
->idle_timeout
= ntohs(nfuf
->idle_timeout
);
3276 update
->hard_timeout
= ntohs(nfuf
->hard_timeout
);
3277 update
->table_id
= nfuf
->table_id
;
3278 update
->cookie
= nfuf
->cookie
;
3280 error
= nx_pull_match(msg
, match_len
, ntohs(nfuf
->priority
),
3281 update
->match
, NULL
, NULL
);
3286 actions_len
= length
- sizeof *nfuf
- ROUND_UP(match_len
, 8);
3287 error
= ofpacts_pull_openflow10(msg
, actions_len
, ofpacts
);
3292 update
->ofpacts
= ofpacts
->data
;
3293 update
->ofpacts_len
= ofpacts
->size
;
3296 VLOG_WARN_RL(&bad_ofmsg_rl
,
3297 "NXST_FLOW_MONITOR reply has bad event %"PRIu16
,
3298 ntohs(nfuh
->event
));
3299 return OFPERR_OFPET_BAD_REQUEST
;
3303 VLOG_WARN_RL(&bad_ofmsg_rl
, "NXST_FLOW_MONITOR reply has %zu "
3304 "leftover bytes at end", msg
->size
);
3305 return OFPERR_OFPBRC_BAD_LEN
;
3309 ofputil_decode_flow_monitor_cancel(const struct ofp_header
*oh
)
3311 return ntohl(((const struct nx_flow_monitor_cancel
*) oh
)->id
);
3315 ofputil_encode_flow_monitor_cancel(uint32_t id
)
3317 struct nx_flow_monitor_cancel
*nfmc
;
3320 nfmc
= make_nxmsg(sizeof *nfmc
, NXT_FLOW_MONITOR_CANCEL
, &msg
);
3321 nfmc
->id
= htonl(id
);
3326 ofputil_start_flow_update(struct list
*replies
)
3330 msg
= ofpbuf_new(1024);
3331 ofputil_put_stats_header(htonl(0), OFPT10_STATS_REPLY
,
3332 htons(OFPST_VENDOR
),
3333 htonl(NXST_FLOW_MONITOR
), msg
);
3336 list_push_back(replies
, &msg
->list_node
);
3340 ofputil_append_flow_update(const struct ofputil_flow_update
*update
,
3341 struct list
*replies
)
3343 struct nx_flow_update_header
*nfuh
;
3347 msg
= ofpbuf_from_list(list_back(replies
));
3348 start_ofs
= msg
->size
;
3350 if (update
->event
== NXFME_ABBREV
) {
3351 struct nx_flow_update_abbrev
*nfua
;
3353 nfua
= ofpbuf_put_zeros(msg
, sizeof *nfua
);
3354 nfua
->xid
= update
->xid
;
3356 struct nx_flow_update_full
*nfuf
;
3359 ofpbuf_put_zeros(msg
, sizeof *nfuf
);
3360 match_len
= nx_put_match(msg
, false, update
->match
,
3361 htonll(0), htonll(0));
3362 ofpacts_put_openflow10(update
->ofpacts
, update
->ofpacts_len
, msg
);
3364 nfuf
= ofpbuf_at_assert(msg
, start_ofs
, sizeof *nfuf
);
3365 nfuf
->reason
= htons(update
->reason
);
3366 nfuf
->priority
= htons(update
->match
->priority
);
3367 nfuf
->idle_timeout
= htons(update
->idle_timeout
);
3368 nfuf
->hard_timeout
= htons(update
->hard_timeout
);
3369 nfuf
->match_len
= htons(match_len
);
3370 nfuf
->table_id
= update
->table_id
;
3371 nfuf
->cookie
= update
->cookie
;
3374 nfuh
= ofpbuf_at_assert(msg
, start_ofs
, sizeof *nfuh
);
3375 nfuh
->length
= htons(msg
->size
- start_ofs
);
3376 nfuh
->event
= htons(update
->event
);
3378 ofputil_postappend_stats_reply(start_ofs
, replies
);
3382 ofputil_encode_packet_out(const struct ofputil_packet_out
*po
)
3384 struct ofp_packet_out
*opo
;
3388 size
= sizeof *opo
+ po
->ofpacts_len
;
3389 if (po
->buffer_id
== UINT32_MAX
) {
3390 size
+= po
->packet_len
;
3393 msg
= ofpbuf_new(size
);
3394 put_openflow(sizeof *opo
, OFPT_PACKET_OUT
, msg
);
3395 ofpacts_put_openflow10(po
->ofpacts
, po
->ofpacts_len
, msg
);
3398 opo
->buffer_id
= htonl(po
->buffer_id
);
3399 opo
->in_port
= htons(po
->in_port
);
3400 opo
->actions_len
= htons(msg
->size
- sizeof *opo
);
3402 if (po
->buffer_id
== UINT32_MAX
) {
3403 ofpbuf_put(msg
, po
->packet
, po
->packet_len
);
3406 update_openflow_length(msg
);
3411 /* Returns a string representing the message type of 'type'. The string is the
3412 * enumeration constant for the type, e.g. "OFPT_HELLO". For statistics
3413 * messages, the constant is followed by "request" or "reply",
3414 * e.g. "OFPST_AGGREGATE reply". */
3416 ofputil_msg_type_name(const struct ofputil_msg_type
*type
)
3421 /* Allocates and stores in '*bufferp' a new ofpbuf with a size of
3422 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
3423 * an arbitrary transaction id. Allocated bytes beyond the header, if any, are
3426 * The caller is responsible for freeing '*bufferp' when it is no longer
3429 * The OpenFlow header length is initially set to 'openflow_len'; if the
3430 * message is later extended, the length should be updated with
3431 * update_openflow_length() before sending.
3433 * Returns the header. */
3435 make_openflow(size_t openflow_len
, uint8_t type
, struct ofpbuf
**bufferp
)
3437 *bufferp
= ofpbuf_new(openflow_len
);
3438 return put_openflow_xid(openflow_len
, type
, alloc_xid(), *bufferp
);
3441 /* Similar to make_openflow() but creates a Nicira vendor extension message
3442 * with the specific 'subtype'. 'subtype' should be in host byte order. */
3444 make_nxmsg(size_t openflow_len
, uint32_t subtype
, struct ofpbuf
**bufferp
)
3446 return make_nxmsg_xid(openflow_len
, subtype
, alloc_xid(), bufferp
);
3449 /* Allocates and stores in '*bufferp' a new ofpbuf with a size of
3450 * 'openflow_len', starting with an OpenFlow header with the given 'type' and
3451 * transaction id 'xid'. Allocated bytes beyond the header, if any, are
3454 * The caller is responsible for freeing '*bufferp' when it is no longer
3457 * The OpenFlow header length is initially set to 'openflow_len'; if the
3458 * message is later extended, the length should be updated with
3459 * update_openflow_length() before sending.
3461 * Returns the header. */
3463 make_openflow_xid(size_t openflow_len
, uint8_t type
, ovs_be32 xid
,
3464 struct ofpbuf
**bufferp
)
3466 *bufferp
= ofpbuf_new(openflow_len
);
3467 return put_openflow_xid(openflow_len
, type
, xid
, *bufferp
);
3470 /* Similar to make_openflow_xid() but creates a Nicira vendor extension message
3471 * with the specific 'subtype'. 'subtype' should be in host byte order. */
3473 make_nxmsg_xid(size_t openflow_len
, uint32_t subtype
, ovs_be32 xid
,
3474 struct ofpbuf
**bufferp
)
3476 *bufferp
= ofpbuf_new(openflow_len
);
3477 return put_nxmsg_xid(openflow_len
, subtype
, xid
, *bufferp
);
3480 /* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
3481 * with the given 'type' and an arbitrary transaction id. Allocated bytes
3482 * beyond the header, if any, are zeroed.
3484 * The OpenFlow header length is initially set to 'openflow_len'; if the
3485 * message is later extended, the length should be updated with
3486 * update_openflow_length() before sending.
3488 * Returns the header. */
3490 put_openflow(size_t openflow_len
, uint8_t type
, struct ofpbuf
*buffer
)
3492 return put_openflow_xid(openflow_len
, type
, alloc_xid(), buffer
);
3495 /* Appends 'openflow_len' bytes to 'buffer', starting with an OpenFlow header
3496 * with the given 'type' and an transaction id 'xid'. Allocated bytes beyond
3497 * the header, if any, are zeroed.
3499 * The OpenFlow header length is initially set to 'openflow_len'; if the
3500 * message is later extended, the length should be updated with
3501 * update_openflow_length() before sending.
3503 * Returns the header. */
3505 put_openflow_xid(size_t openflow_len
, uint8_t type
, ovs_be32 xid
,
3506 struct ofpbuf
*buffer
)
3508 struct ofp_header
*oh
;
3510 assert(openflow_len
>= sizeof *oh
);
3511 assert(openflow_len
<= UINT16_MAX
);
3513 oh
= ofpbuf_put_uninit(buffer
, openflow_len
);
3514 oh
->version
= OFP10_VERSION
;
3516 oh
->length
= htons(openflow_len
);
3518 memset(oh
+ 1, 0, openflow_len
- sizeof *oh
);
3522 /* Similar to put_openflow() but append a Nicira vendor extension message with
3523 * the specific 'subtype'. 'subtype' should be in host byte order. */
3525 put_nxmsg(size_t openflow_len
, uint32_t subtype
, struct ofpbuf
*buffer
)
3527 return put_nxmsg_xid(openflow_len
, subtype
, alloc_xid(), buffer
);
3530 /* Similar to put_openflow_xid() but append a Nicira vendor extension message
3531 * with the specific 'subtype'. 'subtype' should be in host byte order. */
3533 put_nxmsg_xid(size_t openflow_len
, uint32_t subtype
, ovs_be32 xid
,
3534 struct ofpbuf
*buffer
)
3536 struct nicira_header
*nxh
;
3538 nxh
= put_openflow_xid(openflow_len
, OFPT_VENDOR
, xid
, buffer
);
3539 nxh
->vendor
= htonl(NX_VENDOR_ID
);
3540 nxh
->subtype
= htonl(subtype
);
3544 /* Updates the 'length' field of the OpenFlow message in 'buffer' to
3545 * 'buffer->size'. */
3547 update_openflow_length(struct ofpbuf
*buffer
)
3549 struct ofp_header
*oh
= ofpbuf_at_assert(buffer
, 0, sizeof *oh
);
3550 oh
->length
= htons(buffer
->size
);
3554 ofputil_put_stats_header(ovs_be32 xid
, uint8_t ofp_type
,
3555 ovs_be16 ofpst_type
, ovs_be32 nxst_subtype
,
3558 if (ofpst_type
== htons(OFPST_VENDOR
)) {
3559 struct nicira_stats_msg
*nsm
;
3561 nsm
= put_openflow_xid(sizeof *nsm
, ofp_type
, xid
, msg
);
3562 nsm
->vsm
.osm
.type
= ofpst_type
;
3563 nsm
->vsm
.vendor
= htonl(NX_VENDOR_ID
);
3564 nsm
->subtype
= nxst_subtype
;
3566 struct ofp_stats_msg
*osm
;
3568 osm
= put_openflow_xid(sizeof *osm
, ofp_type
, xid
, msg
);
3569 osm
->type
= ofpst_type
;
3573 /* Creates a statistics request message with total length 'openflow_len'
3574 * (including all headers) and the given 'ofpst_type', and stores the buffer
3575 * containing the new message in '*bufferp'. If 'ofpst_type' is OFPST_VENDOR
3576 * then 'nxst_subtype' is used as the Nicira vendor extension statistics
3577 * subtype (otherwise 'nxst_subtype' is ignored).
3579 * Initializes bytes following the headers to all-bits-zero.
3581 * Returns the first byte of the new message. */
3583 ofputil_make_stats_request(size_t openflow_len
, uint16_t ofpst_type
,
3584 uint32_t nxst_subtype
, struct ofpbuf
**bufferp
)
3588 msg
= *bufferp
= ofpbuf_new(openflow_len
);
3589 ofputil_put_stats_header(alloc_xid(), OFPT10_STATS_REQUEST
,
3590 htons(ofpst_type
), htonl(nxst_subtype
), msg
);
3591 ofpbuf_padto(msg
, openflow_len
);
3597 put_stats_reply__(const struct ofp_stats_msg
*request
, struct ofpbuf
*msg
)
3599 ovs_be32 nxst_subtype
;
3601 assert(request
->header
.type
== OFPT10_STATS_REQUEST
||
3602 request
->header
.type
== OFPT10_STATS_REPLY
);
3604 nxst_subtype
= (request
->type
!= htons(OFPST_VENDOR
)
3606 : ((const struct nicira_stats_msg
*) request
)->subtype
);
3607 ofputil_put_stats_header(request
->header
.xid
, OFPT10_STATS_REPLY
,
3608 request
->type
, nxst_subtype
, msg
);
3611 /* Creates a statistics reply message with total length 'openflow_len'
3612 * (including all headers) and the same type (either a standard OpenFlow
3613 * statistics type or a Nicira extension type and subtype) as 'request', and
3614 * stores the buffer containing the new message in '*bufferp'.
3616 * Initializes bytes following the headers to all-bits-zero.
3618 * Returns the first byte of the new message. */
3620 ofputil_make_stats_reply(size_t openflow_len
,
3621 const struct ofp_stats_msg
*request
,
3622 struct ofpbuf
**bufferp
)
3626 msg
= *bufferp
= ofpbuf_new(openflow_len
);
3627 put_stats_reply__(request
, msg
);
3628 ofpbuf_padto(msg
, openflow_len
);
3633 /* Initializes 'replies' as a list of ofpbufs that will contain a series of
3634 * replies to 'request', which should be an OpenFlow or Nicira extension
3635 * statistics request. Initially 'replies' will have a single reply message
3636 * that has only a header. The functions ofputil_reserve_stats_reply() and
3637 * ofputil_append_stats_reply() may be used to add to the reply. */
3639 ofputil_start_stats_reply(const struct ofp_stats_msg
*request
,
3640 struct list
*replies
)
3644 msg
= ofpbuf_new(1024);
3645 put_stats_reply__(request
, msg
);
3648 list_push_back(replies
, &msg
->list_node
);
3651 /* Prepares to append up to 'len' bytes to the series of statistics replies in
3652 * 'replies', which should have been initialized with
3653 * ofputil_start_stats_reply(). Returns an ofpbuf with at least 'len' bytes of
3654 * tailroom. (The 'len' bytes have not actually be allocated; the caller must
3655 * do so with e.g. ofpbuf_put_uninit().) */
3657 ofputil_reserve_stats_reply(size_t len
, struct list
*replies
)
3659 struct ofpbuf
*msg
= ofpbuf_from_list(list_back(replies
));
3660 struct ofp_stats_msg
*osm
= msg
->data
;
3662 if (msg
->size
+ len
<= UINT16_MAX
) {
3663 ofpbuf_prealloc_tailroom(msg
, len
);
3665 osm
->flags
|= htons(OFPSF_REPLY_MORE
);
3667 msg
= ofpbuf_new(MAX(1024, sizeof(struct nicira_stats_msg
) + len
));
3668 put_stats_reply__(osm
, msg
);
3669 list_push_back(replies
, &msg
->list_node
);
3674 /* Appends 'len' bytes to the series of statistics replies in 'replies', and
3675 * returns the first byte. */
3677 ofputil_append_stats_reply(size_t len
, struct list
*replies
)
3679 return ofpbuf_put_uninit(ofputil_reserve_stats_reply(len
, replies
), len
);
3682 /* Sometimes, when composing stats replies, it's difficult to predict how long
3683 * an individual reply chunk will be before actually encoding it into the reply
3684 * buffer. This function allows easy handling of this case: just encode the
3685 * reply, then use this function to break the message into two pieces if it
3686 * exceeds the OpenFlow message limit.
3688 * In detail, if the final stats message in 'replies' is too long for OpenFlow,
3689 * this function breaks it into two separate stats replies, the first one with
3690 * the first 'start_ofs' bytes, the second one containing the bytes from that
3693 ofputil_postappend_stats_reply(size_t start_ofs
, struct list
*replies
)
3695 struct ofpbuf
*msg
= ofpbuf_from_list(list_back(replies
));
3697 assert(start_ofs
<= UINT16_MAX
);
3698 if (msg
->size
> UINT16_MAX
) {
3699 size_t len
= msg
->size
- start_ofs
;
3700 memcpy(ofputil_append_stats_reply(len
, replies
),
3701 (const uint8_t *) msg
->data
+ start_ofs
, len
);
3702 msg
->size
= start_ofs
;
3706 /* Returns the first byte past the ofp_stats_msg header in 'oh'. */
3708 ofputil_stats_body(const struct ofp_header
*oh
)
3710 assert(oh
->type
== OFPT10_STATS_REQUEST
|| oh
->type
== OFPT10_STATS_REPLY
);
3711 return (const struct ofp_stats_msg
*) oh
+ 1;
3714 /* Returns the number of bytes past the ofp_stats_msg header in 'oh'. */
3716 ofputil_stats_body_len(const struct ofp_header
*oh
)
3718 assert(oh
->type
== OFPT10_STATS_REQUEST
|| oh
->type
== OFPT10_STATS_REPLY
);
3719 return ntohs(oh
->length
) - sizeof(struct ofp_stats_msg
);
3722 /* Returns the first byte past the nicira_stats_msg header in 'oh'. */
3724 ofputil_nxstats_body(const struct ofp_header
*oh
)
3726 assert(oh
->type
== OFPT10_STATS_REQUEST
|| oh
->type
== OFPT10_STATS_REPLY
);
3727 return ((const struct nicira_stats_msg
*) oh
) + 1;
3730 /* Returns the number of bytes past the nicira_stats_msg header in 'oh'. */
3732 ofputil_nxstats_body_len(const struct ofp_header
*oh
)
3734 assert(oh
->type
== OFPT10_STATS_REQUEST
|| oh
->type
== OFPT10_STATS_REPLY
);
3735 return ntohs(oh
->length
) - sizeof(struct nicira_stats_msg
);
3738 /* Creates and returns an OFPT_ECHO_REQUEST message with an empty payload. */
3740 make_echo_request(void)
3742 struct ofp_header
*rq
;
3743 struct ofpbuf
*out
= ofpbuf_new(sizeof *rq
);
3744 rq
= ofpbuf_put_uninit(out
, sizeof *rq
);
3745 rq
->version
= OFP10_VERSION
;
3746 rq
->type
= OFPT_ECHO_REQUEST
;
3747 rq
->length
= htons(sizeof *rq
);
3752 /* Creates and returns an OFPT_ECHO_REPLY message matching the
3753 * OFPT_ECHO_REQUEST message in 'rq'. */
3755 make_echo_reply(const struct ofp_header
*rq
)
3757 size_t size
= ntohs(rq
->length
);
3758 struct ofpbuf
*out
= ofpbuf_new(size
);
3759 struct ofp_header
*reply
= ofpbuf_put(out
, rq
, size
);
3760 reply
->type
= OFPT_ECHO_REPLY
;
3765 ofputil_encode_barrier_request(void)
3769 make_openflow(sizeof(struct ofp_header
), OFPT10_BARRIER_REQUEST
, &msg
);
3774 ofputil_frag_handling_to_string(enum ofp_config_flags flags
)
3776 switch (flags
& OFPC_FRAG_MASK
) {
3777 case OFPC_FRAG_NORMAL
: return "normal";
3778 case OFPC_FRAG_DROP
: return "drop";
3779 case OFPC_FRAG_REASM
: return "reassemble";
3780 case OFPC_FRAG_NX_MATCH
: return "nx-match";
3787 ofputil_frag_handling_from_string(const char *s
, enum ofp_config_flags
*flags
)
3789 if (!strcasecmp(s
, "normal")) {
3790 *flags
= OFPC_FRAG_NORMAL
;
3791 } else if (!strcasecmp(s
, "drop")) {
3792 *flags
= OFPC_FRAG_DROP
;
3793 } else if (!strcasecmp(s
, "reassemble")) {
3794 *flags
= OFPC_FRAG_REASM
;
3795 } else if (!strcasecmp(s
, "nx-match")) {
3796 *flags
= OFPC_FRAG_NX_MATCH
;
3803 /* Converts the OpenFlow 1.1+ port number 'ofp11_port' into an OpenFlow 1.0
3804 * port number and stores the latter in '*ofp10_port', for the purpose of
3805 * decoding OpenFlow 1.1+ protocol messages. Returns 0 if successful,
3806 * otherwise an OFPERR_* number.
3808 * See the definition of OFP11_MAX for an explanation of the mapping. */
3810 ofputil_port_from_ofp11(ovs_be32 ofp11_port
, uint16_t *ofp10_port
)
3812 uint32_t ofp11_port_h
= ntohl(ofp11_port
);
3814 if (ofp11_port_h
< OFPP_MAX
) {
3815 *ofp10_port
= ofp11_port_h
;
3817 } else if (ofp11_port_h
>= OFPP11_MAX
) {
3818 *ofp10_port
= ofp11_port_h
- OFPP11_OFFSET
;
3821 VLOG_WARN_RL(&bad_ofmsg_rl
, "port %"PRIu32
" is outside the supported "
3822 "range 0 through %d or 0x%"PRIx32
" through 0x%"PRIx32
,
3823 ofp11_port_h
, OFPP_MAX
- 1,
3824 (uint32_t) OFPP11_MAX
, UINT32_MAX
);
3825 return OFPERR_OFPBAC_BAD_OUT_PORT
;
3829 /* Returns the OpenFlow 1.1+ port number equivalent to the OpenFlow 1.0 port
3830 * number 'ofp10_port', for encoding OpenFlow 1.1+ protocol messages.
3832 * See the definition of OFP11_MAX for an explanation of the mapping. */
3834 ofputil_port_to_ofp11(uint16_t ofp10_port
)
3836 return htonl(ofp10_port
< OFPP_MAX
3838 : ofp10_port
+ OFPP11_OFFSET
);
3841 /* Checks that 'port' is a valid output port for the OFPAT10_OUTPUT action, given
3842 * that the switch will never have more than 'max_ports' ports. Returns 0 if
3843 * 'port' is valid, otherwise an OpenFlow return code. */
3845 ofputil_check_output_port(uint16_t port
, int max_ports
)
3853 case OFPP_CONTROLLER
:
3859 if (port
< max_ports
) {
3862 return OFPERR_OFPBAC_BAD_OUT_PORT
;
3866 #define OFPUTIL_NAMED_PORTS \
3867 OFPUTIL_NAMED_PORT(IN_PORT) \
3868 OFPUTIL_NAMED_PORT(TABLE) \
3869 OFPUTIL_NAMED_PORT(NORMAL) \
3870 OFPUTIL_NAMED_PORT(FLOOD) \
3871 OFPUTIL_NAMED_PORT(ALL) \
3872 OFPUTIL_NAMED_PORT(CONTROLLER) \
3873 OFPUTIL_NAMED_PORT(LOCAL) \
3874 OFPUTIL_NAMED_PORT(NONE)
3876 /* Checks whether 's' is the string representation of an OpenFlow port number,
3877 * either as an integer or a string name (e.g. "LOCAL"). If it is, stores the
3878 * number in '*port' and returns true. Otherwise, returns false. */
3880 ofputil_port_from_string(const char *name
, uint16_t *port
)
3886 static const struct pair pairs
[] = {
3887 #define OFPUTIL_NAMED_PORT(NAME) {#NAME, OFPP_##NAME},
3889 #undef OFPUTIL_NAMED_PORT
3891 static const int n_pairs
= ARRAY_SIZE(pairs
);
3894 if (str_to_int(name
, 0, &i
) && i
>= 0 && i
< UINT16_MAX
) {
3899 for (i
= 0; i
< n_pairs
; i
++) {
3900 if (!strcasecmp(name
, pairs
[i
].name
)) {
3901 *port
= pairs
[i
].value
;
3908 /* Appends to 's' a string representation of the OpenFlow port number 'port'.
3909 * Most ports' string representation is just the port number, but for special
3910 * ports, e.g. OFPP_LOCAL, it is the name, e.g. "LOCAL". */
3912 ofputil_format_port(uint16_t port
, struct ds
*s
)
3917 #define OFPUTIL_NAMED_PORT(NAME) case OFPP_##NAME: name = #NAME; break;
3919 #undef OFPUTIL_NAMED_PORT
3922 ds_put_format(s
, "%"PRIu16
, port
);
3925 ds_put_cstr(s
, name
);
3928 /* Given a buffer 'b' that contains an array of OpenFlow ports of type
3929 * 'ofp_version', tries to pull the first element from the array. If
3930 * successful, initializes '*pp' with an abstract representation of the
3931 * port and returns 0. If no ports remain to be decoded, returns EOF.
3932 * On an error, returns a positive OFPERR_* value. */
3934 ofputil_pull_phy_port(uint8_t ofp_version
, struct ofpbuf
*b
,
3935 struct ofputil_phy_port
*pp
)
3937 if (ofp_version
== OFP10_VERSION
) {
3938 const struct ofp10_phy_port
*opp
= ofpbuf_try_pull(b
, sizeof *opp
);
3939 return opp
? ofputil_decode_ofp10_phy_port(pp
, opp
) : EOF
;
3941 const struct ofp11_port
*op
= ofpbuf_try_pull(b
, sizeof *op
);
3942 return op
? ofputil_decode_ofp11_port(pp
, op
) : EOF
;
3946 /* Given a buffer 'b' that contains an array of OpenFlow ports of type
3947 * 'ofp_version', returns the number of elements. */
3948 size_t ofputil_count_phy_ports(uint8_t ofp_version
, struct ofpbuf
*b
)
3950 return b
->size
/ ofputil_get_phy_port_size(ofp_version
);
3953 /* Returns the 'enum ofputil_action_code' corresponding to 'name' (e.g. if
3954 * 'name' is "output" then the return value is OFPUTIL_OFPAT10_OUTPUT), or -1 if
3955 * 'name' is not the name of any action.
3957 * ofp-util.def lists the mapping from names to action. */
3959 ofputil_action_code_from_name(const char *name
)
3961 static const char *names
[OFPUTIL_N_ACTIONS
] = {
3963 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) NAME,
3964 #define OFPAT11_ACTION(ENUM, STRUCT, NAME) NAME,
3965 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) NAME,
3966 #include "ofp-util.def"
3971 for (p
= names
; p
< &names
[ARRAY_SIZE(names
)]; p
++) {
3972 if (*p
&& !strcasecmp(name
, *p
)) {
3979 /* Appends an action of the type specified by 'code' to 'buf' and returns the
3980 * action. Initializes the parts of 'action' that identify it as having type
3981 * <ENUM> and length 'sizeof *action' and zeros the rest. For actions that
3982 * have variable length, the length used and cleared is that of struct
3985 ofputil_put_action(enum ofputil_action_code code
, struct ofpbuf
*buf
)
3988 case OFPUTIL_ACTION_INVALID
:
3991 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
3992 case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
3993 #define OFPAT11_ACTION OFPAT10_ACTION
3994 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
3995 case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf);
3996 #include "ofp-util.def"
4001 #define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
4003 ofputil_init_##ENUM(struct STRUCT *s) \
4005 memset(s, 0, sizeof *s); \
4006 s->type = htons(ENUM); \
4007 s->len = htons(sizeof *s); \
4011 ofputil_put_##ENUM(struct ofpbuf *buf) \
4013 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
4014 ofputil_init_##ENUM(s); \
4017 #define OFPAT11_ACTION OFPAT10_ACTION
4018 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
4020 ofputil_init_##ENUM(struct STRUCT *s) \
4022 memset(s, 0, sizeof *s); \
4023 s->type = htons(OFPAT10_VENDOR); \
4024 s->len = htons(sizeof *s); \
4025 s->vendor = htonl(NX_VENDOR_ID); \
4026 s->subtype = htons(ENUM); \
4030 ofputil_put_##ENUM(struct ofpbuf *buf) \
4032 struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \
4033 ofputil_init_##ENUM(s); \
4036 #include "ofp-util.def"
4038 /* "Normalizes" the wildcards in 'rule'. That means:
4040 * 1. If the type of level N is known, then only the valid fields for that
4041 * level may be specified. For example, ARP does not have a TOS field,
4042 * so nw_tos must be wildcarded if 'rule' specifies an ARP flow.
4043 * Similarly, IPv4 does not have any IPv6 addresses, so ipv6_src and
4044 * ipv6_dst (and other fields) must be wildcarded if 'rule' specifies an
4047 * 2. If the type of level N is not known (or not understood by Open
4048 * vSwitch), then no fields at all for that level may be specified. For
4049 * example, Open vSwitch does not understand SCTP, an L4 protocol, so the
4050 * L4 fields tp_src and tp_dst must be wildcarded if 'rule' specifies an
4054 ofputil_normalize_rule(struct cls_rule
*rule
)
4057 MAY_NW_ADDR
= 1 << 0, /* nw_src, nw_dst */
4058 MAY_TP_ADDR
= 1 << 1, /* tp_src, tp_dst */
4059 MAY_NW_PROTO
= 1 << 2, /* nw_proto */
4060 MAY_IPVx
= 1 << 3, /* tos, frag, ttl */
4061 MAY_ARP_SHA
= 1 << 4, /* arp_sha */
4062 MAY_ARP_THA
= 1 << 5, /* arp_tha */
4063 MAY_IPV6
= 1 << 6, /* ipv6_src, ipv6_dst, ipv6_label */
4064 MAY_ND_TARGET
= 1 << 7 /* nd_target */
4067 struct flow_wildcards wc
;
4069 /* Figure out what fields may be matched. */
4070 if (rule
->flow
.dl_type
== htons(ETH_TYPE_IP
)) {
4071 may_match
= MAY_NW_PROTO
| MAY_IPVx
| MAY_NW_ADDR
;
4072 if (rule
->flow
.nw_proto
== IPPROTO_TCP
||
4073 rule
->flow
.nw_proto
== IPPROTO_UDP
||
4074 rule
->flow
.nw_proto
== IPPROTO_ICMP
) {
4075 may_match
|= MAY_TP_ADDR
;
4077 } else if (rule
->flow
.dl_type
== htons(ETH_TYPE_IPV6
)) {
4078 may_match
= MAY_NW_PROTO
| MAY_IPVx
| MAY_IPV6
;
4079 if (rule
->flow
.nw_proto
== IPPROTO_TCP
||
4080 rule
->flow
.nw_proto
== IPPROTO_UDP
) {
4081 may_match
|= MAY_TP_ADDR
;
4082 } else if (rule
->flow
.nw_proto
== IPPROTO_ICMPV6
) {
4083 may_match
|= MAY_TP_ADDR
;
4084 if (rule
->flow
.tp_src
== htons(ND_NEIGHBOR_SOLICIT
)) {
4085 may_match
|= MAY_ND_TARGET
| MAY_ARP_SHA
;
4086 } else if (rule
->flow
.tp_src
== htons(ND_NEIGHBOR_ADVERT
)) {
4087 may_match
|= MAY_ND_TARGET
| MAY_ARP_THA
;
4090 } else if (rule
->flow
.dl_type
== htons(ETH_TYPE_ARP
)) {
4091 may_match
= MAY_NW_PROTO
| MAY_NW_ADDR
| MAY_ARP_SHA
| MAY_ARP_THA
;
4096 /* Clear the fields that may not be matched. */
4098 if (!(may_match
& MAY_NW_ADDR
)) {
4099 wc
.nw_src_mask
= wc
.nw_dst_mask
= htonl(0);
4101 if (!(may_match
& MAY_TP_ADDR
)) {
4102 wc
.tp_src_mask
= wc
.tp_dst_mask
= htons(0);
4104 if (!(may_match
& MAY_NW_PROTO
)) {
4105 wc
.wildcards
|= FWW_NW_PROTO
;
4107 if (!(may_match
& MAY_IPVx
)) {
4108 wc
.wildcards
|= FWW_NW_DSCP
;
4109 wc
.wildcards
|= FWW_NW_ECN
;
4110 wc
.wildcards
|= FWW_NW_TTL
;
4112 if (!(may_match
& MAY_ARP_SHA
)) {
4113 wc
.wildcards
|= FWW_ARP_SHA
;
4115 if (!(may_match
& MAY_ARP_THA
)) {
4116 wc
.wildcards
|= FWW_ARP_THA
;
4118 if (!(may_match
& MAY_IPV6
)) {
4119 wc
.ipv6_src_mask
= wc
.ipv6_dst_mask
= in6addr_any
;
4120 wc
.wildcards
|= FWW_IPV6_LABEL
;
4122 if (!(may_match
& MAY_ND_TARGET
)) {
4123 wc
.nd_target_mask
= in6addr_any
;
4126 /* Log any changes. */
4127 if (!flow_wildcards_equal(&wc
, &rule
->wc
)) {
4128 bool log
= !VLOG_DROP_INFO(&bad_ofmsg_rl
);
4129 char *pre
= log
? cls_rule_to_string(rule
) : NULL
;
4132 cls_rule_zero_wildcarded_fields(rule
);
4135 char *post
= cls_rule_to_string(rule
);
4136 VLOG_INFO("normalization changed ofp_match, details:");
4137 VLOG_INFO(" pre: %s", pre
);
4138 VLOG_INFO("post: %s", post
);
4145 /* Parses a key or a key-value pair from '*stringp'.
4147 * On success: Stores the key into '*keyp'. Stores the value, if present, into
4148 * '*valuep', otherwise an empty string. Advances '*stringp' past the end of
4149 * the key-value pair, preparing it for another call. '*keyp' and '*valuep'
4150 * are substrings of '*stringp' created by replacing some of its bytes by null
4151 * terminators. Returns true.
4153 * If '*stringp' is just white space or commas, sets '*keyp' and '*valuep' to
4154 * NULL and returns false. */
4156 ofputil_parse_key_value(char **stringp
, char **keyp
, char **valuep
)
4158 char *pos
, *key
, *value
;
4162 pos
+= strspn(pos
, ", \t\r\n");
4164 *keyp
= *valuep
= NULL
;
4169 key_len
= strcspn(pos
, ":=(, \t\r\n");
4170 if (key
[key_len
] == ':' || key
[key_len
] == '=') {
4171 /* The value can be separated by a colon. */
4174 value
= key
+ key_len
+ 1;
4175 value_len
= strcspn(value
, ", \t\r\n");
4176 pos
= value
+ value_len
+ (value
[value_len
] != '\0');
4177 value
[value_len
] = '\0';
4178 } else if (key
[key_len
] == '(') {
4179 /* The value can be surrounded by balanced parentheses. The outermost
4180 * set of parentheses is removed. */
4184 value
= key
+ key_len
+ 1;
4185 for (value_len
= 0; level
> 0; value_len
++) {
4186 switch (value
[value_len
]) {
4200 value
[value_len
- 1] = '\0';
4201 pos
= value
+ value_len
;
4203 /* There might be no value at all. */
4204 value
= key
+ key_len
; /* Will become the empty string below. */
4205 pos
= key
+ key_len
+ (key
[key_len
] != '\0');
4207 key
[key_len
] = '\0';