2 * Copyright (c) 2012, 2013, 2014 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.
19 #include "byte-order.h"
20 #include "dynamic-string.h"
24 #include "openflow/nicira-ext.h"
25 #include "openflow/openflow.h"
26 #include "ovs-thread.h"
29 VLOG_DEFINE_THIS_MODULE(ofp_msgs);
32 #define OFPT10_STATS_REQUEST 16
33 #define OFPT10_STATS_REPLY 17
34 #define OFPT11_STATS_REQUEST 18
35 #define OFPT11_STATS_REPLY 19
36 #define OFPST_VENDOR 0xffff
38 /* A thin abstraction of OpenFlow headers:
40 * - 'version' and 'type' come straight from struct ofp_header, so these are
41 * always present and meaningful.
43 * - 'stat' comes from the 'type' member in statistics messages only. It is
44 * meaningful, therefore, only if 'version' and 'type' taken together
45 * specify a statistics request or reply. Otherwise it is 0.
47 * - 'vendor' is meaningful only for vendor messages, that is, if 'version'
48 * and 'type' specify a vendor message or if 'version' and 'type' specify
49 * a statistics message and 'stat' specifies a vendor statistic type.
52 * - 'subtype' is meaningful only for vendor messages and otherwise 0. It
53 * specifies a vendor-defined subtype. There is no standard format for
54 * these but 32 bits seems like it should be enough. */
56 uint8_t version; /* From ofp_header. */
57 uint8_t type; /* From ofp_header. */
58 uint16_t stat; /* From ofp10_stats_msg or ofp11_stats_msg. */
59 uint32_t vendor; /* From ofp_vendor_header,
60 * ofp10_vendor_stats_msg, or
61 * ofp11_vendor_stats_msg. */
62 uint32_t subtype; /* From nicira_header, nicira10_stats_msg, or
63 * nicira11_stats_msg. */
65 BUILD_ASSERT_DECL(sizeof(struct ofphdrs) == 12);
67 /* A mapping from OpenFlow headers to OFPRAW_*. */
69 struct hmap_node hmap_node; /* In 'raw_instance_map'. */
70 struct ofphdrs hdrs; /* Key. */
71 enum ofpraw raw; /* Value. */
72 unsigned int hdrs_len; /* ofphdrs_len(hdrs). */
75 /* Information about a particular 'enum ofpraw'. */
77 /* All possible instantiations of this OFPRAW_* into OpenFlow headers. */
78 struct raw_instance *instances; /* min_version - max_version + 1 elems. */
82 unsigned int min_body;
83 unsigned int extra_multiple;
88 /* All understood OpenFlow message types, indexed by their 'struct ofphdrs'. */
89 static struct hmap raw_instance_map;
90 #include "ofp-msgs.inc"
92 static ovs_be32 alloc_xid(void);
94 /* ofphdrs functions. */
95 static uint32_t ofphdrs_hash(const struct ofphdrs *);
96 static bool ofphdrs_equal(const struct ofphdrs *a, const struct ofphdrs *b);
97 static enum ofperr ofphdrs_decode(struct ofphdrs *,
98 const struct ofp_header *oh, size_t length);
99 static void ofphdrs_decode_assert(struct ofphdrs *,
100 const struct ofp_header *oh, size_t length);
101 size_t ofphdrs_len(const struct ofphdrs *);
103 static const struct raw_info *raw_info_get(enum ofpraw);
104 static struct raw_instance *raw_instance_get(const struct raw_info *,
107 static enum ofperr ofpraw_from_ofphdrs(enum ofpraw *, const struct ofphdrs *);
109 /* Returns a transaction ID to use for an outgoing OpenFlow message. */
113 static atomic_count next_xid = ATOMIC_COUNT_INIT(1);
115 return htonl(atomic_count_inc(&next_xid));
119 ofphdrs_hash(const struct ofphdrs *hdrs)
121 BUILD_ASSERT_DECL(sizeof *hdrs == 12);
122 return hash_words((const uint32_t *) hdrs, 3, 0);
126 ofphdrs_equal(const struct ofphdrs *a, const struct ofphdrs *b)
128 return !memcmp(a, b, sizeof *a);
132 log_bad_vendor(uint32_t vendor)
134 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
136 VLOG_WARN_RL(&rl, "OpenFlow message has unknown vendor %#"PRIx32, vendor);
140 ofphdrs_decode(struct ofphdrs *hdrs,
141 const struct ofp_header *oh, size_t length)
143 memset(hdrs, 0, sizeof *hdrs);
144 if (length < sizeof *oh) {
145 return OFPERR_OFPBRC_BAD_LEN;
148 /* Get base message version and type (OFPT_*). */
149 hdrs->version = oh->version;
150 hdrs->type = oh->type;
152 if (hdrs->type == OFPT_VENDOR) {
154 const struct ofp_vendor_header *ovh;
156 if (length < sizeof *ovh) {
157 return OFPERR_OFPBRC_BAD_LEN;
160 ovh = (const struct ofp_vendor_header *) oh;
161 hdrs->vendor = ntohl(ovh->vendor);
162 if (hdrs->vendor == NX_VENDOR_ID) {
163 /* Get Nicira message subtype (NXT_*). */
164 const struct nicira_header *nh;
166 if (length < sizeof *nh) {
167 return OFPERR_OFPBRC_BAD_LEN;
169 nh = (const struct nicira_header *) oh;
170 hdrs->subtype = ntohl(nh->subtype);
172 log_bad_vendor(hdrs->vendor);
173 return OFPERR_OFPBRC_BAD_VENDOR;
175 } else if (hdrs->version == OFP10_VERSION
176 && (hdrs->type == OFPT10_STATS_REQUEST ||
177 hdrs->type == OFPT10_STATS_REPLY)) {
178 const struct ofp10_stats_msg *osm;
180 /* Get statistic type (OFPST_*). */
181 if (length < sizeof *osm) {
182 return OFPERR_OFPBRC_BAD_LEN;
184 osm = (const struct ofp10_stats_msg *) oh;
185 hdrs->stat = ntohs(osm->type);
187 if (hdrs->stat == OFPST_VENDOR) {
189 const struct ofp10_vendor_stats_msg *ovsm;
191 if (length < sizeof *ovsm) {
192 return OFPERR_OFPBRC_BAD_LEN;
195 ovsm = (const struct ofp10_vendor_stats_msg *) oh;
196 hdrs->vendor = ntohl(ovsm->vendor);
197 if (hdrs->vendor == NX_VENDOR_ID) {
198 /* Get Nicira statistic type (NXST_*). */
199 const struct nicira10_stats_msg *nsm;
201 if (length < sizeof *nsm) {
202 return OFPERR_OFPBRC_BAD_LEN;
204 nsm = (const struct nicira10_stats_msg *) oh;
205 hdrs->subtype = ntohl(nsm->subtype);
207 log_bad_vendor(hdrs->vendor);
208 return OFPERR_OFPBRC_BAD_VENDOR;
211 } else if (hdrs->version != OFP10_VERSION
212 && (hdrs->type == OFPT11_STATS_REQUEST ||
213 hdrs->type == OFPT11_STATS_REPLY)) {
214 const struct ofp11_stats_msg *osm;
216 /* Get statistic type (OFPST_*). */
217 if (length < sizeof *osm) {
218 return OFPERR_OFPBRC_BAD_LEN;
220 osm = (const struct ofp11_stats_msg *) oh;
221 hdrs->stat = ntohs(osm->type);
223 if (hdrs->stat == OFPST_VENDOR) {
225 const struct ofp11_vendor_stats_msg *ovsm;
227 if (length < sizeof *ovsm) {
228 return OFPERR_OFPBRC_BAD_LEN;
231 ovsm = (const struct ofp11_vendor_stats_msg *) oh;
232 hdrs->vendor = ntohl(ovsm->vendor);
233 if (hdrs->vendor == NX_VENDOR_ID) {
234 /* Get Nicira statistic type (NXST_*). */
235 const struct nicira11_stats_msg *nsm;
237 if (length < sizeof *nsm) {
238 return OFPERR_OFPBRC_BAD_LEN;
240 nsm = (const struct nicira11_stats_msg *) oh;
241 hdrs->subtype = ntohl(nsm->subtype);
243 log_bad_vendor(hdrs->vendor);
244 return OFPERR_OFPBRC_BAD_VENDOR;
253 ofphdrs_decode_assert(struct ofphdrs *hdrs,
254 const struct ofp_header *oh, size_t length)
256 enum ofperr error = ofphdrs_decode(hdrs, oh, length);
261 ofp_is_stat_request(enum ofp_version version, uint8_t type)
265 return type == OFPT10_STATS_REQUEST;
271 return type == OFPT11_STATS_REQUEST;
278 ofp_is_stat_reply(enum ofp_version version, uint8_t type)
282 return type == OFPT10_STATS_REPLY;
288 return type == OFPT11_STATS_REPLY;
295 ofp_is_stat(enum ofp_version version, uint8_t type)
297 return (ofp_is_stat_request(version, type) ||
298 ofp_is_stat_reply(version, type));
302 ofphdrs_is_stat(const struct ofphdrs *hdrs)
304 return ofp_is_stat(hdrs->version, hdrs->type);
308 ofphdrs_len(const struct ofphdrs *hdrs)
310 if (hdrs->type == OFPT_VENDOR) {
311 return sizeof(struct nicira_header);
314 switch ((enum ofp_version) hdrs->version) {
316 if (hdrs->type == OFPT10_STATS_REQUEST ||
317 hdrs->type == OFPT10_STATS_REPLY) {
318 return (hdrs->stat == OFPST_VENDOR
319 ? sizeof(struct nicira10_stats_msg)
320 : sizeof(struct ofp10_stats_msg));
329 if (hdrs->type == OFPT11_STATS_REQUEST ||
330 hdrs->type == OFPT11_STATS_REPLY) {
331 return (hdrs->stat == OFPST_VENDOR
332 ? sizeof(struct nicira11_stats_msg)
333 : sizeof(struct ofp11_stats_msg));
338 return sizeof(struct ofp_header);
341 /* Determines the OFPRAW_* type of the OpenFlow message at 'oh', which has
342 * length 'oh->length'. (The caller must ensure that 'oh->length' bytes of
343 * data are readable at 'oh'.) On success, returns 0 and stores the type into
344 * '*raw'. On failure, returns an OFPERR_* error code and zeros '*raw'.
346 * This function checks that 'oh' is a valid length for its particular type of
347 * message, and returns an error if not. */
349 ofpraw_decode(enum ofpraw *raw, const struct ofp_header *oh)
353 ofpbuf_use_const(&msg, oh, ntohs(oh->length));
354 return ofpraw_pull(raw, &msg);
357 /* Does the same job as ofpraw_decode(), except that it assert-fails if
358 * ofpraw_decode() would have reported an error. Thus, it's able to use the
359 * return value for the OFPRAW_* message type instead of an error code.
361 * (It only makes sense to use this function if you previously called
362 * ofpraw_decode() on the message and thus know that it's OK.) */
364 ofpraw_decode_assert(const struct ofp_header *oh)
369 error = ofpraw_decode(&raw, oh);
374 /* Determines the OFPRAW_* type of the OpenFlow message in 'msg', which starts
375 * at 'ofpbuf_data(msg)' and has length 'ofpbuf_size(msg)' bytes. On success,
376 * returns 0 and stores the type into '*rawp'. On failure, returns an OFPERR_*
377 * error code and zeros '*rawp'.
379 * This function checks that the message has a valid length for its particular
380 * type of message, and returns an error if not.
382 * In addition to setting '*rawp', this function pulls off the OpenFlow header
383 * (including the stats headers, vendor header, and any subtype header) with
384 * ofpbuf_pull(). It also sets 'msg->frame' to the start of the OpenFlow
385 * header and 'msg->l3' just beyond the headers (that is, to the final value of
386 * ofpbuf_data(msg)). */
388 ofpraw_pull(enum ofpraw *rawp, struct ofpbuf *msg)
390 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
392 const struct raw_instance *instance;
393 const struct raw_info *info;
396 unsigned int min_len;
402 /* Set default outputs. */
403 msg->frame = ofpbuf_data(msg);
404 ofpbuf_set_l3(msg, msg->frame);
407 len = ofpbuf_size(msg);
408 error = ofphdrs_decode(&hdrs, ofpbuf_data(msg), len);
413 error = ofpraw_from_ofphdrs(&raw, &hdrs);
418 info = raw_info_get(raw);
419 instance = raw_instance_get(info, hdrs.version);
420 msg->frame = ofpbuf_pull(msg, instance->hdrs_len);
421 ofpbuf_set_l3(msg, ofpbuf_data(msg));
423 min_len = instance->hdrs_len + info->min_body;
424 switch (info->extra_multiple) {
426 if (len != min_len) {
427 VLOG_WARN_RL(&rl, "received %s with incorrect length %u (expected "
428 "length %u)", info->name, len, min_len);
429 return OFPERR_OFPBRC_BAD_LEN;
435 VLOG_WARN_RL(&rl, "received %s with incorrect length %u (expected "
436 "length at least %u bytes)",
437 info->name, len, min_len);
438 return OFPERR_OFPBRC_BAD_LEN;
443 if (len < min_len || (len - min_len) % info->extra_multiple) {
444 VLOG_WARN_RL(&rl, "received %s with incorrect length %u (must be "
445 "exactly %u bytes or longer by an integer multiple "
447 info->name, len, min_len, info->extra_multiple);
448 return OFPERR_OFPBRC_BAD_LEN;
457 /* Does the same job as ofpraw_pull(), except that it assert-fails if
458 * ofpraw_pull() would have reported an error. Thus, it's able to use the
459 * return value for the OFPRAW_* message type instead of an error code.
461 * (It only makes sense to use this function if you previously called
462 * ofpraw_decode() on the message and thus know that it's OK.) */
464 ofpraw_pull_assert(struct ofpbuf *msg)
469 error = ofpraw_pull(&raw, msg);
474 /* Determines the OFPRAW_* type of the OpenFlow message that starts at 'oh' and
475 * has length 'length' bytes. On success, returns 0 and stores the type into
476 * '*rawp'. On failure, returns an OFPERR_* error code and zeros '*rawp'.
478 * Unlike other functions for decoding message types, this one is not picky
479 * about message length. For example, it will successfully decode a message
480 * whose body is shorter than the minimum length for a message of its type.
481 * Thus, this is the correct function to use for decoding the type of a message
482 * that might have been truncated, such as the payload of an OpenFlow error
483 * message (which is allowed to be truncated to 64 bytes). */
485 ofpraw_decode_partial(enum ofpraw *raw,
486 const struct ofp_header *oh, size_t length)
491 error = ofphdrs_decode(&hdrs, oh, length);
493 error = ofpraw_from_ofphdrs(raw, &hdrs);
502 /* Encoding messages using OFPRAW_* values. */
504 static void ofpraw_put__(enum ofpraw, uint8_t version, ovs_be32 xid,
505 size_t extra_tailroom, struct ofpbuf *);
507 /* Allocates and returns a new ofpbuf that contains an OpenFlow header for
508 * 'raw' with OpenFlow version 'version' and a fresh OpenFlow transaction ID.
509 * The ofpbuf has enough tailroom for the minimum body length of 'raw', plus
510 * 'extra_tailroom' additional bytes.
512 * Each 'raw' value is valid only for certain OpenFlow versions. The caller
513 * must specify a valid (raw, version) pair.
515 * In the returned ofpbuf, 'frame' points to the beginning of the
516 * OpenFlow header and 'l3' points just after it, to where the
517 * message's body will start. The caller must actually allocate the
518 * body into the space reserved for it, e.g. with ofpbuf_put_uninit().
520 * The caller owns the returned ofpbuf and must free it when it is no longer
521 * needed, e.g. with ofpbuf_delete(). */
523 ofpraw_alloc(enum ofpraw raw, uint8_t version, size_t extra_tailroom)
525 return ofpraw_alloc_xid(raw, version, alloc_xid(), extra_tailroom);
528 /* Same as ofpraw_alloc() but the caller provides the transaction ID. */
530 ofpraw_alloc_xid(enum ofpraw raw, uint8_t version, ovs_be32 xid,
531 size_t extra_tailroom)
533 struct ofpbuf *buf = ofpbuf_new(0);
534 ofpraw_put__(raw, version, xid, extra_tailroom, buf);
538 /* Same as ofpraw_alloc(), but obtains the OpenFlow version and transaction ID
539 * from 'request->version' and 'request->xid', respectively.
541 * Even though the version comes from 'request->version', the caller must still
542 * know what it is doing, by specifying a valid pairing of 'raw' and
543 * 'request->version', just like ofpraw_alloc(). */
545 ofpraw_alloc_reply(enum ofpraw raw, const struct ofp_header *request,
546 size_t extra_tailroom)
548 return ofpraw_alloc_xid(raw, request->version, request->xid,
552 /* Allocates and returns a new ofpbuf that contains an OpenFlow header that is
553 * a stats reply to the stats request in 'request', using the same OpenFlow
554 * version and transaction ID as 'request'. The ofpbuf has enough tailroom for
555 * the stats reply's minimum body length, plus 'extra_tailroom' additional
558 * 'request' must be a stats request, that is, an OFPRAW_OFPST* or OFPRAW_NXST*
559 * value. Every stats request has a corresponding reply, so the (raw, version)
560 * pairing pitfalls of the other ofpraw_alloc_*() functions don't apply here.
562 * In the returned ofpbuf, 'frame' points to the beginning of the
563 * OpenFlow header and 'l3' points just after it, to where the
564 * message's body will start. The caller must actually allocate the
565 * body into the space reserved for it, e.g. with ofpbuf_put_uninit().
567 * The caller owns the returned ofpbuf and must free it when it is no longer
568 * needed, e.g. with ofpbuf_delete(). */
570 ofpraw_alloc_stats_reply(const struct ofp_header *request,
571 size_t extra_tailroom)
573 enum ofpraw request_raw;
574 enum ofpraw reply_raw;
577 error = ofpraw_decode_partial(&request_raw, request,
578 ntohs(request->length));
581 reply_raw = ofpraw_stats_request_to_reply(request_raw, request->version);
582 ovs_assert(reply_raw);
584 return ofpraw_alloc_reply(reply_raw, request, extra_tailroom);
587 /* Appends to 'buf' an OpenFlow header for 'raw' with OpenFlow version
588 * 'version' and a fresh OpenFlow transaction ID. Preallocates enough tailroom
589 * in 'buf' for the minimum body length of 'raw', plus 'extra_tailroom'
592 * Each 'raw' value is valid only for certain OpenFlow versions. The caller
593 * must specify a valid (raw, version) pair.
595 * Upon return, 'buf->frame' points to the beginning of the OpenFlow header and
596 * 'buf->l3' points just after it, to where the message's body will start. The
597 * caller must actually allocating the body into the space reserved for it,
598 * e.g. with ofpbuf_put_uninit(). */
600 ofpraw_put(enum ofpraw raw, uint8_t version, struct ofpbuf *buf)
602 ofpraw_put__(raw, version, alloc_xid(), 0, buf);
605 /* Same as ofpraw_put() but the caller provides the transaction ID. */
607 ofpraw_put_xid(enum ofpraw raw, uint8_t version, ovs_be32 xid,
610 ofpraw_put__(raw, version, xid, 0, buf);
613 /* Same as ofpraw_put(), but obtains the OpenFlow version and transaction ID
614 * from 'request->version' and 'request->xid', respectively.
616 * Even though the version comes from 'request->version', the caller must still
617 * know what it is doing, by specifying a valid pairing of 'raw' and
618 * 'request->version', just like ofpraw_put(). */
620 ofpraw_put_reply(enum ofpraw raw, const struct ofp_header *request,
623 ofpraw_put__(raw, request->version, request->xid, 0, buf);
626 /* Appends to 'buf' an OpenFlow header that is a stats reply to the stats
627 * request in 'request', using the same OpenFlow version and transaction ID as
628 * 'request'. Preallocate enough tailroom in 'buf for the stats reply's
629 * minimum body length, plus 'extra_tailroom' additional bytes.
631 * 'request' must be a stats request, that is, an OFPRAW_OFPST* or OFPRAW_NXST*
632 * value. Every stats request has a corresponding reply, so the (raw, version)
633 * pairing pitfalls of the other ofpraw_alloc_*() functions don't apply here.
635 * In the returned ofpbuf, 'frame' points to the beginning of the
636 * OpenFlow header and 'l3' points just after it, to where the
637 * message's body will start. The caller must actually allocate the
638 * body into the space reserved for it, e.g. with ofpbuf_put_uninit().
640 * The caller owns the returned ofpbuf and must free it when it is no longer
641 * needed, e.g. with ofpbuf_delete(). */
643 ofpraw_put_stats_reply(const struct ofp_header *request, struct ofpbuf *buf)
648 error = ofpraw_decode_partial(&raw, request, ntohs(request->length));
651 raw = ofpraw_stats_request_to_reply(raw, request->version);
654 ofpraw_put__(raw, request->version, request->xid, 0, buf);
658 ofpraw_put__(enum ofpraw raw, uint8_t version, ovs_be32 xid,
659 size_t extra_tailroom, struct ofpbuf *buf)
661 const struct raw_info *info = raw_info_get(raw);
662 const struct raw_instance *instance = raw_instance_get(info, version);
663 const struct ofphdrs *hdrs = &instance->hdrs;
664 struct ofp_header *oh;
666 ofpbuf_prealloc_tailroom(buf, (instance->hdrs_len + info->min_body
668 buf->frame = ofpbuf_put_uninit(buf, instance->hdrs_len);
669 ofpbuf_set_l3(buf, ofpbuf_tail(buf));
672 oh->version = version;
673 oh->type = hdrs->type;
674 oh->length = htons(ofpbuf_size(buf));
677 if (hdrs->type == OFPT_VENDOR) {
678 struct nicira_header *nh = buf->frame;
680 ovs_assert(hdrs->vendor == NX_VENDOR_ID);
681 nh->vendor = htonl(hdrs->vendor);
682 nh->subtype = htonl(hdrs->subtype);
683 } else if (version == OFP10_VERSION
684 && (hdrs->type == OFPT10_STATS_REQUEST ||
685 hdrs->type == OFPT10_STATS_REPLY)) {
686 struct ofp10_stats_msg *osm = buf->frame;
688 osm->type = htons(hdrs->stat);
689 osm->flags = htons(0);
691 if (hdrs->stat == OFPST_VENDOR) {
692 struct ofp10_vendor_stats_msg *ovsm = buf->frame;
694 ovsm->vendor = htonl(hdrs->vendor);
695 if (hdrs->vendor == NX_VENDOR_ID) {
696 struct nicira10_stats_msg *nsm = buf->frame;
698 nsm->subtype = htonl(hdrs->subtype);
699 memset(nsm->pad, 0, sizeof nsm->pad);
704 } else if (version != OFP10_VERSION
705 && (hdrs->type == OFPT11_STATS_REQUEST ||
706 hdrs->type == OFPT11_STATS_REPLY)) {
707 struct ofp11_stats_msg *osm = buf->frame;
709 osm->type = htons(hdrs->stat);
710 osm->flags = htons(0);
711 memset(osm->pad, 0, sizeof osm->pad);
713 if (hdrs->stat == OFPST_VENDOR) {
714 struct ofp11_vendor_stats_msg *ovsm = buf->frame;
716 ovsm->vendor = htonl(hdrs->vendor);
717 if (hdrs->vendor == NX_VENDOR_ID) {
718 struct nicira11_stats_msg *nsm = buf->frame;
720 nsm->subtype = htonl(hdrs->subtype);
728 /* Returns 'raw''s name.
730 * The name is the name used for 'raw' in the OpenFlow specification. For
731 * example, ofpraw_get_name(OFPRAW_OFPT10_FEATURES_REPLY) is
732 * "OFPT_FEATURES_REPLY".
734 * The caller must not modify or free the returned string. */
736 ofpraw_get_name(enum ofpraw raw)
738 return raw_info_get(raw)->name;
741 /* Returns the stats reply that corresponds to 'raw' in the given OpenFlow
744 ofpraw_stats_request_to_reply(enum ofpraw raw, uint8_t version)
746 const struct raw_info *info = raw_info_get(raw);
747 const struct raw_instance *instance = raw_instance_get(info, version);
748 enum ofpraw reply_raw;
752 hdrs = instance->hdrs;
753 switch ((enum ofp_version)hdrs.version) {
755 ovs_assert(hdrs.type == OFPT10_STATS_REQUEST);
756 hdrs.type = OFPT10_STATS_REPLY;
763 ovs_assert(hdrs.type == OFPT11_STATS_REQUEST);
764 hdrs.type = OFPT11_STATS_REPLY;
770 error = ofpraw_from_ofphdrs(&reply_raw, &hdrs);
776 /* Determines the OFPTYPE_* type of the OpenFlow message at 'oh', which has
777 * length 'oh->length'. (The caller must ensure that 'oh->length' bytes of
778 * data are readable at 'oh'.) On success, returns 0 and stores the type into
779 * '*typep'. On failure, returns an OFPERR_* error code and zeros '*typep'.
781 * This function checks that 'oh' is a valid length for its particular type of
782 * message, and returns an error if not. */
784 ofptype_decode(enum ofptype *typep, const struct ofp_header *oh)
789 error = ofpraw_decode(&raw, oh);
790 *typep = error ? 0 : ofptype_from_ofpraw(raw);
794 /* Determines the OFPTYPE_* type of the OpenFlow message in 'msg', which starts
795 * at 'ofpbuf_data(msg)' and has length 'ofpbuf_size(msg)' bytes. On success,
796 * returns 0 and stores the type into '*typep'. On failure, returns an
797 * OFPERR_* error code and zeros '*typep'.
799 * This function checks that the message has a valid length for its particular
800 * type of message, and returns an error if not.
802 * In addition to setting '*typep', this function pulls off the OpenFlow header
803 * (including the stats headers, vendor header, and any subtype header) with
804 * ofpbuf_pull(). It also sets 'msg->frame' to the start of the OpenFlow
805 * header and 'msg->l3' just beyond the headers (that is, to the final value of
806 * ofpbuf_data(msg)). */
808 ofptype_pull(enum ofptype *typep, struct ofpbuf *buf)
813 error = ofpraw_pull(&raw, buf);
814 *typep = error ? 0 : ofptype_from_ofpraw(raw);
818 /* Returns the OFPTYPE_* type that corresponds to 'raw'.
820 * (This is a one-way trip, because the mapping from ofpraw to ofptype is
823 ofptype_from_ofpraw(enum ofpraw raw)
825 return raw_info_get(raw)->type;
828 /* Updates the 'length' field of the OpenFlow message in 'buf' to
829 * 'ofpbuf_size(buf)'. */
831 ofpmsg_update_length(struct ofpbuf *buf)
833 struct ofp_header *oh = ofpbuf_at_assert(buf, 0, sizeof *oh);
834 oh->length = htons(ofpbuf_size(buf));
837 /* Returns just past the OpenFlow header (including the stats headers, vendor
838 * header, and any subtype header) in 'oh'. */
840 ofpmsg_body(const struct ofp_header *oh)
844 ofphdrs_decode_assert(&hdrs, oh, ntohs(oh->length));
845 return (const uint8_t *) oh + ofphdrs_len(&hdrs);
848 /* Return if it's a stat/multipart (OFPST) request message. */
850 ofpmsg_is_stat_request(const struct ofp_header *oh)
852 return ofp_is_stat_request(oh->version, oh->type);
855 static ovs_be16 *ofpmp_flags__(const struct ofp_header *);
857 /* Initializes 'replies' as a new list of stats messages that reply to
858 * 'request', which must be a stats request message. Initially the list will
859 * consist of only a single reply part without any body. The caller should
860 * use calls to the other ofpmp_*() functions to add to the body and split the
861 * message into multiple parts, if necessary. */
863 ofpmp_init(struct list *replies, const struct ofp_header *request)
869 msg = ofpraw_alloc_stats_reply(request, 1000);
870 list_push_back(replies, &msg->list_node);
873 /* Prepares to append up to 'len' bytes to the series of statistics replies in
874 * 'replies', which should have been initialized with ofpmp_init(), if
875 * necessary adding a new reply to the list.
877 * Returns an ofpbuf with at least 'len' bytes of tailroom. The 'len' bytes
878 * have not actually been allocated, so the caller must do so with
879 * e.g. ofpbuf_put_uninit(). */
881 ofpmp_reserve(struct list *replies, size_t len)
883 struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
885 if (ofpbuf_size(msg) + len <= UINT16_MAX) {
886 ofpbuf_prealloc_tailroom(msg, len);
889 unsigned int hdrs_len;
893 ofphdrs_decode_assert(&hdrs, ofpbuf_data(msg), ofpbuf_size(msg));
894 hdrs_len = ofphdrs_len(&hdrs);
896 next = ofpbuf_new(MAX(1024, hdrs_len + len));
897 ofpbuf_put(next, ofpbuf_data(msg), hdrs_len);
898 next->frame = ofpbuf_data(next);
899 ofpbuf_set_l3(next, ofpbuf_tail(next));
900 list_push_back(replies, &next->list_node);
902 *ofpmp_flags__(ofpbuf_data(msg)) |= htons(OFPSF_REPLY_MORE);
908 /* Appends 'len' bytes to the series of statistics replies in 'replies', and
909 * returns the first byte. */
911 ofpmp_append(struct list *replies, size_t len)
913 return ofpbuf_put_uninit(ofpmp_reserve(replies, len), len);
916 /* Sometimes, when composing stats replies, it's difficult to predict how long
917 * an individual reply chunk will be before actually encoding it into the reply
918 * buffer. This function allows easy handling of this case: just encode the
919 * reply, then use this function to break the message into two pieces if it
920 * exceeds the OpenFlow message limit.
922 * In detail, if the final stats message in 'replies' is too long for OpenFlow,
923 * this function breaks it into two separate stats replies, the first one with
924 * the first 'start_ofs' bytes, the second one containing the bytes from that
927 ofpmp_postappend(struct list *replies, size_t start_ofs)
929 struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
931 ovs_assert(start_ofs <= UINT16_MAX);
932 if (ofpbuf_size(msg) > UINT16_MAX) {
933 size_t len = ofpbuf_size(msg) - start_ofs;
934 memcpy(ofpmp_append(replies, len),
935 (const uint8_t *) ofpbuf_data(msg) + start_ofs, len);
936 ofpbuf_set_size(msg, start_ofs);
940 /* Returns the OpenFlow version of the replies being constructed in 'replies',
941 * which should have been initialized by ofpmp_init(). */
943 ofpmp_version(struct list *replies)
945 struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
946 const struct ofp_header *oh = ofpbuf_data(msg);
951 /* Determines the OFPRAW_* type of the OpenFlow messages in 'replies', which
952 * should have been initialized by ofpmp_init(). */
954 ofpmp_decode_raw(struct list *replies)
956 struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
960 error = ofpraw_decode_partial(&raw, ofpbuf_data(msg), ofpbuf_size(msg));
966 ofpmp_flags__(const struct ofp_header *oh)
968 switch ((enum ofp_version)oh->version) {
970 return &((struct ofp10_stats_msg *) oh)->flags;
976 return &((struct ofp11_stats_msg *) oh)->flags;
982 /* Returns the OFPSF_* flags found in the OpenFlow stats header of 'oh', which
983 * must be an OpenFlow stats request or reply.
985 * (OFPSF_REPLY_MORE is the only defined flag.) */
987 ofpmp_flags(const struct ofp_header *oh)
989 return ntohs(*ofpmp_flags__(oh));
992 /* Returns true if the OFPSF_REPLY_MORE flag is set in the OpenFlow stats
993 * header of 'oh', which must be an OpenFlow stats request or reply, false if
996 ofpmp_more(const struct ofp_header *oh)
998 return (ofpmp_flags(oh) & OFPSF_REPLY_MORE) != 0;
1001 static void ofpmsgs_init(void);
1003 static const struct raw_info *
1004 raw_info_get(enum ofpraw raw)
1008 ovs_assert(raw < ARRAY_SIZE(raw_infos));
1009 return &raw_infos[raw];
1012 static struct raw_instance *
1013 raw_instance_get(const struct raw_info *info, uint8_t version)
1015 ovs_assert(version >= info->min_version && version <= info->max_version);
1016 return &info->instances[version - info->min_version];
1020 ofpraw_from_ofphdrs(enum ofpraw *raw, const struct ofphdrs *hdrs)
1022 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
1024 struct raw_instance *raw_hdrs;
1029 hash = ofphdrs_hash(hdrs);
1030 HMAP_FOR_EACH_WITH_HASH (raw_hdrs, hmap_node, hash, &raw_instance_map) {
1031 if (ofphdrs_equal(hdrs, &raw_hdrs->hdrs)) {
1032 *raw = raw_hdrs->raw;
1037 if (!VLOG_DROP_WARN(&rl)) {
1041 ds_put_format(&s, "version %"PRIu8", type %"PRIu8,
1042 hdrs->version, hdrs->type);
1043 if (ofphdrs_is_stat(hdrs)) {
1044 ds_put_format(&s, ", stat %"PRIu16, hdrs->stat);
1047 ds_put_format(&s, ", vendor 0x%"PRIx32", subtype %"PRIu32,
1048 hdrs->vendor, hdrs->subtype);
1050 VLOG_WARN("unknown OpenFlow message (%s)", ds_cstr(&s));
1054 return (hdrs->vendor ? OFPERR_OFPBRC_BAD_SUBTYPE
1055 : ofphdrs_is_stat(hdrs) ? OFPERR_OFPBRC_BAD_STAT
1056 : OFPERR_OFPBRC_BAD_TYPE);
1062 static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
1063 const struct raw_info *info;
1065 if (!ovsthread_once_start(&once)) {
1069 hmap_init(&raw_instance_map);
1070 for (info = raw_infos; info < &raw_infos[ARRAY_SIZE(raw_infos)]; info++)
1072 int n_instances = info->max_version - info->min_version + 1;
1073 struct raw_instance *inst;
1075 for (inst = info->instances;
1076 inst < &info->instances[n_instances];
1078 inst->hdrs_len = ofphdrs_len(&inst->hdrs);
1079 hmap_insert(&raw_instance_map, &inst->hmap_node,
1080 ofphdrs_hash(&inst->hdrs));
1084 ovsthread_once_done(&once);