From 3570ee9844655d02eb365deda907b7c6295788ae Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Tue, 9 Jun 2009 18:19:02 -0700 Subject: [PATCH] xenserver: Send VIF details to controller The controller needs to know various things about virtual interfaces as they move about the network. This commit sends the VIF, virtual machine, and network UUIDs associated with the VIF, as well as its MAC address over the management channel. Feature #1324 --- include/openflow/openflow-mgmt.h | 19 +++++- vswitchd/mgmt.c | 43 +++++++++++++ xenserver/README | 6 ++ xenserver/etc_xensource_scripts_vif | 8 ++- .../root_vswitch_scripts_dump-vif-details | 61 +++++++++++++++++++ xenserver/vswitch-xen.spec | 3 + 6 files changed, 137 insertions(+), 3 deletions(-) create mode 100755 xenserver/root_vswitch_scripts_dump-vif-details diff --git a/include/openflow/openflow-mgmt.h b/include/openflow/openflow-mgmt.h index c78094272..c900c1822 100644 --- a/include/openflow/openflow-mgmt.h +++ b/include/openflow/openflow-mgmt.h @@ -96,7 +96,7 @@ OFP_ASSERT(sizeof(struct ofmptsr_dp) == 32); */ #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. */ @@ -107,7 +107,9 @@ struct ofmptsr_dp_uuid { }; 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. */ @@ -118,12 +120,25 @@ struct ofmptsr_mgmt_uuid { }; 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. diff --git a/vswitchd/mgmt.c b/vswitchd/mgmt.c index b31d141e6..90f3ecb60 100644 --- a/vswitchd/mgmt.c +++ b/vswitchd/mgmt.c @@ -306,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; + struct svec port_list; const char *host_uuid; int i; @@ -381,6 +382,48 @@ send_resources_update(uint32_t xid, bool use_xid) } } + /* 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); diff --git a/xenserver/README b/xenserver/README index 7cd04ab69..234483520 100644 --- a/xenserver/README +++ b/xenserver/README @@ -48,6 +48,12 @@ files are: 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 diff --git a/xenserver/etc_xensource_scripts_vif b/xenserver/etc_xensource_scripts_vif index fcf13a690..796da9971 100755 --- a/xenserver/etc_xensource_scripts_vif +++ b/xenserver/etc_xensource_scripts_vif @@ -14,6 +14,7 @@ # 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 '/'` @@ -86,12 +87,17 @@ add_to_bridge() ${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" diff --git a/xenserver/root_vswitch_scripts_dump-vif-details b/xenserver/root_vswitch_scripts_dump-vif-details new file mode 100755 index 000000000..2e9aa0391 --- /dev/null +++ b/xenserver/root_vswitch_scripts_dump-vif-details @@ -0,0 +1,61 @@ +#!/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 \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) diff --git a/xenserver/vswitch-xen.spec b/xenserver/vswitch-xen.spec index fc9b6d200..ee3fce3d6 100644 --- a/xenserver/vswitch-xen.spec +++ b/xenserver/vswitch-xen.spec @@ -65,6 +65,8 @@ install -m 755 xenserver/opt_xensource_libexec_interface-reconfigure \ $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 @@ -286,6 +288,7 @@ fi /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 -- 2.43.0