xenserver: Send VIF details to controller
authorJustin Pettit <jpettit@nicira.com>
Wed, 10 Jun 2009 01:19:02 +0000 (18:19 -0700)
committerJustin Pettit <jpettit@nicira.com>
Wed, 10 Jun 2009 01:22:24 +0000 (18:22 -0700)
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
vswitchd/mgmt.c
xenserver/README
xenserver/etc_xensource_scripts_vif
xenserver/root_vswitch_scripts_dump-vif-details [new file with mode: 0755]
xenserver/vswitch-xen.spec

index c78094272699788e3a0ba0398060262bd3593757..c900c1822a6997530fd5bb3878c0f503ee6b8ff8 100644 (file)
@@ -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.
index b31d141e6ddc73961d5c7adb9d6b3e2c46218ee7..90f3ecb60c48ed83f7ac77e5fd654cba8c124891 100644 (file)
@@ -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);
index 7cd04ab695d9c6a1127c00db13dbd8613cf7d4ac..2344835209a0230fdd2441f0eb2453148d8c27ac 100644 (file)
@@ -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
index fcf13a690244673f282e38e3c8d3e6b05b05a52a..796da997139a3e3c13cf91a8c5f647a217bcbf78 100755 (executable)
@@ -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 (executable)
index 0000000..2e9aa03
--- /dev/null
@@ -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 <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)
index fc9b6d2003a17817274c91c3120306b136080467..ee3fce3d60d6f2da88f874168465c29528d2f585 100644 (file)
@@ -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