GNU Linux-libre 4.9.282-gnu1
[releases.git] / samples / bpf / tc_l2_redirect.sh
1 #!/bin/bash
2
3 [[ -z $TC ]] && TC='tc'
4 [[ -z $IP ]] && IP='ip'
5
6 REDIRECT_USER='./tc_l2_redirect'
7 REDIRECT_BPF='./tc_l2_redirect_kern.o'
8
9 RP_FILTER=$(< /proc/sys/net/ipv4/conf/all/rp_filter)
10 IPV6_FORWARDING=$(< /proc/sys/net/ipv6/conf/all/forwarding)
11
12 function config_common {
13         local tun_type=$1
14
15         $IP netns add ns1
16         $IP netns add ns2
17         $IP link add ve1 type veth peer name vens1
18         $IP link add ve2 type veth peer name vens2
19         $IP link set dev ve1 up
20         $IP link set dev ve2 up
21         $IP link set dev ve1 mtu 1500
22         $IP link set dev ve2 mtu 1500
23         $IP link set dev vens1 netns ns1
24         $IP link set dev vens2 netns ns2
25
26         $IP -n ns1 link set dev lo up
27         $IP -n ns1 link set dev vens1 up
28         $IP -n ns1 addr add 10.1.1.101/24 dev vens1
29         $IP -n ns1 addr add 2401:db01::65/64 dev vens1 nodad
30         $IP -n ns1 route add default via 10.1.1.1 dev vens1
31         $IP -n ns1 route add default via 2401:db01::1 dev vens1
32
33         $IP -n ns2 link set dev lo up
34         $IP -n ns2 link set dev vens2 up
35         $IP -n ns2 addr add 10.2.1.102/24 dev vens2
36         $IP -n ns2 addr add 2401:db02::66/64 dev vens2 nodad
37         $IP -n ns2 addr add 10.10.1.102 dev lo
38         $IP -n ns2 addr add 2401:face::66/64 dev lo nodad
39         $IP -n ns2 link add ipt2 type ipip local 10.2.1.102 remote 10.2.1.1
40         $IP -n ns2 link add ip6t2 type ip6tnl mode any local 2401:db02::66 remote 2401:db02::1
41         $IP -n ns2 link set dev ipt2 up
42         $IP -n ns2 link set dev ip6t2 up
43         $IP netns exec ns2 $TC qdisc add dev vens2 clsact
44         $IP netns exec ns2 $TC filter add dev vens2 ingress bpf da obj $REDIRECT_BPF sec drop_non_tun_vip
45         if [[ $tun_type == "ipip" ]]; then
46                 $IP -n ns2 route add 10.1.1.0/24 dev ipt2
47                 $IP netns exec ns2 sysctl -q -w net.ipv4.conf.all.rp_filter=0
48                 $IP netns exec ns2 sysctl -q -w net.ipv4.conf.ipt2.rp_filter=0
49         else
50                 $IP -n ns2 route add 10.1.1.0/24 dev ip6t2
51                 $IP -n ns2 route add 2401:db01::/64 dev ip6t2
52                 $IP netns exec ns2 sysctl -q -w net.ipv4.conf.all.rp_filter=0
53                 $IP netns exec ns2 sysctl -q -w net.ipv4.conf.ip6t2.rp_filter=0
54         fi
55
56         $IP addr add 10.1.1.1/24 dev ve1
57         $IP addr add 2401:db01::1/64 dev ve1 nodad
58         $IP addr add 10.2.1.1/24 dev ve2
59         $IP addr add 2401:db02::1/64 dev ve2 nodad
60
61         $TC qdisc add dev ve2 clsact
62         $TC filter add dev ve2 ingress bpf da obj $REDIRECT_BPF sec l2_to_iptun_ingress_forward
63
64         sysctl -q -w net.ipv4.conf.all.rp_filter=0
65         sysctl -q -w net.ipv6.conf.all.forwarding=1
66 }
67
68 function cleanup {
69         set +e
70         [[ -z $DEBUG ]] || set +x
71         $IP netns delete ns1 >& /dev/null
72         $IP netns delete ns2 >& /dev/null
73         $IP link del ve1 >& /dev/null
74         $IP link del ve2 >& /dev/null
75         $IP link del ipt >& /dev/null
76         $IP link del ip6t >& /dev/null
77         sysctl -q -w net.ipv4.conf.all.rp_filter=$RP_FILTER
78         sysctl -q -w net.ipv6.conf.all.forwarding=$IPV6_FORWARDING
79         rm -f /sys/fs/bpf/tc/globals/tun_iface
80         [[ -z $DEBUG ]] || set -x
81         set -e
82 }
83
84 function l2_to_ipip {
85         echo -n "l2_to_ipip $1: "
86
87         local dir=$1
88
89         config_common ipip
90
91         $IP link add ipt type ipip external
92         $IP link set dev ipt up
93         sysctl -q -w net.ipv4.conf.ipt.rp_filter=0
94         sysctl -q -w net.ipv4.conf.ipt.forwarding=1
95
96         if [[ $dir == "egress" ]]; then
97                 $IP route add 10.10.1.0/24 via 10.2.1.102 dev ve2
98                 $TC filter add dev ve2 egress bpf da obj $REDIRECT_BPF sec l2_to_iptun_ingress_redirect
99                 sysctl -q -w net.ipv4.conf.ve1.forwarding=1
100         else
101                 $TC qdisc add dev ve1 clsact
102                 $TC filter add dev ve1 ingress bpf da obj $REDIRECT_BPF sec l2_to_iptun_ingress_redirect
103         fi
104
105         $REDIRECT_USER -U /sys/fs/bpf/tc/globals/tun_iface -i $(< /sys/class/net/ipt/ifindex)
106
107         $IP netns exec ns1 ping -c1 10.10.1.102 >& /dev/null
108
109         if [[ $dir == "egress" ]]; then
110                 # test direct egress to ve2 (i.e. not forwarding from
111                 # ve1 to ve2).
112                 ping -c1 10.10.1.102 >& /dev/null
113         fi
114
115         cleanup
116
117         echo "OK"
118 }
119
120 function l2_to_ip6tnl {
121         echo -n "l2_to_ip6tnl $1: "
122
123         local dir=$1
124
125         config_common ip6tnl
126
127         $IP link add ip6t type ip6tnl mode any external
128         $IP link set dev ip6t up
129         sysctl -q -w net.ipv4.conf.ip6t.rp_filter=0
130         sysctl -q -w net.ipv4.conf.ip6t.forwarding=1
131
132         if [[ $dir == "egress" ]]; then
133                 $IP route add 10.10.1.0/24 via 10.2.1.102 dev ve2
134                 $IP route add 2401:face::/64 via 2401:db02::66 dev ve2
135                 $TC filter add dev ve2 egress bpf da obj $REDIRECT_BPF sec l2_to_ip6tun_ingress_redirect
136                 sysctl -q -w net.ipv4.conf.ve1.forwarding=1
137         else
138                 $TC qdisc add dev ve1 clsact
139                 $TC filter add dev ve1 ingress bpf da obj $REDIRECT_BPF sec l2_to_ip6tun_ingress_redirect
140         fi
141
142         $REDIRECT_USER -U /sys/fs/bpf/tc/globals/tun_iface -i $(< /sys/class/net/ip6t/ifindex)
143
144         $IP netns exec ns1 ping -c1 10.10.1.102 >& /dev/null
145         $IP netns exec ns1 ping -6 -c1 2401:face::66 >& /dev/null
146
147         if [[ $dir == "egress" ]]; then
148                 # test direct egress to ve2 (i.e. not forwarding from
149                 # ve1 to ve2).
150                 ping -c1 10.10.1.102 >& /dev/null
151                 ping -6 -c1 2401:face::66 >& /dev/null
152         fi
153
154         cleanup
155
156         echo "OK"
157 }
158
159 cleanup
160 test_names="l2_to_ipip l2_to_ip6tnl"
161 test_dirs="ingress egress"
162 if [[ $# -ge 2 ]]; then
163         test_names=$1
164         test_dirs=$2
165 elif [[ $# -ge 1 ]]; then
166         test_names=$1
167 fi
168
169 for t in $test_names; do
170         for d in $test_dirs; do
171                 $t $d
172         done
173 done