From 16f472da124080c8190ce28bd0385ea7d1a6ee23 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Fri, 18 Jun 2021 17:17:12 +0900 Subject: [PATCH] Explicitly support DHCP + add tests + update libslirp to v4.6.1 Close issue 124 The test should pass with libslirp < 4.6.0 and libslirp >= 4.6.1, but should fail with libslirp == 4.6.0 . https://gitlab.freedesktop.org/slirp/libslirp/-/issues/48 Signed-off-by: Akihiro Suda --- .github/workflows/main.yaml | 4 ++-- Dockerfile.artifact | 2 +- Dockerfile.buildtests | 2 +- Dockerfile.tests | 4 ++-- Makefile.am | 2 +- Vagrantfile | 2 ++ main.c | 9 +++++++++ slirp4netns.1 | 6 +++++- slirp4netns.1.md | 4 +++- tests/common.sh | 3 +++ tests/test-slirp4netns-dhcp.sh | 35 ++++++++++++++++++++++++++++++++++ 11 files changed, 64 insertions(+), 9 deletions(-) create mode 100755 tests/test-slirp4netns-dhcp.sh diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 6522075..0a7529e 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - libslirp_commit: [master, v4.6.0, v4.5.0, v4.1.0] + libslirp_commit: [master, v4.6.1, v4.5.0, v4.1.0] steps: - uses: actions/checkout@v2 - run: docker build -t slirp4netns-tests --build-arg LIBSLIRP_COMMIT -f Dockerfile.tests . @@ -47,7 +47,7 @@ jobs: run: sh ./run-vagrant-tests env: LIBSECCOMP_COMMIT: v2.5.0 - LIBSLIRP_COMMIT: v4.6.0 + LIBSLIRP_COMMIT: v4.6.1 artifact: runs-on: ubuntu-20.04 steps: diff --git a/Dockerfile.artifact b/Dockerfile.artifact index e742778..49b8e9b 100644 --- a/Dockerfile.artifact +++ b/Dockerfile.artifact @@ -1,4 +1,4 @@ -ARG LIBSLIRP_COMMIT=v4.6.0 +ARG LIBSLIRP_COMMIT=v4.6.1 ARG DEBIAN_VERSION=10 FROM --platform=$TARGETPLATFORM debian:${DEBIAN_VERSION} AS build diff --git a/Dockerfile.buildtests b/Dockerfile.buildtests index c0db007..4873e7d 100644 --- a/Dockerfile.buildtests +++ b/Dockerfile.buildtests @@ -1,4 +1,4 @@ -ARG LIBSLIRP_COMMIT=v4.6.0 +ARG LIBSLIRP_COMMIT=v4.6.1 # Alpine FROM alpine:3 AS buildtest-alpine3-static diff --git a/Dockerfile.tests b/Dockerfile.tests index 329896d..1b5ed2e 100644 --- a/Dockerfile.tests +++ b/Dockerfile.tests @@ -1,4 +1,4 @@ -ARG LIBSLIRP_COMMIT=v4.6.0 +ARG LIBSLIRP_COMMIT=v4.6.1 FROM ubuntu:20.04 AS build ENV DEBIAN_FRONTEND=noninteractive @@ -16,6 +16,6 @@ RUN ./autogen.sh && ./configure && make -j $(nproc) FROM build AS test USER 0 -RUN apt update && apt install -y git libtool iproute2 clang clang-format clang-tidy iputils-ping iperf3 ncat jq +RUN apt update && apt install -y git libtool iproute2 clang clang-format clang-tidy iputils-ping iperf3 ncat jq udhcpc USER 1000:1000 CMD ["make", "ci"] diff --git a/Makefile.am b/Makefile.am index c15a579..45609ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ AM_CFLAGS = @GLIB_CFLAGS@ @SLIRP_CFLAGS@ @LIBCAP_CFLAGS@ @LIBSECCOMP_CFLAGS@ noinst_LIBRARIES = libparson.a AM_TESTS_ENVIRONMENT = PATH="$(abs_top_builddir):$(PATH)" -TESTS = tests/test-slirp4netns.sh tests/test-slirp4netns-configure.sh tests/test-slirp4netns-exit-fd.sh tests/test-slirp4netns-ready-fd.sh tests/test-slirp4netns-api-socket.sh tests/test-slirp4netns-disable-host-loopback.sh tests/test-slirp4netns-cidr.sh tests/test-slirp4netns-outbound-addr.sh tests/test-slirp4netns-disable-dns.sh tests/test-slirp4netns-seccomp.sh tests/test-slirp4netns-macaddress.sh +TESTS = tests/test-slirp4netns.sh tests/test-slirp4netns-configure.sh tests/test-slirp4netns-exit-fd.sh tests/test-slirp4netns-ready-fd.sh tests/test-slirp4netns-api-socket.sh tests/test-slirp4netns-disable-host-loopback.sh tests/test-slirp4netns-cidr.sh tests/test-slirp4netns-outbound-addr.sh tests/test-slirp4netns-disable-dns.sh tests/test-slirp4netns-seccomp.sh tests/test-slirp4netns-macaddress.sh tests/test-slirp4netns-dhcp.sh EXTRA_DIST = \ slirp4netns.1.md \ diff --git a/Vagrantfile b/Vagrantfile index 39679cd..9a4c089 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -23,6 +23,8 @@ Vagrant.configure("2") do |config| glib2-devel libcap-devel \ git-core libtool iproute iputils iperf3 nmap jq + # TODO: install udhcpc (required by test-slirp4netns-dhcp.sh) + cd /src chown vagrant . diff --git a/main.c b/main.c index 1844c59..f2dcb9c 100644 --- a/main.c +++ b/main.c @@ -266,6 +266,13 @@ static int parent(int sock, int ready_fd, int exit_fd, const char *api_socket, struct slirp4netns_config *cfg, pid_t target_pid) { int rc, tapfd; + struct in_addr vdhcp_end = { +#define NB_BOOTP_CLIENTS 16 + /* NB_BOOTP_CLIENTS is hard-coded to 16 in libslirp: + https://gitlab.freedesktop.org/slirp/libslirp/-/issues/49 */ + .s_addr = htonl(ntohl(cfg->vdhcp_start.s_addr) + NB_BOOTP_CLIENTS - 1), +#undef NB_BOOTP_CLIENTS + }; if ((tapfd = recvfd(sock)) < 0) { return tapfd; } @@ -277,6 +284,8 @@ static int parent(int sock, int ready_fd, int exit_fd, const char *api_socket, printf("* Netmask: %s\n", inet_ntoa(cfg->vnetmask)); printf("* Gateway: %s\n", inet_ntoa(cfg->vhost)); printf("* DNS: %s\n", inet_ntoa(cfg->vnameserver)); + printf("* DHCP begin: %s\n", inet_ntoa(cfg->vdhcp_start)); + printf("* DHCP end: %s\n", inet_ntoa(vdhcp_end)); printf("* Recommended IP: %s\n", inet_ntoa(cfg->recommended_vguest)); if (api_socket != NULL) { printf("* API Socket: %s\n", api_socket); diff --git a/slirp4netns.1 b/slirp4netns.1 index 235dce0..b72bfe4 100644 --- a/slirp4netns.1 +++ b/slirp4netns.1 @@ -1,5 +1,5 @@ .nh -.TH SLIRP4NETNS 1 "November 2020" "Rootless Containers" "User Commands" +.TH SLIRP4NETNS 1 "June 2021" "Rootless Containers" "User Commands" .SH NAME .PP @@ -31,6 +31,10 @@ Gateway/Host: 10.0.2.2 (network address + 2) .IP \(bu 2 DNS: 10.0.2.3 (network address + 3) .IP \(bu 2 +DHCP begin: 10.0.2.15 (network address + 15) +.IP \(bu 2 +DHCP end: 10.0.2.30 (network address + 30) +.IP \(bu 2 IPv6 CIDR: fd00::/64 .IP \(bu 2 IPv6 Gateway/Host: fd00::2 diff --git a/slirp4netns.1.md b/slirp4netns.1.md index ed34e5e..f60b6b7 100644 --- a/slirp4netns.1.md +++ b/slirp4netns.1.md @@ -1,4 +1,4 @@ -SLIRP4NETNS 1 "November 2020" "Rootless Containers" "User Commands" +SLIRP4NETNS 1 "June 2021" "Rootless Containers" "User Commands" ================================================== # NAME @@ -21,6 +21,8 @@ Default configuration: * CIDR: 10.0.2.0/24 * Gateway/Host: 10.0.2.2 (network address + 2) * DNS: 10.0.2.3 (network address + 3) +* DHCP begin: 10.0.2.15 (network address + 15) +* DHCP end: 10.0.2.30 (network address + 30) * IPv6 CIDR: fd00::/64 * IPv6 Gateway/Host: fd00::2 * IPv6 DNS: fd00::3 diff --git a/tests/common.sh b/tests/common.sh index 3ca220f..9cc225e 100755 --- a/tests/common.sh +++ b/tests/common.sh @@ -1,5 +1,8 @@ #!/bin/bash +# See https://www.gnu.org/software/automake/manual/html_node/Scripts_002dbased-Testsuites.html#Testsuite-progress-on-console +TEST_EXIT_CODE_SKIP=77 + function nsenter_flags { pid=$1 flags="--target=${pid}" diff --git a/tests/test-slirp4netns-dhcp.sh b/tests/test-slirp4netns-dhcp.sh new file mode 100755 index 0000000..ea03e3c --- /dev/null +++ b/tests/test-slirp4netns-dhcp.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# This test should pass with libslirp < 4.6.0 and libslirp >= 4.6.1, +# but should fail with libslirp == 4.6.0 . +# https://gitlab.freedesktop.org/slirp/libslirp/-/issues/48 + +set -xeuo pipefail + +. $(dirname $0)/common.sh + +if ! command -v udhcpc 2>&1; then + echo "udhcpc is missing, skipping the test" + exit "$TEST_EXIT_CODE_SKIP" +fi + +unshare -r -n sleep infinity & +child=$! + +wait_for_network_namespace $child + +slirp4netns $child tap0 & +slirp_pid=$! + +udhcpc_log=$(mktemp /tmp/slirp4netns-test-udhcpc.XXXXXXXXXX) + +function cleanup { + kill -9 $child $slirp_pid + rm -f $udhcpc_log +} +trap cleanup EXIT + +nsenter $(nsenter_flags $child) ip link set lo up +nsenter $(nsenter_flags $child) ip link set tap0 up +nsenter $(nsenter_flags $child) timeout 10s udhcpc -q -i tap0 -s /bin/true 2>&1 | tee $udhcpc_log +grep 10.0.2.15 $udhcpc_log