*/
#define OFMP_UUID_LEN 36
-/* Resource TLV for UUIDs associated with this datapath. */
+/* Resource TLV for XenServer UUIDs associated with this datapath. */
struct ofmptsr_dp_uuid {
uint16_t type; /* OFMPTSR_DP_UUID. */
uint16_t len; /* Length. */
};
OFP_ASSERT(sizeof(struct ofmptsr_dp_uuid) == 16);
-/* Resource TLV for UUID associated with this managment instance. */
+/* Resource TLV for XenServer UUID associated with this managment
+ * instance.
+ */
struct ofmptsr_mgmt_uuid {
uint16_t type; /* OFMPTSR_MGMT_UUID. */
uint16_t len; /* 52. */
};
OFP_ASSERT(sizeof(struct ofmptsr_mgmt_uuid) == 56);
+/* Resource TLV for details about this XenServer vif. */
+struct ofmptsr_vif {
+ uint16_t type; /* OFMPTSR_VIF. */
+ uint16_t len; /* 136. */
+ uint8_t name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated name. */
+ uint8_t vif_uuid[OFMP_UUID_LEN]; /* VIF UUID. */
+ uint8_t vm_uuid[OFMP_UUID_LEN]; /* VM UUID. */
+ uint8_t net_uuid[OFMP_UUID_LEN]; /* Network UUID. */
+ uint64_t vif_mac; /* Management ID. */
+};
+OFP_ASSERT(sizeof(struct ofmptsr_vif) == 136);
+
/* 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. */
+ OFMPTSR_VIF, /* Xen: vif details. */
};
/* Body of resources request.
struct ofmp_resources_update *ofmpru;
struct ofmp_tlv *tlv;
struct svec br_list;
+ struct svec port_list;
const char *host_uuid;
int i;
}
}
+ /* On XenServer systems, extended information about virtual interfaces
+ * (VIFs) is available, which is needed by the controller.
+ */
+ svec_init(&port_list);
+ bridge_get_ifaces(&port_list);
+ for (i=0; i < port_list.n; i++) {
+ const char *vif_uuid, *vm_uuid, *net_uuid;
+ uint64_t vif_mac;
+ struct ofmptsr_vif *vif_tlv;
+
+ vif_uuid = cfg_get_string(0, "port.%s.vif-uuid", port_list.names[i]);
+ if (!vif_uuid) {
+ continue;
+ }
+
+ vif_tlv = ofpbuf_put_zeros(buffer, sizeof(*vif_tlv));
+ vif_tlv->type = htons(OFMPTSR_VIF);
+ vif_tlv->len = htons(sizeof(*vif_tlv));
+
+ memcpy(vif_tlv->name, port_list.names[i], strlen(port_list.names[i])+1);
+ memcpy(vif_tlv->vif_uuid, vif_uuid, sizeof(vif_tlv->vif_uuid));
+
+ vm_uuid = cfg_get_string(0, "port.%s.vm-uuid", port_list.names[i]);
+ if (vm_uuid) {
+ memcpy(vif_tlv->vm_uuid, vm_uuid, sizeof(vif_tlv->vm_uuid));
+ } else {
+ /* In case the vif disappeared underneath us. */
+ memset(vif_tlv->vm_uuid, '\0', sizeof(vif_tlv->vm_uuid));
+ }
+
+ net_uuid = cfg_get_string(0, "port.%s.net-uuid", port_list.names[i]);
+ if (net_uuid) {
+ memcpy(vif_tlv->net_uuid, net_uuid, sizeof(vif_tlv->net_uuid));
+ } else {
+ /* In case the vif disappeared underneath us. */
+ memset(vif_tlv->net_uuid, '\0', sizeof(vif_tlv->net_uuid));
+ }
+
+ vif_mac = cfg_get_mac(0, "port.%s.vif-mac", port_list.names[i]);
+ vif_tlv->vif_mac = htonll(vif_mac);
+ }
+
/* Put end marker. */
tlv = ofpbuf_put_zeros(buffer, sizeof(*tlv));
tlv->type = htons(OFMPTSR_END);
vswitch-aware replacement for Citrix script of the same name.
+ root_vswitch_scripts_dump-vif-details
+
+ Script to retrieve extended information about VIFs that are
+ needed by the controller. This is called by the "vif" script,
+ which is run when virtual interfaces are added and removed.
+
usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py
xsconsole plugin to configure the pool-wide configuration keys
# Keep other-config/ keys in sync with device.ml:vif_udev_keys
cfg_mod="/root/vswitch/bin/ovs-cfg-mod"
+dump_vif_details="/root/vswitch/scripts/dump-vif-details"
service="/sbin/service"
TYPE=`echo ${XENBUS_PATH} | cut -f 2 -d '/'`
${IP} link set "${vif}" address "${address}" || logger -t scripts-vif "Failed to ip link set ${vif} address ${address}"
${IP} addr flush "${vif}" || logger -t scripts-vif "Failed to ip addr flush ${vif}"
+ local vif_details=$($dump_vif_details $DOMID $DEVID)
+ if [ $? -ne 0 -o -z "${vif_details}" ]; then
+ logger -t scripts-vif "Failed to retrieve vif details for vswitch"
+ fi
+
$cfg_mod -F /etc/ovs-vswitchd.conf \
--del-match="bridge.*.port=$vif" \
--del-match="vlan.$vif.[!0-9]*" \
--del-match="port.$vif.[!0-9]*" \
--add="bridge.$bridge.port=$vif" \
- $vid -c
+ $vid $vif_details -c >/tmp/j
$service vswitch reload
${IP} link set "${vif}" up || logger -t scripts-vif "Failed to ip link set ${vif} up"
--- /dev/null
+#!/usr/bin/python
+#
+# Script to retrieve extended information about VIFs that are
+# needed by the controller. This is called by the "vif" script,
+# which is run when virtual interfaces are added and removed.
+
+# Copyright (C) 2009 Nicira Networks, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without warranty of any kind.
+
+import sys
+import XenAPI
+import xen.lowlevel.xs
+
+# Query XenStore for the opaque reference of this vif
+def get_vif_ref(domid, devid):
+ xenstore = xen.lowlevel.xs.xs()
+ t = xenstore.transaction_start()
+ vif_ref = xenstore.read(t, '/xapi/%s/private/vif/%s/ref' % (domid, devid))
+ xenstore.transaction_end(t)
+ return vif_ref
+
+# Query XAPI for the information we need using the vif's opaque reference
+def dump_vif_info(domid, devid, vif_ref):
+ try:
+ session = XenAPI.xapi_local()
+ session.xenapi.login_with_password("root", "")
+ vif_rec = session.xenapi.VIF.get_record(vif_ref)
+ net_rec = session.xenapi.network.get_record(vif_rec["network"])
+ vm_rec = session.xenapi.VM.get_record(vif_rec["VM"])
+
+ sys.stdout.write('--add=port.vif%s.%s.network-uuid=%s '
+ % (domid, devid, net_rec["uuid"]))
+ sys.stdout.write('--add=port.vif%s.%s.vif-mac=%s '
+ % (domid, devid, vif_rec["MAC"]))
+ sys.stdout.write('--add=port.vif%s.%s.vif-uuid=%s '
+ % (domid, devid, vif_rec["uuid"]))
+ sys.stdout.write('--add=port.vif%s.%s.vm-uuid=%s '
+ % (domid, devid, vm_rec["uuid"]))
+ finally:
+ session.xenapi.session.logout()
+
+if __name__ == '__main__':
+ if (len(sys.argv) != 3):
+ sys.stderr.write("ERROR: %s <domid> <devid>\n")
+ sys.exit(1)
+
+ domid = sys.argv[1]
+ devid = sys.argv[2]
+
+ vif_ref = get_vif_ref(domid, devid)
+ if not vif_ref:
+ sys.stderr.write("ERROR: Could not find interface vif%s.%s\n"
+ % (domid, devid))
+ sys.exit(1)
+
+ dump_vif_info(domid, devid, vif_ref)
+ sys.exit(0)
$RPM_BUILD_ROOT%{_prefix}/scripts/interface-reconfigure
install -m 755 xenserver/etc_xensource_scripts_vif \
$RPM_BUILD_ROOT%{_prefix}/scripts/vif
+install -m 755 xenserver/root_vswitch_scripts_dump-vif-details \
+ $RPM_BUILD_ROOT%{_prefix}/scripts/dump-vif-details
install -m 755 \
xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py \
$RPM_BUILD_ROOT%{_prefix}/scripts/XSFeatureVSwitch.py
/root/vswitch/kernel_modules/brcompat_mod.ko
/root/vswitch/kernel_modules/openvswitch_mod.ko
/root/vswitch/kernel_modules/veth_mod.ko
+/root/vswitch/scripts/dump-vif-details
/root/vswitch/scripts/interface-reconfigure
/root/vswitch/scripts/vif
/root/vswitch/scripts/XSFeatureVSwitch.py