0001
0002
0003
0004
0005
0006 lib_dir=$(dirname $0)/../../../net/forwarding
0007
0008 ALL_TESTS="
0009 ipv6_route_add
0010 ipv6_route_replace
0011 ipv6_route_nexthop_group_share
0012 ipv6_route_rate
0013 "
0014 NUM_NETIFS=4
0015 source $lib_dir/lib.sh
0016 source $lib_dir/devlink_lib.sh
0017
0018 tor1_create()
0019 {
0020 simple_if_init $tor1_p1 2001:db8:1::2/128 2001:db8:1::3/128
0021 }
0022
0023 tor1_destroy()
0024 {
0025 simple_if_fini $tor1_p1 2001:db8:1::2/128 2001:db8:1::3/128
0026 }
0027
0028 tor2_create()
0029 {
0030 simple_if_init $tor2_p1 2001:db8:2::2/128 2001:db8:2::3/128
0031 }
0032
0033 tor2_destroy()
0034 {
0035 simple_if_fini $tor2_p1 2001:db8:2::2/128 2001:db8:2::3/128
0036 }
0037
0038 spine_create()
0039 {
0040 ip link set dev $spine_p1 up
0041 ip link set dev $spine_p2 up
0042
0043 __addr_add_del $spine_p1 add 2001:db8:1::1/64
0044 __addr_add_del $spine_p2 add 2001:db8:2::1/64
0045 }
0046
0047 spine_destroy()
0048 {
0049 __addr_add_del $spine_p2 del 2001:db8:2::1/64
0050 __addr_add_del $spine_p1 del 2001:db8:1::1/64
0051
0052 ip link set dev $spine_p2 down
0053 ip link set dev $spine_p1 down
0054 }
0055
0056 ipv6_offload_check()
0057 {
0058 local pfx="$1"; shift
0059 local expected_num=$1; shift
0060 local num
0061
0062
0063 sleep .1
0064
0065 num=$(ip -6 route show match ${pfx} | grep "offload" | wc -l)
0066
0067 if [ $num -eq $expected_num ]; then
0068 return 0
0069 fi
0070
0071 return 1
0072 }
0073
0074 ipv6_route_add_prefix()
0075 {
0076 RET=0
0077
0078
0079 ip -6 route add 2001:db8:3::/64 dev $spine_p1 metric 100
0080 ipv6_offload_check "2001:db8:3::/64 dev $spine_p1 metric 100" 1
0081 check_err $? "prefix route not offloaded"
0082
0083
0084
0085 ip -6 route append 2001:db8:3::/64 dev $spine_p1 metric 200
0086 ipv6_offload_check "2001:db8:3::/64 dev $spine_p1 metric 100" 1
0087 check_err $? "lowest metric not offloaded after append"
0088 ipv6_offload_check "2001:db8:3::/64 dev $spine_p1 metric 200" 0
0089 check_err $? "highest metric offloaded when should not"
0090
0091
0092
0093 ip -6 route append 2001:db8:3::/64 dev $spine_p1 metric 10
0094 ipv6_offload_check "2001:db8:3::/64 dev $spine_p1 metric 10" 1
0095 check_err $? "lowest metric not offloaded after prepend"
0096 ipv6_offload_check "2001:db8:3::/64 dev $spine_p1 metric 100" 0
0097 check_err $? "mid metric offloaded when should not"
0098 ipv6_offload_check "2001:db8:3::/64 dev $spine_p1 metric 200" 0
0099 check_err $? "highest metric offloaded when should not"
0100
0101
0102
0103 ip -6 route flush 2001:db8:3::/64 dev $spine_p1
0104 ip -6 route add 2001:db8:3::/64 dev $spine_p2
0105 ipv6_offload_check "2001:db8:3::/64 dev $spine_p2" 1
0106
0107 log_test "IPv6 prefix route add"
0108
0109 ip -6 route flush 2001:db8:3::/64
0110 }
0111
0112 ipv6_route_add_mpath()
0113 {
0114 RET=0
0115
0116
0117 ip -6 route add 2001:db8:3::/64 metric 100 \
0118 nexthop via 2001:db8:1::2 dev $spine_p1 \
0119 nexthop via 2001:db8:2::2 dev $spine_p2
0120 ipv6_offload_check "2001:db8:3::/64 metric 100" 2
0121 check_err $? "multipath route not offloaded when should"
0122
0123
0124 ip -6 route append 2001:db8:3::/64 metric 100 \
0125 nexthop via 2001:db8:1::3 dev $spine_p1
0126 ipv6_offload_check "2001:db8:3::/64 metric 100" 3
0127 check_err $? "appended nexthop not offloaded when should"
0128
0129
0130
0131 ip -6 route del 2001:db8:3::/64
0132 ip -6 route add 2001:db8:3::/64 metric 100 \
0133 nexthop via 2001:db8:1::2 dev $spine_p1 \
0134 nexthop via 2001:db8:2::2 dev $spine_p2
0135 ipv6_offload_check "2001:db8:3::/64 metric 100" 2
0136 check_err $? "multipath route not offloaded after delete & add"
0137
0138
0139
0140 ip -6 route append 2001:db8:3::/64 metric 200 \
0141 nexthop via 2001:db8:1::3 dev $spine_p1
0142 ipv6_offload_check "2001:db8:3::/64 metric 100" 2
0143 check_err $? "lowest metric not offloaded after append"
0144 ipv6_offload_check "2001:db8:3::/64 metric 200" 0
0145 check_err $? "highest metric offloaded when should not"
0146
0147
0148
0149 ip -6 route append 2001:db8:3::/64 metric 10 \
0150 nexthop via 2001:db8:1::3 dev $spine_p1
0151 ipv6_offload_check "2001:db8:3::/64 metric 10" 1
0152 check_err $? "lowest metric not offloaded after prepend"
0153 ipv6_offload_check "2001:db8:3::/64 metric 100" 0
0154 check_err $? "mid metric offloaded when should not"
0155 ipv6_offload_check "2001:db8:3::/64 metric 200" 0
0156 check_err $? "highest metric offloaded when should not"
0157
0158 log_test "IPv6 multipath route add"
0159
0160 ip -6 route flush 2001:db8:3::/64
0161 }
0162
0163 ipv6_route_add()
0164 {
0165 ipv6_route_add_prefix
0166 ipv6_route_add_mpath
0167 }
0168
0169 ipv6_route_replace()
0170 {
0171 RET=0
0172
0173
0174 ip -6 route add 2001:db8:3::/64 metric 100 dev $spine_p1
0175 ipv6_offload_check "2001:db8:3::/64 metric 100" 1
0176 check_err $? "prefix route not offloaded when should"
0177 ip -6 route replace 2001:db8:3::/64 metric 100 dev $spine_p2
0178 ipv6_offload_check "2001:db8:3::/64 metric 100" 1
0179 check_err $? "prefix route not offloaded after replace"
0180
0181
0182 ip -6 route replace 2001:db8:3::/64 metric 100 \
0183 nexthop via 2001:db8:1::2 dev $spine_p1 \
0184 nexthop via 2001:db8:2::2 dev $spine_p2
0185 ipv6_offload_check "2001:db8:3::/64 metric 100" 2
0186 check_err $? "multipath route not offloaded after replace"
0187
0188
0189
0190 ip -6 route replace 2001:db8:3::/64 metric 100 dev $spine_p1
0191 ipv6_offload_check "2001:db8:3::/64 metric 100 dev $spine_p1" 0
0192 check_err $? "prefix route offloaded after 'replacing' multipath route"
0193 ipv6_offload_check "2001:db8:3::/64 metric 100" 2
0194 check_err $? "multipath route not offloaded after being 'replaced' by prefix route"
0195
0196
0197 ip -6 route replace 2001:db8:3::/64 metric 100 \
0198 nexthop via 2001:db8:1::3 dev $spine_p1 \
0199 nexthop via 2001:db8:2::3 dev $spine_p2
0200 ipv6_offload_check "2001:db8:3::/64 metric 100" 2
0201 check_err $? "multipath route not offloaded after replacing multipath route"
0202
0203
0204
0205 ip -6 route replace 2001:db8:3::/64 metric 200 \
0206 nexthop via 2001:db8:1::3 dev $spine_p1 \
0207 nexthop via 2001:db8:2::3 dev $spine_p2
0208 ipv6_offload_check "2001:db8:3::/64 metric 100" 2
0209 check_err $? "multipath route not offloaded after non-existing route was 'replaced'"
0210 ipv6_offload_check "2001:db8:3::/64 metric 200" 0
0211 check_err $? "multipath route offloaded after 'replacing' non-existing route"
0212
0213 log_test "IPv6 route replace"
0214
0215 ip -6 route flush 2001:db8:3::/64
0216 }
0217
0218 ipv6_route_nexthop_group_share()
0219 {
0220 RET=0
0221
0222
0223
0224
0225 ip -6 route add 2001:db8:3::/64 \
0226 nexthop via 2001:db8:1::2 dev $spine_p1 \
0227 nexthop via 2001:db8:2::2 dev $spine_p2
0228 ip -6 route add 2001:db8:4::/64 \
0229 nexthop via 2001:db8:1::2 dev $spine_p1 \
0230 nexthop via 2001:db8:2::2 dev $spine_p2
0231 ipv6_offload_check "2001:db8:3::/64" 2
0232 check_err $? "multipath route not offloaded when should"
0233 ipv6_offload_check "2001:db8:4::/64" 2
0234 check_err $? "multipath route not offloaded when should"
0235 ip -6 route del 2001:db8:3::/64
0236 ipv6_offload_check "2001:db8:4::/64" 2
0237 check_err $? "multipath route not offloaded after deletion of route sharing the nexthop group"
0238
0239
0240
0241 ip -6 route add 2001:db8:3::/64 \
0242 nexthop via 2001:db8:1::2 dev $spine_p1 \
0243 nexthop via 2001:db8:2::2 dev $spine_p2
0244 ip -6 route del 2001:db8:4::/64 \
0245 nexthop via 2001:db8:1::2 dev $spine_p1
0246 ipv6_offload_check "2001:db8:4::/64" 1
0247 check_err $? "singlepath route not offloaded after unsharing the nexthop group"
0248 ipv6_offload_check "2001:db8:3::/64" 2
0249 check_err $? "multipath route not offloaded after unsharing the nexthop group"
0250
0251 log_test "IPv6 nexthop group sharing"
0252
0253 ip -6 route flush 2001:db8:3::/64
0254 ip -6 route flush 2001:db8:4::/64
0255 }
0256
0257 ipv6_route_rate()
0258 {
0259 local batch_dir=$(mktemp -d)
0260 local num_rts=$((40 * 1024))
0261 local num_nhs=16
0262 local total
0263 local start
0264 local diff
0265 local end
0266 local nhs
0267 local i
0268
0269 RET=0
0270
0271
0272
0273
0274
0275 total=$((nums_nhs * num_rts))
0276
0277 for i in $(seq 1 $num_nhs); do
0278 ip -6 address add 2001:db8:1::10:$i/128 dev $tor1_p1
0279 nexthops+=" nexthop via 2001:db8:1::10:$i dev $spine_p1"
0280 done
0281
0282 for i in $(seq 1 $num_rts); do
0283 echo "route add 2001:db8:8:$(printf "%x" $i)::/64$nexthops" \
0284 >> $batch_dir/add.batch
0285 echo "route del 2001:db8:8:$(printf "%x" $i)::/64$nexthops" \
0286 >> $batch_dir/del.batch
0287 done
0288
0289 start=$(date +%s.%N)
0290
0291 ip -batch $batch_dir/add.batch
0292 count=$(ip -6 route show | grep offload | wc -l)
0293 while [ $count -lt $total ]; do
0294 sleep .01
0295 count=$(ip -6 route show | grep offload | wc -l)
0296 done
0297
0298 end=$(date +%s.%N)
0299
0300 diff=$(echo "$end - $start" | bc -l)
0301 test "$(echo "$diff > 60" | bc -l)" -eq 0
0302 check_err $? "route insertion took too long"
0303 log_info "inserted $num_rts routes in $diff seconds"
0304
0305 log_test "IPv6 routes insertion rate"
0306
0307 ip -batch $batch_dir/del.batch
0308 for i in $(seq 1 $num_nhs); do
0309 ip -6 address del 2001:db8:1::10:$i/128 dev $tor1_p1
0310 done
0311 rm -rf $batch_dir
0312 }
0313
0314 setup_prepare()
0315 {
0316 spine_p1=${NETIFS[p1]}
0317 tor1_p1=${NETIFS[p2]}
0318
0319 spine_p2=${NETIFS[p3]}
0320 tor2_p1=${NETIFS[p4]}
0321
0322 vrf_prepare
0323 forwarding_enable
0324
0325 tor1_create
0326 tor2_create
0327 spine_create
0328 }
0329
0330 cleanup()
0331 {
0332 pre_cleanup
0333
0334 spine_destroy
0335 tor2_destroy
0336 tor1_destroy
0337
0338 forwarding_restore
0339 vrf_cleanup
0340 }
0341
0342 trap cleanup EXIT
0343
0344 setup_prepare
0345 setup_wait
0346
0347 tests_run
0348
0349 exit $EXIT_STATUS