Dynamips NIO connections.

This commit is contained in:
Jeremy committed 2015-02-13 15:11:14 -07:00
1 parent 83edc649d2
commit a5ac7c5481
18 files changed
+515 -270

No files matched your search

+9 -35
View File
@@ -170,35 +170,7 @@ class Dynamips(BaseManager):
return hypervisor
def create_nio(self, executable, nio_settings):
"""
Creates a new NIO.
:param nio_settings: information to create the NIO
:returns: a NIO object
"""
nio = None
if nio_settings["type"] == "nio_udp":
lport = nio_settings["lport"]
rhost = nio_settings["rhost"]
rport = nio_settings["rport"]
try:
# TODO: handle IPv6
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.connect((rhost, rport))
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
nio = NIOUDP(lport, rhost, rport)
elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"]
if not self._has_privileged_access(executable):
raise aiohttp.web.HTTPForbidden(text="{} has no privileged access to {}.".format(executable, tap_device))
nio = NIOTAP(tap_device)
assert nio is not None
return nio
@asyncio.coroutine
def create_nio(self, node, nio_settings):
"""
Creates a new NIO.
@@ -221,12 +193,12 @@ class Dynamips(BaseManager):
except OSError as e:
raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
# check if we have an allocated NIO UDP auto
nio = node.hypervisor.get_nio_udp_auto(lport)
if not nio:
# otherwise create an NIO UDP
nio = NIOUDP(node.hypervisor, lport, rhost, rport)
else:
nio.connect(rhost, rport)
#nio = node.hypervisor.get_nio_udp_auto(lport)
#if not nio:
# otherwise create an NIO UDP
nio = NIOUDP(node.hypervisor, lport, rhost, rport)
#else:
# nio.connect(rhost, rport)
elif nio_settings["type"] == "nio_generic_ethernet":
ethernet_device = nio_settings["ethernet_device"]
if sys.platform.startswith("win"):
@@ -259,6 +231,8 @@ class Dynamips(BaseManager):
nio = NIOVDE(node.hypervisor, control_file, local_file)
elif nio_settings["type"] == "nio_null":
nio = NIONull(node.hypervisor)
yield from nio.create()
return nio
# def set_ghost_ios(self, router):
+1 -1
View File
@@ -38,7 +38,7 @@ class NIO:
def __init__(self, name, hypervisor):
self._hypervisor = hypervisor
self._name = None
self._name = name
self._bandwidth = None # no bandwidth constraint by default
self._input_filter = None # no input filter applied by default
self._output_filter = None # no output filter applied by default
+8 -5
View File
@@ -38,12 +38,11 @@ class NIOFIFO(NIO):
def __init__(self, hypervisor):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOFIFO._instance_count
# create an unique ID and name
nio_id = NIOFIFO._instance_count
NIOFIFO._instance_count += 1
self._name = 'nio_fifo' + str(self._id)
name = 'nio_fifo' + str(nio_id)
NIO.__init__(name, self, hypervisor)
@classmethod
def reset(cls):
@@ -71,3 +70,7 @@ class NIOFIFO(NIO):
nio=nio))
log.info("NIO FIFO {name} crossconnected with {nio_name}.".format(name=self._name, nio_name=nio.name))
def __json__(self):
return {"type": "nio_fifo"}
@@ -39,13 +39,12 @@ class NIOGenericEthernet(NIO):
def __init__(self, hypervisor, ethernet_device):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOGenericEthernet._instance_count
# create an unique ID and name
nio_id = NIOGenericEthernet._instance_count
NIOGenericEthernet._instance_count += 1
self._name = 'nio_gen_eth' + str(self._id)
name = 'nio_gen_eth' + str(nio_id)
self._ethernet_device = ethernet_device
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -73,3 +72,8 @@ class NIOGenericEthernet(NIO):
"""
return self._ethernet_device
def __json__(self):
return {"type": "nio_generic_ethernet",
"ethernet_device": self._ethernet_device}
@@ -39,13 +39,12 @@ class NIOLinuxEthernet(NIO):
def __init__(self, hypervisor, ethernet_device):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOLinuxEthernet._instance_count
# create an unique ID and name
nio_id = NIOLinuxEthernet._instance_count
NIOLinuxEthernet._instance_count += 1
self._name = 'nio_linux_eth' + str(self._id)
name = 'nio_linux_eth' + str(nio_id)
self._ethernet_device = ethernet_device
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -73,3 +72,8 @@ class NIOLinuxEthernet(NIO):
"""
return self._ethernet_device
def __json__(self):
return {"type": "nio_linux_ethernet",
"ethernet_device": self._ethernet_device}
+10 -5
View File
@@ -40,15 +40,14 @@ class NIOMcast(NIO):
def __init__(self, hypervisor, group, port):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOMcast._instance_count
# create an unique ID and name
nio_id = NIOMcast._instance_count
NIOMcast._instance_count += 1
self._name = 'nio_mcast' + str(self._id)
name = 'nio_mcast' + str(nio_id)
self._group = group
self._port = port
self._ttl = 1 # default TTL
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -109,3 +108,9 @@ class NIOMcast(NIO):
yield from self._hypervisor.send("nio set_mcast_ttl {name} {ttl}".format(name=self._name,
ttl=ttl))
self._ttl = ttl
def __json__(self):
return {"type": "nio_mcast",
"mgroup": self._mgroup,
"mport": self._mport}
+8 -5
View File
@@ -38,12 +38,11 @@ class NIONull(NIO):
def __init__(self, hypervisor):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIONull._instance_count
# create an unique ID and name
nio_id = NIONull._instance_count
NIONull._instance_count += 1
self._name = 'nio_null' + str(self._id)
name = 'nio_null' + str(nio_id)
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -58,3 +57,7 @@ class NIONull(NIO):
yield from self._hypervisor.send("nio create_null {}".format(self._name))
log.info("NIO NULL {name} created.".format(name=self._name))
def __json__(self):
return {"type": "nio_null"}
+9 -5
View File
@@ -39,13 +39,12 @@ class NIOTAP(NIO):
def __init__(self, hypervisor, tap_device):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOTAP._instance_count
# create an unique ID and name
nio_id = NIOTAP._instance_count
NIOTAP._instance_count += 1
self._name = 'nio_tap' + str(self._id)
name = 'nio_tap' + str(nio_id)
self._tap_device = tap_device
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -70,3 +69,8 @@ class NIOTAP(NIO):
"""
return self._tap_device
def __json__(self):
return {"type": "nio_tap",
"tap_device": self._tap_device}
+11 -5
View File
@@ -41,15 +41,14 @@ class NIOUDP(NIO):
def __init__(self, hypervisor, lport, rhost, rport):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOUDP._instance_count
# create an unique ID and name
nio_id = NIOUDP._instance_count
NIOUDP._instance_count += 1
self._name = 'nio_udp' + str(self._id)
name = 'nio_udp' + str(nio_id)
self._lport = lport
self._rhost = rhost
self._rport = rport
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -101,3 +100,10 @@ class NIOUDP(NIO):
"""
return self._rport
def __json__(self):
return {"type": "nio_udp",
"lport": self._lport,
"rport": self._rport,
"rhost": self._rhost}
@@ -41,17 +41,15 @@ class NIOUDPAuto(NIO):
def __init__(self, hypervisor, laddr, lport_start, lport_end):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOUDPAuto._instance_count
# create an unique ID and name
nio_id = NIOUDPAuto._instance_count
NIOUDPAuto._instance_count += 1
self._name = 'nio_udp_auto' + str(self._id)
name = 'nio_udp_auto' + str(nio_id)
self._laddr = laddr
self._lport = None
self._raddr = None
self._rport = None
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -133,3 +131,10 @@ class NIOUDPAuto(NIO):
log.info("NIO UDP AUTO {name} connected to {raddr}:{rport}".format(name=self._name,
raddr=raddr,
rport=rport))
def __json__(self):
return {"type": "nio_udp_auto",
"lport": self._lport,
"rport": self._rport,
"raddr": self._raddr}
+10 -5
View File
@@ -40,14 +40,13 @@ class NIOUNIX(NIO):
def __init__(self, hypervisor, local_file, remote_file):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOUNIX._instance_count
# create an unique ID and name
nio_id = NIOUNIX._instance_count
NIOUNIX._instance_count += 1
self._name = 'nio_unix' + str(self._id)
name = 'nio_unix' + str(nio_id)
self._local_file = local_file
self._remote_file = remote_file
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -87,3 +86,9 @@ class NIOUNIX(NIO):
"""
return self._remote_file
def __json__(self):
return {"type": "nio_unix",
"local_file": self._local_file,
"remote_file": self._remote_file}
+22 -13
View File
@@ -19,6 +19,7 @@
Interface for VDE (Virtual Distributed Ethernet) NIOs (Unix based OSes only).
"""
import asyncio
from .nio import NIO
import logging
@@ -39,22 +40,13 @@ class NIOVDE(NIO):
def __init__(self, hypervisor, control_file, local_file):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIOVDE._instance_count
# create an unique ID and name
nio_id = NIOVDE._instance_count
NIOVDE._instance_count += 1
self._name = 'nio_vde' + str(self._id)
name = 'nio_vde' + str(nio_id)
self._control_file = control_file
self._local_file = local_file
self._hypervisor.send("nio create_vde {name} {control} {local}".format(name=self._name,
control=control_file,
local=local_file))
log.info("NIO VDE {name} created with control={control}, local={local}".format(name=self._name,
control=control_file,
local=local_file))
NIO.__init__(self, name, hypervisor)
@classmethod
def reset(cls):
@@ -64,6 +56,17 @@ class NIOVDE(NIO):
cls._instance_count = 0
@asyncio.coroutine
def create(self):
self._hypervisor.send("nio create_vde {name} {control} {local}".format(name=self._name,
control=self._control_file,
local=self._local_file))
log.info("NIO VDE {name} created with control={control}, local={local}".format(name=self._name,
control=self._control_file,
local=self._local_file))
@property
def control_file(self):
"""
@@ -83,3 +86,9 @@ class NIOVDE(NIO):
"""
return self._local_file
def __json__(self):
return {"type": "nio_vde",
"local_file": self._local_file,
"control_file": self._control_file}
+168 -158
View File
@@ -145,16 +145,16 @@ class Router(BaseVM):
"system_id": self._system_id}
# FIXME: add default slots/wics
# slot_id = 0
# slot_number = 0
# for slot in self._slots:
# if slot:
# slot = str(slot)
# router_defaults["slot" + str(slot_id)] = slot
# slot_id += 1
# router_defaults["slot" + str(slot_number)] = slot
# slot_number += 1
# if self._slots[0] and self._slots[0].wics:
# for wic_slot_id in range(0, len(self._slots[0].wics)):
# router_defaults["wic" + str(wic_slot_id)] = None
# for wic_slot_number in range(0, len(self._slots[0].wics)):
# router_defaults["wic" + str(wic_slot_number)] = None
return router_info
@@ -991,23 +991,23 @@ class Router(BaseVM):
return slot_bindings
@asyncio.coroutine
def slot_add_binding(self, slot_id, adapter):
def slot_add_binding(self, slot_number, adapter):
"""
Adds a slot binding (a module into a slot).
:param slot_id: slot ID
:param slot_number: slot number
:param adapter: device to add in the corresponding slot
"""
try:
slot = self._slots[slot_id]
slot = self._slots[slot_number]
except IndexError:
raise DynamipsError('Slot {slot_id} does not exist on router "{name}"'.format(name=self._name, slot_id=slot_id))
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name, slot_number=slot_number))
if slot is not None:
current_adapter = slot
raise DynamipsError('Slot {slot_id} is already occupied by adapter {adapter} on router "{name}"'.format(name=self._name,
slot_id=slot_id,
raise DynamipsError('Slot {slot_number} is already occupied by adapter {adapter} on router "{name}"'.format(name=self._name,
slot_number=slot_number,
adapter=current_adapter))
is_running = yield from self.is_running()
@@ -1019,42 +1019,44 @@ class Router(BaseVM):
raise DynamipsError('Adapter {adapter} cannot be added while router "{name}" is running'.format(adapter=adapter,
name=self._name))
yield from self._hypervisor.send('vm slot_add_binding "{name}" {slot_id} 0 {adapter}'.format(name=self._name,
slot_id=slot_id,
adapter=adapter))
yield from self._hypervisor.send('vm slot_add_binding "{name}" {slot_number} 0 {adapter}'.format(name=self._name,
slot_number=slot_number,
adapter=adapter))
log.info('Router "{name}" [{id}]: adapter {adapter} inserted into slot {slot_id}'.format(name=self._name,
id=self._id,
adapter=adapter,
slot_id=slot_id))
log.info('Router "{name}" [{id}]: adapter {adapter} inserted into slot {slot_number}'.format(name=self._name,
id=self._id,
adapter=adapter,
slot_number=slot_number))
self._slots[slot_id] = adapter
self._slots[slot_number] = adapter
# Generate an OIR event if the router is running
if is_running:
yield from self._hypervisor.send('vm slot_oir_start "{name}" {slot_id} 0'.format(name=self._name, slot_id=slot_id))
yield from self._hypervisor.send('vm slot_oir_start "{name}" {slot_number} 0'.format(name=self._name,
slot_number=slot_number))
log.info('Router "{name}" [{id}]: OIR start event sent to slot {slot_id}'.format(name=self._name,
id=self._id,
slot_id=slot_id))
log.info('Router "{name}" [{id}]: OIR start event sent to slot {slot_number}'.format(name=self._name,
id=self._id,
slot_number=slot_number))
@asyncio.coroutine
def slot_remove_binding(self, slot_id):
def slot_remove_binding(self, slot_number):
"""
Removes a slot binding (a module from a slot).
:param slot_id: slot ID
:param slot_number: slot number
"""
try:
adapter = self._slots[slot_id]
adapter = self._slots[slot_number]
except IndexError:
raise DynamipsError('Slot {slot_id} does not exist on router "{name}"'.format(name=self._name, slot_id=slot_id))
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if adapter is None:
raise DynamipsError('No adapter in slot {slot_id} on router "{name}"'.format(name=self._name,
slot_id=slot_id))
raise DynamipsError('No adapter in slot {slot_number} on router "{name}"'.format(name=self._name,
slot_number=slot_number))
is_running = yield from self.is_running()
@@ -1068,239 +1070,245 @@ class Router(BaseVM):
# Generate an OIR event if the router is running
if is_running:
yield from self._hypervisor.send('vm slot_oir_stop "{name}" {slot_id} 0'.format(name=self._name, slot_id=slot_id))
yield from self._hypervisor.send('vm slot_oir_stop "{name}" {slot_number} 0'.format(name=self._name,
slot_number=slot_number))
log.info('Router "{name}" [{id}]: OIR stop event sent to slot {slot_id}'.format(name=self._name,
log.info('Router "{name}" [{id}]: OIR stop event sent to slot {slot_number}'.format(name=self._name,
id=self._id,
slot_id=slot_id))
slot_number=slot_number))
yield from self._hypervisor.send('vm slot_remove_binding "{name}" {slot_id} 0'.format(name=self._name, slot_id=slot_id))
yield from self._hypervisor.send('vm slot_remove_binding "{name}" {slot_number} 0'.format(name=self._name,
slot_number=slot_number))
log.info('Router "{name}" [{id}]: adapter {adapter} removed from slot {slot_id}'.format(name=self._name,
log.info('Router "{name}" [{id}]: adapter {adapter} removed from slot {slot_number}'.format(name=self._name,
id=self._id,
adapter=adapter,
slot_id=slot_id))
self._slots[slot_id] = None
slot_number=slot_number))
self._slots[slot_number] = None
@asyncio.coroutine
def install_wic(self, wic_slot_id, wic):
def install_wic(self, wic_slot_number, wic):
"""
Installs a WIC adapter into this router.
:param wic_slot_id: WIC slot ID
:param wic_slot_number: WIC slot number
:param wic: WIC to be installed
"""
# WICs are always installed on adapters in slot 0
slot_id = 0
slot_number = 0
# Do not check if slot has an adapter because adapters with WICs interfaces
# must be inserted by default in the router and cannot be removed.
adapter = self._slots[slot_id]
adapter = self._slots[slot_number]
if wic_slot_id > len(adapter.wics) - 1:
raise DynamipsError("WIC slot {wic_slot_id} doesn't exist".format(wic_slot_id=wic_slot_id))
if wic_slot_number > len(adapter.wics) - 1:
raise DynamipsError("WIC slot {wic_slot_number} doesn't exist".format(wic_slot_number=wic_slot_number))
if not adapter.wic_slot_available(wic_slot_id):
raise DynamipsError("WIC slot {wic_slot_id} is already occupied by another WIC".format(wic_slot_id=wic_slot_id))
if not adapter.wic_slot_available(wic_slot_number):
raise DynamipsError("WIC slot {wic_slot_number} is already occupied by another WIC".format(wic_slot_number=wic_slot_number))
# Dynamips WICs slot IDs start on a multiple of 16
# WIC1 = 16, WIC2 = 32 and WIC3 = 48
internal_wic_slot_id = 16 * (wic_slot_id + 1)
yield from self._hypervisor.send('vm slot_add_binding "{name}" {slot_id} {wic_slot_id} {wic}'.format(name=self._name,
slot_id=slot_id,
wic_slot_id=internal_wic_slot_id,
internal_wic_slot_number = 16 * (wic_slot_number + 1)
yield from self._hypervisor.send('vm slot_add_binding "{name}" {slot_number} {wic_slot_number} {wic}'.format(name=self._name,
slot_number=slot_number,
wic_slot_number=internal_wic_slot_number,
wic=wic))
log.info('Router "{name}" [{id}]: {wic} inserted into WIC slot {wic_slot_id}'.format(name=self._name,
log.info('Router "{name}" [{id}]: {wic} inserted into WIC slot {wic_slot_number}'.format(name=self._name,
id=self._id,
wic=wic,
wic_slot_id=wic_slot_id))
wic_slot_number=wic_slot_number))
adapter.install_wic(wic_slot_id, wic)
adapter.install_wic(wic_slot_number, wic)
@asyncio.coroutine
def uninstall_wic(self, wic_slot_id):
def uninstall_wic(self, wic_slot_number):
"""
Uninstalls a WIC adapter from this router.
:param wic_slot_id: WIC slot ID
:param wic_slot_number: WIC slot number
"""
# WICs are always installed on adapters in slot 0
slot_id = 0
slot_number = 0
# Do not check if slot has an adapter because adapters with WICs interfaces
# must be inserted by default in the router and cannot be removed.
adapter = self._slots[slot_id]
adapter = self._slots[slot_number]
if wic_slot_id > len(adapter.wics) - 1:
raise DynamipsError("WIC slot {wic_slot_id} doesn't exist".format(wic_slot_id=wic_slot_id))
if wic_slot_number > len(adapter.wics) - 1:
raise DynamipsError("WIC slot {wic_slot_number} doesn't exist".format(wic_slot_number=wic_slot_number))
if adapter.wic_slot_available(wic_slot_id):
raise DynamipsError("No WIC is installed in WIC slot {wic_slot_id}".format(wic_slot_id=wic_slot_id))
if adapter.wic_slot_available(wic_slot_number):
raise DynamipsError("No WIC is installed in WIC slot {wic_slot_number}".format(wic_slot_number=wic_slot_number))
# Dynamips WICs slot IDs start on a multiple of 16
# WIC1 = 16, WIC2 = 32 and WIC3 = 48
internal_wic_slot_id = 16 * (wic_slot_id + 1)
yield from self._hypervisor.send('vm slot_remove_binding "{name}" {slot_id} {wic_slot_id}'.format(name=self._name,
slot_id=slot_id,
wic_slot_id=internal_wic_slot_id))
internal_wic_slot_number = 16 * (wic_slot_number + 1)
yield from self._hypervisor.send('vm slot_remove_binding "{name}" {slot_number} {wic_slot_number}'.format(name=self._name,
slot_number=slot_number,
wic_slot_number=internal_wic_slot_number))
log.info('Router "{name}" [{id}]: {wic} removed from WIC slot {wic_slot_id}'.format(name=self._name,
id=self._id,
wic=adapter.wics[wic_slot_id],
wic_slot_id=wic_slot_id))
adapter.uninstall_wic(wic_slot_id)
log.info('Router "{name}" [{id}]: {wic} removed from WIC slot {wic_slot_number}'.format(name=self._name,
id=self._id,
wic=adapter.wics[wic_slot_number],
wic_slot_number=wic_slot_number))
adapter.uninstall_wic(wic_slot_number)
@asyncio.coroutine
def get_slot_nio_bindings(self, slot_id):
def get_slot_nio_bindings(self, slot_number):
"""
Returns slot NIO bindings.
:param slot_id: slot ID
:param slot_number: slot number
:returns: list of NIO bindings
"""
nio_bindings = yield from self._hypervisor.send('vm slot_nio_bindings "{name}" {slot_id}'.format(name=self._name,
slot_id=slot_id))
nio_bindings = yield from self._hypervisor.send('vm slot_nio_bindings "{name}" {slot_number}'.format(name=self._name,
slot_number=slot_number))
return nio_bindings
@asyncio.coroutine
def slot_add_nio_binding(self, slot_id, port_id, nio):
def slot_add_nio_binding(self, slot_number, port_number, nio):
"""
Adds a slot NIO binding.
:param slot_id: slot ID
:param port_id: port ID
:param slot_number: slot number
:param port_number: port number
:param nio: NIO instance to add to the slot/port
"""
try:
adapter = self._slots[slot_id]
adapter = self._slots[slot_number]
except IndexError:
raise DynamipsError('Slot {slot_id} does not exist on router "{name}"'.format(name=self._name,
slot_id=slot_id))
if not adapter.port_exists(port_id):
raise DynamipsError("Port {port_id} does not exist in adapter {adapter}".format(adapter=adapter,
port_id=port_id))
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
port_number=port_number))
yield from self._hypervisor.send('vm slot_add_nio_binding "{name}" {slot_id} {port_id} {nio}'.format(name=self._name,
slot_id=slot_id,
port_id=port_id,
nio=nio))
yield from self._hypervisor.send('vm slot_add_nio_binding "{name}" {slot_number} {port_number} {nio}'.format(name=self._name,
slot_number=slot_number,
port_number=port_number,
nio=nio))
log.info('Router "{name}" [{id}]: NIO {nio_name} bound to port {slot_id}/{port_id}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_id=slot_id,
port_id=port_id))
log.info('Router "{name}" [{id}]: NIO {nio_name} bound to port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_number=slot_number,
port_number=port_number))
yield from self.slot_enable_nio(slot_id, port_id)
adapter.add_nio(port_id, nio)
yield from self.slot_enable_nio(slot_number, port_number)
adapter.add_nio(port_number, nio)
@asyncio.coroutine
def slot_remove_nio_binding(self, slot_id, port_id):
def slot_remove_nio_binding(self, slot_number, port_number):
"""
Removes a slot NIO binding.
:param slot_id: slot ID
:param port_id: port ID
:param slot_number: slot number
:param port_number: port number
:returns: removed NIO instance
"""
try:
adapter = self._slots[slot_id]
adapter = self._slots[slot_number]
except IndexError:
raise DynamipsError('Slot {slot_id} does not exist on router "{name}"'.format(name=self._name, slot_id=slot_id))
if not adapter.port_exists(port_id):
raise DynamipsError("Port {port_id} does not exist in adapter {adapter}".format(adapter=adapter, port_id=port_id))
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
port_number=port_number))
yield from self.slot_disable_nio(slot_id, port_id)
yield from self._hypervisor.send('vm slot_remove_nio_binding "{name}" {slot_id} {port_id}'.format(name=self._name,
slot_id=slot_id,
port_id=port_id))
yield from self.slot_disable_nio(slot_number, port_number)
yield from self._hypervisor.send('vm slot_remove_nio_binding "{name}" {slot_number} {port_number}'.format(name=self._name,
slot_number=slot_number,
port_number=port_number))
nio = adapter.get_nio(port_id)
adapter.remove_nio(port_id)
nio = adapter.get_nio(port_number)
adapter.remove_nio(port_number)
log.info('Router "{name}" [{id}]: NIO {nio_name} removed from port {slot_id}/{port_id}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_id=slot_id,
port_id=port_id))
log.info('Router "{name}" [{id}]: NIO {nio_name} removed from port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_number=slot_number,
port_number=port_number))
return nio
@asyncio.coroutine
def slot_enable_nio(self, slot_id, port_id):
def slot_enable_nio(self, slot_number, port_number):
"""
Enables a slot NIO binding.
:param slot_id: slot ID
:param port_id: port ID
:param slot_number: slot number
:param port_number: port number
"""
is_running = yield from self.is_running()
if is_running: # running router
yield from self._hypervisor.send('vm slot_enable_nio "{name}" {slot_id} {port_id}'.format(name=self._name,
slot_id=slot_id,
port_id=port_id))
yield from self._hypervisor.send('vm slot_enable_nio "{name}" {slot_number} {port_number}'.format(name=self._name,
slot_number=slot_number,
port_number=port_number))
log.info('Router "{name}" [{id}]: NIO enabled on port {slot_id}/{port_id}'.format(name=self._name,
id=self._id,
slot_id=slot_id,
port_id=port_id))
log.info('Router "{name}" [{id}]: NIO enabled on port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,
slot_number=slot_number,
port_number=port_number))
@asyncio.coroutine
def slot_disable_nio(self, slot_id, port_id):
def slot_disable_nio(self, slot_number, port_number):
"""
Disables a slot NIO binding.
:param slot_id: slot ID
:param port_id: port ID
:param slot_number: slot number
:param port_number: port number
"""
is_running = yield from self.is_running()
if is_running: # running router
yield from self._hypervisor.send('vm slot_disable_nio "{name}" {slot_id} {port_id}'.format(name=self._name,
slot_id=slot_id,
port_id=port_id))
yield from self._hypervisor.send('vm slot_disable_nio "{name}" {slot_number} {port_number}'.format(name=self._name,
slot_number=slot_number,
port_number=port_number))
log.info('Router "{name}" [{id}]: NIO disabled on port {slot_id}/{port_id}'.format(name=self._name,
id=self._id,
slot_id=slot_id,
port_id=port_id))
log.info('Router "{name}" [{id}]: NIO disabled on port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,
slot_number=slot_number,
port_number=port_number))
@asyncio.coroutine
def start_capture(self, slot_id, port_id, output_file, data_link_type="DLT_EN10MB"):
def start_capture(self, slot_number, port_number, output_file, data_link_type="DLT_EN10MB"):
"""
Starts a packet capture.
:param slot_id: slot ID
:param port_id: port ID
:param slot_number: slot number
:param port_number: port number
:param output_file: PCAP destination file for the capture
:param data_link_type: PCAP data link type (DLT_*), default is DLT_EN10MB
"""
try:
adapter = self._slots[slot_id]
adapter = self._slots[slot_number]
except IndexError:
raise DynamipsError('Slot {slot_id} does not exist on router "{name}"'.format(name=self._name, slot_id=slot_id))
if not adapter.port_exists(port_id):
raise DynamipsError("Port {port_id} does not exist in adapter {adapter}".format(adapter=adapter, port_id=port_id))
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
port_number=port_number))
data_link_type = data_link_type.lower()
if data_link_type.startswith("dlt_"):
data_link_type = data_link_type[4:]
nio = adapter.get_nio(port_id)
nio = adapter.get_nio(port_number)
if nio.input_filter[0] is not None and nio.output_filter[0] is not None:
raise DynamipsError("Port {port_id} has already a filter applied on {adapter}".format(adapter=adapter,
port_id=port_id))
raise DynamipsError("Port {port_number} has already a filter applied on {adapter}".format(adapter=adapter,
port_number=port_number))
# FIXME: capture
# try:
@@ -1311,36 +1319,38 @@ class Router(BaseVM):
yield from nio.bind_filter("both", "capture")
yield from nio.setup_filter("both", '{} "{}"'.format(data_link_type, output_file))
log.info('Router "{name}" [{id}]: starting packet capture on port {slot_id}/{port_id}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_id=slot_id,
port_id=port_id))
log.info('Router "{name}" [{id}]: starting packet capture on port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_number=slot_number,
port_number=port_number))
@asyncio.coroutine
def stop_capture(self, slot_id, port_id):
def stop_capture(self, slot_number, port_number):
"""
Stops a packet capture.
:param slot_id: slot ID
:param port_id: port ID
:param slot_number: slot number
:param port_number: port number
"""
try:
adapter = self._slots[slot_id]
adapter = self._slots[slot_number]
except IndexError:
raise DynamipsError('Slot {slot_id} does not exist on router "{name}"'.format(name=self._name, slot_id=slot_id))
if not adapter.port_exists(port_id):
raise DynamipsError("Port {port_id} does not exist in adapter {adapter}".format(adapter=adapter, port_id=port_id))
raise DynamipsError('Slot {slot_number} does not exist on router "{name}"'.format(name=self._name,
slot_number=slot_number))
if not adapter.port_exists(port_number):
raise DynamipsError("Port {port_number} does not exist in adapter {adapter}".format(adapter=adapter,
port_number=port_number))
nio = adapter.get_nio(port_id)
nio = adapter.get_nio(port_number)
yield from nio.unbind_filter("both")
log.info('Router "{name}" [{id}]: stopping packet capture on port {slot_id}/{port_id}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_id=slot_id,
port_id=port_id))
log.info('Router "{name}" [{id}]: stopping packet capture on port {slot_number}/{port_number}'.format(name=self._name,
id=self._id,
nio_name=nio.name,
slot_number=slot_number,
port_number=port_number))
def _create_slots(self, numslots):
"""