Merge pull request #1116 from GNS3/dynamips_ubridge

Use ubridge for dynamips routers
This commit is contained in:
Jeremy Grossmann 2017-07-11 12:37:20 +07:00 committed by GitHub
commit fcd7dfbde6
11 changed files with 64 additions and 24 deletions

View File

@ -475,7 +475,7 @@ class BaseNode:
""" """
Returns the uBridge hypervisor. Returns the uBridge hypervisor.
:returns: path to uBridge :returns: instance of uBridge
""" """
if self._ubridge_hypervisor and not self._ubridge_hypervisor.is_running(): if self._ubridge_hypervisor and not self._ubridge_hypervisor.is_running():
@ -512,6 +512,8 @@ class BaseNode:
:param command: command to send :param command: command to send
""" """
if not self._ubridge_hypervisor or not self._ubridge_hypervisor.is_running():
yield from self._start_ubridge()
if not self._ubridge_hypervisor or not self._ubridge_hypervisor.is_running(): if not self._ubridge_hypervisor or not self._ubridge_hypervisor.is_running():
raise NodeError("Cannot send command '{}': uBridge is not running".format(command)) raise NodeError("Cannot send command '{}': uBridge is not running".format(command))
try: try:
@ -557,7 +559,7 @@ class BaseNode:
self._ubridge_hypervisor = None self._ubridge_hypervisor = None
@asyncio.coroutine @asyncio.coroutine
def _add_ubridge_udp_connection(self, bridge_name, source_nio, destination_nio): def add_ubridge_udp_connection(self, bridge_name, source_nio, destination_nio):
""" """
Creates an UDP connection in uBridge. Creates an UDP connection in uBridge.

View File

@ -351,7 +351,7 @@ class Dynamips(BaseManager):
sock.connect(sa) sock.connect(sa)
except OSError as e: except OSError as e:
raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e)) raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
nio = NIOUDP(node.hypervisor, lport, rhost, rport) nio = NIOUDP(node, lport, rhost, rport, nio_settings.get("filters", {}))
elif nio_settings["type"] == "nio_generic_ethernet": elif nio_settings["type"] == "nio_generic_ethernet":
ethernet_device = nio_settings["ethernet_device"] ethernet_device = nio_settings["ethernet_device"]
if sys.platform.startswith("win"): if sys.platform.startswith("win"):

View File

@ -21,8 +21,11 @@ Interface for UDP NIOs.
import asyncio import asyncio
import uuid import uuid
from gns3server.compute.nios import nio_udp
from .nio import NIO from .nio import NIO
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -38,28 +41,61 @@ class NIOUDP(NIO):
:param rport: remote port number :param rport: remote port number
""" """
def __init__(self, hypervisor, lport, rhost, rport): def __init__(self, node, lport, rhost, rport, filters):
# create an unique name # create an unique name
name = 'udp-{}'.format(uuid.uuid4()) name = 'udp-{}'.format(uuid.uuid4())
self._lport = lport self._lport = lport
self._rhost = rhost self._rhost = rhost
self._rport = rport self._rport = rport
super().__init__(name, hypervisor) self._filters = filters
self._local_tunnel_lport = None
self._local_tunnel_rport = None
self._node = node
super().__init__(name, node.hypervisor)
@asyncio.coroutine @asyncio.coroutine
def create(self): def create(self):
if not self._hypervisor: if not self._hypervisor:
return return
# Ubridge is not supported
if not hasattr(self._node, "add_ubridge_udp_connection"):
yield from self._hypervisor.send("nio create_udp {name} {lport} {rhost} {rport}".format(name=self._name, yield from self._hypervisor.send("nio create_udp {name} {lport} {rhost} {rport}".format(name=self._name,
lport=self._lport, lport=self._lport,
rhost=self._rhost, rhost=self._rhost,
rport=self._rport)) rport=self._rport))
return
self._local_tunnel_lport = self._node.manager.port_manager.get_free_udp_port(self._node.project)
self._local_tunnel_rport = self._node.manager.port_manager.get_free_udp_port(self._node.project)
name = 'DYNAMIPS-{}-{}'.format(self._local_tunnel_lport, self._local_tunnel_rport)
yield from self._hypervisor.send("nio create_udp {name} {lport} {rhost} {rport}".format(name=self._name,
lport=self._local_tunnel_lport,
rhost='127.0.0.1',
rport=self._local_tunnel_rport))
log.info("NIO UDP {name} created with lport={lport}, rhost={rhost}, rport={rport}".format(name=self._name, log.info("NIO UDP {name} created with lport={lport}, rhost={rhost}, rport={rport}".format(name=self._name,
lport=self._lport, lport=self._lport,
rhost=self._rhost, rhost=self._rhost,
rport=self._rport)) rport=self._rport))
yield from self._node.add_ubridge_udp_connection(
name,
nio_udp.NIOUDP(self._local_tunnel_rport,
'127.0.0.1',
self._local_tunnel_lport,
self._filters),
nio_udp.NIOUDP(self._lport,
self._rhost,
self._rport,
self._filters)
)
@asyncio.coroutine
def close(self):
if self._local_tunnel_lport:
self._node.manager.port_manager.release_udp_port(self._local_tunnel_lport, self ._node.project)
if self._local_tunnel_rport:
self._node.manager.port_manager.release_udp_port(self._local_tunnel_rport, self._node.project)
self._node.manager.port_manager.release_udp_port(self._lport, self._node.project)
@property @property
def lport(self): def lport(self):

View File

