/* 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.
#include "svec.h"
#include "vconn.h"
#include "vconn-ssl.h"
+#include "xenserver.h"
#include "xtoxll.h"
#define THIS_MODULE VLM_mgmt
struct ofmp_resources_update *ofmpru;
struct ofmp_tlv *tlv;
struct svec br_list;
+ const char *host_uuid;
int i;
if (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]);
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. */