Assert on structure sizes in openflow.h.
authorBen Pfaff <blp@nicira.com>
Thu, 17 Jul 2008 05:51:35 +0000 (22:51 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 17 Jul 2008 16:47:25 +0000 (09:47 -0700)
This causes the build to fail if structures are not the sizes that we
expect.

include/openflow.h

index 5e3e8c52100668cd0cfb400602a23f0fc940a734..3525e166bf832377ba3c86a2210ad737a4c78bdc 100644 (file)
 #include <stdint.h>
 #endif
 
+#ifndef __cplusplus
+/* Build-time assertion for use in a declaration context. */
+#define OFP_ASSERT(EXPR)                                                \
+        extern int (*build_assert(void))[ sizeof(struct {               \
+                    unsigned int build_assert_failed : (EXPR) ? 1 : -1; })]
+#else /* __cplusplus */
+#include <boost/static_assert.hpp>
+#define OFP_ASSERT BOOST_STATIC_ASSERT
+#endif /* __cplusplus */
+
 /* Maximum length of a OpenFlow packet. */
 #define OFP_MAXLEN (sizeof(struct ofp_switch_features) \
         + (sizeof(struct ofp_phy_port) * OFPP_MAX) + 200)
@@ -108,6 +118,7 @@ struct ofp_header {
                            Replies use the same id as was in the request
                            to facilitate pairing. */
 };
+OFP_ASSERT(sizeof(struct ofp_header) == 8);
 
 #define OFP_DEFAULT_MISS_SEND_LEN   128
 
@@ -123,6 +134,7 @@ struct ofp_switch_config {
     uint16_t miss_send_len;     /* Max bytes of new flow that datapath should
                                    send to the controller. */
 };
