0001
0002
0003
0004
0005
0006
0007 readonly port=8000
0008
0009 readonly ns_prefix="ns-$$-"
0010 readonly ns1="${ns_prefix}1"
0011 readonly ns2="${ns_prefix}2"
0012
0013 readonly ns1_v4=192.168.1.1
0014 readonly ns2_v4=192.168.1.2
0015 readonly ns1_v6=fd::1
0016 readonly ns2_v6=fd::2
0017
0018
0019 readonly udpport=5555
0020
0021 readonly mplsudpport=6635
0022 readonly mplsproto=137
0023
0024 readonly infile="$(mktemp)"
0025 readonly outfile="$(mktemp)"
0026
0027 setup() {
0028 ip netns add "${ns1}"
0029 ip netns add "${ns2}"
0030
0031 ip link add dev veth1 mtu 1500 netns "${ns1}" type veth \
0032 peer name veth2 mtu 1500 netns "${ns2}"
0033
0034 ip netns exec "${ns1}" ethtool -K veth1 tso off
0035
0036 ip -netns "${ns1}" link set veth1 up
0037 ip -netns "${ns2}" link set veth2 up
0038
0039 ip -netns "${ns1}" -4 addr add "${ns1_v4}/24" dev veth1
0040 ip -netns "${ns2}" -4 addr add "${ns2_v4}/24" dev veth2
0041 ip -netns "${ns1}" -6 addr add "${ns1_v6}/64" dev veth1 nodad
0042 ip -netns "${ns2}" -6 addr add "${ns2_v6}/64" dev veth2 nodad
0043
0044
0045 ip -netns "${ns1}" -4 route flush table main
0046 ip -netns "${ns1}" -6 route flush table main
0047 ip -netns "${ns1}" -4 route add "${ns2_v4}" mtu 1450 dev veth1
0048 ip -netns "${ns1}" -6 route add "${ns2_v6}" mtu 1430 dev veth1
0049
0050 sleep 1
0051
0052 dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none
0053 }
0054
0055 cleanup() {
0056 ip netns del "${ns2}"
0057 ip netns del "${ns1}"
0058
0059 if [[ -f "${outfile}" ]]; then
0060 rm "${outfile}"
0061 fi
0062 if [[ -f "${infile}" ]]; then
0063 rm "${infile}"
0064 fi
0065
0066 if [[ -n $server_pid ]]; then
0067 kill $server_pid 2> /dev/null
0068 fi
0069 }
0070
0071 server_listen() {
0072 ip netns exec "${ns2}" nc "${netcat_opt}" -l "${port}" > "${outfile}" &
0073 server_pid=$!
0074 sleep 0.2
0075 }
0076
0077 client_connect() {
0078 ip netns exec "${ns1}" timeout 2 nc "${netcat_opt}" -w 1 "${addr2}" "${port}" < "${infile}"
0079 echo $?
0080 }
0081
0082 verify_data() {
0083 wait "${server_pid}"
0084 server_pid=
0085
0086
0087 insum=($(sha1sum ${infile}))
0088 outsum=($(sha1sum ${outfile}))
0089 if [[ "${insum[0]}" != "${outsum[0]}" ]]; then
0090 echo "data mismatch"
0091 exit 1
0092 fi
0093 }
0094
0095 set -e
0096
0097
0098 if [[ "$#" -eq "0" ]]; then
0099 echo "ipip"
0100 $0 ipv4 ipip none 100
0101
0102 echo "ip6ip6"
0103 $0 ipv6 ip6tnl none 100
0104
0105 echo "sit"
0106 $0 ipv6 sit none 100
0107
0108 echo "ip4 vxlan"
0109 $0 ipv4 vxlan eth 2000
0110
0111 echo "ip6 vxlan"
0112 $0 ipv6 ip6vxlan eth 2000
0113
0114 for mac in none mpls eth ; do
0115 echo "ip gre $mac"
0116 $0 ipv4 gre $mac 100
0117
0118 echo "ip6 gre $mac"
0119 $0 ipv6 ip6gre $mac 100
0120
0121 echo "ip gre $mac gso"
0122 $0 ipv4 gre $mac 2000
0123
0124 echo "ip6 gre $mac gso"
0125 $0 ipv6 ip6gre $mac 2000
0126
0127 echo "ip udp $mac"
0128 $0 ipv4 udp $mac 100
0129
0130 echo "ip6 udp $mac"
0131 $0 ipv6 ip6udp $mac 100
0132
0133 echo "ip udp $mac gso"
0134 $0 ipv4 udp $mac 2000
0135
0136 echo "ip6 udp $mac gso"
0137 $0 ipv6 ip6udp $mac 2000
0138 done
0139
0140 echo "OK. All tests passed"
0141 exit 0
0142 fi
0143
0144 if [[ "$#" -ne "4" ]]; then
0145 echo "Usage: $0"
0146 echo " or: $0 <ipv4|ipv6> <tuntype> <none|mpls|eth> <data_len>"
0147 exit 1
0148 fi
0149
0150 case "$1" in
0151 "ipv4")
0152 readonly addr1="${ns1_v4}"
0153 readonly addr2="${ns2_v4}"
0154 readonly ipproto=4
0155 readonly netcat_opt=-${ipproto}
0156 readonly foumod=fou
0157 readonly foutype=ipip
0158 readonly fouproto=4
0159 readonly fouproto_mpls=${mplsproto}
0160 readonly gretaptype=gretap
0161 ;;
0162 "ipv6")
0163 readonly addr1="${ns1_v6}"
0164 readonly addr2="${ns2_v6}"
0165 readonly ipproto=6
0166 readonly netcat_opt=-${ipproto}
0167 readonly foumod=fou6
0168 readonly foutype=ip6tnl
0169 readonly fouproto="41 -6"
0170 readonly fouproto_mpls="${mplsproto} -6"
0171 readonly gretaptype=ip6gretap
0172 ;;
0173 *)
0174 echo "unknown arg: $1"
0175 exit 1
0176 ;;
0177 esac
0178
0179 readonly tuntype=$2
0180 readonly mac=$3
0181 readonly datalen=$4
0182
0183 echo "encap ${addr1} to ${addr2}, type ${tuntype}, mac ${mac} len ${datalen}"
0184
0185 trap cleanup EXIT
0186
0187 setup
0188
0189
0190 echo "test basic connectivity"
0191 server_listen
0192 client_connect
0193 verify_data
0194
0195
0196
0197 ip netns exec "${ns1}" tc qdisc add dev veth1 clsact
0198 ip netns exec "${ns1}" tc filter add dev veth1 egress \
0199 bpf direct-action object-file ./test_tc_tunnel.o \
0200 section "encap_${tuntype}_${mac}"
0201 echo "test bpf encap without decap (expect failure)"
0202 server_listen
0203 ! client_connect
0204
0205 if [[ "$tuntype" =~ "udp" ]]; then
0206
0207 ttype="${foutype}"
0208 targs="encap fou encap-sport auto encap-dport $udpport"
0209
0210 modprobe "${foumod}" ||true
0211 if [[ "$mac" == "mpls" ]]; then
0212 dport=${mplsudpport}
0213 dproto=${fouproto_mpls}
0214 tmode="mode any ttl 255"
0215 else
0216 dport=${udpport}
0217 dproto=${fouproto}
0218 fi
0219 ip netns exec "${ns2}" ip fou add port $dport ipproto ${dproto}
0220 targs="encap fou encap-sport auto encap-dport $dport"
0221 elif [[ "$tuntype" =~ "gre" && "$mac" == "eth" ]]; then
0222 ttype=$gretaptype
0223 elif [[ "$tuntype" =~ "vxlan" && "$mac" == "eth" ]]; then
0224 ttype="vxlan"
0225 targs="id 1 dstport 8472 udp6zerocsumrx"
0226 else
0227 ttype=$tuntype
0228 targs=""
0229 fi
0230
0231
0232 if [[ "${tuntype}" == "sit" ]]; then
0233 link_addr1="${ns1_v4}"
0234 link_addr2="${ns2_v4}"
0235 else
0236 link_addr1="${addr1}"
0237 link_addr2="${addr2}"
0238 fi
0239
0240
0241
0242
0243 ip netns exec "${ns2}" ip link add name testtun0 type "${ttype}" \
0244 ${tmode} remote "${link_addr1}" local "${link_addr2}" $targs
0245
0246 expect_tun_fail=0
0247
0248 if [[ "$tuntype" == "ip6udp" && "$mac" == "mpls" ]]; then
0249
0250 expect_tun_fail=1
0251 elif [[ "$tuntype" =~ "udp" && "$mac" == "eth" ]]; then
0252
0253 expect_tun_fail=1
0254 elif [[ "$tuntype" =~ (gre|vxlan) && "$mac" == "eth" ]]; then
0255
0256 ethaddr=$(ip netns exec "${ns2}" ip link show veth2 | \
0257 awk '/ether/ { print $2 }')
0258 ip netns exec "${ns2}" ip link set testtun0 address $ethaddr
0259 elif [[ "$mac" == "mpls" ]]; then
0260 modprobe mpls_iptunnel ||true
0261 modprobe mpls_gso ||true
0262 ip netns exec "${ns2}" sysctl -qw net.mpls.platform_labels=65536
0263 ip netns exec "${ns2}" ip -f mpls route add 1000 dev lo
0264 ip netns exec "${ns2}" ip link set lo up
0265 ip netns exec "${ns2}" sysctl -qw net.mpls.conf.testtun0.input=1
0266 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.lo.rp_filter=0
0267 fi
0268
0269
0270
0271
0272
0273 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.rp_filter=0
0274
0275
0276 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.testtun0.rp_filter=0
0277 ip netns exec "${ns2}" ip link set dev testtun0 up
0278 if [[ "$expect_tun_fail" == 1 ]]; then
0279
0280 echo "test bpf encap with tunnel device decap (expect failure)"
0281 ! client_connect
0282 else
0283 echo "test bpf encap with tunnel device decap"
0284 client_connect
0285 verify_data
0286 server_listen
0287 fi
0288
0289
0290 if [[ "${tuntype}" == "sit" ]]; then
0291 echo OK
0292 exit 0
0293 fi
0294
0295
0296 ip netns exec "${ns2}" ip link del dev testtun0
0297 ip netns exec "${ns2}" tc qdisc add dev veth2 clsact
0298 ip netns exec "${ns2}" tc filter add dev veth2 ingress \
0299 bpf direct-action object-file ./test_tc_tunnel.o section decap
0300 echo "test bpf encap with bpf decap"
0301 client_connect
0302 verify_data
0303
0304 echo OK