--- openflow-2013-01-14.h	2015-07-23 09:54:17.248479366 -0700
+++ openflow-2013-01-07.h	2015-07-23 09:54:17.252479366 -0700
@@ -301,17 +301,25 @@
     OFPPF_PAUSE_ASYM = 1 << 15  /* Asymmetric pause. */
 };
 
-/* Description of a port */
-struct ofp_port {
-    uint32_t port_no;
-    uint8_t pad[4];
-    uint8_t hw_addr[OFP_ETH_ALEN];
-    uint8_t pad2[2];                  /* Align to 64 bits. */
-    char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */
+/* Port description property types.
+ */
+enum ofp_port_desc_prop_type {
+    OFPPDPT_ETHERNET          = 0,      /* Ethernet property. */
+    OFPPDPT_EXPERIMENTER      = 0xFFFF, /* Experimenter property. */
+};
 
-    uint32_t config;        /* Bitmap of OFPPC_* flags. */
-    uint32_t state;         /* Bitmap of OFPPS_* flags. */
+/* Common header for all port description properties. */
+struct ofp_port_desc_prop_header {
+    uint16_t         type;    /* One of OFPPDPT_*. */
+    uint16_t         length;  /* Length in bytes of this property. */
+};
+OFP_ASSERT(sizeof(struct ofp_port_desc_prop_header) == 4);
 
+/* Ethernet port description property. */
+struct ofp_port_desc_prop_ethernet {
+    uint16_t         type;    /* OFPPDPT_ETHERNET. */
+    uint16_t         length;  /* Length in bytes of this property. */
+    uint8_t          pad[4];  /* Align to 64 bits. */
     /* Bitmaps of OFPPF_* that describe features.  All bits zeroed if
      * unsupported or unavailable. */
     uint32_t curr;          /* Current features. */
@@ -322,7 +330,40 @@
     uint32_t curr_speed;    /* Current port bitrate in kbps. */
     uint32_t max_speed;     /* Max port bitrate in kbps */
 };
-OFP_ASSERT(sizeof(struct ofp_port) == 64);
+OFP_ASSERT(sizeof(struct ofp_port_desc_prop_ethernet) == 32);
+
+/* Experimenter port description property. */
+struct ofp_port_desc_prop_experimenter {
+    uint16_t         type;    /* OFPPDPT_EXPERIMENTER. */
+    uint16_t         length;  /* Length in bytes of this property. */
+    uint32_t         experimenter;  /* Experimenter ID which takes the same
+                                       form as in struct
+                                       ofp_experimenter_header. */
+    uint32_t         exp_type;      /* Experimenter defined. */
+    /* Followed by:
+     *   - Exactly (length - 12) bytes containing the experimenter data, then
+     *   - Exactly (length + 7)/8*8 - (length) (between 0 and 7)
+     *     bytes of all-zero bytes */
+    uint32_t         experimenter_data[0];
+};
+OFP_ASSERT(sizeof(struct ofp_port_desc_prop_experimenter) == 12);
+
+/* Description of a port */
+struct ofp_port {
+    uint32_t port_no;
+    uint16_t length;
+    uint8_t pad[2];
+    uint8_t hw_addr[OFP_ETH_ALEN];
+    uint8_t pad2[2];                  /* Align to 64 bits. */
+    char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */
+
+    uint32_t config;        /* Bitmap of OFPPC_* flags. */
+    uint32_t state;         /* Bitmap of OFPPS_* flags. */
+
+    /* Port description property list - 0 or more properties */
+    struct ofp_port_desc_prop_header properties[0];
+};
+OFP_ASSERT(sizeof(struct ofp_port) == 40);
 
 /* Switch features. */
 struct ofp_switch_features {
@@ -357,7 +398,46 @@
     uint8_t pad[7];          /* Align to 64-bits. */
     struct ofp_port desc;
 };
-OFP_ASSERT(sizeof(struct ofp_port_status) == 80);
+OFP_ASSERT(sizeof(struct ofp_port_status) == 56);
+
+/* Port mod property types.
+ */
+enum ofp_port_mod_prop_type {
+    OFPPMPT_ETHERNET          = 0,      /* Ethernet property. */
+    OFPPMPT_EXPERIMENTER      = 0xFFFF, /* Experimenter property. */
+};
+
+/* Common header for all port mod properties. */
+struct ofp_port_mod_prop_header {
+    uint16_t         type;    /* One of OFPPMPT_*. */
+    uint16_t         length;  /* Length in bytes of this property. */
+};
+OFP_ASSERT(sizeof(struct ofp_port_mod_prop_header) == 4);
+
+/* Ethernet port mod property. */
+struct ofp_port_mod_prop_ethernet {
+    uint16_t      type;       /* OFPPMPT_ETHERNET. */
+    uint16_t      length;     /* Length in bytes of this property. */
+    uint32_t      advertise;  /* Bitmap of OFPPF_*.  Zero all bits to prevent
+                                 any action taking place. */
+};
+OFP_ASSERT(sizeof(struct ofp_port_mod_prop_ethernet) == 8);
+
+/* Experimenter port mod property. */
+struct ofp_port_mod_prop_experimenter {
+    uint16_t         type;    /* OFPPMPT_EXPERIMENTER. */
+    uint16_t         length;  /* Length in bytes of this property. */
+    uint32_t         experimenter;  /* Experimenter ID which takes the same
+                                       form as in struct
+                                       ofp_experimenter_header. */
+    uint32_t         exp_type;      /* Experimenter defined. */
+    /* Followed by:
+     *   - Exactly (length - 12) bytes containing the experimenter data, then
+     *   - Exactly (length + 7)/8*8 - (length) (between 0 and 7)
+     *     bytes of all-zero bytes */
+    uint32_t         experimenter_data[0];
+};
+OFP_ASSERT(sizeof(struct ofp_port_mod_prop_experimenter) == 12);
 
 /* Modify behavior of the physical port */
 struct ofp_port_mod {
@@ -373,11 +453,10 @@
     uint32_t config;        /* Bitmap of OFPPC_* flags. */
     uint32_t mask;          /* Bitmap of OFPPC_* flags to be changed. */
 
-    uint32_t advertise;     /* Bitmap of OFPPF_*.  Zero all bits to prevent
-                               any action taking place. */
-    uint8_t pad3[4];        /* Pad to 64 bits. */
+    /* Port mod property list - 0 or more properties */
+    struct ofp_port_mod_prop_header properties[0];
 };
-OFP_ASSERT(sizeof(struct ofp_port_mod) == 40);
+OFP_ASSERT(sizeof(struct ofp_port_mod) == 32);
 
 /* ## -------------------------- ## */
 /* ## OpenFlow Extensible Match. ## */
@@ -1587,6 +1666,9 @@
     OFPPMFC_BAD_CONFIG    = 2,   /* Specified config is invalid. */
     OFPPMFC_BAD_ADVERTISE = 3,   /* Specified advertise is invalid. */
     OFPPMFC_EPERM         = 4,   /* Permissions error. */
+    OFPPMFC_BAD_TYPE      = 5,   /* Unknown property type. */
+    OFPPMFC_BAD_LEN       = 6,   /* Length problem in properties. */
+    OFPPMFC_BAD_ARGUMENT  = 7,   /* Unsupported property value. */
 };
 
 /* ofp_error_msg 'code' values for OFPET_TABLE_MOD_FAILED.  'data' contains
@@ -2008,7 +2090,7 @@
 };
 OFP_ASSERT(sizeof(struct ofp_table_stats) == 24);
 
-/* Body for ofp_multipart_request of type OFPMP_PORT. */
+/* Body for ofp_multipart_request of type OFPMP_PORT_STATS. */
 struct ofp_port_stats_request {
     uint32_t port_no;        /* OFPMP_PORT message must request statistics
                               * either for a single port (specified in
@@ -2018,15 +2100,26 @@
 };
 OFP_ASSERT(sizeof(struct ofp_port_stats_request) == 8);
 
-/* Body of reply to OFPMP_PORT request. If a counter is unsupported, set
- * the field to all ones. */
-struct ofp_port_stats {
-    uint32_t port_no;
-    uint8_t pad[4];          /* Align to 64-bits. */
-    uint64_t rx_packets;     /* Number of received packets. */
-    uint64_t tx_packets;     /* Number of transmitted packets. */
-    uint64_t rx_bytes;       /* Number of received bytes. */
-    uint64_t tx_bytes;       /* Number of transmitted bytes. */
+/* Port stats property types.
+ */
+enum ofp_port_stats_prop_type {
+    OFPPSPT_ETHERNET          = 0,      /* Ethernet property. */
+    OFPPSPT_EXPERIMENTER      = 0xFFFF, /* Experimenter property. */
+};
+
+/* Common header for all port stats properties. */
+struct ofp_port_stats_prop_header {
+    uint16_t         type;    /* One of OFPPSPT_*. */
+    uint16_t         length;  /* Length in bytes of this property. */
+};
+OFP_ASSERT(sizeof(struct ofp_port_stats_prop_header) == 4);
+
+/* Ethernet port stats property. */
+struct ofp_port_stats_prop_ethernet {
+    uint16_t         type;    /* OFPPSPT_ETHERNET. */
+    uint16_t         length;  /* Length in bytes of this property. */
+    uint8_t          pad[4];  /* Align to 64 bits. */
+
     uint64_t rx_dropped;     /* Number of packets dropped by RX. */
     uint64_t tx_dropped;     /* Number of packets dropped by TX. */
     uint64_t rx_errors;      /* Number of receive errors.  This is a super-set
@@ -2041,11 +2134,43 @@
     uint64_t rx_over_err;    /* Number of packets with RX overrun. */
     uint64_t rx_crc_err;     /* Number of CRC errors. */
     uint64_t collisions;     /* Number of collisions. */
+};
+OFP_ASSERT(sizeof(struct ofp_port_stats_prop_ethernet) == 72);
+
+/* Experimenter port stats property. */
+struct ofp_port_stats_prop_experimenter {
+    uint16_t         type;    /* OFPPSPT_EXPERIMENTER. */
+    uint16_t         length;  /* Length in bytes of this property. */
+    uint32_t         experimenter;  /* Experimenter ID which takes the same
+                                       form as in struct
+                                       ofp_experimenter_header. */
+    uint32_t         exp_type;      /* Experimenter defined. */
+    /* Followed by:
+     *   - Exactly (length - 12) bytes containing the experimenter data, then
+     *   - Exactly (length + 7)/8*8 - (length) (between 0 and 7)
+     *     bytes of all-zero bytes */
+    uint32_t         experimenter_data[0];
+};
+OFP_ASSERT(sizeof(struct ofp_port_stats_prop_experimenter) == 12);
+
+/* Body of reply to OFPMP_PORT_STATS request. If a counter is unsupported,
+ * set the field to all ones. */
+struct ofp_port_stats {
+    uint16_t length;         /* Length of this entry. */
+    uint8_t pad[2];          /* Align to 64 bits. */
+    uint32_t port_no;
     uint32_t duration_sec;   /* Time port has been alive in seconds. */
     uint32_t duration_nsec;  /* Time port has been alive in nanoseconds beyond
                                 duration_sec. */
+    uint64_t rx_packets;     /* Number of received packets. */
+    uint64_t tx_packets;     /* Number of transmitted packets. */
+    uint64_t rx_bytes;       /* Number of received bytes. */
+    uint64_t tx_bytes;       /* Number of transmitted bytes. */
+
+    /* Port description property list - 0 or more properties */
+    struct ofp_port_desc_prop_header properties[0];
 };
-OFP_ASSERT(sizeof(struct ofp_port_stats) == 112);
+OFP_ASSERT(sizeof(struct ofp_port_stats) == 48);
 
 /* Body of OFPMP_GROUP request. */
 struct ofp_group_stats_request {