@ -122,8 +122,8 @@ class ATMSwitch(Device):
@asyncio.coroutine @asyncio.coroutine
def close(self): def close(self):
for nio in self._nios.values(): for nio in self._nios.values():
if nio and isinstance(nio, NIOUDP): if nio:
self.manager.port_manager.release_udp_port(nio.lport, self._project) yield from nio.close()
if self._hypervisor: if self._hypervisor:
try: try:

View File

@ -120,8 +120,8 @@ class EthernetHub(Bridge):
""" """
for nio in self._nios: for nio in self._nios:
if nio and isinstance(nio, NIOUDP): if nio:
self.manager.port_manager.release_udp_port(nio.lport, self._project) yield from nio.close()
try: try:
yield from Bridge.delete(self) yield from Bridge.delete(self)

View File

@ -216,8 +216,8 @@ class EthernetSwitch(Device):
""" """
for nio in self._nios.values(): for nio in self._nios.values():
if nio and isinstance(nio, NIOUDP): if nio:
self.manager.port_manager.release_udp_port(nio.lport, self._project) yield from nio.close()
self.manager.port_manager.release_tcp_port(self._console, self._project) self.manager.port_manager.release_tcp_port(self._console, self._project)
if self._hypervisor: if self._hypervisor:
try: try:

View File

@ -121,8 +121,8 @@ class FrameRelaySwitch(Device):
@asyncio.coroutine @asyncio.coroutine
def close(self): def close(self):
for nio in self._nios.values(): for nio in self._nios.values():
if nio and isinstance(nio, NIOUDP): if nio:
self.manager.port_manager.release_udp_port(nio.lport, self._project) yield from nio.close()
if self._hypervisor: if self._hypervisor:
try: try:

View File

@ -388,8 +388,10 @@ class Router(BaseNode):
for adapter in self._slots: for adapter in self._slots:
if adapter is not None: if adapter is not None:
for nio in adapter.ports.values(): for nio in adapter.ports.values():
if nio and isinstance(nio, NIOUDP): if nio:
self.manager.port_manager.release_udp_port(nio.lport, self._project) yield from nio.close()
yield from self._stop_ubridge()
if self in self._hypervisor.devices: if self in self._hypervisor.devices:
self._hypervisor.devices.remove(self) self._hypervisor.devices.remove(self)

View File

@ -912,7 +912,7 @@ class QemuVM(BaseNode):
for adapter_number, adapter in enumerate(self._ethernet_adapters): for adapter_number, adapter in enumerate(self._ethernet_adapters):
nio = adapter.get_nio(0) nio = adapter.get_nio(0)
if nio: if nio:
yield from self._add_ubridge_udp_connection("QEMU-{}-{}".format(self._id, adapter_number), yield from self.add_ubridge_udp_connection("QEMU-{}-{}".format(self._id, adapter_number),
self._local_udp_tunnels[adapter_number][1], self._local_udp_tunnels[adapter_number][1],
nio) nio)
@ -1133,7 +1133,7 @@ class QemuVM(BaseNode):
if self.ubridge: if self.ubridge:
try: try:
yield from self._add_ubridge_udp_connection("QEMU-{}-{}".format(self._id, adapter_number), yield from self.add_ubridge_udp_connection("QEMU-{}-{}".format(self._id, adapter_number),
self._local_udp_tunnels[adapter_number][1], self._local_udp_tunnels[adapter_number][1],
nio) nio)
except IndexError: except IndexError:

View File

@ -285,7 +285,7 @@ class VirtualBoxVM(BaseNode):
for adapter_number in range(0, self._adapters): for adapter_number in range(0, self._adapters):
nio = self._ethernet_adapters[adapter_number].get_nio(0) nio = self._ethernet_adapters[adapter_number].get_nio(0)
if nio: if nio:
yield from self._add_ubridge_udp_connection("VBOX-{}-{}".format(self._id, adapter_number), yield from self.add_ubridge_udp_connection("VBOX-{}-{}".format(self._id, adapter_number),
self._local_udp_tunnels[adapter_number][1], self._local_udp_tunnels[adapter_number][1],
nio) nio)
@ -974,7 +974,7 @@ class VirtualBoxVM(BaseNode):
if self.ubridge: if self.ubridge:
try: try:
yield from self._add_ubridge_udp_connection("VBOX-{}-{}".format(self._id, adapter_number), yield from self.add_ubridge_udp_connection("VBOX-{}-{}".format(self._id, adapter_number),
self._local_udp_tunnels[adapter_number][1], self._local_udp_tunnels[adapter_number][1],
nio) nio)
except KeyError: except KeyError:

View File

@ -264,7 +264,7 @@ class VPCSVM(BaseNode):
if self.use_ubridge: if self.use_ubridge:
yield from self._start_ubridge() yield from self._start_ubridge()
if nio: if nio:
yield from self._add_ubridge_udp_connection("VPCS-{}".format(self._id), self._local_udp_tunnel[1], nio) yield from self.add_ubridge_udp_connection("VPCS-{}".format(self._id), self._local_udp_tunnel[1], nio)
yield from self.start_wrap_console() yield from self.start_wrap_console()
@ -379,7 +379,7 @@ class VPCSVM(BaseNode):
port_number=port_number)) port_number=port_number))
if self.ubridge: if self.ubridge:
yield from self._add_ubridge_udp_connection("VPCS-{}".format(self._id), self._local_udp_tunnel[1], nio) yield from self.add_ubridge_udp_connection("VPCS-{}".format(self._id), self._local_udp_tunnel[1], nio)
elif self.is_running(): elif self.is_running():
raise VPCSError("Sorry, updating a link to a started VPCS instance is not supported without using uBridge.") raise VPCSError("Sorry, updating a link to a started VPCS instance is not supported without using uBridge.")