Skip to content

Commit 3570ee9

Browse files
author
Justin Pettit
committed
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
1 parent ae825ab commit 3570ee9

6 files changed

Lines changed: 137 additions & 3 deletions

File tree

include/openflow/openflow-mgmt.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ OFP_ASSERT(sizeof(struct ofmptsr_dp) == 32);
9696
*/
9797
#define OFMP_UUID_LEN 36
9898

99-
/* Resource TLV for UUIDs associated with this datapath. */
99+
/* Resource TLV for XenServer UUIDs associated with this datapath. */
100100
struct ofmptsr_dp_uuid {
101101
uint16_t type; /* OFMPTSR_DP_UUID. */
102102
uint16_t len; /* Length. */
@@ -107,7 +107,9 @@ struct ofmptsr_dp_uuid {
107107
};
108108
OFP_ASSERT(sizeof(struct ofmptsr_dp_uuid) == 16);
109109

110-
/* Resource TLV for UUID associated with this managment instance. */
110+
/* Resource TLV for XenServer UUID associated with this managment
111+
* instance.
112+
*/
111113
struct ofmptsr_mgmt_uuid {
112114
uint16_t type; /* OFMPTSR_MGMT_UUID. */
113115
uint16_t len; /* 52. */
@@ -118,12 +120,25 @@ struct ofmptsr_mgmt_uuid {
118120
};
119121
OFP_ASSERT(sizeof(struct ofmptsr_mgmt_uuid) == 56);
120122

123+
/* Resource TLV for details about this XenServer vif. */
124+
struct ofmptsr_vif {
125+
uint16_t type; /* OFMPTSR_VIF. */
126+
uint16_t len; /* 136. */
127+
uint8_t name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated name. */
128+
uint8_t vif_uuid[OFMP_UUID_LEN]; /* VIF UUID. */
129+
uint8_t vm_uuid[OFMP_UUID_LEN]; /* VM UUID. */
130+
uint8_t net_uuid[OFMP_UUID_LEN]; /* Network UUID. */
131+
uint64_t vif_mac; /* Management ID. */
132+
};
133+
OFP_ASSERT(sizeof(struct ofmptsr_vif) == 136);
134+
121135
/* TLV types for switch resource descriptions. */
122136
enum ofmp_switch_resources {
123137
OFMPTSR_END = 0, /* Terminator. */
124138
OFMPTSR_DP, /* Datapath. */
125139
OFMPTSR_DP_UUID, /* Xen: datapath uuid's. */
126140
OFMPTSR_MGMT_UUID, /* Xen: management uuid. */
141+
OFMPTSR_VIF, /* Xen: vif details. */
127142
};
128143

129144
/* Body of resources request.

vswitchd/mgmt.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ send_resources_update(uint32_t xid, bool use_xid)
306306
struct ofmp_resources_update *ofmpru;
307307
struct ofmp_tlv *tlv;
308308
struct svec br_list;
309+
struct svec port_list;
309310
const char *host_uuid;
310311
int i;
311312

@@ -381,6 +382,48 @@ send_resources_update(uint32_t xid, bool use_xid)
381382
}
382383
}
383384

385+
/* On XenServer systems, extended information about virtual interfaces
386+
* (VIFs) is available, which is needed by the controller.
387+
*/
388+
svec_init(&port_list);
389+
bridge_get_ifaces(&port_list);
390+
for (i=0; i < port_list.n; i++) {
391+
const char *vif_uuid, *vm_uuid, *net_uuid;
392+
uint64_t vif_mac;
393+
struct ofmptsr_vif *vif_tlv;
394+
395+
vif_uuid = cfg_get_string(0, "port.%s.vif-uuid", port_list.names[i]);
396+
if (!vif_uuid) {
397+
continue;
398+
}
399+
400+
vif_tlv = ofpbuf_put_zeros(buffer, sizeof(*vif_tlv));
401+
vif_tlv->type = htons(OFMPTSR_VIF);
402+
vif_tlv->len = htons(sizeof(*vif_tlv));
403+
404+
memcpy(vif_tlv->name, port_list.names[i], strlen(port_list.names[i])+1);
405+
memcpy(vif_tlv->vif_uuid, vif_uuid, sizeof(vif_tlv->vif_uuid));
406+
407+
vm_uuid = cfg_get_string(0, "port.%s.vm-uuid", port_list.names[i]);
408+
if (vm_uuid) {
409+
memcpy(vif_tlv->vm_uuid, vm_uuid, sizeof(vif_tlv->vm_uuid));
410+
} else {
411+
/* In case the vif disappeared underneath us. */
412+
memset(vif_tlv->vm_uuid, '\0', sizeof(vif_tlv->vm_uuid));
413+
}
414+
415+
net_uuid = cfg_get_string(0, "port.%s.net-uuid", port_list.names[i]);
416+
if (net_uuid) {
417+
memcpy(vif_tlv->net_uuid, net_uuid, sizeof(vif_tlv->net_uuid));
418+
} else {
419+
/* In case the vif disappeared underneath us. */
420+
memset(vif_tlv->net_uuid, '\0', sizeof(vif_tlv->net_uuid));
421+
}
422+
423+
vif_mac = cfg_get_mac(0, "port.%s.vif-mac", port_list.names[i]);
424+
vif_tlv->vif_mac = htonll(vif_mac);
425+
}
426+
384427
/* Put end marker. */
385428
tlv = ofpbuf_put_zeros(buffer, sizeof(*tlv));
386429
tlv->type = htons(OFMPTSR_END);

xenserver/README

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ files are:
4848

4949
vswitch-aware replacement for Citrix script of the same name.
5050

51+
root_vswitch_scripts_dump-vif-details
52+
53+
Script to retrieve extended information about VIFs that are
54+
needed by the controller. This is called by the "vif" script,
55+
which is run when virtual interfaces are added and removed.
56+
5157
usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py
5258

5359
xsconsole plugin to configure the pool-wide configuration keys

xenserver/etc_xensource_scripts_vif

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# Keep other-config/ keys in sync with device.ml:vif_udev_keys
1515

1616
cfg_mod="/root/vswitch/bin/ovs-cfg-mod"
17+
dump_vif_details="/root/vswitch/scripts/dump-vif-details"
1718
service="/sbin/service"
1819

1920
TYPE=`echo ${XENBUS_PATH} | cut -f 2 -d '/'`
@@ -86,12 +87,17 @@ add_to_bridge()
8687
${IP} link set "${vif}" address "${address}" || logger -t scripts-vif "Failed to ip link set ${vif} address ${address}"
8788
${IP} addr flush "${vif}" || logger -t scripts-vif "Failed to ip addr flush ${vif}"
8889

90+
local vif_details=$($dump_vif_details $DOMID $DEVID)
91+
if [ $? -ne 0 -o -z "${vif_details}" ]; then
92+
logger -t scripts-vif "Failed to retrieve vif details for vswitch"
93+
fi
94+
8995
$cfg_mod -F /etc/ovs-vswitchd.conf \
9096
--del-match="bridge.*.port=$vif" \
9197
--del-match="vlan.$vif.[!0-9]*" \
9298
--del-match="port.$vif.[!0-9]*" \
9399
--add="bridge.$bridge.port=$vif" \
94-
$vid -c
100+
$vid $vif_details -c >/tmp/j
95101
$service vswitch reload
96102

97103
${IP} link set "${vif}" up || logger -t scripts-vif "Failed to ip link set ${vif} up"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/python
2+
#
3+
# Script to retrieve extended information about VIFs that are
4+
# needed by the controller. This is called by the "vif" script,
5+
# which is run when virtual interfaces are added and removed.
6+
7+
# Copyright (C) 2009 Nicira Networks, Inc.
8+
#
9+
# Copying and distribution of this file, with or without modification,
10+
# are permitted in any medium without royalty provided the copyright
11+
# notice and this notice are preserved. This file is offered as-is,
12+
# without warranty of any kind.
13+
14+
import sys
15+
import XenAPI
16+
import xen.lowlevel.xs
17+
18+
# Query XenStore for the opaque reference of this vif
19+
def get_vif_ref(domid, devid):
20+
xenstore = xen.lowlevel.xs.xs()
21+
t = xenstore.transaction_start()
22+
vif_ref = xenstore.read(t, '/xapi/%s/private/vif/%s/ref' % (domid, devid))
23+
xenstore.transaction_end(t)
24+
return vif_ref
25+
26+
# Query XAPI for the information we need using the vif's opaque reference
27+
def dump_vif_info(domid, devid, vif_ref):
28+
try:
29+
session = XenAPI.xapi_local()
30+
session.xenapi.login_with_password("root", "")
31+
vif_rec = session.xenapi.VIF.get_record(vif_ref)
32+
net_rec = session.xenapi.network.get_record(vif_rec["network"])
33+
vm_rec = session.xenapi.VM.get_record(vif_rec["VM"])
34+
35+
sys.stdout.write('--add=port.vif%s.%s.network-uuid=%s '
36+
% (domid, devid, net_rec["uuid"]))
37+
sys.stdout.write('--add=port.vif%s.%s.vif-mac=%s '
38+
% (domid, devid, vif_rec["MAC"]))
39+
sys.stdout.write('--add=port.vif%s.%s.vif-uuid=%s '
40+
% (domid, devid, vif_rec["uuid"]))
41+
sys.stdout.write('--add=port.vif%s.%s.vm-uuid=%s '
42+
% (domid, devid, vm_rec["uuid"]))
43+
finally:
44+
session.xenapi.session.logout()
45+
46+
if __name__ == '__main__':
47+
if (len(sys.argv) != 3):
48+
sys.stderr.write("ERROR: %s <domid> <devid>\n")
49+
sys.exit(1)
50+
51+
domid = sys.argv[1]
52+
devid = sys.argv[2]
53+
54+
vif_ref = get_vif_ref(domid, devid)
55+
if not vif_ref:
56+
sys.stderr.write("ERROR: Could not find interface vif%s.%s\n"
57+
% (domid, devid))
58+
sys.exit(1)
59+
60+
dump_vif_info(domid, devid, vif_ref)
61+
sys.exit(0)

xenserver/vswitch-xen.spec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ install -m 755 xenserver/opt_xensource_libexec_interface-reconfigure \
6565
$RPM_BUILD_ROOT%{_prefix}/scripts/interface-reconfigure
6666
install -m 755 xenserver/etc_xensource_scripts_vif \
6767
$RPM_BUILD_ROOT%{_prefix}/scripts/vif
68+
install -m 755 xenserver/root_vswitch_scripts_dump-vif-details \
69+
$RPM_BUILD_ROOT%{_prefix}/scripts/dump-vif-details
6870
install -m 755 \
6971
xenserver/usr_lib_xsconsole_plugins-base_XSFeatureVSwitch.py \
7072
$RPM_BUILD_ROOT%{_prefix}/scripts/XSFeatureVSwitch.py
@@ -286,6 +288,7 @@ fi
286288
/root/vswitch/kernel_modules/brcompat_mod.ko
287289
/root/vswitch/kernel_modules/openvswitch_mod.ko
288290
/root/vswitch/kernel_modules/veth_mod.ko
291+
/root/vswitch/scripts/dump-vif-details
289292
/root/vswitch/scripts/interface-reconfigure
290293
/root/vswitch/scripts/vif
291294
/root/vswitch/scripts/XSFeatureVSwitch.py

0 commit comments

Comments
 (0)