xref: /linux/tools/testing/selftests/drivers/net/bonding/bond_stacked_header_parse.sh (revision 91a4855d6c03e770e42f17c798a36a3c46e63de2)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test that bond_header_parse() does not infinitely recurse with stacked bonds.
5#
6# When a non-Ethernet device (e.g. GRE) is enslaved to a bond that is itself
7# enslaved to another bond (bond1 -> bond0 -> gre), receiving a packet via
8# AF_PACKET SOCK_DGRAM triggers dev_parse_header() -> bond_header_parse().
9# Since parse() used skb->dev (always the topmost bond) instead of a passed-in
10# dev pointer, it would recurse back into itself indefinitely.
11
12# shellcheck disable=SC2034
13ALL_TESTS="
14	bond_test_stacked_header_parse
15"
16REQUIRE_MZ=no
17NUM_NETIFS=0
18lib_dir=$(dirname "$0")
19source "$lib_dir"/../../../net/forwarding/lib.sh
20
21# shellcheck disable=SC2329
22bond_test_stacked_header_parse()
23{
24	local devdummy="test-dummy0"
25	local devgre="test-gre0"
26	local devbond0="test-bond0"
27	local devbond1="test-bond1"
28
29	# shellcheck disable=SC2034
30	RET=0
31
32	# Setup: dummy -> gre -> bond0 -> bond1
33	ip link add name "$devdummy" type dummy
34	ip addr add 10.0.0.1/24 dev "$devdummy"
35	ip link set "$devdummy" up
36
37	ip link add name "$devgre" type gre local 10.0.0.1
38
39	ip link add name "$devbond0" type bond mode active-backup
40	ip link add name "$devbond1" type bond mode active-backup
41
42	ip link set "$devgre" master "$devbond0"
43	ip link set "$devbond0" master "$devbond1"
44
45	ip link set "$devgre" up
46	ip link set "$devbond0" up
47	ip link set "$devbond1" up
48
49	# tcpdump on a non-Ethernet bond uses AF_PACKET SOCK_DGRAM (cooked
50	# capture), which triggers dev_parse_header() -> bond_header_parse()
51	# on receive. With the bug, this recurses infinitely.
52	timeout 5 tcpdump -c 1 -i "$devbond1" >/dev/null 2>&1 &
53	local tcpdump_pid=$!
54	sleep 1
55
56	# Send a GRE packet to 10.0.0.1 so it arrives via gre -> bond0 -> bond1
57	python3 -c "from scapy.all import *; send(IP(src='10.0.0.2', dst='10.0.0.1')/GRE()/IP()/UDP(), verbose=0)"
58	check_err $? "failed to send GRE packet (scapy installed?)"
59
60	wait "$tcpdump_pid" 2>/dev/null
61
62	ip link del "$devbond1" 2>/dev/null
63	ip link del "$devbond0" 2>/dev/null
64	ip link del "$devgre" 2>/dev/null
65	ip link del "$devdummy" 2>/dev/null
66
67	log_test "Stacked bond header_parse does not recurse"
68}
69
70tests_run
71
72exit "$EXIT_STATUS"
73