1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4lib_dir=$(dirname $0)/../../../net/forwarding
5
6ALL_TESTS="
7	mac_profile_test
8"
9NUM_NETIFS=4
10source $lib_dir/lib.sh
11source $lib_dir/tc_common.sh
12source $lib_dir/devlink_lib.sh
13
14h1_create()
15{
16	simple_if_init $h1 192.0.2.1/24
17	ip route add 198.51.100.0/24 vrf v$h1 nexthop via 192.0.2.2
18
19	tc qdisc add dev $h1 ingress
20}
21
22h1_destroy()
23{
24	tc qdisc del dev $h1 ingress
25
26	ip route del 198.51.100.0/24 vrf v$h1
27	simple_if_fini $h1 192.0.2.1/24
28}
29
30h2_create()
31{
32	simple_if_init $h2 198.51.100.1/24
33	ip route add 192.0.2.0/24 vrf v$h2 nexthop via 198.51.100.2
34
35	tc qdisc add dev $h2 ingress
36}
37
38h2_destroy()
39{
40	tc qdisc del dev $h2 ingress
41
42	ip route del 192.0.2.0/24 vrf v$h2
43	simple_if_fini $h2 198.51.100.1/24
44}
45
46router_create()
47{
48	ip link set dev $rp1 up
49	ip link set dev $rp2 up
50
51	tc qdisc add dev $rp1 clsact
52	tc qdisc add dev $rp2 clsact
53	ip address add 192.0.2.2/24 dev $rp1
54	ip address add 198.51.100.2/24 dev $rp2
55}
56
57router_destroy()
58{
59	ip address del 198.51.100.2/24 dev $rp2
60	ip address del 192.0.2.2/24 dev $rp1
61	tc qdisc del dev $rp2 clsact
62	tc qdisc del dev $rp1 clsact
63
64	ip link set dev $rp2 down
65	ip link set dev $rp1 down
66}
67
68setup_prepare()
69{
70	h1=${NETIFS[p1]}
71	rp1=${NETIFS[p2]}
72
73	rp2=${NETIFS[p3]}
74	h2=${NETIFS[p4]}
75
76	vrf_prepare
77
78	h1_create
79	h2_create
80
81	router_create
82
83	forwarding_enable
84}
85
86cleanup()
87{
88	pre_cleanup
89
90	forwarding_restore
91
92	router_destroy
93
94	h2_destroy
95	h1_destroy
96
97	vrf_cleanup
98}
99
100h1_to_h2()
101{
102	local test_name=$@; shift
103	local smac=$(mac_get $rp2)
104
105	RET=0
106
107	# Replace neighbour to avoid first packet being forwarded in software
108	ip neigh replace dev $rp2 198.51.100.1 lladdr $(mac_get $h2)
109
110	# Add a filter to ensure that packets are forwarded in hardware. Cannot
111	# match on source MAC because it is not set in eACL after routing
112	tc filter add dev $rp2 egress proto ip pref 1 handle 101 \
113		flower skip_sw ip_proto udp src_port 12345 dst_port 54321 \
114		action pass
115
116	# Add a filter to ensure that packets are received with the correct
117	# source MAC
118	tc filter add dev $h2 ingress proto ip pref 1 handle 101 \
119		flower skip_sw src_mac $smac ip_proto udp src_port 12345 \
120		dst_port 54321 action pass
121
122	$MZ $h1 -a own -b $(mac_get $rp1) -t udp "sp=12345,dp=54321" \
123		-A 192.0.2.1 -B 198.51.100.1 -c 10 -p 100 -d 1msec -q
124
125	tc_check_packets "dev $rp2 egress" 101 10
126	check_err $? "packets not forwarded in hardware"
127
128	tc_check_packets "dev $h2 ingress" 101 10
129	check_err $? "packets not forwarded with correct source mac"
130
131	log_test "h1->h2: $test_name"
132
133	tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
134	tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower
135	ip neigh del dev $rp2 198.51.100.1 lladdr $(mac_get $h2)
136}
137
138h2_to_h1()
139{
140	local test_name=$@; shift
141	local rp1_mac=$(mac_get $rp1)
142
143	RET=0
144
145	ip neigh replace dev $rp1 192.0.2.1 lladdr $(mac_get $h1)
146
147	tc filter add dev $rp1 egress proto ip pref 1 handle 101 \
148		flower skip_sw ip_proto udp src_port 54321 dst_port 12345 \
149		action pass
150
151	tc filter add dev $h1 ingress proto ip pref 1 handle 101 \
152		flower skip_sw src_mac $rp1_mac ip_proto udp src_port 54321 \
153		dst_port 12345 action pass
154
155	$MZ $h2 -a own -b $(mac_get $rp2) -t udp "sp=54321,dp=12345" \
156		-A 198.51.100.1 -B 192.0.2.1 -c 10 -p 100 -d 1msec -q
157
158	tc_check_packets "dev $rp1 egress" 101 10
159	check_err $? "packets not forwarded in hardware"
160
161	tc_check_packets "dev $h1 ingress" 101 10
162	check_err $? "packets not forwarded with correct source mac"
163
164	log_test "h2->h1: $test_name"
165
166	tc filter del dev $h1 ingress protocol ip pref 1 handle 101 flower
167	tc filter del dev $rp1 egress protocol ip pref 1 handle 101 flower
168	ip neigh del dev $rp1 192.0.2.1 lladdr $(mac_get $h1)
169}
170
171smac_test()
172{
173	local test_name=$@; shift
174
175	# Test that packets forwarded to $h2 via $rp2 are forwarded with the
176	# current source MAC of $rp2
177	h1_to_h2 $test_name
178
179	# Test that packets forwarded to $h1 via $rp1 are forwarded with the
180	# current source MAC of $rp1. This MAC is never changed during the test,
181	# but given the shared nature of MAC profile, the point is to see that
182	# changes to the MAC of $rp2 do not affect that of $rp1
183	h2_to_h1 $test_name
184}
185
186mac_profile_test()
187{
188	local rp2_mac=$(mac_get $rp2)
189
190	# Test behavior when the RIF backing $rp2 is transitioned to use
191	# a new MAC profile
192	ip link set dev $rp2 addr 00:11:22:33:44:55
193	smac_test "new mac profile"
194
195	# Test behavior when the MAC profile used by the RIF is edited
196	ip link set dev $rp2 address 00:22:22:22:22:22
197	smac_test "edit mac profile"
198
199	# Restore original MAC
200	ip link set dev $rp2 addr $rp2_mac
201}
202
203trap cleanup EXIT
204
205setup_prepare
206setup_wait
207
208mac_profiles=$(devlink_resource_size_get rif_mac_profiles)
209if [[ $mac_profiles -ne 1 ]]; then
210	tests_run
211fi
212
213exit $EXIT_STATUS
214