From ac1eef256fe2839815605809cbc2886e370de362 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 24 Oct 2016 12:35:50 +0200 Subject: [PATCH] Use tap adapter instead of veth for docker (allow usage of vlan) Ref #716 --- gns3server/compute/docker/docker_vm.py | 28 ++++++++++---------------- tests/compute/docker/test_docker_vm.py | 12 +++++------ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index abbd4598..ed4df187 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -639,35 +639,34 @@ class DockerVM(BaseNode): for index in range(4096): if "veth-gns3-e{}".format(index) not in psutil.net_if_addrs(): adapter.ifc = "eth{}".format(str(index)) - adapter.host_ifc = "veth-gns3-e{}".format(str(index)) - adapter.guest_ifc = "veth-gns3-i{}".format(str(index)) + adapter.host_ifc = "tap-gns3-e{}".format(str(index)) break if not hasattr(adapter, "ifc"): raise DockerError("Adapter {adapter_number} couldn't allocate interface on Docker container '{name}'. Too many Docker interfaces already exists".format(name=self.name, adapter_number=adapter_number)) - yield from self._ubridge_send('docker create_veth {hostif} {guestif}'.format(guestif=adapter.guest_ifc, hostif=adapter.host_ifc)) - - log.debug("Move container %s adapter %s to namespace %s", self.name, adapter.guest_ifc, namespace) + yield from self._ubridge_send('bridge create bridge{}'.format(adapter_number)) + yield from self._ubridge_send('bridge add_nio_tap bridge{adapter_number} {hostif}'.format(adapter_number=adapter_number, + hostif=adapter.host_ifc)) + log.debug("Move container %s adapter %s to namespace %s", self.name, adapter.host_ifc, namespace) try: - yield from self._ubridge_send('docker move_to_ns {ifc} {ns} eth{adapter}'.format(ifc=adapter.guest_ifc, + yield from self._ubridge_send('docker move_to_ns {ifc} {ns} eth{adapter}'.format(ifc=adapter.host_ifc, ns=namespace, adapter=adapter_number)) except UbridgeError as e: raise UbridgeNamespaceError(e) if isinstance(nio, NIOUDP): - yield from self._ubridge_send('bridge create bridge{}'.format(adapter_number)) - yield from self._ubridge_send('bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(ifc=adapter.host_ifc, adapter=adapter_number)) - yield from self._ubridge_send('bridge add_nio_udp bridge{adapter} {lport} {rhost} {rport}'.format(adapter=adapter_number, lport=nio.lport, rhost=nio.rhost, rport=nio.rport)) - if nio.capturing: - yield from self._ubridge_send('bridge start_capture bridge{adapter} "{pcap_file}"'.format(adapter=adapter_number, - pcap_file=nio.pcap_output_file)) + if nio and nio.capturing: + yield from self._ubridge_send('bridge start_capture bridge{adapter} "{pcap_file}"'.format(adapter=adapter_number, + pcap_file=nio.pcap_output_file)) + + if nio: yield from self._ubridge_send('bridge start bridge{adapter}'.format(adapter=adapter_number)) def _delete_ubridge_connection(self, adapter_number): @@ -678,15 +677,10 @@ class DockerVM(BaseNode): if not self.ubridge: return - adapter = self._ethernet_adapters[adapter_number] try: yield from self._ubridge_send("bridge delete bridge{name}".format(name=adapter_number)) except UbridgeError as e: log.debug(str(e)) - try: - yield from self._ubridge_send('docker delete_veth {hostif}'.format(hostif=adapter.host_ifc)) - except UbridgeError as e: - log.debug(str(e)) @asyncio.coroutine def _get_namespace(self): diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py index 97419c43..60d9e80c 100644 --- a/tests/compute/docker/test_docker_vm.py +++ b/tests/compute/docker/test_docker_vm.py @@ -693,10 +693,9 @@ def test_add_ubridge_connection(loop, vm): loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0, 42))) calls = [ - call.send("docker create_veth veth-gns3-e0 veth-gns3-i0"), - call.send('docker move_to_ns veth-gns3-i0 42 eth0'), call.send('bridge create bridge0'), - call.send('bridge add_nio_linux_raw bridge0 veth-gns3-e0'), + call.send("bridge add_nio_tap bridge0 tap-gns3-e0"), + call.send('docker move_to_ns tap-gns3-e0 42 eth0'), call.send('bridge add_nio_udp bridge0 4242 127.0.0.1 4343'), call.send('bridge start_capture bridge0 "/tmp/capture.pcap"'), call.send('bridge start bridge0') @@ -713,8 +712,10 @@ def test_add_ubridge_connection_none_nio(loop, vm): loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0, 42))) calls = [ - call.send("docker create_veth veth-gns3-e0 veth-gns3-i0"), - call.send('docker move_to_ns veth-gns3-i0 42 eth0'), + call.send('bridge create bridge0'), + call.send("bridge add_nio_tap bridge0 tap-gns3-e0"), + call.send('docker move_to_ns tap-gns3-e0 42 eth0'), + ] # We need to check any_order ortherwise mock is confused by asyncio vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True) @@ -761,7 +762,6 @@ def test_delete_ubridge_connection(loop, vm): calls = [ call.send("bridge delete bridge0"), - call.send('docker delete_veth veth-gns3-e0') ] vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)