1*4882a593Smuzhiyun#!/bin/bash 2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0 3*4882a593Smuzhiyun 4*4882a593SmuzhiyunALL_TESTS=" 5*4882a593Smuzhiyun ping_ipv4 6*4882a593Smuzhiyun ping_ipv6 7*4882a593Smuzhiyun sip_in_class_e 8*4882a593Smuzhiyun mc_mac_mismatch 9*4882a593Smuzhiyun ipv4_sip_equal_dip 10*4882a593Smuzhiyun ipv6_sip_equal_dip 11*4882a593Smuzhiyun ipv4_dip_link_local 12*4882a593Smuzhiyun" 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunNUM_NETIFS=4 15*4882a593Smuzhiyunsource lib.sh 16*4882a593Smuzhiyunsource tc_common.sh 17*4882a593Smuzhiyun 18*4882a593Smuzhiyunrequire_command $MCD 19*4882a593Smuzhiyunrequire_command $MC_CLI 20*4882a593Smuzhiyuntable_name=selftests 21*4882a593Smuzhiyun 22*4882a593Smuzhiyunh1_create() 23*4882a593Smuzhiyun{ 24*4882a593Smuzhiyun vrf_create "vrf-h1" 25*4882a593Smuzhiyun ip link set dev $h1 master vrf-h1 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun ip link set dev vrf-h1 up 28*4882a593Smuzhiyun ip link set dev $h1 up 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun ip address add 192.0.2.2/24 dev $h1 31*4882a593Smuzhiyun ip address add 2001:db8:1::2/64 dev $h1 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1 34*4882a593Smuzhiyun ip route add 2001:db8:2::/64 vrf vrf-h1 nexthop via 2001:db8:1::1 35*4882a593Smuzhiyun} 36*4882a593Smuzhiyun 37*4882a593Smuzhiyunh1_destroy() 38*4882a593Smuzhiyun{ 39*4882a593Smuzhiyun ip route del 2001:db8:2::/64 vrf vrf-h1 40*4882a593Smuzhiyun ip route del 198.51.100.0/24 vrf vrf-h1 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun ip address del 2001:db8:1::2/64 dev $h1 43*4882a593Smuzhiyun ip address del 192.0.2.2/24 dev $h1 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun ip link set dev $h1 down 46*4882a593Smuzhiyun vrf_destroy "vrf-h1" 47*4882a593Smuzhiyun} 48*4882a593Smuzhiyun 49*4882a593Smuzhiyunh2_create() 50*4882a593Smuzhiyun{ 51*4882a593Smuzhiyun vrf_create "vrf-h2" 52*4882a593Smuzhiyun ip link set dev $h2 master vrf-h2 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun ip link set dev vrf-h2 up 55*4882a593Smuzhiyun ip link set dev $h2 up 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun ip address add 198.51.100.2/24 dev $h2 58*4882a593Smuzhiyun ip address add 2001:db8:2::2/64 dev $h2 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1 61*4882a593Smuzhiyun ip route add 2001:db8:1::/64 vrf vrf-h2 nexthop via 2001:db8:2::1 62*4882a593Smuzhiyun} 63*4882a593Smuzhiyun 64*4882a593Smuzhiyunh2_destroy() 65*4882a593Smuzhiyun{ 66*4882a593Smuzhiyun ip route del 2001:db8:1::/64 vrf vrf-h2 67*4882a593Smuzhiyun ip route del 192.0.2.0/24 vrf vrf-h2 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun ip address del 2001:db8:2::2/64 dev $h2 70*4882a593Smuzhiyun ip address del 198.51.100.2/24 dev $h2 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun ip link set dev $h2 down 73*4882a593Smuzhiyun vrf_destroy "vrf-h2" 74*4882a593Smuzhiyun} 75*4882a593Smuzhiyun 76*4882a593Smuzhiyunrouter_create() 77*4882a593Smuzhiyun{ 78*4882a593Smuzhiyun ip link set dev $rp1 up 79*4882a593Smuzhiyun ip link set dev $rp2 up 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun tc qdisc add dev $rp2 clsact 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun ip address add 192.0.2.1/24 dev $rp1 84*4882a593Smuzhiyun ip address add 2001:db8:1::1/64 dev $rp1 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun ip address add 198.51.100.1/24 dev $rp2 87*4882a593Smuzhiyun ip address add 2001:db8:2::1/64 dev $rp2 88*4882a593Smuzhiyun} 89*4882a593Smuzhiyun 90*4882a593Smuzhiyunrouter_destroy() 91*4882a593Smuzhiyun{ 92*4882a593Smuzhiyun ip address del 2001:db8:2::1/64 dev $rp2 93*4882a593Smuzhiyun ip address del 198.51.100.1/24 dev $rp2 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun ip address del 2001:db8:1::1/64 dev $rp1 96*4882a593Smuzhiyun ip address del 192.0.2.1/24 dev $rp1 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun tc qdisc del dev $rp2 clsact 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun ip link set dev $rp2 down 101*4882a593Smuzhiyun ip link set dev $rp1 down 102*4882a593Smuzhiyun} 103*4882a593Smuzhiyun 104*4882a593Smuzhiyunstart_mcd() 105*4882a593Smuzhiyun{ 106*4882a593Smuzhiyun SMCROUTEDIR="$(mktemp -d)" 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun for ((i = 1; i <= $NUM_NETIFS; ++i)); do 109*4882a593Smuzhiyun echo "phyint ${NETIFS[p$i]} enable" >> \ 110*4882a593Smuzhiyun $SMCROUTEDIR/$table_name.conf 111*4882a593Smuzhiyun done 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun $MCD -N -I $table_name -f $SMCROUTEDIR/$table_name.conf \ 114*4882a593Smuzhiyun -P $SMCROUTEDIR/$table_name.pid 115*4882a593Smuzhiyun} 116*4882a593Smuzhiyun 117*4882a593Smuzhiyunkill_mcd() 118*4882a593Smuzhiyun{ 119*4882a593Smuzhiyun pkill $MCD 120*4882a593Smuzhiyun rm -rf $SMCROUTEDIR 121*4882a593Smuzhiyun} 122*4882a593Smuzhiyun 123*4882a593Smuzhiyunsetup_prepare() 124*4882a593Smuzhiyun{ 125*4882a593Smuzhiyun h1=${NETIFS[p1]} 126*4882a593Smuzhiyun rp1=${NETIFS[p2]} 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun rp2=${NETIFS[p3]} 129*4882a593Smuzhiyun h2=${NETIFS[p4]} 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun rp1mac=$(mac_get $rp1) 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun start_mcd 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun vrf_prepare 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun h1_create 138*4882a593Smuzhiyun h2_create 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun router_create 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun forwarding_enable 143*4882a593Smuzhiyun} 144*4882a593Smuzhiyun 145*4882a593Smuzhiyuncleanup() 146*4882a593Smuzhiyun{ 147*4882a593Smuzhiyun pre_cleanup 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun forwarding_restore 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun router_destroy 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun h2_destroy 154*4882a593Smuzhiyun h1_destroy 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun vrf_cleanup 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun kill_mcd 159*4882a593Smuzhiyun} 160*4882a593Smuzhiyun 161*4882a593Smuzhiyunping_ipv4() 162*4882a593Smuzhiyun{ 163*4882a593Smuzhiyun ping_test $h1 198.51.100.2 164*4882a593Smuzhiyun} 165*4882a593Smuzhiyun 166*4882a593Smuzhiyunping_ipv6() 167*4882a593Smuzhiyun{ 168*4882a593Smuzhiyun ping6_test $h1 2001:db8:2::2 169*4882a593Smuzhiyun} 170*4882a593Smuzhiyun 171*4882a593Smuzhiyunsip_in_class_e() 172*4882a593Smuzhiyun{ 173*4882a593Smuzhiyun RET=0 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun # Disable rpfilter to prevent packets to be dropped because of it. 176*4882a593Smuzhiyun sysctl_set net.ipv4.conf.all.rp_filter 0 177*4882a593Smuzhiyun sysctl_set net.ipv4.conf.$rp1.rp_filter 0 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \ 180*4882a593Smuzhiyun flower src_ip 240.0.0.1 ip_proto udp action pass 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun $MZ $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec \ 183*4882a593Smuzhiyun -A 240.0.0.1 -b $rp1mac -B 198.51.100.2 -q 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun tc_check_packets "dev $rp2 egress" 101 5 186*4882a593Smuzhiyun check_err $? "Packets were dropped" 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun log_test "Source IP in class E" 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower 191*4882a593Smuzhiyun sysctl_restore net.ipv4.conf.$rp1.rp_filter 192*4882a593Smuzhiyun sysctl_restore net.ipv4.conf.all.rp_filter 193*4882a593Smuzhiyun} 194*4882a593Smuzhiyun 195*4882a593Smuzhiyuncreate_mcast_sg() 196*4882a593Smuzhiyun{ 197*4882a593Smuzhiyun local if_name=$1; shift 198*4882a593Smuzhiyun local s_addr=$1; shift 199*4882a593Smuzhiyun local mcast=$1; shift 200*4882a593Smuzhiyun local dest_ifs=${@} 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun $MC_CLI -I $table_name add $if_name $s_addr $mcast $dest_ifs 203*4882a593Smuzhiyun} 204*4882a593Smuzhiyun 205*4882a593Smuzhiyundelete_mcast_sg() 206*4882a593Smuzhiyun{ 207*4882a593Smuzhiyun local if_name=$1; shift 208*4882a593Smuzhiyun local s_addr=$1; shift 209*4882a593Smuzhiyun local mcast=$1; shift 210*4882a593Smuzhiyun local dest_ifs=${@} 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun $MC_CLI -I $table_name remove $if_name $s_addr $mcast $dest_ifs 213*4882a593Smuzhiyun} 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun__mc_mac_mismatch() 216*4882a593Smuzhiyun{ 217*4882a593Smuzhiyun local desc=$1; shift 218*4882a593Smuzhiyun local proto=$1; shift 219*4882a593Smuzhiyun local sip=$1; shift 220*4882a593Smuzhiyun local dip=$1; shift 221*4882a593Smuzhiyun local flags=${1:-""}; shift 222*4882a593Smuzhiyun local dmac=01:02:03:04:05:06 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun RET=0 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \ 227*4882a593Smuzhiyun flower dst_ip $dip action pass 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun create_mcast_sg $rp1 $sip $dip $rp2 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun $MZ $flags $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec -b $dmac \ 232*4882a593Smuzhiyun -B $dip -q 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun tc_check_packets "dev $rp2 egress" 101 5 235*4882a593Smuzhiyun check_err $? "Packets were dropped" 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun log_test "Multicast MAC mismatch: $desc" 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun delete_mcast_sg $rp1 $sip $dip $rp2 240*4882a593Smuzhiyun tc filter del dev $rp2 egress protocol $proto pref 1 handle 101 flower 241*4882a593Smuzhiyun} 242*4882a593Smuzhiyun 243*4882a593Smuzhiyunmc_mac_mismatch() 244*4882a593Smuzhiyun{ 245*4882a593Smuzhiyun __mc_mac_mismatch "IPv4" "ip" 192.0.2.2 225.1.2.3 246*4882a593Smuzhiyun __mc_mac_mismatch "IPv6" "ipv6" 2001:db8:1::2 ff0e::3 "-6" 247*4882a593Smuzhiyun} 248*4882a593Smuzhiyun 249*4882a593Smuzhiyunipv4_sip_equal_dip() 250*4882a593Smuzhiyun{ 251*4882a593Smuzhiyun RET=0 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun # Disable rpfilter to prevent packets to be dropped because of it. 254*4882a593Smuzhiyun sysctl_set net.ipv4.conf.all.rp_filter 0 255*4882a593Smuzhiyun sysctl_set net.ipv4.conf.$rp1.rp_filter 0 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \ 258*4882a593Smuzhiyun flower src_ip 198.51.100.2 action pass 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun $MZ $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec \ 261*4882a593Smuzhiyun -A 198.51.100.2 -b $rp1mac -B 198.51.100.2 -q 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun tc_check_packets "dev $rp2 egress" 101 5 264*4882a593Smuzhiyun check_err $? "Packets were dropped" 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun log_test "Source IP is equal to destination IP: IPv4" 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower 269*4882a593Smuzhiyun sysctl_restore net.ipv4.conf.$rp1.rp_filter 270*4882a593Smuzhiyun sysctl_restore net.ipv4.conf.all.rp_filter 271*4882a593Smuzhiyun} 272*4882a593Smuzhiyun 273*4882a593Smuzhiyunipv6_sip_equal_dip() 274*4882a593Smuzhiyun{ 275*4882a593Smuzhiyun RET=0 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \ 278*4882a593Smuzhiyun flower src_ip 2001:db8:2::2 action pass 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun $MZ -6 $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec \ 281*4882a593Smuzhiyun -A 2001:db8:2::2 -b $rp1mac -B 2001:db8:2::2 -q 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun tc_check_packets "dev $rp2 egress" 101 5 284*4882a593Smuzhiyun check_err $? "Packets were dropped" 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun log_test "Source IP is equal to destination IP: IPv6" 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun tc filter del dev $rp2 egress protocol ipv6 pref 1 handle 101 flower 289*4882a593Smuzhiyun} 290*4882a593Smuzhiyun 291*4882a593Smuzhiyunipv4_dip_link_local() 292*4882a593Smuzhiyun{ 293*4882a593Smuzhiyun local dip=169.254.1.1 294*4882a593Smuzhiyun 295*4882a593Smuzhiyun RET=0 296*4882a593Smuzhiyun 297*4882a593Smuzhiyun tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \ 298*4882a593Smuzhiyun flower dst_ip $dip action pass 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun ip neigh add 169.254.1.1 lladdr 00:11:22:33:44:55 dev $rp2 301*4882a593Smuzhiyun ip route add 169.254.1.0/24 dev $rp2 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun $MZ $h1 -t udp "sp=54321,dp=12345" -c 5 -d 1msec -b $rp1mac -B $dip -q 304*4882a593Smuzhiyun 305*4882a593Smuzhiyun tc_check_packets "dev $rp2 egress" 101 5 306*4882a593Smuzhiyun check_err $? "Packets were dropped" 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun log_test "IPv4 destination IP is link-local" 309*4882a593Smuzhiyun 310*4882a593Smuzhiyun ip route del 169.254.1.0/24 dev $rp2 311*4882a593Smuzhiyun ip neigh del 169.254.1.1 lladdr 00:11:22:33:44:55 dev $rp2 312*4882a593Smuzhiyun tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower 313*4882a593Smuzhiyun} 314*4882a593Smuzhiyun 315*4882a593Smuzhiyuntrap cleanup EXIT 316*4882a593Smuzhiyun 317*4882a593Smuzhiyunsetup_prepare 318*4882a593Smuzhiyunsetup_wait 319*4882a593Smuzhiyun 320*4882a593Smuzhiyuntests_run 321*4882a593Smuzhiyun 322*4882a593Smuzhiyunexit $EXIT_STATUS 323