cmsg_ip.sh 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. source lib.sh
  4. IP4=172.16.0.1/24
  5. TGT4=172.16.0.2
  6. IP6=2001:db8:1::1/64
  7. TGT6=2001:db8:1::2
  8. TMPF=$(mktemp --suffix ".pcap")
  9. cleanup()
  10. {
  11. rm -f $TMPF
  12. cleanup_ns $NS
  13. }
  14. trap cleanup EXIT
  15. tcpdump -h | grep immediate-mode >> /dev/null
  16. if [ $? -ne 0 ]; then
  17. echo "SKIP - tcpdump with --immediate-mode option required"
  18. exit $ksft_skip
  19. fi
  20. # Namespaces
  21. setup_ns NS
  22. NSEXE="ip netns exec $NS"
  23. $NSEXE sysctl -w net.ipv4.ping_group_range='0 2147483647' > /dev/null
  24. # Connectivity
  25. ip -netns $NS link add type dummy
  26. ip -netns $NS link set dev dummy0 up
  27. ip -netns $NS addr add $IP4 dev dummy0
  28. ip -netns $NS addr add $IP6 dev dummy0
  29. # Test
  30. BAD=0
  31. TOTAL=0
  32. check_result() {
  33. ((TOTAL++))
  34. if [ $1 -ne $2 ]; then
  35. echo " Case $3 returned $1, expected $2"
  36. ((BAD++))
  37. fi
  38. }
  39. # IPV6_DONTFRAG
  40. for ovr in setsock cmsg both diff; do
  41. for df in 0 1; do
  42. for p in u U i r; do
  43. [ $p == "u" ] && prot=UDP
  44. [ $p == "U" ] && prot=UDP
  45. [ $p == "i" ] && prot=ICMP
  46. [ $p == "r" ] && prot=RAW
  47. [ $ovr == "setsock" ] && m="-F $df"
  48. [ $ovr == "cmsg" ] && m="-f $df"
  49. [ $ovr == "both" ] && m="-F $df -f $df"
  50. [ $ovr == "diff" ] && m="-F $((1 - df)) -f $df"
  51. $NSEXE ./cmsg_sender -s -S 2000 -6 -p $p $m $TGT6 1234
  52. check_result $? $df "DONTFRAG $prot $ovr"
  53. done
  54. done
  55. done
  56. # IP_TOS + IPV6_TCLASS
  57. test_dscp() {
  58. local -r IPVER=$1
  59. local -r TGT=$2
  60. local -r MATCH=$3
  61. local -r TOS=0x10
  62. local -r TOS2=0x20
  63. local -r ECN=0x3
  64. ip $IPVER -netns $NS rule add tos $TOS lookup 300
  65. ip $IPVER -netns $NS route add table 300 prohibit any
  66. for ovr in setsock cmsg both diff; do
  67. for p in u U i r; do
  68. [ $p == "u" ] && prot=UDP
  69. [ $p == "U" ] && prot=UDP
  70. [ $p == "i" ] && prot=ICMP
  71. [ $p == "r" ] && prot=RAW
  72. [ $ovr == "setsock" ] && m="-C"
  73. [ $ovr == "cmsg" ] && m="-c"
  74. [ $ovr == "both" ] && m="-C $((TOS2)) -c"
  75. [ $ovr == "diff" ] && m="-C $((TOS )) -c"
  76. $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null &
  77. BG=$!
  78. sleep 0.05
  79. $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS2)) $TGT 1234
  80. check_result $? 0 "$MATCH $prot $ovr - pass"
  81. while [ -d /proc/$BG ]; do
  82. $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS2)) $TGT 1234
  83. done
  84. tcpdump -r $TMPF -v 2>&1 | grep "$MATCH $TOS2" >> /dev/null
  85. check_result $? 0 "$MATCH $prot $ovr - packet data"
  86. rm $TMPF
  87. [ $ovr == "both" ] && m="-C $((TOS )) -c"
  88. [ $ovr == "diff" ] && m="-C $((TOS2)) -c"
  89. # Match prohibit rule: expect failure
  90. $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS)) -s $TGT 1234
  91. check_result $? 1 "$MATCH $prot $ovr - rejection"
  92. # Match prohibit rule: IPv4 masks ECN: expect failure
  93. if [[ "$IPVER" == "-4" ]]; then
  94. $NSEXE ./cmsg_sender $IPVER -p $p $m "$((TOS | ECN))" -s $TGT 1234
  95. check_result $? 1 "$MATCH $prot $ovr - rejection (ECN)"
  96. fi
  97. done
  98. done
  99. }
  100. test_dscp -4 $TGT4 tos
  101. test_dscp -6 $TGT6 class
  102. # IP_TTL + IPV6_HOPLIMIT
  103. test_ttl_hoplimit() {
  104. local -r IPVER=$1
  105. local -r TGT=$2
  106. local -r MATCH=$3
  107. local -r LIM=4
  108. for ovr in setsock cmsg both diff; do
  109. for p in u U i r; do
  110. [ $p == "u" ] && prot=UDP
  111. [ $p == "U" ] && prot=UDP
  112. [ $p == "i" ] && prot=ICMP
  113. [ $p == "r" ] && prot=RAW
  114. [ $ovr == "setsock" ] && m="-L"
  115. [ $ovr == "cmsg" ] && m="-l"
  116. [ $ovr == "both" ] && m="-L $LIM -l"
  117. [ $ovr == "diff" ] && m="-L $((LIM + 1)) -l"
  118. $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null &
  119. BG=$!
  120. sleep 0.05
  121. $NSEXE ./cmsg_sender $IPVER -p $p $m $LIM $TGT 1234
  122. check_result $? 0 "$MATCH $prot $ovr - pass"
  123. while [ -d /proc/$BG ]; do
  124. $NSEXE ./cmsg_sender $IPVER -p $p $m $LIM $TGT 1234
  125. done
  126. tcpdump -r $TMPF -v 2>&1 | grep "$MATCH $LIM[^0-9]" >> /dev/null
  127. check_result $? 0 "$MATCH $prot $ovr - packet data"
  128. rm $TMPF
  129. done
  130. done
  131. }
  132. test_ttl_hoplimit -4 $TGT4 ttl
  133. test_ttl_hoplimit -6 $TGT6 hlim
  134. # IPV6 exthdr
  135. for p in u U i r; do
  136. # Very basic "does it crash" test
  137. for h in h d r; do
  138. $NSEXE ./cmsg_sender -p $p -6 -H $h $TGT6 1234
  139. check_result $? 0 "ExtHdr $prot $ovr - pass"
  140. done
  141. done
  142. # Summary
  143. if [ $BAD -ne 0 ]; then
  144. echo "FAIL - $BAD/$TOTAL cases failed"
  145. exit 1
  146. else
  147. echo "OK"
  148. exit 0
  149. fi