vswitch: Send Xen UUIDs associated with system and networks
authorJustin Pettit <jpettit@nicira.com>
Fri, 5 Jun 2009 19:13:37 +0000 (12:13 -0700)
committerJustin Pettit <jpettit@nicira.com>
Fri, 5 Jun 2009 19:13:37 +0000 (12:13 -0700)
This commit sends information about Xen UUIDs to the controller through
the management connection.  Specifically, it sends the XenServer UUID
and a list of network UUIDs associated with each datapath.

include/openflow/openflow-mgmt.h
vswitchd/mgmt.c

index 1b4f1a0c9535835a1575c436d56f4593229d4faf..a94e224413e71c3151c1132522c8ad02003b3ef1 100644 (file)
@@ -84,17 +84,45 @@ OFP_ASSERT(sizeof(struct ofmp_capability_reply) == 32);
 /* Resource TLV for datapath description. */
 struct ofmptsr_dp {
     uint16_t type;                        /* OFMPTSR_DP. */
-    uint16_t len;                         /* 28. */
+    uint16_t len;                         /* 32. */
     uint8_t pad[4];
     uint64_t dp_id;                       /* Datapath ID. */
     uint8_t name[OFP_MAX_PORT_NAME_LEN];  /* Null-terminated name. */
 };
 OFP_ASSERT(sizeof(struct ofmptsr_dp) == 32);
 
+/* UUIDs will be passed around as *non-terminated* strings in their
+ * canonical form (e.g., 550e8400-e29b-41d4-a716-446655440000).
+ */
+#define OFMP_UUID_LEN 36
+
+/* Resource TLV for UUIDs associated with this datapath. */
+struct ofmptsr_dp_uuid {
+    uint16_t type;                        /* OFMPTSR_DP_UUID. */
+    uint16_t len;                         /* Length. */
+    uint8_t pad[4];
+    uint64_t dp_id;                       /* Datapath ID. */
+    uint8_t uuid_list[0];                 /* List of UUID associated with 
+                                           * this datapath. */
+};
+OFP_ASSERT(sizeof(struct ofmptsr_dp_uuid) == 16);
+
+/* Resource TLV for UUID associated with this managment instance. */
+struct ofmptsr_mgmt_uuid {
+    uint16_t type;                        /* OFMPTSR_MGMT_UUID. */
+    uint16_t len;                         /* 52. */
+    uint8_t pad[4];
+    uint64_t mgmt_id;                     /* Management ID. */
+    uint8_t uuid[OFMP_UUID_LEN];          /* Null-terminated name. */
+};
+OFP_ASSERT(sizeof(struct ofmptsr_mgmt_uuid) == 52);
+
 /* TLV types for switch resource descriptions. */
 enum ofmp_switch_resources {
     OFMPTSR_END = 0,                      /* Terminator. */
     OFMPTSR_DP,                           /* Datapath. */
+    OFMPTSR_DP_UUID,                      /* Xen: datapath uuid's. */
+    OFMPTSR_MGMT_UUID,                    /* Xen: management uuid. */
 };
 
 /* Body of resources request.
index f5dcd184027ccb37174d27d68c79f7aaa84b87f5..b31d141e6ddc73961d5c7adb9d6b3e2c46218ee7 100644 (file)
@@ -47,6 +47,7 @@
 #include "svec.h"
 #include "vconn.h"
 #include "vconn-ssl.h"
+#include "xenserver.h"
 #include "xtoxll.h"
 
 #define THIS_MODULE VLM_mgmt
@@ -305,6 +306,7 @@ send_resources_update(uint32_t xid, bool use_xid)
     struct ofmp_resources_update *ofmpru;
     struct ofmp_tlv *tlv;
     struct svec br_list;
+    const char *host_uuid;
     int i;
 
     if (use_xid) {
@@ -314,11 +316,28 @@ send_resources_update(uint32_t xid, bool use_xid)
         ofmpru = make_ofmp(sizeof *ofmpru, OFMPT_RESOURCES_UPDATE, &buffer);
     }
 
+    /* On XenServer systems, each host has its own UUID, which we provide
+     * to the controller. 
+     */ 
+    host_uuid = xenserver_get_host_uuid();
+    if (host_uuid) {
+        struct ofmptsr_mgmt_uuid *mgmt_uuid_tlv;
+
+        mgmt_uuid_tlv = ofpbuf_put_zeros(buffer, sizeof(*mgmt_uuid_tlv));
+        mgmt_uuid_tlv->type = htons(OFMPTSR_MGMT_UUID);
+        mgmt_uuid_tlv->len = htons(sizeof(*mgmt_uuid_tlv));
+        mgmt_uuid_tlv->mgmt_id = htonll(mgmt_id);
+        memcpy(mgmt_uuid_tlv->uuid, host_uuid, OFMP_UUID_LEN);
+    }
+
     svec_init(&br_list);
     cfg_get_subsections(&br_list, "bridge");
     for (i=0; i < br_list.n; i++) {
         struct ofmptsr_dp *dp_tlv;
-        uint64_t dp_id = bridge_get_datapathid(br_list.names[i]);
+        uint64_t dp_id;
+        int n_uuid;
+
+        dp_id = bridge_get_datapathid(br_list.names[i]);
         if (!dp_id) {
             VLOG_WARN_RL(&rl, "bridge %s doesn't seem to exist", 
                     br_list.names[i]);
@@ -330,6 +349,36 @@ send_resources_update(uint32_t xid, bool use_xid)
 
         dp_tlv->dp_id = htonll(dp_id);
         memcpy(dp_tlv->name, br_list.names[i], strlen(br_list.names[i])+1);
+
+        /* On XenServer systems, each network has one or more UUIDs
+         * associated with it, which we provide to the controller. 
+         */
+        n_uuid = cfg_count("bridge.%s.xs-network-uuids", br_list.names[i]);
+        if (n_uuid) {
+            struct ofmptsr_dp_uuid *dp_uuid_tlv;
+            size_t tlv_len = sizeof(*dp_uuid_tlv) + n_uuid * OFMP_UUID_LEN;
+            int j;
+
+            dp_uuid_tlv = ofpbuf_put_zeros(buffer, sizeof(*dp_uuid_tlv));
+            dp_uuid_tlv->type = htons(OFMPTSR_DP_UUID);
+            dp_uuid_tlv->len = htons(tlv_len);
+            dp_uuid_tlv->dp_id = htonll(dp_id);
+
+            for (j=0; j<n_uuid; j++) {
+                const char *dp_uuid = cfg_get_string(j, 
+                        "bridge.%s.xs-network-uuids", br_list.names[i]);
+
+                /* The UUID list could change underneath us, so just
+                 * fill with zeros in that case.  Another update will be
+                 * initiated shortly, which should contain corrected data.
+                 */
+                if (dp_uuid) {
+                    ofpbuf_put(buffer, dp_uuid, OFMP_UUID_LEN);
+                } else {
+                    ofpbuf_put_zeros(buffer, OFMP_UUID_LEN);
+                }
+            }
+        }
     }
 
     /* Put end marker. */