[ovs-dev] [of1.1 v5 1/5] ofp-msgs: New approach to encoding and decoding OpenFlow headers.
Simon Horman
horms at verge.net.au
Fri Jul 20 06:05:17 UTC 2012
On Thu, Jul 05, 2012 at 11:12:29PM -0700, Ben Pfaff wrote:
> OpenFlow headers are not as uniform as they could be, with size, alignment,
> and numbering changes from one version to another and across varieties
> (e.g. ordinary messages vs. "stats" messages). Until now the Open vSwitch
> internal APIs haven't done a good job of abstracting those differences in
> header formats. This commit changes that; from this commit forward very
> little code actually needs to understand the header format or numbering.
> Instead, it can just encode or decode, or pull or put, the header using
> a more abstract API using the ofpraw_, ofptype_, and other APIs in the
> new ofp-msgs module.
>
> Signed-off-by: Ben Pfaff <blp at nicira.com>
[snip]
> diff --git a/lib/ofp-msgs.h b/lib/ofp-msgs.h
> new file mode 100644
> index 0000000..439a7d6
> --- /dev/null
> +++ b/lib/ofp-msgs.h
> @@ -0,0 +1,413 @@
[snip]
> +/* Raw identifiers for OpenFlow messages.
> + *
> + * Some OpenFlow messages with similar meanings have multiple variants across
> + * OpenFlow versions or vendor extensions. Each variant has a different
> + * OFPRAW_* enumeration constant. More specifically, if two messages have
> + * different types, different numbers, or different arguments, then they must
> + * have different OFPRAW_* values.
> + *
> + * The comments here must follow a stylized form because the "extract-ofp-msgs"
> + * program parses them at build time to generate data tables. The syntax of
> + * each comment is:
> + *
> + * type versions (number): arguments.
> + *
> + * where the syntax of each part is:
> + *
> + * - type: One of OFPT (standard OpenFlow message), OFPST (standard OpenFlow
> + * statistics message), NXT (Nicira extension message), or NXST (Nicira
> + * extension statistics message).
> + *
> + * As new vendors implement extensions it will make sense to expand the
> + * dictionary of possible types.
> + *
> + * - versions: The OpenFlow version or versions in which this message is
> + * supported, e.g. "1.0" or "1.1" or "1.0+".
> + *
> + * - number:
> + * For OFPT, the 'type' in struct ofp_header.
> + * For OFPST, the 'type' in struct ofp_stats_msg or ofp11_stats_msg.
> + * For NXT, the 'subtype' in struct nicira_header.
> + * For NXST, the 'subtype' in struct nicira10_stats_msg or
> + * nicira11_stats_msg.
> + *
> + * - arguments: The types of data that follow the OpenFlow headers (the
> + * message "body"). This can be "void" if the message has no body.
> + * Otherwise, it should be a comma-separated sequence of C types. The
> + * last type in the sequence can end with [] if the body ends in a
> + * variable-length sequence.
> + *
> + * The arguments are used to validate the lengths of messages when a
> + * header is parsed. Any message whose length isn't valid as a length of
> + * the specified types will be rejected with OFPERR_OFPBRC_BAD_LEN.
> + *
> + * A few OpenFlow messages, such as OFPT_PACKET_IN, intentionally end with
> + * only part of a structure, up to some specified member. The syntax "up
> + * to <member>" indicates this, e.g. "struct ofp11_packet_in up to data".
> + */
> +enum ofpraw {
> +/* Standard messages. */
> +
> + /* OFPT 1.0+ (0): uint8_t[]. */
> + OFPRAW_OFPT_HELLO,
> +
> + /* OFPT 1.0+ (1): struct ofp_error_msg, uint8_t[]. */
> + OFPRAW_OFPT_ERROR,
> +
> + /* OFPT 1.0+ (2): uint8_t[]. */
> + OFPRAW_OFPT_ECHO_REQUEST,
> +
> + /* OFPT 1.0+ (3): uint8_t[]. */
> + OFPRAW_OFPT_ECHO_REPLY,
> +
> + /* OFPT 1.0+ (5): void. */
> + OFPRAW_OFPT_FEATURES_REQUEST,
> +
> + /* OFPT 1.0 (6): struct ofp_switch_features, struct ofp10_phy_port[]. */
> + OFPRAW_OFPT10_FEATURES_REPLY,
> + /* OFPT 1.1+ (6): struct ofp_switch_features, struct ofp11_port[]. */
> + OFPRAW_OFPT11_FEATURES_REPLY,
> +
> + /* OFPT 1.0+ (7): void. */
> + OFPRAW_OFPT_GET_CONFIG_REQUEST,
> +
> + /* OFPT 1.0+ (8): struct ofp_switch_config. */
> + OFPRAW_OFPT_GET_CONFIG_REPLY,
> +
> + /* OFPT 1.0-1.1 (9): struct ofp_switch_config. */
> + OFPRAW_OFPT_SET_CONFIG,
> +
> + /* OFPT 1.0 (10): struct ofp_packet_in up to data, uint8_t[]. */
> + OFPRAW_OFPT10_PACKET_IN,
> + /* OFPT 1.1 (11): struct ofp11_packet_in up to data, uint8_t[]. */
> + OFPRAW_OFPT11_PACKET_IN,
I believe that OFPRAW_OFPT11_PACKET_IN's number should be 10.
> + /* NXT 1.0+ (17): struct nx_packet_in, uint8_t[]. */
> + OFPRAW_NXT_PACKET_IN,
> +
> + /* OFPT 1.0 (11): struct ofp_flow_removed. */
> + OFPRAW_OFPT10_FLOW_REMOVED,
> + /* NXT 1.0+ (14): struct nx_flow_removed, uint8_t[8][]. */
> + OFPRAW_NXT_FLOW_REMOVED,
I'm unsure how important the arguments are.
For example, in the case of Flow Removed, OF1.1 has a 40byte
struct ofp11_flow_removed followed by an 88 byte struct ofp11_match.
OF1.2 has a 40 byte struct ofp13_flow_removed, followed by a 4 byte
ofp12_match, followed by uing8_t[], followed by a pad to ensure 8 byte
alignment.
In this case should both be covered by something like this?
OFPRAW_OFPT11_FLOW_REMOVED,
/* OFPT 1.2 (11): struct ofp11_flow_removed, uint8_t[8][]. */
Or are two separate entries needed?
/* OFPT 1.1 (11): struct ofp11_flow_removed, struct ofp11_match[]. */
OFPRAW_OFPT11_FLOW_REMOVED,
/* OFPT 1.2 (11): struct ofp12_flow_removed, uint8_t[8][]. */
OFPRAW_OFPT12_FLOW_REMOVED,
In the case of the latter I see.
./lib/ofp-msgs.h:138: Duplicate message definition for (2, 11, 0, 0, 0).
./lib/ofp-msgs.h:135: Here is the location of the previous definition.
Which seems to be a bit limiting, though I'm unsure if there is a real
use case for separately defining the OF1.1 and OF1.2 types.
[snip]
More information about the dev
mailing list