From b1eb0984bc5c71e05329892e0976c8d013f2360c Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Tue, 29 Sep 2026 18:14:23 +0800 Subject: [PATCH] fix(docker): bring the veth host end up before a relay attach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unified veth host end is born admin-down (carrier off until a link attaches), and libpcap cannot open a packet socket on an admin-down interface — its netlink promiscuous-mode transaction returns ENOENT, so 'bridge add_nio_ethernet' failed on every runtime relay link (and would on any relay link at container start). Bring the interface up for the attach; the carrier pass in the caller refines the state afterwards (a suspended NIO sets it back down). Verified live with a direct uBridge probe: attach on a down veth -> ENOENT, after 'link set up' -> OK. --- gns3server/compute/docker/docker_vm.py | 7 +++++++ tests/compute/docker/test_docker_kernel_datapath.py | 3 +++ 2 files changed, 10 insertions(+) diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index 63ca5a089..2c95b23ee 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -1959,6 +1959,13 @@ class DockerVM(BaseNode): if host_ifc is not None and bridge_name not in self._bridges: await self._ubridge_send(f"bridge create {bridge_name}") self._bridges.add(bridge_name) + # libpcap cannot open a packet socket on an admin-down interface + # (its netlink promiscuous-mode transaction returns ENOENT), and + # the unified veth host end is born down (carrier off until a + # link attaches) — bring it up for the relay attach. The carrier + # pass in the caller refines the state afterwards (a suspended + # NIO sets it back down). + await self._ubridge_send(f'link set "{host_ifc}" up') await self._ubridge_send(f'bridge add_nio_ethernet {bridge_name} "{host_ifc}"') await self._ubridge_send( "bridge add_nio_udp {bridge_name} {lport} {rhost} {rport}".format( diff --git a/tests/compute/docker/test_docker_kernel_datapath.py b/tests/compute/docker/test_docker_kernel_datapath.py index a467a21c9..6cf1f2ca1 100644 --- a/tests/compute/docker/test_docker_kernel_datapath.py +++ b/tests/compute/docker/test_docker_kernel_datapath.py @@ -222,6 +222,9 @@ async def test_add_ubridge_connection_udp_relays_over_veth(vm): [ call.send(f'docker create_veth "{host_ifc}" "{vm._veth_names(0, 0)[1]}"'), call.send("bridge create bridge0"), + # the host end is born down; libpcap cannot attach to an + # admin-down interface, so the relay brings it up first + call.send(f'link set "{host_ifc}" up'), call.send(f'bridge add_nio_ethernet bridge0 "{host_ifc}"'), call.send("bridge add_nio_udp bridge0 4242 127.0.0.1 4343"), call.send("bridge start bridge0"),