mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
test: add the rtnetlink test suit
It is much easier to create complex configurations from bash scripts with help of the iproute2 tools. PiperOrigin-RevId: 646286415
This commit is contained in:
@@ -242,7 +242,7 @@ network-tests: iptables-tests packetdrill-tests packetimpact-tests
|
||||
.PHONY: network-tests
|
||||
|
||||
syscall-tests: $(RUNTIME_BIN) ## Run all system call tests.
|
||||
@$(call test,--test_env=RUNTIME=$(RUNTIME_BIN) --cxxopt=-Werror $(PARTITIONS) test/syscalls/...)
|
||||
@$(call test,--test_env=RUNTIME=$(RUNTIME_BIN) --cxxopt=-Werror $(PARTITIONS) test/syscalls/... test/rtnetlink/...)
|
||||
.PHONY: syscall-tests
|
||||
|
||||
packetimpact-tests:
|
||||
|
||||
@@ -8,7 +8,8 @@ RUN apt-get update && apt-get install -y curl gnupg2 git \
|
||||
apt-transport-https ca-certificates gnupg-agent \
|
||||
software-properties-common \
|
||||
pkg-config libffi-dev patch diffutils libssl-dev iptables kmod \
|
||||
clang crossbuild-essential-amd64 erofs-utils busybox-static libbpf-dev
|
||||
clang crossbuild-essential-amd64 erofs-utils busybox-static libbpf-dev \
|
||||
iproute2 netcat
|
||||
|
||||
# This package is needed to build eBPF on amd64, but not on arm64 where it
|
||||
# doesn't exist.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
load("//test/runner:defs.bzl", "syscall_test")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
licenses = ["notice"],
|
||||
)
|
||||
|
||||
syscall_test(
|
||||
size = "small",
|
||||
container = True,
|
||||
overlay = True,
|
||||
save = False,
|
||||
test = "//test/rtnetlink/linux:veth_test",
|
||||
use_tmpfs = True,
|
||||
)
|
||||
|
||||
syscall_test(
|
||||
size = "small",
|
||||
container = True,
|
||||
overlay = True,
|
||||
save = False,
|
||||
test = "//test/rtnetlink/linux:bridge_test",
|
||||
use_tmpfs = True,
|
||||
)
|
||||
@@ -0,0 +1,40 @@
|
||||
load("//tools:defs.bzl", "go_binary")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
default_visibility = [
|
||||
"//:sandbox",
|
||||
],
|
||||
licenses = ["notice"],
|
||||
)
|
||||
|
||||
sh_library(
|
||||
name = "rtnetlink_test",
|
||||
srcs = ["rtnetlink_test.sh"],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "veth_test",
|
||||
srcs = ["veth_test.sh"],
|
||||
deps = [":rtnetlink_test"],
|
||||
)
|
||||
|
||||
sh_binary(
|
||||
name = "bridge_test",
|
||||
srcs = ["bridge_test.sh"],
|
||||
data = [
|
||||
":tcp_serv",
|
||||
],
|
||||
deps = [
|
||||
":rtnetlink_test",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "tcp_serv",
|
||||
srcs = ["tcp_serv.go"],
|
||||
pure = True,
|
||||
deps = [
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
)
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2024 The gVisor Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -xeo pipefail
|
||||
source "$(dirname "$0")/rtnetlink_test.sh"
|
||||
TCP_SRV="$(dirname "$0")/tcp_serv"
|
||||
if [[ ! -f "$TCP_SRV" ]]; then
|
||||
TCP_SRV="$(dirname "$0")/tcp_serv_/tcp_serv"
|
||||
fi
|
||||
|
||||
ip netns attach rootns "$$"
|
||||
ip link add br0 type bridge
|
||||
ip netns add test0
|
||||
ip netns add test1
|
||||
|
||||
ip link add hveth0 type veth peer name veth0 netns test0
|
||||
ip link add hveth1 type veth peer name veth1 netns test1
|
||||
ip link set up dev hveth0
|
||||
ip link set up dev hveth1
|
||||
|
||||
ip link set hveth0 master br0
|
||||
ip link set hveth1 master br0
|
||||
|
||||
ip addr add 192.168.0.3/24 dev br0
|
||||
ip link set up dev br0
|
||||
ip netns exec test0 ip link set up dev veth0
|
||||
ip netns exec test1 ip link set up dev veth1
|
||||
ip netns exec test0 ip addr add 192.168.0.1/24 dev veth0
|
||||
ip netns exec test1 ip addr add 192.168.0.2/24 dev veth1
|
||||
|
||||
check_connectivity test1 192.168.0.2 8800 test0 "ping from test0"
|
||||
check_connectivity test1 192.168.0.2 8801 rootns "ping from rootns"
|
||||
|
||||
# Destroy namespaces and the bridge.
|
||||
ip netns del test0
|
||||
ip link del br0
|
||||
ip netns del test1
|
||||
if ! wait_for ! ip link show hveth0 2>/dev/null; then
|
||||
fail "hveth0 hasn't been destroyed"
|
||||
fi
|
||||
if ! wait_for ! ip link show hveth1 2>/dev/null; then
|
||||
fail "hveth1 hasn't been destroyed"
|
||||
fi
|
||||
if ! wait_for ! ip link show br0 2>/dev/null; then
|
||||
fail "br0 hasn't been destroyed"
|
||||
fi
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2024 The gVisor Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -xeo pipefail
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Don't report any test cases.
|
||||
echo "$@" | grep list_tests && exit 1
|
||||
|
||||
if [[ -z "$TEST_ON_GVISOR" ]]; then
|
||||
if [[ ! -d /var/run ]]; then
|
||||
echo "SKIP: /var/run doesn't exist but it is required for the ip tool."
|
||||
exit 0
|
||||
fi
|
||||
mount -t tmpfs test /var/run
|
||||
else
|
||||
mkdir -p /var/run
|
||||
mount -t tmpfs test /var/run
|
||||
fi
|
||||
|
||||
# check_connectivity checks that a TCP connection can be established between two
|
||||
# specified namespaces.
|
||||
# Arguments:
|
||||
# * network namespace where a server will be started
|
||||
# * IP address in the server network namespace.
|
||||
# * port for a test TCP connection
|
||||
# * network namespace where a client will be started
|
||||
# * test message that will be send from server to client
|
||||
check_connectivity() {
|
||||
local srv_netns="$1"
|
||||
local srv_ip="$2"
|
||||
local port="$3"
|
||||
local clt_netns="$4"
|
||||
local test_msg="$5"
|
||||
|
||||
# Create a sync pipe that will be closed when TCP_SRV creates a listen socket.
|
||||
exec {pipe}<> <(:)
|
||||
exec {pipe_r}</proc/self/fd/$pipe
|
||||
exec {pipe_w}>/proc/self/fd/$pipe
|
||||
exec {pipe}>&-
|
||||
echo "$test_msg" | ip netns exec "$srv_netns" "$TCP_SRV" "--port=$port" "--sync-fd=$pipe_w" 1>&2 &
|
||||
pid=$!
|
||||
exec {pipe_w}>&-
|
||||
cat <&$pipe_r
|
||||
exec {pipe_r}>&-
|
||||
# The server has been started.
|
||||
|
||||
out=$(ip netns exec "$clt_netns" nc -nvd "$srv_ip" "$port")
|
||||
if [[ "$out" != "$test_msg" ]]; then
|
||||
fail "unexpected output '$out' (expected '$test_msg'"
|
||||
fi
|
||||
wait "$pid"
|
||||
}
|
||||
|
||||
wait_for() {
|
||||
for _ in $(seq 50); do
|
||||
if eval "$@"; then
|
||||
return 0
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2024 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// tcp_serv creates a TCP server socket, reads data from stdin, and sends that
|
||||
// data to the socket. The same thing can be done with the nc tool, but
|
||||
// tcp_serv can signal when a tcp socket is created.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func main() {
|
||||
port := flag.Int("port", 8888, "port to listen on")
|
||||
syncFD := flag.Int("sync-fd", -1, "file descriptor that will be closed after creating a socket")
|
||||
flag.Parse()
|
||||
address := fmt.Sprintf(":%d", *port)
|
||||
|
||||
listener, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating listener: %s", err)
|
||||
return
|
||||
}
|
||||
defer listener.Close()
|
||||
if *syncFD >= 0 {
|
||||
unix.Close(*syncFD)
|
||||
}
|
||||
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
log.Fatalf("Error accepting connection: %s", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
data := make([]byte, 1024)
|
||||
for {
|
||||
count, err := os.Stdin.Read(data)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
_, err = conn.Write(data[:count])
|
||||
if err != nil {
|
||||
log.Fatalf("Error sending data: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2024 The gVisor Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -xeo pipefail
|
||||
source "$(dirname "$0")/rtnetlink_test.sh"
|
||||
|
||||
# Create a new veth pair in the current namespace.
|
||||
ip link add name test_veth01 type veth peer name test_veth02
|
||||
ip a
|
||||
ip a | grep test_veth01
|
||||
ip a | grep test_veth02
|
||||
ip link del name test_veth01
|
||||
ip a
|
||||
# Check that test_veth02 has been destroyed.
|
||||
if ! wait_for ! ip link show test_veth02; then
|
||||
fail "test_veth02 hasn't been destroyed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ip netns add test
|
||||
ip link add test_veth01 type veth peer name test_veth02 netns test
|
||||
ip link show test_veth01
|
||||
ip netns exec test ip link show test_veth02
|
||||
ip netns del test
|
||||
if ! wait_for ! ip link show test_veth01; then
|
||||
fail "test_veth01 hasn't been destroyed"
|
||||
fi
|
||||
|
||||
@@ -211,6 +211,7 @@ def syscall_test_variants(
|
||||
save_resume = False,
|
||||
size = "medium",
|
||||
timeout = None,
|
||||
overlay = False,
|
||||
**kwargs):
|
||||
"""Generates syscall tests for all variants.
|
||||
|
||||
@@ -258,6 +259,7 @@ def syscall_test_variants(
|
||||
save_resume = save_resume,
|
||||
size = size,
|
||||
timeout = timeout,
|
||||
overlay = overlay,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@@ -367,6 +369,7 @@ def syscall_test(
|
||||
tags = None,
|
||||
save = True,
|
||||
size = "medium",
|
||||
overlay = False,
|
||||
**kwargs):
|
||||
"""syscall_test is a macro that will create targets for all platforms.
|
||||
|
||||
@@ -430,6 +433,7 @@ def syscall_test(
|
||||
False, # save, generate all tests without save variant.
|
||||
False, # save_resume, generate all tests without save_resume variant.
|
||||
size,
|
||||
overlay = overlay,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ func runTestCaseNative(testBin string, tc *gtest.TestCase, args []string, t *tes
|
||||
// setup_container takes in its target argv as positional arguments.
|
||||
cmd.Path = getSetupContainerPath()
|
||||
cmd.Args = append([]string{cmd.Path}, cmd.Args...)
|
||||
cmd.SysProcAttr.Cloneflags |= unix.CLONE_NEWUSER | unix.CLONE_NEWNET | unix.CLONE_NEWIPC | unix.CLONE_NEWUTS
|
||||
cmd.SysProcAttr.Cloneflags |= unix.CLONE_NEWUSER | unix.CLONE_NEWNET | unix.CLONE_NEWIPC | unix.CLONE_NEWUTS | unix.CLONE_NEWNS
|
||||
// Set current user/group as root inside the namespace.
|
||||
cmd.SysProcAttr.UidMappings = []syscall.SysProcIDMap{
|
||||
{ContainerID: 0, HostID: os.Getuid(), Size: 1},
|
||||
|
||||
Reference in New Issue
Block a user