brintos

brintos / linux-shallow public Read only

0
0
Text · 7.0 KiB · eef5cbf Raw
284 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03#4# 2 namespaces: one host and one router. Use arping from the host to send a5# garp to the router. Router accepts or ignores based on its arp_accept6# or accept_untracked_na configuration.7 8source lib.sh9 10TESTS="arp ndisc"11 12ROUTER_INTF="veth-router"13ROUTER_ADDR="10.0.10.1"14ROUTER_ADDR_V6="2001:db8:abcd:0012::1"15 16HOST_INTF="veth-host"17HOST_ADDR="10.0.10.2"18HOST_ADDR_V6="2001:db8:abcd:0012::2"19 20SUBNET_WIDTH=2421PREFIX_WIDTH_V6=6422 23cleanup() {24	cleanup_ns ${HOST_NS} ${ROUTER_NS}25}26 27cleanup_v6() {28	cleanup_ns ${HOST_NS_V6} ${ROUTER_NS_V6}29}30 31setup() {32	set -e33	local arp_accept=$134 35	# Set up two namespaces36	setup_ns HOST_NS ROUTER_NS37 38	# Set up interfaces veth0 and veth1, which are pairs in separate39	# namespaces. veth0 is veth-router, veth1 is veth-host.40	# first, set up the inteface's link to the namespace41	# then, set the interface "up"42	ip netns exec ${ROUTER_NS} ip link add name ${ROUTER_INTF} \43		type veth peer name ${HOST_INTF}44 45	ip netns exec ${ROUTER_NS} ip link set dev ${ROUTER_INTF} up46	ip netns exec ${ROUTER_NS} ip link set dev ${HOST_INTF} netns ${HOST_NS}47 48	ip netns exec ${HOST_NS} ip link set dev ${HOST_INTF} up49	ip netns exec ${ROUTER_NS} ip addr add ${ROUTER_ADDR}/${SUBNET_WIDTH} \50		dev ${ROUTER_INTF}51 52	ip netns exec ${HOST_NS} ip addr add ${HOST_ADDR}/${SUBNET_WIDTH} \53		dev ${HOST_INTF}54	ip netns exec ${HOST_NS} ip route add default via ${HOST_ADDR} \55		dev ${HOST_INTF}56	ip netns exec ${ROUTER_NS} ip route add default via ${ROUTER_ADDR} \57		dev ${ROUTER_INTF}58 59	ROUTER_CONF=net.ipv4.conf.${ROUTER_INTF}60	ip netns exec ${ROUTER_NS} sysctl -w \61		${ROUTER_CONF}.arp_accept=${arp_accept} >/dev/null 2>&162	set +e63}64 65setup_v6() {66	set -e67	local accept_untracked_na=$168 69	# Set up two namespaces70	setup_ns HOST_NS_V6 ROUTER_NS_V671 72	# Set up interfaces veth0 and veth1, which are pairs in separate73	# namespaces. veth0 is veth-router, veth1 is veth-host.74	# first, set up the inteface's link to the namespace75	# then, set the interface "up"76	ip -n ${ROUTER_NS_V6} link add name ${ROUTER_INTF} \77		type veth peer name ${HOST_INTF} netns ${HOST_NS_V6}78 79	# Add tc rule to filter out host na message80	tc -n ${ROUTER_NS_V6} qdisc add dev ${ROUTER_INTF} clsact81	tc -n ${ROUTER_NS_V6} filter add dev ${ROUTER_INTF} \82		ingress protocol ipv6 pref 1 handle 101 \83		flower src_ip ${HOST_ADDR_V6} ip_proto icmpv6 type 136 skip_hw action pass84 85	HOST_CONF=net.ipv6.conf.${HOST_INTF}86	ip netns exec ${HOST_NS_V6} sysctl -qw ${HOST_CONF}.ndisc_notify=187	ip netns exec ${HOST_NS_V6} sysctl -qw ${HOST_CONF}.disable_ipv6=088	ROUTER_CONF=net.ipv6.conf.${ROUTER_INTF}89	ip netns exec ${ROUTER_NS_V6} sysctl -w \90		${ROUTER_CONF}.forwarding=1 >/dev/null 2>&191	ip netns exec ${ROUTER_NS_V6} sysctl -w \92		${ROUTER_CONF}.drop_unsolicited_na=0 >/dev/null 2>&193	ip netns exec ${ROUTER_NS_V6} sysctl -w \94		${ROUTER_CONF}.accept_untracked_na=${accept_untracked_na} \95		>/dev/null 2>&196 97	ip -n ${ROUTER_NS_V6} link set dev ${ROUTER_INTF} up98	ip -n ${HOST_NS_V6} link set dev ${HOST_INTF} up99	ip -n ${ROUTER_NS_V6} addr add ${ROUTER_ADDR_V6}/${PREFIX_WIDTH_V6} \100		dev ${ROUTER_INTF} nodad101	ip -n ${HOST_NS_V6} addr add ${HOST_ADDR_V6}/${PREFIX_WIDTH_V6} \102		dev ${HOST_INTF}103	set +e104}105 106verify_arp() {107	local arp_accept=$1108	local same_subnet=$2109 110	neigh_show_output=$(ip netns exec ${ROUTER_NS} ip neigh get \111		${HOST_ADDR} dev ${ROUTER_INTF} 2>/dev/null)112 113	if [ ${arp_accept} -eq 1 ]; then114		# Neighbor entries expected115		[[ ${neigh_show_output} ]]116	elif [ ${arp_accept} -eq 2 ]; then117		if [ ${same_subnet} -eq 1 ]; then118			# Neighbor entries expected119			[[ ${neigh_show_output} ]]120		else121			[[ -z "${neigh_show_output}" ]]122		fi123	else124		[[ -z "${neigh_show_output}" ]]125	fi126 }127 128arp_test_gratuitous() {129	set -e130	local arp_accept=$1131	local same_subnet=$2132 133	if [ ${arp_accept} -eq 2 ]; then134		test_msg=("test_arp: "135			  "accept_arp=$1 "136			  "same_subnet=$2")137		if [ ${same_subnet} -eq 0 ]; then138			HOST_ADDR=10.0.11.3139		else140			HOST_ADDR=10.0.10.3141		fi142	else143		test_msg=("test_arp: "144			  "accept_arp=$1")145	fi146	# Supply arp_accept option to set up which sets it in sysctl147	setup ${arp_accept}148	ip netns exec ${HOST_NS} arping -A -I ${HOST_INTF} -U ${HOST_ADDR} -c1 2>&1 >/dev/null149 150	if verify_arp $1 $2; then151		printf "    TEST: %-60s  [ OK ]\n" "${test_msg[*]}"152	else153		printf "    TEST: %-60s  [FAIL]\n" "${test_msg[*]}"154	fi155	cleanup156	set +e157}158 159arp_test_gratuitous_combinations() {160	arp_test_gratuitous 0161	arp_test_gratuitous 1162	arp_test_gratuitous 2 0 # Second entry indicates subnet or not163	arp_test_gratuitous 2 1164}165 166verify_ndisc() {167	local accept_untracked_na=$1168	local same_subnet=$2169 170	neigh_show_output=$(ip -6 -netns ${ROUTER_NS_V6} neigh show \171		to ${HOST_ADDR_V6} dev ${ROUTER_INTF} nud stale)172 173	if [ ${accept_untracked_na} -eq 1 ]; then174		# Neighbour entry expected to be present175		[[ ${neigh_show_output} ]]176	elif [ ${accept_untracked_na} -eq 2 ]; then177		if [ ${same_subnet} -eq 1 ]; then178			[[ ${neigh_show_output} ]]179		else180			[[ -z "${neigh_show_output}" ]]181		fi182	else183		# Neighbour entry expected to be absent for all other cases184		[[ -z "${neigh_show_output}" ]]185	fi186}187 188ndisc_test_untracked_advertisements() {189	set -e190	test_msg=("test_ndisc: "191		  "accept_untracked_na=$1")192 193	local accept_untracked_na=$1194	local same_subnet=$2195	if [ ${accept_untracked_na} -eq 2 ]; then196		test_msg=("test_ndisc: "197			  "accept_untracked_na=$1 "198			  "same_subnet=$2")199		if [ ${same_subnet} -eq 0 ]; then200			# Not same subnet201			HOST_ADDR_V6=2000:db8:abcd:0013::4202		else203			HOST_ADDR_V6=2001:db8:abcd:0012::3204		fi205	fi206	setup_v6 $1207	slowwait_for_counter 15 1 \208		tc_rule_handle_stats_get "dev ${ROUTER_INTF} ingress" 101 ".packets" "-n ${ROUTER_NS_V6}"209 210	if verify_ndisc $1 $2; then211		printf "    TEST: %-60s  [ OK ]\n" "${test_msg[*]}"212	else213		printf "    TEST: %-60s  [FAIL]\n" "${test_msg[*]}"214	fi215 216	cleanup_v6217	set +e218}219 220ndisc_test_untracked_combinations() {221	ndisc_test_untracked_advertisements 0222	ndisc_test_untracked_advertisements 1223	ndisc_test_untracked_advertisements 2 0224	ndisc_test_untracked_advertisements 2 1225}226 227################################################################################228# usage229 230usage()231{232	cat <<EOF233usage: ${0##*/} OPTS234 235	-t <test>       Test(s) to run (default: all)236			(options: $TESTS)237EOF238}239 240################################################################################241# main242 243while getopts ":t:h" opt; do244	case $opt in245		t) TESTS=$OPTARG;;246		h) usage; exit 0;;247		*) usage; exit 1;;248	esac249done250 251if [ "$(id -u)" -ne 0 ];then252	echo "SKIP: Need root privileges"253	exit $ksft_skip;254fi255 256if [ ! -x "$(command -v ip)" ]; then257	echo "SKIP: Could not run test without ip tool"258	exit $ksft_skip259fi260 261if [ ! -x "$(command -v tcpdump)" ]; then262	echo "SKIP: Could not run test without tcpdump tool"263	exit $ksft_skip264fi265 266if [ ! -x "$(command -v arping)" ]; then267	echo "SKIP: Could not run test without arping tool"268	exit $ksft_skip269fi270 271# start clean272cleanup &> /dev/null273cleanup_v6 &> /dev/null274 275for t in $TESTS276do277	case $t in278	arp_test_gratuitous_combinations|arp) arp_test_gratuitous_combinations;;279	ndisc_test_untracked_combinations|ndisc) \280		ndisc_test_untracked_combinations;;281	help) echo "Test names: $TESTS"; exit 0;;282esac283done284