mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Tools-side support for creating and destroying netchannel2 interfaces.
Signed-off-by: Steven Smith <steven.smith@citrix.com>
This commit is contained in:
1 parent
3672ce675c
commit
636eaa12d9
8 files changed
+280
-4
No files matched your search
@@ -11,6 +11,7 @@ XENDOMAINS_SYSCONFIG = init.d/sysconfig.xendomains
|
||||
XEN_SCRIPTS = network-bridge vif-bridge
|
||||
XEN_SCRIPTS += network-route vif-route
|
||||
XEN_SCRIPTS += network-nat vif-nat
|
||||
XEN_SCRIPTS += vif2
|
||||
XEN_SCRIPTS += block
|
||||
XEN_SCRIPTS += block-enbd block-nbd
|
||||
XEN_SCRIPTS += blktap
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
|
||||
dir=$(dirname "$0")
|
||||
. "$dir/xen-hotplug-common.sh"
|
||||
. "$dir/xen-network-common.sh"
|
||||
|
||||
bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")
|
||||
if [ -z "$bridge" ]
|
||||
then
|
||||
nr_bridges=$(($(brctl show | cut -f 1 | grep -v "^$" | wc -l) - 1))
|
||||
if [ "$nr_bridges" != 1 ]
|
||||
then
|
||||
fatal "no bridge specified, and don't know which one to use ($nr_bridges found)"
|
||||
fi
|
||||
bridge=$(brctl show | cut -d "
|
||||
" -f 2 | cut -f 1)
|
||||
fi
|
||||
|
||||
command="$1"
|
||||
shift
|
||||
|
||||
case "$command" in
|
||||
"online")
|
||||
if [ "$bridge" != "-" ]
|
||||
then
|
||||
setup_bridge_port "$vif"
|
||||
add_to_bridge "$bridge" "$vif"
|
||||
else
|
||||
# Just let the normal udev rules for interfaces handle it.
|
||||
true
|
||||
fi
|
||||
success
|
||||
;;
|
||||
|
||||
"add")
|
||||
success
|
||||
;;
|
||||
|
||||
"remove")
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown command: $command"
|
||||
echo 'Valid commands are: add, remove, online'
|
||||
exit 1
|
||||
esac
|
||||
@@ -1,8 +1,9 @@
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} online"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", RUN+="$env{script} offline"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif2-*", RUN+="/etc/xen/scripts/vif2 $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="$env{script} online"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="$env{script} offline"
|
||||
SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi $env{ACTION}"
|
||||
SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
|
||||
KERNEL=="evtchn", NAME="xen/%k"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
# A collection of DevControllers
|
||||
#
|
||||
|
||||
from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, vfbif, vscsiif
|
||||
from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, vfbif, vscsiif, netif2
|
||||
from xen.xend.server.BlktapController import BlktapController, Blktap2Controller
|
||||
from xen.xend.server.ConsoleController import ConsoleController
|
||||
|
||||
@@ -37,6 +37,7 @@ class XendDevices:
|
||||
controllers = {
|
||||
'vbd': blkif.BlkifController,
|
||||
'vif': netif.NetifController,
|
||||
'vif2': netif2.NetifController2,
|
||||
'vtpm': tpmif.TPMifController,
|
||||
'pci': pciif.PciController,
|
||||
'ioports': iopif.IOPortsController,
|
||||
|
||||
@@ -1222,7 +1222,7 @@ class XendDomainInfo:
|
||||
break
|
||||
self._waitForDevice_destroy(deviceClass, devid, backend)
|
||||
|
||||
if rm_cfg:
|
||||
if rm_cfg and deviceClass != "vif2":
|
||||
if deviceClass == 'vif':
|
||||
if self.domid is not None:
|
||||
mac = ''
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
#============================================================================
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
|
||||
# Copyright (C) 2005 XenSource Ltd
|
||||
# Copyright (C) 2008 Citrix Systems Inc.
|
||||
#============================================================================
|
||||
#
|
||||
# Based closely on netif.py.
|
||||
#
|
||||
|
||||
"""Support for virtual network interfaces, version 2.
|
||||
"""
|
||||
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
|
||||
from xen.xend import XendOptions
|
||||
from xen.xend.server.DevController import DevController
|
||||
from xen.xend.XendError import VmError
|
||||
from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
|
||||
from xen.xend.xenstore.xstransact import xstransact
|
||||
import xen.util.xsm.xsm as security
|
||||
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
xoptions = XendOptions.instance()
|
||||
|
||||
def randomMAC():
|
||||
"""Generate a random MAC address.
|
||||
|
||||
Uses OUI (Organizationally Unique Identifier) 00-16-3E, allocated to
|
||||
Xensource, Inc. The OUI list is available at
|
||||
http://standards.ieee.org/regauth/oui/oui.txt.
|
||||
|
||||
The remaining 3 fields are random, with the first bit of the first
|
||||
random field set 0.
|
||||
|
||||
@return: MAC address string
|
||||
"""
|
||||
mac = [ 0x00, 0x16, 0x3e,
|
||||
random.randint(0x00, 0x7f),
|
||||
random.randint(0x00, 0xff),
|
||||
random.randint(0x00, 0xff) ]
|
||||
return ':'.join(map(lambda x: "%02x" % x, mac))
|
||||
|
||||
class NetifController2(DevController):
|
||||
def __init__(self, vm):
|
||||
DevController.__init__(self, vm)
|
||||
|
||||
def getDeviceDetails(self, config):
|
||||
"""@see DevController.getDeviceDetails"""
|
||||
|
||||
devid = self.allocateDeviceID()
|
||||
|
||||
bridge = config.get('bridge')
|
||||
back_mac = config.get('back_mac')
|
||||
if not back_mac:
|
||||
if bridge:
|
||||
back_mac = "fe:ff:ff:ff:ff:ff"
|
||||
else:
|
||||
back_mac = randomMAC()
|
||||
front_mac = config.get('front_mac') or randomMAC()
|
||||
front_trust = config.get("trusted") or "0"
|
||||
back_trust = config.get("back_trusted") or "1"
|
||||
max_bypasses = config.get("max_bypasses") or "5"
|
||||
pdev = config.get('pdev')
|
||||
front_filter = config.get("front_filter_mac")
|
||||
if front_filter == None:
|
||||
if back_trust == "0":
|
||||
front_filter = "1"
|
||||
else:
|
||||
front_filter = "0"
|
||||
back_filter = config.get("filter_mac")
|
||||
if back_filter == None:
|
||||
if front_trust == "0":
|
||||
back_filter = "1"
|
||||
else:
|
||||
back_filter = "0"
|
||||
back = { 'mac': back_mac, 'remote-mac': front_mac,
|
||||
'handle': "%i" % devid, 'local-trusted': back_trust,
|
||||
'remote-trusted': front_trust, 'filter-mac': back_filter,
|
||||
'max-bypasses': max_bypasses }
|
||||
|
||||
front = { 'mac': front_mac, 'remote-mac': back_mac,
|
||||
'local-trusted': front_trust, 'remote-trusted': back_trust,
|
||||
'filter-mac': front_filter }
|
||||
|
||||
if bridge:
|
||||
back['bridge'] = bridge
|
||||
|
||||
if pdev:
|
||||
back['pdev'] = pdev
|
||||
|
||||
return (devid, back, front)
|
||||
|
||||
def getDeviceConfiguration(self, devid, transaction = None):
|
||||
"""@see DevController.configuration"""
|
||||
|
||||
if transaction is None:
|
||||
read_fn = xstransact.Read
|
||||
else:
|
||||
read_fn = transaction.read
|
||||
def front_read(x):
|
||||
return read_fn(frontpath + x)
|
||||
def back_read(x):
|
||||
return read_fn(backpath + x)
|
||||
|
||||
result = DevController.getDeviceConfiguration(self, devid, transaction)
|
||||
|
||||
dev = self.convertToDeviceNumber(devid)
|
||||
frontpath = self.frontendPath(dev) + "/"
|
||||
|
||||
backpath = front_read("backend") + "/"
|
||||
|
||||
front_mac = front_read("mac")
|
||||
back_mac = back_read("mac")
|
||||
|
||||
front_trusted = back_read("remote-trusted")
|
||||
back_trusted = back_read("local-trusted")
|
||||
max_bypasses = back_read("max-bypasses")
|
||||
|
||||
bridge = back_read("bridge")
|
||||
|
||||
pdev = back_read("pdev")
|
||||
|
||||
if front_mac:
|
||||
result["front_mac"] = front_mac
|
||||
if back_mac:
|
||||
result["back_mac"] = back_mac
|
||||
if front_trusted:
|
||||
result["front_trusted"] = front_trusted
|
||||
if back_trusted:
|
||||
result["back_trusted"] = back_trusted
|
||||
if bridge:
|
||||
result["bridge"] = bridge
|
||||
if pdev:
|
||||
result["pdev"] = pdev
|
||||
if max_bypasses:
|
||||
result["max-bypasses"] = max_bypasses
|
||||
return result
|
||||
|
||||
def destroyDevice(self, devid, force):
|
||||
dev = self.convertToDeviceNumber(devid)
|
||||
self.writeBackend(dev, "online", "0")
|
||||
if force:
|
||||
self.writeBackend(dev, "shutdown-request", "force")
|
||||
else:
|
||||
self.writeBackend(dev, "shutdown-request", "normal")
|
||||
self.vm._removeVm("device/%s/%d" % (self.deviceClass, dev))
|
||||
@@ -393,6 +393,12 @@ gopts.var('vif', val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT,"
|
||||
This option may be repeated to add more than one vif.
|
||||
Specifying vifs will increase the number of interfaces as needed.""")
|
||||
|
||||
gopts.var('vif2', val="front_mac=MAC,back_mac=MAC,backend=DOM,pdev=PDEV,max_bypasses=N,bridge=BRIDGE,filter_mac=<0|1>,front_filter_mac=<0|1>",
|
||||
fn=append_value, default=[],
|
||||
use="""Add a netchannel2 network interface using given front
|
||||
and backend MAC addresses. Randomly generated
|
||||
addresses will be used if either address is missing.""")
|
||||
|
||||
gopts.var('vtpm', val="instance=INSTANCE,backend=DOM,type=TYPE",
|
||||
fn=append_value, default=[],
|
||||
use="""Add a TPM interface. On the backend side use the given
|
||||
@@ -931,6 +937,8 @@ def configure_vifs(config_devs, vals):
|
||||
|
||||
vifs = vals.vif
|
||||
vifs_n = len(vifs)
|
||||
vifs2 = vals.vif2
|
||||
vifs2_n = len(vifs2)
|
||||
|
||||
if hasattr(vals, 'nics'):
|
||||
if vals.nics > 0:
|
||||
@@ -957,6 +965,18 @@ def configure_vifs(config_devs, vals):
|
||||
map(f, d.keys())
|
||||
config_devs.append(['device', config_vif])
|
||||
|
||||
for c in vifs2:
|
||||
d = comma_sep_kv_to_dict(c)
|
||||
config_vif = ['vif2']
|
||||
|
||||
for k in d.keys():
|
||||
if k not in ['front_mac', 'back_mac', 'backend', 'trusted',
|
||||
'back_trusted', 'front_filter_mac', 'filter_mac',
|
||||
'bridge', 'pdev', 'max_bypasses' ]:
|
||||
err('Invalid vif2 option: ' + k)
|
||||
config_vif.append([k, d[k]])
|
||||
config_devs.append(['device', config_vif])
|
||||
|
||||
|
||||
def configure_hvm(config_image, vals):
|
||||
"""Create the config for HVM devices.
|
||||
|
||||
@@ -181,6 +181,15 @@ SUBCOMMAND_HELP = {
|
||||
'Destroy a domain\'s virtual network device.'),
|
||||
'network-list' : ('<Domain> [--long]',
|
||||
'List virtual network interfaces for a domain.'),
|
||||
'network2-attach': ('<Domain> [front_mac=<mac>] [back_mac=<mac>] '
|
||||
'[backend=<BackDomain>] [trusted=<0|1>] '
|
||||
'[back_trusted=<0|1>] [bridge=<bridge>] '
|
||||
'[max_bypasses=n]'
|
||||
'Create a new version 2 virtual network device.'),
|
||||
'network2-detach': ('<Domain> <DevId> [-f|--force]',
|
||||
'Destroy a domain\'s version 2 virtual network device.'),
|
||||
'network2-list' : ('<Domain> [--long]',
|
||||
'List version 2 virtual network interfaces for a domain.'),
|
||||
'vnet-create' : ('<ConfigFile>','Create a vnet from ConfigFile.'),
|
||||
'vnet-delete' : ('<VnetId>', 'Delete a Vnet.'),
|
||||
'vnet-list' : ('[-l|--long]', 'List Vnets.'),
|
||||
@@ -399,6 +408,9 @@ device_commands = [
|
||||
"network-attach",
|
||||
"network-detach",
|
||||
"network-list",
|
||||
"network2-attach",
|
||||
"network2-detach",
|
||||
"network2-list",
|
||||
"vtpm-list",
|
||||
"pci-attach",
|
||||
"pci-detach",
|
||||
@@ -2436,6 +2448,35 @@ def xm_block_configure(args):
|
||||
server.xend.domain.device_configure(dom, vbd)
|
||||
|
||||
|
||||
def xm_network2_attach(args):
|
||||
xenapi_unsupported()
|
||||
arg_check(args, 'network2-attach', 1, 4)
|
||||
dom = args[0]
|
||||
vif = ['vif2']
|
||||
vif_params = ['front_mac', 'back_mac', 'backend', 'trusted',
|
||||
'back_trusted', "front_filter_mac", "filter_mac",
|
||||
'bridge', 'pdev', "max_bypasses" ]
|
||||
for a in args[1:]:
|
||||
vif_param = a.split("=")
|
||||
if len(vif_param) != 2 or vif_param[1] == "" or \
|
||||
vif_param[0] not in vif_params:
|
||||
err("Invalid argument: %s" % a)
|
||||
usage("network2-attach")
|
||||
vif.append(vif_param)
|
||||
server.xend.domain.device_create(dom, vif)
|
||||
|
||||
def xm_network2_detach(args):
|
||||
xenapi_unsupported()
|
||||
arg_check(args, "network2-detch", 2, 3)
|
||||
detach(args, "vif2")
|
||||
|
||||
def xm_network2_list(args):
|
||||
xenapi_unsupported()
|
||||
(use_long, params) = arg_check_for_resource_list(args, "network2-list")
|
||||
dom = params[0]
|
||||
devs = server.xend.domain.getDeviceSxprs(dom, 'vif2')
|
||||
map(PrettyPrint.prettyprint, devs)
|
||||
|
||||
def xm_network_attach(args):
|
||||
arg_check(args, 'network-attach', 1, 11)
|
||||
|
||||
@@ -3239,6 +3280,9 @@ commands = {
|
||||
"network-attach": xm_network_attach,
|
||||
"network-detach": xm_network_detach,
|
||||
"network-list": xm_network_list,
|
||||
"network2-attach": xm_network2_attach,
|
||||
"network2-detach": xm_network2_detach,
|
||||
"network2-list": xm_network2_list,
|
||||
# network (as in XenAPI)
|
||||
"network-new": xm_network_new,
|
||||
"network-del": xm_network_del,
|
||||
|
||||