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