tc_l2_redirect.sh 4.9 KB

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