1f08c3bdfSopenharmony_ci#!/bin/sh 2f08c3bdfSopenharmony_ci# SPDX-License-Identifier: GPL-2.0-or-later 3f08c3bdfSopenharmony_ci# Copyright (c) Linux Test Project, 2014-2021 4f08c3bdfSopenharmony_ci# Copyright (c) 2015 Red Hat, Inc. 5f08c3bdfSopenharmony_ci 6f08c3bdfSopenharmony_ciTST_CLEANUP=netns_ns_exec_cleanup 7f08c3bdfSopenharmony_ciTST_NEEDS_ROOT=1 8f08c3bdfSopenharmony_ciTST_NEEDS_CMDS="ip ping" 9f08c3bdfSopenharmony_ciTST_NEEDS_DRIVERS="veth" 10f08c3bdfSopenharmony_ci. tst_test.sh 11f08c3bdfSopenharmony_ci 12f08c3bdfSopenharmony_ci# Set to 1 only for test cases using ifconfig (ioctl). 13f08c3bdfSopenharmony_ciUSE_IFCONFIG=0 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci# Variables which can be used in test cases (set by netns_setup() function): 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci# Use in test cases to execute commands inside a namespace. Set to 'ns_exec' or 18f08c3bdfSopenharmony_ci# 'ip netns exec' command according to NS_EXEC_PROGRAM argument specified in 19f08c3bdfSopenharmony_ci# netns_setup() function call. 20f08c3bdfSopenharmony_ciNS_EXEC= 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci# Set to "net" for ns_create/ns_exec as their options requires 23f08c3bdfSopenharmony_ci# to specify a namespace type. Empty for ip command. 24f08c3bdfSopenharmony_ciNS_TYPE= 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_ci# IP addresses of veth0 (IP0) and veth1 (IP1) devices (ipv4/ipv6 variant 27f08c3bdfSopenharmony_ci# is determined according to the IP_VERSION argument specified in netns_setup() 28f08c3bdfSopenharmony_ci# function call. 29f08c3bdfSopenharmony_ciIP0= 30f08c3bdfSopenharmony_ciIP1= 31f08c3bdfSopenharmony_ciNETMASK= 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci# 'ping' or 'ping6' according to the IP_VERSION argument specified 34f08c3bdfSopenharmony_ci# in netns_setup() function call. 35f08c3bdfSopenharmony_citping= 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci# Network namespaces handles for manipulating and executing commands inside 38f08c3bdfSopenharmony_ci# namespaces. For 'ns_exec' handles are PIDs of daemonized processes running 39f08c3bdfSopenharmony_ci# in namespaces. 40f08c3bdfSopenharmony_ciNS_HANDLE0= 41f08c3bdfSopenharmony_ciNS_HANDLE1= 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_ci# Adds "inet6 add" to the 'ifconfig' arguments which is required for the ipv6 44f08c3bdfSopenharmony_ci# version. Always use with 'ifconfig', even if ipv4 version of a test case is 45f08c3bdfSopenharmony_ci# used, in which case IFCONF_IN6_ARG will be empty string. Usage: 46f08c3bdfSopenharmony_ci# ifconfig <device> $IFCONF_IN6_ARG IP/NETMASK 47f08c3bdfSopenharmony_ciIFCONF_IN6_ARG= 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ci# Sets up global variables which can be used in test cases (documented above), 50f08c3bdfSopenharmony_ci# creates two network namespaces and a pair of virtual ethernet devices, each 51f08c3bdfSopenharmony_ci# device in one namespace. Each device is then enabled and assigned an IP 52f08c3bdfSopenharmony_ci# address according to the function parameters. IFCONF_IN6_ARG variable is set 53f08c3bdfSopenharmony_ci# only if ipv6 variant of test case is used (determined by IP_VERSION argument). 54f08c3bdfSopenharmony_ci# 55f08c3bdfSopenharmony_ci# SYNOPSIS: 56f08c3bdfSopenharmony_ci# netns_setup <NS_EXEC_PROGRAM> <IP_VERSION> <COMM_TYPE> <IP4_VETH0> 57f08c3bdfSopenharmony_ci# <IP4_VETH1> <IP6_VETH0> <IP6_VETH1> 58f08c3bdfSopenharmony_ci# 59f08c3bdfSopenharmony_ci# OPTIONS: 60f08c3bdfSopenharmony_ci# * NS_EXEC_PROGRAM (ns_exec|ip) 61f08c3bdfSopenharmony_ci# Program which will be used to enter and run other commands 62f08c3bdfSopenharmony_ci# inside a network namespace. 63f08c3bdfSopenharmony_ci# * IP_VERSION (ipv4|ipv6) 64f08c3bdfSopenharmony_ci# Version of IP. (ipv4|ipv6) 65f08c3bdfSopenharmony_ci# * COMM_TYPE (netlink|ioctl) 66f08c3bdfSopenharmony_ci# Communication type between kernel and user space 67f08c3bdfSopenharmony_ci# for enabling and assigning IP addresses to the virtual 68f08c3bdfSopenharmony_ci# ethernet devices. Uses 'ip' command for netlink and 'ifconfig' 69f08c3bdfSopenharmony_ci# for ioctl. (If set to ioctl, function also checks the existance 70f08c3bdfSopenharmony_ci# of the 'ifconfig' command.) 71f08c3bdfSopenharmony_ci# * IP4_VETH0, IP4_VETH1 72f08c3bdfSopenharmony_ci# IPv4 addresses for veth0 and veth1 devices. 73f08c3bdfSopenharmony_ci# * IP6_VETH0, IP6_VETH1 74f08c3bdfSopenharmony_ci# IPv6 addresses for veth0 and veth1 devices. 75f08c3bdfSopenharmony_ci# 76f08c3bdfSopenharmony_ci# On success function returns, on error tst_brk is called and TC is terminated. 77f08c3bdfSopenharmony_cinetns_setup() 78f08c3bdfSopenharmony_ci{ 79f08c3bdfSopenharmony_ci case "$1" in 80f08c3bdfSopenharmony_ci ns_exec) 81f08c3bdfSopenharmony_ci setns_check 82f08c3bdfSopenharmony_ci [ $? -eq 32 ] && tst_brk TCONF "setns not supported" 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci NS_TYPE="net" 85f08c3bdfSopenharmony_ci netns_ns_exec_setup 86f08c3bdfSopenharmony_ci TST_CLEANUP=netns_ns_exec_cleanup 87f08c3bdfSopenharmony_ci ;; 88f08c3bdfSopenharmony_ci ip) 89f08c3bdfSopenharmony_ci netns_ip_setup 90f08c3bdfSopenharmony_ci TST_CLEANUP=netns_ip_cleanup 91f08c3bdfSopenharmony_ci ;; 92f08c3bdfSopenharmony_ci *) 93f08c3bdfSopenharmony_ci tst_brk TBROK \ 94f08c3bdfSopenharmony_ci "first argument must be a program used to enter a network namespace (ns_exec|ip)" 95f08c3bdfSopenharmony_ci ;; 96f08c3bdfSopenharmony_ci esac 97f08c3bdfSopenharmony_ci 98f08c3bdfSopenharmony_ci case "$3" in 99f08c3bdfSopenharmony_ci netlink) 100f08c3bdfSopenharmony_ci ;; 101f08c3bdfSopenharmony_ci ioctl) 102f08c3bdfSopenharmony_ci USE_IFCONFIG=1 103f08c3bdfSopenharmony_ci tst_require_cmds ifconfig 104f08c3bdfSopenharmony_ci ;; 105f08c3bdfSopenharmony_ci *) 106f08c3bdfSopenharmony_ci tst_brk TBROK \ 107f08c3bdfSopenharmony_ci "third argument must be a comm. type between kernel and user space (netlink|ioctl)" 108f08c3bdfSopenharmony_ci ;; 109f08c3bdfSopenharmony_ci esac 110f08c3bdfSopenharmony_ci 111f08c3bdfSopenharmony_ci if [ -z "$4" ]; then 112f08c3bdfSopenharmony_ci tst_brk TBROK "fourth argument must be the IPv4 address for veth0" 113f08c3bdfSopenharmony_ci fi 114f08c3bdfSopenharmony_ci if [ -z "$5" ]; then 115f08c3bdfSopenharmony_ci tst_brk TBROK "fifth argument must be the IPv4 address for veth1" 116f08c3bdfSopenharmony_ci fi 117f08c3bdfSopenharmony_ci if [ -z "$6" ]; then 118f08c3bdfSopenharmony_ci tst_brk TBROK "sixth argument must be the IPv6 address for veth0" 119f08c3bdfSopenharmony_ci fi 120f08c3bdfSopenharmony_ci if [ -z "$7" ]; then 121f08c3bdfSopenharmony_ci tst_brk TBROK "seventh argument must be the IPv6 address for veth1" 122f08c3bdfSopenharmony_ci fi 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_ci case "$2" in 125f08c3bdfSopenharmony_ci ipv4) 126f08c3bdfSopenharmony_ci IP0=$4 127f08c3bdfSopenharmony_ci IP1=$5 128f08c3bdfSopenharmony_ci tping="ping" 129f08c3bdfSopenharmony_ci NETMASK=24 130f08c3bdfSopenharmony_ci ;; 131f08c3bdfSopenharmony_ci ipv6) 132f08c3bdfSopenharmony_ci IFCONF_IN6_ARG="inet6 add" 133f08c3bdfSopenharmony_ci IP0=$6 134f08c3bdfSopenharmony_ci IP1=$7 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci if tst_cmd_available ping6; then 137f08c3bdfSopenharmony_ci tping="ping6" 138f08c3bdfSopenharmony_ci else 139f08c3bdfSopenharmony_ci tping="ping -6" 140f08c3bdfSopenharmony_ci tst_res_ TINFO "ping6 binary/symlink is missing, using workaround. Please, report missing ping6 to your distribution." 141f08c3bdfSopenharmony_ci fi 142f08c3bdfSopenharmony_ci NETMASK=64 143f08c3bdfSopenharmony_ci ;; 144f08c3bdfSopenharmony_ci *) 145f08c3bdfSopenharmony_ci tst_brk TBROK "second argument must be an ip version (ipv4|ipv6)" 146f08c3bdfSopenharmony_ci ;; 147f08c3bdfSopenharmony_ci esac 148f08c3bdfSopenharmony_ci 149f08c3bdfSopenharmony_ci netns_set_ip 150f08c3bdfSopenharmony_ci} 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_ci# Sets up NS_EXEC to use 'ns_exec', creates two network namespaces and stores 153f08c3bdfSopenharmony_ci# their handles into NS_HANDLE0 and NS_HANDLE1 variables (in this case handles 154f08c3bdfSopenharmony_ci# are PIDs of daemonized processes running in these namespaces). Virtual 155f08c3bdfSopenharmony_ci# ethernet device is then created for each namespace. 156f08c3bdfSopenharmony_cinetns_ns_exec_setup() 157f08c3bdfSopenharmony_ci{ 158f08c3bdfSopenharmony_ci local ret 159f08c3bdfSopenharmony_ci 160f08c3bdfSopenharmony_ci NS_EXEC="ns_exec" 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci NS_HANDLE0=$(ns_create $NS_TYPE) 163f08c3bdfSopenharmony_ci if [ $? -eq 1 ]; then 164f08c3bdfSopenharmony_ci tst_res TINFO "$NS_HANDLE0" 165f08c3bdfSopenharmony_ci tst_brk TBROK "unable to create a new network namespace" 166f08c3bdfSopenharmony_ci fi 167f08c3bdfSopenharmony_ci 168f08c3bdfSopenharmony_ci NS_HANDLE1=$(ns_create $NS_TYPE) 169f08c3bdfSopenharmony_ci if [ $? -eq 1 ]; then 170f08c3bdfSopenharmony_ci tst_res TINFO "$NS_HANDLE1" 171f08c3bdfSopenharmony_ci tst_brk TBROK "unable to create a new network namespace" 172f08c3bdfSopenharmony_ci fi 173f08c3bdfSopenharmony_ci 174f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 $NS_TYPE ip link add veth0 type veth peer name veth1 || \ 175f08c3bdfSopenharmony_ci tst_brk TBROK "unable to create veth pair devices" 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 $NS_TYPE ns_ifmove veth1 $NS_HANDLE1 178f08c3bdfSopenharmony_ci ret=$? 179f08c3bdfSopenharmony_ci [ $ret -eq 0 ] && return 180f08c3bdfSopenharmony_ci [ $ret -eq 32 ] && tst_brk TCONF "IFLA_NET_NS_PID not supported" 181f08c3bdfSopenharmony_ci 182f08c3bdfSopenharmony_ci tst_brk TBROK "unable to add device veth1 to the separate network namespace" 183f08c3bdfSopenharmony_ci} 184f08c3bdfSopenharmony_ci 185f08c3bdfSopenharmony_ci# Sets up NS_EXEC to use 'ip netns exec', creates two network namespaces 186f08c3bdfSopenharmony_ci# and stores their handles into NS_HANDLE0 and NS_HANDLE1 variables. Virtual 187f08c3bdfSopenharmony_ci# ethernet device is then created for each namespace. 188f08c3bdfSopenharmony_cinetns_ip_setup() 189f08c3bdfSopenharmony_ci{ 190f08c3bdfSopenharmony_ci ip netns > /dev/null || \ 191f08c3bdfSopenharmony_ci tst_brk TCONF "ip without netns support (required iproute2 >= ss111010 - v3.0.0)" 192f08c3bdfSopenharmony_ci 193f08c3bdfSopenharmony_ci NS_EXEC="ip netns exec" 194f08c3bdfSopenharmony_ci 195f08c3bdfSopenharmony_ci NS_HANDLE0=tst_net_ns0 196f08c3bdfSopenharmony_ci NS_HANDLE1=tst_net_ns1 197f08c3bdfSopenharmony_ci 198f08c3bdfSopenharmony_ci ip netns del $NS_HANDLE0 2>/dev/null 199f08c3bdfSopenharmony_ci ip netns del $NS_HANDLE1 2>/dev/null 200f08c3bdfSopenharmony_ci 201f08c3bdfSopenharmony_ci ip netns add $NS_HANDLE0 || \ 202f08c3bdfSopenharmony_ci tst_brk TBROK "unable to create a new network namespace" 203f08c3bdfSopenharmony_ci ip netns add $NS_HANDLE1 || \ 204f08c3bdfSopenharmony_ci tst_brk TBROK "unable to create a new network namespace" 205f08c3bdfSopenharmony_ci 206f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 ip link add veth0 type veth peer name veth1 || \ 207f08c3bdfSopenharmony_ci tst_brk TBROK "unable to create veth pair devices" 208f08c3bdfSopenharmony_ci 209f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 ip link set veth1 netns $NS_HANDLE1 || \ 210f08c3bdfSopenharmony_ci tst_brk TBROK "unable to add device veth1 to the separate network namespace" 211f08c3bdfSopenharmony_ci} 212f08c3bdfSopenharmony_ci 213f08c3bdfSopenharmony_ci# Enables virtual ethernet devices and assigns IP addresses for both 214f08c3bdfSopenharmony_ci# of them (IPv4/IPv6 variant is decided by netns_setup() function). 215f08c3bdfSopenharmony_cinetns_set_ip() 216f08c3bdfSopenharmony_ci{ 217f08c3bdfSopenharmony_ci [ "$NS_EXEC" ] || tst_brk TBROK "netns_setup() function must be called first" 218f08c3bdfSopenharmony_ci 219f08c3bdfSopenharmony_ci # This applies only for ipv6 variant: 220f08c3bdfSopenharmony_ci # Do not accept Router Advertisements (accept_ra) and do not use 221f08c3bdfSopenharmony_ci # Duplicate Address Detection (accept_dad) which uses Neighbor 222f08c3bdfSopenharmony_ci # Discovery Protocol - the problem is that until DAD can confirm that 223f08c3bdfSopenharmony_ci # there is no other host with the same address, the address is 224f08c3bdfSopenharmony_ci # considered to be "tentative" (attempts to bind() to the address fail 225f08c3bdfSopenharmony_ci # with EADDRNOTAVAIL) which may cause problems for tests using ipv6. 226f08c3bdfSopenharmony_ci echo 0 | $NS_EXEC $NS_HANDLE0 $NS_TYPE \ 227f08c3bdfSopenharmony_ci tee /proc/sys/net/ipv6/conf/veth0/accept_dad \ 228f08c3bdfSopenharmony_ci /proc/sys/net/ipv6/conf/veth0/accept_ra >/dev/null 229f08c3bdfSopenharmony_ci echo 0 | $NS_EXEC $NS_HANDLE1 $NS_TYPE \ 230f08c3bdfSopenharmony_ci tee /proc/sys/net/ipv6/conf/veth1/accept_dad \ 231f08c3bdfSopenharmony_ci /proc/sys/net/ipv6/conf/veth1/accept_ra >/dev/null 232f08c3bdfSopenharmony_ci 233f08c3bdfSopenharmony_ci case $USE_IFCONFIG in 234f08c3bdfSopenharmony_ci 1) 235f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 $NS_TYPE ifconfig veth0 $IFCONF_IN6_ARG $IP0/$NETMASK || 236f08c3bdfSopenharmony_ci tst_brk TBROK "adding address to veth0 failed" 237f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE1 $NS_TYPE ifconfig veth1 $IFCONF_IN6_ARG $IP1/$NETMASK || 238f08c3bdfSopenharmony_ci tst_brk TBROK "adding address to veth1 failed" 239f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 $NS_TYPE ifconfig veth0 up || 240f08c3bdfSopenharmony_ci tst_brk TBROK "enabling veth0 device failed" 241f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE1 $NS_TYPE ifconfig veth1 up || 242f08c3bdfSopenharmony_ci tst_brk TBROK "enabling veth1 device failed" 243f08c3bdfSopenharmony_ci ;; 244f08c3bdfSopenharmony_ci *) 245f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 $NS_TYPE ip address add $IP0/$NETMASK dev veth0 || 246f08c3bdfSopenharmony_ci tst_brk TBROK "adding address to veth0 failed" 247f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE1 $NS_TYPE ip address add $IP1/$NETMASK dev veth1 || 248f08c3bdfSopenharmony_ci tst_brk TBROK "adding address to veth1 failed" 249f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 $NS_TYPE ip link set veth0 up || 250f08c3bdfSopenharmony_ci tst_brk TBROK "enabling veth0 device failed" 251f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE1 $NS_TYPE ip link set veth1 up || 252f08c3bdfSopenharmony_ci tst_brk TBROK "enabling veth1 device failed" 253f08c3bdfSopenharmony_ci ;; 254f08c3bdfSopenharmony_ci esac 255f08c3bdfSopenharmony_ci} 256f08c3bdfSopenharmony_ci 257f08c3bdfSopenharmony_cinetns_ns_exec_cleanup() 258f08c3bdfSopenharmony_ci{ 259f08c3bdfSopenharmony_ci [ "$NS_EXEC" ] || return 260f08c3bdfSopenharmony_ci 261f08c3bdfSopenharmony_ci # removes veth0 device (which also removes the paired veth1 device) 262f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 $NS_TYPE ip link delete veth0 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci kill -9 $NS_HANDLE0 2>/dev/null 265f08c3bdfSopenharmony_ci kill -9 $NS_HANDLE1 2>/dev/null 266f08c3bdfSopenharmony_ci} 267f08c3bdfSopenharmony_ci 268f08c3bdfSopenharmony_ci 269f08c3bdfSopenharmony_cinetns_ip_cleanup() 270f08c3bdfSopenharmony_ci{ 271f08c3bdfSopenharmony_ci [ "$NS_EXEC" ] || return 272f08c3bdfSopenharmony_ci 273f08c3bdfSopenharmony_ci # removes veth0 device (which also removes the paired veth1 device) 274f08c3bdfSopenharmony_ci $NS_EXEC $NS_HANDLE0 ip link delete veth0 275f08c3bdfSopenharmony_ci 276f08c3bdfSopenharmony_ci ip netns del $NS_HANDLE0 2>/dev/null 277f08c3bdfSopenharmony_ci ip netns del $NS_HANDLE1 2>/dev/null 278f08c3bdfSopenharmony_ci} 279