+OFP_ASSERT(sizeof(struct ofp_switch_config) == 12);
 
 /* Capabilities supported by the datapath. */
 enum ofp_capabilities {
@@ -160,6 +172,7 @@ struct ofp_phy_port {
     uint32_t speed;         /* Current speed in Mbps */
     uint32_t features;      /* Bitmap of supported "ofp_port_features"s. */
 };
+OFP_ASSERT(sizeof(struct ofp_phy_port) == 36);
 
 /* Switch features. */
 struct ofp_switch_features {
@@ -186,6 +199,7 @@ struct ofp_switch_features {
                                       is inferred from the length field in
                                       the header. */
 };
+OFP_ASSERT(sizeof(struct ofp_switch_features) == 48);
 
 /* What changed about the phsyical port */
 enum ofp_port_reason {
@@ -201,12 +215,14 @@ struct ofp_port_status {
     uint8_t pad[3];          /* Align to 32-bits */
     struct ofp_phy_port desc;
 };
+OFP_ASSERT(sizeof(struct ofp_port_status) == 48);
 
 /* Modify behavior of the physical port */
 struct ofp_port_mod {
     struct ofp_header header;
     struct ofp_phy_port desc;
 };
+OFP_ASSERT(sizeof(struct ofp_port_mod) == 44);
 
 /* Why is this packet being sent to the controller? */
 enum ofp_reason {
@@ -229,6 +245,7 @@ struct ofp_packet_in {
                                offsetof(struct ofp_packet_in, data) ==
                                sizeof(struct ofp_packet_in) - 2. */
 };
+OFP_ASSERT(sizeof(struct ofp_packet_in) == 20);
 
 enum ofp_action_type {
     OFPAT_OUTPUT,           /* Output to switch port. */
@@ -248,6 +265,7 @@ struct ofp_action_output {
     uint16_t max_len;
     uint16_t port;
 };
+OFP_ASSERT(sizeof(struct ofp_action_output) == 4);
 
 /* The VLAN id is 12-bits, so we'll use the entire 16 bits to indicate
  * special conditions.  All ones is used to indicate that no VLAN id was
@@ -266,6 +284,7 @@ struct ofp_action {
         uint16_t tp;                     /* OFPAT_SET_TP_SRC/DST */
     } arg;
 };
+OFP_ASSERT(sizeof(struct ofp_action) == 8);
 
 /* Send packet (controller -> datapath). */
 struct ofp_packet_out {
@@ -278,6 +297,7 @@ struct ofp_packet_out {
         uint8_t data[0];              /* buffer_id == -1 */
     } u;
 };
+OFP_ASSERT(sizeof(struct ofp_packet_out) == 16);
 
 enum ofp_flow_mod_command {
     OFPFC_ADD,              /* New flow. */
@@ -326,6 +346,7 @@ struct ofp_match {
     uint16_t tp_src;           /* TCP/UDP source port. */
     uint16_t tp_dst;           /* TCP/UDP destination port. */
 };
+OFP_ASSERT(sizeof(struct ofp_match) == 36);
 
 /* Value used in "max_idle" to indicate that the entry is permanent */
 #define OFP_FLOW_PERMANENT 0
@@ -348,6 +369,7 @@ struct ofp_flow_mod {
     struct ofp_action actions[0]; /* The number of actions is inferred from
                                     the length field in the header. */
 };
+OFP_ASSERT(sizeof(struct ofp_flow_mod) == 60);
 
 /* Flow expiration (datapath -> controller). */
 struct ofp_flow_expired {
@@ -362,6 +384,7 @@ struct ofp_flow_expired {
     uint64_t packet_count;    
     uint64_t byte_count;
 };
+OFP_ASSERT(sizeof(struct ofp_flow_expired) == 72);
 
 /* Error message (datapath -> controller). */
 struct ofp_error_msg {
@@ -372,6 +395,7 @@ struct ofp_error_msg {
     uint8_t data[0];          /* Variable-length data.  Interpreted based 
                                  on the type and code. */
 };
+OFP_ASSERT(sizeof(struct ofp_error_msg) == 12);
 
 enum ofp_stats_types {
     /* Individual flow statistics.
@@ -401,6 +425,7 @@ struct ofp_stats_request {
     uint16_t flags;             /* OFPSF_REQ_* flags (none yet defined). */
     uint8_t body[0];            /* Body of the request. */
 };
+OFP_ASSERT(sizeof(struct ofp_stats_request) == 12);
 
 enum ofp_stats_reply_flags {
     OFPSF_REPLY_MORE  = 1 << 0, /* More replies to follow */
@@ -412,6 +437,7 @@ struct ofp_stats_reply {
     uint16_t flags;             /* OFPSF_REPLY_* flags. */
     uint8_t body[0];            /* Body of the reply. */
 };
+OFP_ASSERT(sizeof(struct ofp_stats_reply) == 12);
 
 /* Body for ofp_stats_request of type OFPST_FLOW. */
 struct ofp_flow_stats_request {
@@ -420,6 +446,7 @@ struct ofp_flow_stats_request {
                                  or 0xff for all tables. */
     uint8_t pad[3];           /* Align to 32 bits. */
 };
+OFP_ASSERT(sizeof(struct ofp_flow_stats_request) == 40);
 
 /* Body of reply to OFPST_FLOW request. */
 struct ofp_flow_stats {
@@ -435,6 +462,7 @@ struct ofp_flow_stats {
     uint64_t byte_count;      /* Number of bytes in flow. */
     struct ofp_action actions[0]; /* Actions. */
 };
+OFP_ASSERT(sizeof(struct ofp_flow_stats) == 64);
 
 /* Body for ofp_stats_request of type OFPST_AGGREGATE. */
 struct ofp_aggregate_stats_request {
@@ -443,13 +471,16 @@ struct ofp_aggregate_stats_request {
                                  or 0xff for all tables. */
     uint8_t pad[3];           /* Align to 32 bits. */
 };
+OFP_ASSERT(sizeof(struct ofp_aggregate_stats_request) == 40);
 
 /* Body of reply to OFPST_AGGREGATE request. */
 struct ofp_aggregate_stats_reply {
     uint64_t packet_count;    /* Number of packets in flows. */
     uint64_t byte_count;      /* Number of bytes in flows. */
     uint32_t flow_count;      /* Number of flows. */
+    uint8_t pad[4];           /* Align to 64 bits. */
 };
+OFP_ASSERT(sizeof(struct ofp_aggregate_stats_reply) == 24);
 
 /* Body of reply to OFPST_TABLE request. */
 struct ofp_table_stats {
@@ -461,6 +492,7 @@ struct ofp_table_stats {
     uint8_t pad2[4];         /* Align to 64 bits. */
     uint64_t matched_count;  /* Number of packets that hit table */
 };
+OFP_ASSERT(sizeof(struct ofp_table_stats) == 56);
 
 /* Statistics about a particular port */
 struct ofp_port_stats {
@@ -470,5 +502,6 @@ struct ofp_port_stats {
     uint64_t tx_count;       /* Number of transmitted packets */
     uint64_t drop_count;     /* Number of packets dropped by interface */
 };
+OFP_ASSERT(sizeof(struct ofp_port_stats) == 32);
 
 #endif /* openflow.h */