-
-/* Returns a transaction ID to use for an outgoing OpenFlow message. */
-static ovs_be32
-alloc_xid(void)
-{
- static uint32_t next_xid = 1;
- return htonl(next_xid++);
-}
-\f
-/* Basic parsing of OpenFlow messages. */
-
-struct ofputil_msg_type {
- enum ofputil_msg_code code; /* OFPUTIL_*. */
- uint8_t ofp_version; /* An OpenFlow version or 0 for "any". */
- uint32_t value; /* OFPT_*, OFPST_*, NXT_*, or NXST_*. */
- const char *name; /* e.g. "OFPT_FLOW_REMOVED". */
- unsigned int min_size; /* Minimum total message size in bytes. */
- /* 0 if 'min_size' is the exact size that the message must be. Otherwise,
- * the message may exceed 'min_size' by an even multiple of this value. */
- unsigned int extra_multiple;
-};
-
-/* Represents a malformed OpenFlow message. */
-static const struct ofputil_msg_type ofputil_invalid_type = {
- OFPUTIL_MSG_INVALID, 0, 0, "OFPUTIL_MSG_INVALID", 0, 0
-};
-
-struct ofputil_msg_category {
- const char *name; /* e.g. "OpenFlow message" */
- const struct ofputil_msg_type *types;
- size_t n_types;
- enum ofperr missing_error; /* Error value for missing type. */
-};
-
-static enum ofperr
-ofputil_check_length(const struct ofputil_msg_type *type, unsigned int size)
-{
- switch (type->extra_multiple) {
- case 0:
- if (size != type->min_size) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "received %s with incorrect "
- "length %u (expected length %u)",
- type->name, size, type->min_size);
- return OFPERR_OFPBRC_BAD_LEN;
- }
- return 0;
-
- case 1:
- if (size < type->min_size) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "received %s with incorrect "
- "length %u (expected length at least %u bytes)",
- type->name, size, type->min_size);
- return OFPERR_OFPBRC_BAD_LEN;
- }
- return 0;
-
- default:
- if (size < type->min_size
- || (size - type->min_size) % type->extra_multiple) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "received %s with incorrect "
- "length %u (must be exactly %u bytes or longer "
- "by an integer multiple of %u bytes)",
- type->name, size,
- type->min_size, type->extra_multiple);
- return OFPERR_OFPBRC_BAD_LEN;
- }
- return 0;
- }
-}
-
-static enum ofperr
-ofputil_lookup_openflow_message(const struct ofputil_msg_category *cat,
- uint8_t version, uint32_t value,
- const struct ofputil_msg_type **typep)
-{
- const struct ofputil_msg_type *type;
-
- for (type = cat->types; type < &cat->types[cat->n_types]; type++) {
- if (type->value == value
- && (!type->ofp_version || version == type->ofp_version)) {
- *typep = type;
- return 0;
- }
- }
-
- VLOG_WARN_RL(&bad_ofmsg_rl, "received %s of unknown type %"PRIu32,
- cat->name, value);
- return cat->missing_error;
-}
-
-static enum ofperr
-ofputil_decode_vendor(const struct ofp_header *oh, size_t length,
- const struct ofputil_msg_type **typep)
-{
- static const struct ofputil_msg_type nxt_messages[] = {
- { OFPUTIL_NXT_ROLE_REQUEST, OFP10_VERSION,
- NXT_ROLE_REQUEST, "NXT_ROLE_REQUEST",
- sizeof(struct nx_role_request), 0 },
-
- { OFPUTIL_NXT_ROLE_REPLY, OFP10_VERSION,
- NXT_ROLE_REPLY, "NXT_ROLE_REPLY",
- sizeof(struct nx_role_request), 0 },
-
- { OFPUTIL_NXT_SET_FLOW_FORMAT, OFP10_VERSION,
- NXT_SET_FLOW_FORMAT, "NXT_SET_FLOW_FORMAT",
- sizeof(struct nx_set_flow_format), 0 },
-
- { OFPUTIL_NXT_SET_PACKET_IN_FORMAT, OFP10_VERSION,
- NXT_SET_PACKET_IN_FORMAT, "NXT_SET_PACKET_IN_FORMAT",
- sizeof(struct nx_set_packet_in_format), 0 },
-
- { OFPUTIL_NXT_PACKET_IN, OFP10_VERSION,
- NXT_PACKET_IN, "NXT_PACKET_IN",
- sizeof(struct nx_packet_in), 1 },
-
- { OFPUTIL_NXT_FLOW_MOD, OFP10_VERSION,
- NXT_FLOW_MOD, "NXT_FLOW_MOD",
- sizeof(struct nx_flow_mod), 8 },
-
- { OFPUTIL_NXT_FLOW_REMOVED, OFP10_VERSION,
- NXT_FLOW_REMOVED, "NXT_FLOW_REMOVED",
- sizeof(struct nx_flow_removed), 8 },
-
- { OFPUTIL_NXT_FLOW_MOD_TABLE_ID, OFP10_VERSION,
- NXT_FLOW_MOD_TABLE_ID, "NXT_FLOW_MOD_TABLE_ID",
- sizeof(struct nx_flow_mod_table_id), 0 },
-
- { OFPUTIL_NXT_FLOW_AGE, OFP10_VERSION,
- NXT_FLOW_AGE, "NXT_FLOW_AGE",
- sizeof(struct nicira_header), 0 },
-
- { OFPUTIL_NXT_SET_ASYNC_CONFIG, OFP10_VERSION,
- NXT_SET_ASYNC_CONFIG, "NXT_SET_ASYNC_CONFIG",
- sizeof(struct nx_async_config), 0 },
-
- { OFPUTIL_NXT_SET_CONTROLLER_ID, OFP10_VERSION,
- NXT_SET_CONTROLLER_ID, "NXT_SET_CONTROLLER_ID",
- sizeof(struct nx_controller_id), 0 },
- };
-
- static const struct ofputil_msg_category nxt_category = {
- "Nicira extension message",
- nxt_messages, ARRAY_SIZE(nxt_messages),
- OFPERR_OFPBRC_BAD_SUBTYPE
- };
-
- const struct ofp_vendor_header *ovh;
- const struct nicira_header *nh;
-
- if (length < sizeof(struct ofp_vendor_header)) {
- if (length == ntohs(oh->length)) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "truncated vendor message");
- }
- return OFPERR_OFPBRC_BAD_LEN;
- }
-
- ovh = (const struct ofp_vendor_header *) oh;
- if (ovh->vendor != htonl(NX_VENDOR_ID)) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "received vendor message for unknown "
- "vendor %"PRIx32, ntohl(ovh->vendor));
- return OFPERR_OFPBRC_BAD_VENDOR;
- }
-
- if (length < sizeof(struct nicira_header)) {
- if (length == ntohs(oh->length)) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "received Nicira vendor message of "
- "length %u (expected at least %zu)",
- ntohs(ovh->header.length),
- sizeof(struct nicira_header));
- }
- return OFPERR_OFPBRC_BAD_LEN;
- }
-
- nh = (const struct nicira_header *) oh;
- return ofputil_lookup_openflow_message(&nxt_category, oh->version,
- ntohl(nh->subtype), typep);
-}
-
-static enum ofperr
-check_nxstats_msg(const struct ofp_header *oh, size_t length)
-{
- const struct ofp_stats_msg *osm = (const struct ofp_stats_msg *) oh;
- ovs_be32 vendor;
-
- if (length < sizeof(struct ofp_vendor_stats_msg)) {
- if (length == ntohs(oh->length)) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "truncated vendor stats message");
- }
- return OFPERR_OFPBRC_BAD_LEN;
- }
-
- memcpy(&vendor, osm + 1, sizeof vendor);
- if (vendor != htonl(NX_VENDOR_ID)) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "received vendor stats message for "
- "unknown vendor %"PRIx32, ntohl(vendor));
- return OFPERR_OFPBRC_BAD_VENDOR;
- }
-
- if (length < sizeof(struct nicira_stats_msg)) {
- if (length == ntohs(osm->header.length)) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "truncated Nicira stats message");
- }
- return OFPERR_OFPBRC_BAD_LEN;
- }
-
- return 0;
-}
-
-static enum ofperr
-ofputil_decode_nxst_request(const struct ofp_header *oh, size_t length,
- const struct ofputil_msg_type **typep)
-{
- static const struct ofputil_msg_type nxst_requests[] = {
- { OFPUTIL_NXST_FLOW_REQUEST, OFP10_VERSION,
- NXST_FLOW, "NXST_FLOW request",
- sizeof(struct nx_flow_stats_request), 8 },
-
- { OFPUTIL_NXST_AGGREGATE_REQUEST, OFP10_VERSION,
- NXST_AGGREGATE, "NXST_AGGREGATE request",
- sizeof(struct nx_aggregate_stats_request), 8 },
- };
-
- static const struct ofputil_msg_category nxst_request_category = {
- "Nicira extension statistics request",
- nxst_requests, ARRAY_SIZE(nxst_requests),
- OFPERR_OFPBRC_BAD_SUBTYPE
- };
-
- const struct nicira_stats_msg *nsm;
- enum ofperr error;
-
- error = check_nxstats_msg(oh, length);
- if (error) {
- return error;
- }
-
- nsm = (struct nicira_stats_msg *) oh;
- return ofputil_lookup_openflow_message(&nxst_request_category, oh->version,
- ntohl(nsm->subtype), typep);
-}
-
-static enum ofperr
-ofputil_decode_nxst_reply(const struct ofp_header *oh, size_t length,
- const struct ofputil_msg_type **typep)
-{
- static const struct ofputil_msg_type nxst_replies[] = {
- { OFPUTIL_NXST_FLOW_REPLY, OFP10_VERSION,
- NXST_FLOW, "NXST_FLOW reply",
- sizeof(struct nicira_stats_msg), 8 },
-
- { OFPUTIL_NXST_AGGREGATE_REPLY, OFP10_VERSION,
- NXST_AGGREGATE, "NXST_AGGREGATE reply",
- sizeof(struct nx_aggregate_stats_reply), 0 },
- };
-
- static const struct ofputil_msg_category nxst_reply_category = {
- "Nicira extension statistics reply",
- nxst_replies, ARRAY_SIZE(nxst_replies),
- OFPERR_OFPBRC_BAD_SUBTYPE
- };
-
- const struct nicira_stats_msg *nsm;
- enum ofperr error;
-
- error = check_nxstats_msg(oh, length);
- if (error) {
- return error;
- }
-
- nsm = (struct nicira_stats_msg *) oh;
- return ofputil_lookup_openflow_message(&nxst_reply_category, oh->version,
- ntohl(nsm->subtype), typep);
-}
-
-static enum ofperr
-check_stats_msg(const struct ofp_header *oh, size_t length)
-{
- if (length < sizeof(struct ofp_stats_msg)) {
- if (length == ntohs(oh->length)) {
- VLOG_WARN_RL(&bad_ofmsg_rl, "truncated stats message");
- }
- return OFPERR_OFPBRC_BAD_LEN;
- }
-
- return 0;
-}
-
-static enum ofperr
-ofputil_decode_ofpst_request(const struct ofp_header *oh, size_t length,
- const struct ofputil_msg_type **typep)
-{
- static const struct ofputil_msg_type ofpst_requests[] = {
- { OFPUTIL_OFPST_DESC_REQUEST, OFP10_VERSION,
- OFPST_DESC, "OFPST_DESC request",
- sizeof(struct ofp_stats_msg), 0 },
-
- { OFPUTIL_OFPST_FLOW_REQUEST, OFP10_VERSION,
- OFPST_FLOW, "OFPST_FLOW request",
- sizeof(struct ofp_flow_stats_request), 0 },
-
- { OFPUTIL_OFPST_AGGREGATE_REQUEST, OFP10_VERSION,
- OFPST_AGGREGATE, "OFPST_AGGREGATE request",
- sizeof(struct ofp_flow_stats_request), 0 },
-
- { OFPUTIL_OFPST_TABLE_REQUEST, OFP10_VERSION,
- OFPST_TABLE, "OFPST_TABLE request",
- sizeof(struct ofp_stats_msg), 0 },
-
- { OFPUTIL_OFPST_PORT_REQUEST, OFP10_VERSION,
- OFPST_PORT, "OFPST_PORT request",
- sizeof(struct ofp_port_stats_request), 0 },
-
- { OFPUTIL_OFPST_QUEUE_REQUEST, OFP10_VERSION,
- OFPST_QUEUE, "OFPST_QUEUE request",
- sizeof(struct ofp_queue_stats_request), 0 },
-
- { OFPUTIL_OFPST_PORT_DESC_REQUEST, OFP10_VERSION,
- OFPST_PORT_DESC, "OFPST_PORT_DESC request",
- sizeof(struct ofp_stats_msg), 0 },
-
- { 0, 0,
- OFPST_VENDOR, "OFPST_VENDOR request",
- sizeof(struct ofp_vendor_stats_msg), 1 },
- };
-
- static const struct ofputil_msg_category ofpst_request_category = {
- "OpenFlow statistics",
- ofpst_requests, ARRAY_SIZE(ofpst_requests),
- OFPERR_OFPBRC_BAD_STAT
- };
-
- const struct ofp_stats_msg *request = (const struct ofp_stats_msg *) oh;
- enum ofperr error;
-
- error = check_stats_msg(oh, length);
- if (error) {
- return error;
- }
-
- error = ofputil_lookup_openflow_message(&ofpst_request_category,
- oh->version, ntohs(request->type),
- typep);
- if (!error && request->type == htons(OFPST_VENDOR)) {
- error = ofputil_decode_nxst_request(oh, length, typep);
- }
- return error;
-}
-
-static enum ofperr
-ofputil_decode_ofpst_reply(const struct ofp_header *oh, size_t length,
- const struct ofputil_msg_type **typep)
-{
- static const struct ofputil_msg_type ofpst_replies[] = {
- { OFPUTIL_OFPST_DESC_REPLY, OFP10_VERSION,
- OFPST_DESC, "OFPST_DESC reply",
- sizeof(struct ofp_desc_stats), 0 },
-
- { OFPUTIL_OFPST_FLOW_REPLY, OFP10_VERSION,
- OFPST_FLOW, "OFPST_FLOW reply",
- sizeof(struct ofp_stats_msg), 1 },
-
- { OFPUTIL_OFPST_AGGREGATE_REPLY, OFP10_VERSION,
- OFPST_AGGREGATE, "OFPST_AGGREGATE reply",
- sizeof(struct ofp_aggregate_stats_reply), 0 },
-
- { OFPUTIL_OFPST_TABLE_REPLY, OFP10_VERSION,
- OFPST_TABLE, "OFPST_TABLE reply",
- sizeof(struct ofp_stats_msg), sizeof(struct ofp_table_stats) },
-
- { OFPUTIL_OFPST_PORT_REPLY, OFP10_VERSION,
- OFPST_PORT, "OFPST_PORT reply",
- sizeof(struct ofp_stats_msg), sizeof(struct ofp_port_stats) },
-
- { OFPUTIL_OFPST_QUEUE_REPLY, OFP10_VERSION,
- OFPST_QUEUE, "OFPST_QUEUE reply",
- sizeof(struct ofp_stats_msg), sizeof(struct ofp_queue_stats) },
-
- { OFPUTIL_OFPST_PORT_DESC_REPLY, OFP10_VERSION,
- OFPST_PORT_DESC, "OFPST_PORT_DESC reply",
- sizeof(struct ofp_stats_msg), sizeof(struct ofp10_phy_port) },
-
- { 0, 0,
- OFPST_VENDOR, "OFPST_VENDOR reply",
- sizeof(struct ofp_vendor_stats_msg), 1 },
- };
-
- static const struct ofputil_msg_category ofpst_reply_category = {
- "OpenFlow statistics",
- ofpst_replies, ARRAY_SIZE(ofpst_replies),
- OFPERR_OFPBRC_BAD_STAT
- };
-
- const struct ofp_stats_msg *reply = (const struct ofp_stats_msg *) oh;
- enum ofperr error;
-
- error = check_stats_msg(oh, length);
- if (error) {
- return error;
- }
-
- error = ofputil_lookup_openflow_message(&ofpst_reply_category, oh->version,
- ntohs(reply->type), typep);
- if (!error && reply->type == htons(OFPST_VENDOR)) {
- error = ofputil_decode_nxst_reply(oh, length, typep);
- }
- return error;
-}
-
-static enum ofperr
-ofputil_decode_msg_type__(const struct ofp_header *oh, size_t length,
- const struct ofputil_msg_type **typep)
-{
- static const struct ofputil_msg_type ofpt_messages[] = {
- { OFPUTIL_OFPT_HELLO, OFP10_VERSION,
- OFPT_HELLO, "OFPT_HELLO",
- sizeof(struct ofp_hello), 1 },
-
- { OFPUTIL_OFPT_ERROR, 0,
- OFPT_ERROR, "OFPT_ERROR",
- sizeof(struct ofp_error_msg), 1 },
-
- { OFPUTIL_OFPT_ECHO_REQUEST, OFP10_VERSION,
- OFPT_ECHO_REQUEST, "OFPT_ECHO_REQUEST",
- sizeof(struct ofp_header), 1 },
-
- { OFPUTIL_OFPT_ECHO_REPLY, OFP10_VERSION,
- OFPT_ECHO_REPLY, "OFPT_ECHO_REPLY",
- sizeof(struct ofp_header), 1 },
-
- { OFPUTIL_OFPT_FEATURES_REQUEST, OFP10_VERSION,
- OFPT_FEATURES_REQUEST, "OFPT_FEATURES_REQUEST",
- sizeof(struct ofp_header), 0 },
-
- { OFPUTIL_OFPT_FEATURES_REPLY, OFP10_VERSION,
- OFPT_FEATURES_REPLY, "OFPT_FEATURES_REPLY",
- sizeof(struct ofp_switch_features), sizeof(struct ofp10_phy_port) },
- { OFPUTIL_OFPT_FEATURES_REPLY, OFP11_VERSION,
- OFPT_FEATURES_REPLY, "OFPT_FEATURES_REPLY",
- sizeof(struct ofp_switch_features), sizeof(struct ofp11_port) },
-
- { OFPUTIL_OFPT_GET_CONFIG_REQUEST, OFP10_VERSION,
- OFPT_GET_CONFIG_REQUEST, "OFPT_GET_CONFIG_REQUEST",
- sizeof(struct ofp_header), 0 },
-
- { OFPUTIL_OFPT_GET_CONFIG_REPLY, OFP10_VERSION,
- OFPT_GET_CONFIG_REPLY, "OFPT_GET_CONFIG_REPLY",
- sizeof(struct ofp_switch_config), 0 },
-
- { OFPUTIL_OFPT_SET_CONFIG, OFP10_VERSION,
- OFPT_SET_CONFIG, "OFPT_SET_CONFIG",
- sizeof(struct ofp_switch_config), 0 },
-
- { OFPUTIL_OFPT_PACKET_IN, OFP10_VERSION,
- OFPT_PACKET_IN, "OFPT_PACKET_IN",
- offsetof(struct ofp_packet_in, data), 1 },
-
- { OFPUTIL_OFPT_FLOW_REMOVED, OFP10_VERSION,
- OFPT_FLOW_REMOVED, "OFPT_FLOW_REMOVED",
- sizeof(struct ofp_flow_removed), 0 },
-
- { OFPUTIL_OFPT_PORT_STATUS, OFP10_VERSION,
- OFPT_PORT_STATUS, "OFPT_PORT_STATUS",
- sizeof(struct ofp_port_status) + sizeof(struct ofp10_phy_port), 0 },
- { OFPUTIL_OFPT_PORT_STATUS, OFP11_VERSION,
- OFPT_PORT_STATUS, "OFPT_PORT_STATUS",
- sizeof(struct ofp_port_status) + sizeof(struct ofp11_port), 0 },
-
- { OFPUTIL_OFPT_PACKET_OUT, OFP10_VERSION,
- OFPT10_PACKET_OUT, "OFPT_PACKET_OUT",
- sizeof(struct ofp_packet_out), 1 },
-
- { OFPUTIL_OFPT_FLOW_MOD, OFP10_VERSION,
- OFPT10_FLOW_MOD, "OFPT_FLOW_MOD",
- sizeof(struct ofp_flow_mod), 1 },
-
- { OFPUTIL_OFPT_PORT_MOD, OFP10_VERSION,
- OFPT10_PORT_MOD, "OFPT_PORT_MOD",
- sizeof(struct ofp10_port_mod), 0 },
- { OFPUTIL_OFPT_PORT_MOD, OFP11_VERSION,
- OFPT11_PORT_MOD, "OFPT_PORT_MOD",
- sizeof(struct ofp11_port_mod), 0 },
-
- { 0, OFP10_VERSION,
- OFPT10_STATS_REQUEST, "OFPT_STATS_REQUEST",
- sizeof(struct ofp_stats_msg), 1 },
-
- { 0, OFP10_VERSION,
- OFPT10_STATS_REPLY, "OFPT_STATS_REPLY",
- sizeof(struct ofp_stats_msg), 1 },
-
- { OFPUTIL_OFPT_BARRIER_REQUEST, OFP10_VERSION,
- OFPT10_BARRIER_REQUEST, "OFPT_BARRIER_REQUEST",
- sizeof(struct ofp_header), 0 },
-
- { OFPUTIL_OFPT_BARRIER_REPLY, OFP10_VERSION,
- OFPT10_BARRIER_REPLY, "OFPT_BARRIER_REPLY",
- sizeof(struct ofp_header), 0 },
-
- { 0, 0,
- OFPT_VENDOR, "OFPT_VENDOR",
- sizeof(struct ofp_vendor_header), 1 },
- };
-
- static const struct ofputil_msg_category ofpt_category = {
- "OpenFlow message",
- ofpt_messages, ARRAY_SIZE(ofpt_messages),
- OFPERR_OFPBRC_BAD_TYPE
- };
-
- enum ofperr error;
-
- error = ofputil_lookup_openflow_message(&ofpt_category, oh->version,
- oh->type, typep);
- if (!error) {
- switch ((oh->version << 8) | oh->type) {
- case (OFP10_VERSION << 8) | OFPT_VENDOR:
- case (OFP11_VERSION << 8) | OFPT_VENDOR:
- error = ofputil_decode_vendor(oh, length, typep);
- break;
-
- case (OFP10_VERSION << 8) | OFPT10_STATS_REQUEST:
- case (OFP11_VERSION << 8) | OFPT11_STATS_REQUEST:
- error = ofputil_decode_ofpst_request(oh, length, typep);
- break;
-
- case (OFP10_VERSION << 8) | OFPT10_STATS_REPLY:
- case (OFP11_VERSION << 8) | OFPT11_STATS_REPLY:
- error = ofputil_decode_ofpst_reply(oh, length, typep);
-
- default:
- break;
- }
- }
- return error;
-}
-
-/* Decodes the message type represented by 'oh'. Returns 0 if successful or an
- * OpenFlow error code on failure. Either way, stores in '*typep' a type
- * structure that can be inspected with the ofputil_msg_type_*() functions.
- *
- * oh->length must indicate the correct length of the message (and must be at
- * least sizeof(struct ofp_header)).
- *
- * Success indicates that 'oh' is at least as long as the minimum-length
- * message of its type. */
-enum ofperr
-ofputil_decode_msg_type(const struct ofp_header *oh,
- const struct ofputil_msg_type **typep)
-{
- size_t length = ntohs(oh->length);
- enum ofperr error;
-
- error = ofputil_decode_msg_type__(oh, length, typep);
- if (!error) {
- error = ofputil_check_length(*typep, length);
- }
- if (error) {
- *typep = &ofputil_invalid_type;
- }
- return error;
-}
-
-/* Decodes the message type represented by 'oh', of which only the first
- * 'length' bytes are available. Returns 0 if successful or an OpenFlow error
- * code on failure. Either way, stores in '*typep' a type structure that can
- * be inspected with the ofputil_msg_type_*() functions. */
-enum ofperr
-ofputil_decode_msg_type_partial(const struct ofp_header *oh, size_t length,
- const struct ofputil_msg_type **typep)
-{
- enum ofperr error;
-
- error = (length >= sizeof *oh
- ? ofputil_decode_msg_type__(oh, length, typep)
- : OFPERR_OFPBRC_BAD_LEN);
- if (error) {
- *typep = &ofputil_invalid_type;
- }
- return error;
-}
-
-/* Returns an OFPUTIL_* message type code for 'type'. */
-enum ofputil_msg_code
-ofputil_msg_type_code(const struct ofputil_msg_type *type)
-{
- return type->code;
-}