--- openflow-2013-12-17.h	2015-07-23 09:54:17.752479387 -0700
+++ openflow-2014-04-08.h	2015-07-23 09:54:17.756479387 -0700
@@ -160,6 +160,10 @@
     /* Bundle operations (multiple messages as a single operation). */
     OFPT_BUNDLE_CONTROL     = 33,
     OFPT_BUNDLE_ADD_MESSAGE = 34,
+
+    /* Controller Status async message. */
+    OFPT_CONTROLLER_STATUS  = 35,
+
 };
 
 /* Header on all OpenFlow packets. */
@@ -2043,6 +2047,8 @@
     OFPRRFC_STALE      = 0,      /* Stale Message: old generation_id. */
     OFPRRFC_UNSUP      = 1,      /* Controller role change unsupported. */
     OFPRRFC_BAD_ROLE   = 2,      /* Invalid role. */
+    OFPRRFC_ID_UNSUP   = 3,      /* Switch doesn't support changing ID. */
+    OFPRRFC_ID_IN_USE  = 4,      /* Requested ID is in use. */
 };
 
 /* ofp_error_msg 'code' values for OFPET_METER_MOD_FAILED.  'data' contains
@@ -2257,6 +2263,11 @@
      * The reply body is an array of struct ofp_flow_stats. */
     OFPMP_FLOW_STATS = 17,
 
+    /* Controller status.
+     * The request body is empty.
+     * The reply body is an array of struct ofp_controller_status. */
+    OFPMP_CONTROLLER_STATUS = 18,
+
     /* Experimenter extension.
      * The request and reply bodies begin with
      * struct ofp_experimenter_multipart_header.
@@ -3027,6 +3038,40 @@
 };
 OFP_ASSERT(sizeof(struct ofp_flow_update_paused) == 8);
 
+/* Why is the controller status being reported? */
+enum ofp_controller_status_reason {
+    OFPCSR_REQUEST            = 0,  /* Controller requested status. */
+    OFPCSR_CHANNEL_STATUS     = 1,  /* Oper status of channel changed. */
+    OFPCSR_ROLE               = 2,  /* Controller role changed. */
+    OFPCSR_CONTROLLER_ADDED   = 3,  /* New controller added. */
+    OFPCSR_CONTROLLER_REMOVED = 4,  /* Controller removed from config. */
+    OFPCSR_SHORT_ID           = 5,  /* Controller ID changed. */
+};
+
+/* Body of OFPMP_CONTROLLER_STATUS reply message and body of async
+ * OFPT_CONTROLLER_STATUS message */
+struct ofp_controller_status {
+   uint16_t length;            /* Length of struct, including variable URI. */
+   uint16_t short_id;          /* ID number which identifies the controller. */
+   uint32_t role;              /* Controller's role. One of OFPCR_ROLE_*. */
+   uint8_t reason;             /* One of OFPCSR_* reason codes. */
+   uint8_t channel_status;     /* Status of control channel.
+                                * One of OFPCT_STATUS_*. */
+   char uri[0];                /* Connection URI for controller, null
+                                * terminated. */
+};
+
+struct ofp_controller_status_header {
+    struct ofp_header header;               /* Type OFPT_CONTROLLER_STATUS. */
+    struct ofp_controller_status status;    /* Controller status. */
+};
+
+/* Control channel status. */
+enum ofp_control_channel_status {
+    OFPCT_STATUS_UP     = 0,    /* Control channel is operational. */
+    OFPCT_STATUS_DOWN   = 1,    /* Control channel is not operational. */
+};
+
 /* Body for ofp_multipart_request/reply of type OFPMP_EXPERIMENTER. */
 struct ofp_experimenter_multipart_header {
     uint32_t experimenter;    /* Experimenter ID. */
@@ -3075,6 +3120,11 @@
  *
  *      Slave controllers do not receive OFPT_PACKET_IN or OFPT_FLOW_REMOVED
  *      messages, but they do receive OFPT_PORT_STATUS messages.
+ *
+ * Also configures the ID for the controller.  The default ID is
+ * OFPCID_UNDEFINED, and controllers may set the short_id to change their ID.
+ * Only the OFPCID_UNDEFINED ID may be assigned to more than one controller,
+ * and setting the short_id to a value in use will be rejected.
  */
 
 /* Controller roles. */
@@ -3089,11 +3139,14 @@
 struct ofp_role_request {
     struct ofp_header header;   /* Type OFPT_ROLE_REQUEST/OFPT_ROLE_REPLY. */
     uint32_t role;              /* One of OFPCR_ROLE_*. */
-    uint8_t pad[4];             /* Align to 64 bits. */
+    uint16_t short_id;          /* ID number for the controller. */
+    uint8_t pad[2];             /* Align to 64 bits. */
     uint64_t generation_id;     /* Master Election Generation Id */
 };
 OFP_ASSERT(sizeof(struct ofp_role_request) == 24);
 
+#define OFPCID_UNDEFINED 0
+
 /* Role property types.
  */
 enum ofp_role_prop_type {
@@ -3162,6 +3215,8 @@
     OFPACPT_REQUESTFORWARD_MASTER = 11, /* RequestForward mask for master. */
     OFPACPT_FLOW_STATS_SLAVE     = 12, /* Flow stats mask for slave. */
     OFPACPT_FLOW_STATS_MASTER    = 13, /* Flow stats mask for master. */
+    OFPACPT_CONT_STATUS_SLAVE    = 14, /* Controller status mask for slave. */
+    OFPACPT_CONT_STATUS_MASTER   = 15, /* Controller status mask for master. */
     OFPACPT_EXPERIMENTER_SLAVE   = 0xFFFE, /* Experimenter for slave. */
     OFPACPT_EXPERIMENTER_MASTER  = 0xFFFF, /* Experimenter for master. */
 };
