1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2022 Petr Vorel <pvorel@suse.cz> 4# Copyright (c) Linux Test Project, 2014-2021 5# Copyright (c) 2015 Red Hat, Inc. 6 7TST_NEEDS_ROOT=1 8TST_NEEDS_CMDS="ip ping" 9TST_NEEDS_DRIVERS="veth" 10 11TST_OPTS="eI" 12TST_PARSE_ARGS="netns_parse_args" 13TST_USAGE="netns_usage" 14TST_SETUP="${TST_SETUP:-netns_setup}" 15TST_CLEANUP="${TST_CLEANUP:-netns_cleanup}" 16 17TST_NET_SKIP_VARIABLE_INIT=1 18 19# from tst_net_vars.c 20IPV4_NET16_UNUSED="10.23" 21IPV6_NET32_UNUSED="fd00:23" 22 23# Set to "net" for ns_create/ns_exec as their options requires 24# to specify a namespace type. Empty for ip command. 25NS_TYPE= 26 27# 'ping' or 'ping6' 28tping= 29 30# Network namespaces handles for manipulating and executing commands inside 31# namespaces. For 'ns_exec' handles are PIDs of daemonized processes running 32# in namespaces. 33NS_HANDLE0= 34NS_HANDLE1= 35 36# Adds "inet6 add" to the 'ifconfig' arguments which is required for the ipv6 37# version. Always use with 'ifconfig', even if ipv4 version of a test case is 38# used, in which case IFCONF_IN6_ARG will be empty string. Usage: 39# ifconfig <device> $IFCONF_IN6_ARG IP/NETMASK 40IFCONF_IN6_ARG= 41 42# Program which will be used to enter and run other commands inside a network namespace. 43# (ns_exec|ip) 44NS_EXEC="ip" 45 46# Communication type between kernel and user space for basic setup: enabling and 47# assigning IP addresses to the virtual ethernet devices. (Uses 'ip' command for 48# netlink and 'ifconfig' for ioctl.) 49# (netlink|ioctl) 50COMM_TYPE="netlink" 51 52do_cleanup= 53 54netns_parse_args() 55{ 56 case $1 in 57 e) NS_EXEC="ns_exec" ;; 58 I) COMM_TYPE="ioctl"; tst_require_cmds ifconfig ;; 59 esac 60} 61 62netns_usage() 63{ 64 echo "usage: $0 [ -e ] [ -I ]" 65 echo "OPTIONS" 66 echo "-e Use ns_exec instead of ip" 67 echo "-I Test ioctl (with ifconfig) instead of netlink (with ip)" 68} 69 70netns_setup() 71{ 72 if [ "$NS_EXEC" = "ip" ]; then 73 netns_ip_setup 74 else 75 setns_check 76 [ $? -eq 32 ] && tst_brk TCONF "setns not supported" 77 78 NS_TYPE="net" 79 netns_ns_exec_setup 80 fi 81 82 IP0=$(tst_ipaddr_un -c 1) 83 IP1=$(tst_ipaddr_un -c 2) 84 85 if [ "$TST_IPV6" ]; then 86 IFCONF_IN6_ARG="inet6 add" 87 NETMASK=64 88 else 89 NETMASK=24 90 fi 91 92 tping=ping$TST_IPV6 93 94 netns_set_ip 95 96 tst_res TINFO "testing netns over $COMM_TYPE with $NS_EXEC $PROG" 97 do_cleanup=1 98} 99 100netns_cleanup() 101{ 102 [ "$do_cleanup" ] || return 103 104 if [ "$NS_EXEC" = "ip" ]; then 105 netns_ip_cleanup 106 else 107 netns_ns_exec_cleanup 108 fi 109} 110 111# Sets up NS_EXEC to use 'ns_exec', creates two network namespaces and stores 112# their handles into NS_HANDLE0 and NS_HANDLE1 variables (in this case handles 113# are PIDs of daemonized processes running in these namespaces). Virtual 114# ethernet device is then created for each namespace. 115netns_ns_exec_setup() 116{ 117 local ret 118 119 NS_EXEC="ns_exec" 120 121 NS_HANDLE0=$(ns_create $NS_TYPE) 122 if [ $? -eq 1 ]; then 123 tst_res TINFO "$NS_HANDLE0" 124 tst_brk TBROK "unable to create a new network namespace" 125 fi 126 127 NS_HANDLE1=$(ns_create $NS_TYPE) 128 if [ $? -eq 1 ]; then 129 tst_res TINFO "$NS_HANDLE1" 130 tst_brk TBROK "unable to create a new network namespace" 131 fi 132 133 $NS_EXEC $NS_HANDLE0 $NS_TYPE ip link add veth0 type veth peer name veth1 || \ 134 tst_brk TBROK "unable to create veth pair devices" 135 136 $NS_EXEC $NS_HANDLE0 $NS_TYPE ns_ifmove veth1 $NS_HANDLE1 137 ret=$? 138 [ $ret -eq 0 ] && return 139 [ $ret -eq 32 ] && tst_brk TCONF "IFLA_NET_NS_PID not supported" 140 141 tst_brk TBROK "unable to add device veth1 to the separate network namespace" 142} 143 144# Sets up NS_EXEC to use 'ip netns exec', creates two network namespaces 145# and stores their handles into NS_HANDLE0 and NS_HANDLE1 variables. Virtual 146# ethernet device is then created for each namespace. 147netns_ip_setup() 148{ 149 ip netns > /dev/null || \ 150 tst_brk TCONF "ip without netns support (required iproute2 >= ss111010 - v3.0.0)" 151 152 NS_EXEC="ip netns exec" 153 154 NS_HANDLE0=tst_net_ns0 155 NS_HANDLE1=tst_net_ns1 156 157 ip netns del $NS_HANDLE0 2>/dev/null 158 ip netns del $NS_HANDLE1 2>/dev/null 159 160 ROD ip netns add $NS_HANDLE0 161 ROD ip netns add $NS_HANDLE1 162 163 ROD $NS_EXEC $NS_HANDLE0 ip link add veth0 type veth peer name veth1 164 ROD $NS_EXEC $NS_HANDLE0 ip link set veth1 netns $NS_HANDLE1 165} 166 167# Enables virtual ethernet devices and assigns IP addresses for both 168# of them (IPv4/IPv6 variant is decided by netns_setup() function). 169netns_set_ip() 170{ 171 local cmd="ip" 172 173 # This applies only for ipv6 variant: 174 # Do not accept Router Advertisements (accept_ra) and do not use 175 # Duplicate Address Detection (accept_dad) which uses Neighbor 176 # Discovery Protocol - the problem is that until DAD can confirm that 177 # there is no other host with the same address, the address is 178 # considered to be "tentative" (attempts to bind() to the address fail 179 # with EADDRNOTAVAIL) which may cause problems for tests using ipv6. 180 if [ "$TST_IPV6" ]; then 181 echo 0 | $NS_EXEC $NS_HANDLE0 $NS_TYPE \ 182 tee /proc/sys/net/ipv6/conf/veth0/accept_dad \ 183 /proc/sys/net/ipv6/conf/veth0/accept_ra >/dev/null 184 echo 0 | $NS_EXEC $NS_HANDLE1 $NS_TYPE \ 185 tee /proc/sys/net/ipv6/conf/veth1/accept_dad \ 186 /proc/sys/net/ipv6/conf/veth1/accept_ra >/dev/null 187 fi 188 189 [ "$COMM_TYPE" = "ioctl" ] && cmd="ifconfig" 190 191 if [ "$COMM_TYPE" = "netlink" ]; then 192 ROD $NS_EXEC $NS_HANDLE0 $NS_TYPE ip address add $IP0/$NETMASK dev veth0 193 ROD $NS_EXEC $NS_HANDLE1 $NS_TYPE ip address add $IP1/$NETMASK dev veth1 194 ROD $NS_EXEC $NS_HANDLE0 $NS_TYPE ip link set veth0 up 195 ROD $NS_EXEC $NS_HANDLE1 $NS_TYPE ip link set veth1 up 196 else 197 ROD $NS_EXEC $NS_HANDLE0 $NS_TYPE ifconfig veth0 $IFCONF_IN6_ARG $IP0/$NETMASK 198 ROD $NS_EXEC $NS_HANDLE1 $NS_TYPE ifconfig veth1 $IFCONF_IN6_ARG $IP1/$NETMASK 199 ROD $NS_EXEC $NS_HANDLE0 $NS_TYPE ifconfig veth0 up 200 ROD $NS_EXEC $NS_HANDLE1 $NS_TYPE ifconfig veth1 up 201 fi 202} 203 204netns_ns_exec_cleanup() 205{ 206 [ "$NS_EXEC" ] || return 207 208 # removes veth0 device (which also removes the paired veth1 device) 209 $NS_EXEC $NS_HANDLE0 $NS_TYPE ip link delete veth0 210 211 kill -9 $NS_HANDLE0 2>/dev/null 212 kill -9 $NS_HANDLE1 2>/dev/null 213} 214 215 216netns_ip_cleanup() 217{ 218 [ "$NS_EXEC" ] || return 219 220 # removes veth0 device (which also removes the paired veth1 device) 221 $NS_EXEC $NS_HANDLE0 ip link delete veth0 222 223 ip netns del $NS_HANDLE0 2>/dev/null 224 ip netns del $NS_HANDLE1 2>/dev/null 225} 226 227. tst_net.sh 228