test_xdp_vlan.sh 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #!/bin/bash
  2. TESTNAME=xdp_vlan
  3. usage() {
  4. echo "Testing XDP + TC eBPF VLAN manipulations: $TESTNAME"
  5. echo ""
  6. echo "Usage: $0 [-vfh]"
  7. echo " -v | --verbose : Verbose"
  8. echo " --flush : Flush before starting (e.g. after --interactive)"
  9. echo " --interactive : Keep netns setup running after test-run"
  10. echo ""
  11. }
  12. cleanup()
  13. {
  14. local status=$?
  15. if [ "$status" = "0" ]; then
  16. echo "selftests: $TESTNAME [PASS]";
  17. else
  18. echo "selftests: $TESTNAME [FAILED]";
  19. fi
  20. if [ -n "$INTERACTIVE" ]; then
  21. echo "Namespace setup still active explore with:"
  22. echo " ip netns exec ns1 bash"
  23. echo " ip netns exec ns2 bash"
  24. exit $status
  25. fi
  26. set +e
  27. ip link del veth1 2> /dev/null
  28. ip netns del ns1 2> /dev/null
  29. ip netns del ns2 2> /dev/null
  30. }
  31. # Using external program "getopt" to get --long-options
  32. OPTIONS=$(getopt -o hvfi: \
  33. --long verbose,flush,help,interactive,debug -- "$@")
  34. if (( $? != 0 )); then
  35. usage
  36. echo "selftests: $TESTNAME [FAILED] Error calling getopt, unknown option?"
  37. exit 2
  38. fi
  39. eval set -- "$OPTIONS"
  40. ## --- Parse command line arguments / parameters ---
  41. while true; do
  42. case "$1" in
  43. -v | --verbose)
  44. export VERBOSE=yes
  45. shift
  46. ;;
  47. -i | --interactive | --debug )
  48. INTERACTIVE=yes
  49. shift
  50. ;;
  51. -f | --flush )
  52. cleanup
  53. shift
  54. ;;
  55. -- )
  56. shift
  57. break
  58. ;;
  59. -h | --help )
  60. usage;
  61. echo "selftests: $TESTNAME [SKIP] usage help info requested"
  62. exit 0
  63. ;;
  64. * )
  65. shift
  66. break
  67. ;;
  68. esac
  69. done
  70. if [ "$EUID" -ne 0 ]; then
  71. echo "selftests: $TESTNAME [FAILED] need root privileges"
  72. exit 1
  73. fi
  74. ip link set dev lo xdp off 2>/dev/null > /dev/null
  75. if [ $? -ne 0 ];then
  76. echo "selftests: $TESTNAME [SKIP] need ip xdp support"
  77. exit 0
  78. fi
  79. # Interactive mode likely require us to cleanup netns
  80. if [ -n "$INTERACTIVE" ]; then
  81. ip link del veth1 2> /dev/null
  82. ip netns del ns1 2> /dev/null
  83. ip netns del ns2 2> /dev/null
  84. fi
  85. # Exit on failure
  86. set -e
  87. # Some shell-tools dependencies
  88. which ip > /dev/null
  89. which tc > /dev/null
  90. which ethtool > /dev/null
  91. # Make rest of shell verbose, showing comments as doc/info
  92. if [ -n "$VERBOSE" ]; then
  93. set -v
  94. fi
  95. # Create two namespaces
  96. ip netns add ns1
  97. ip netns add ns2
  98. # Run cleanup if failing or on kill
  99. trap cleanup 0 2 3 6 9
  100. # Create veth pair
  101. ip link add veth1 type veth peer name veth2
  102. # Move veth1 and veth2 into the respective namespaces
  103. ip link set veth1 netns ns1
  104. ip link set veth2 netns ns2
  105. # NOTICE: XDP require VLAN header inside packet payload
  106. # - Thus, disable VLAN offloading driver features
  107. # - For veth REMEMBER TX side VLAN-offload
  108. #
  109. # Disable rx-vlan-offload (mostly needed on ns1)
  110. ip netns exec ns1 ethtool -K veth1 rxvlan off
  111. ip netns exec ns2 ethtool -K veth2 rxvlan off
  112. #
  113. # Disable tx-vlan-offload (mostly needed on ns2)
  114. ip netns exec ns2 ethtool -K veth2 txvlan off
  115. ip netns exec ns1 ethtool -K veth1 txvlan off
  116. export IPADDR1=100.64.41.1
  117. export IPADDR2=100.64.41.2
  118. # In ns1/veth1 add IP-addr on plain net_device
  119. ip netns exec ns1 ip addr add ${IPADDR1}/24 dev veth1
  120. ip netns exec ns1 ip link set veth1 up
  121. # In ns2/veth2 create VLAN device
  122. export VLAN=4011
  123. export DEVNS2=veth2
  124. ip netns exec ns2 ip link add link $DEVNS2 name $DEVNS2.$VLAN type vlan id $VLAN
  125. ip netns exec ns2 ip addr add ${IPADDR2}/24 dev $DEVNS2.$VLAN
  126. ip netns exec ns2 ip link set $DEVNS2 up
  127. ip netns exec ns2 ip link set $DEVNS2.$VLAN up
  128. # Bringup lo in netns (to avoids confusing people using --interactive)
  129. ip netns exec ns1 ip link set lo up
  130. ip netns exec ns2 ip link set lo up
  131. # At this point, the hosts cannot reach each-other,
  132. # because ns2 are using VLAN tags on the packets.
  133. ip netns exec ns2 sh -c 'ping -W 1 -c 1 100.64.41.1 || echo "Okay ping fails"'
  134. # Now we can use the test_xdp_vlan.c program to pop/push these VLAN tags
  135. # ----------------------------------------------------------------------
  136. # In ns1: ingress use XDP to remove VLAN tags
  137. export DEVNS1=veth1
  138. export FILE=test_xdp_vlan.o
  139. # First test: Remove VLAN by setting VLAN ID 0, using "xdp_vlan_change"
  140. export XDP_PROG=xdp_vlan_change
  141. ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG
  142. # In ns1: egress use TC to add back VLAN tag 4011
  143. # (del cmd)
  144. # tc qdisc del dev $DEVNS1 clsact 2> /dev/null
  145. #
  146. ip netns exec ns1 tc qdisc add dev $DEVNS1 clsact
  147. ip netns exec ns1 tc filter add dev $DEVNS1 egress \
  148. prio 1 handle 1 bpf da obj $FILE sec tc_vlan_push
  149. # Now the namespaces can reach each-other, test with ping:
  150. ip netns exec ns2 ping -W 2 -c 3 $IPADDR1
  151. ip netns exec ns1 ping -W 2 -c 3 $IPADDR2
  152. # Second test: Replace xdp prog, that fully remove vlan header
  153. #
  154. # Catch kernel bug for generic-XDP, that does didn't allow us to
  155. # remove a VLAN header, because skb->protocol still contain VLAN
  156. # ETH_P_8021Q indication, and this cause overwriting of our changes.
  157. #
  158. export XDP_PROG=xdp_vlan_remove_outer2
  159. ip netns exec ns1 ip link set $DEVNS1 xdp off
  160. ip netns exec ns1 ip link set $DEVNS1 xdp object $FILE section $XDP_PROG
  161. # Now the namespaces should still be able reach each-other, test with ping:
  162. ip netns exec ns2 ping -W 2 -c 3 $IPADDR1
  163. ip netns exec ns1 ping -W 2 -c 3 $IPADDR2