Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'expand-cmsg_ipv6-sh-with-ipv4-support'

Willem de Bruijn says:

====================
expand cmsg_ipv6.sh with ipv4 support

Expand IPV6_TCLASS to also cover IP_TOS.
Expand IPV6_HOPLIMIT to also cover IP_TTL.

A series of two patches for basic readability (patch 1 is a noop),
and so that git does not interpret code changes + file rename as
a whole file del + add.
====================

Link: https://patch.msgid.link/20250225022431.2083926-1-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+240 -190
+1 -1
tools/testing/selftests/net/Makefile
··· 34 34 TEST_PROGS += cmsg_so_mark.sh 35 35 TEST_PROGS += cmsg_so_priority.sh 36 36 TEST_PROGS += test_so_rcv.sh 37 - TEST_PROGS += cmsg_time.sh cmsg_ipv6.sh 37 + TEST_PROGS += cmsg_time.sh cmsg_ip.sh 38 38 TEST_PROGS += netns-name.sh 39 39 TEST_PROGS += link_netns.py 40 40 TEST_PROGS += nl_netdev.py
+184
tools/testing/selftests/net/cmsg_ip.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + source lib.sh 5 + 6 + IP4=172.16.0.1/24 7 + TGT4=172.16.0.2 8 + IP6=2001:db8:1::1/64 9 + TGT6=2001:db8:1::2 10 + TMPF=$(mktemp --suffix ".pcap") 11 + 12 + cleanup() 13 + { 14 + rm -f $TMPF 15 + cleanup_ns $NS 16 + } 17 + 18 + trap cleanup EXIT 19 + 20 + tcpdump -h | grep immediate-mode >> /dev/null 21 + if [ $? -ne 0 ]; then 22 + echo "SKIP - tcpdump with --immediate-mode option required" 23 + exit $ksft_skip 24 + fi 25 + 26 + # Namespaces 27 + setup_ns NS 28 + NSEXE="ip netns exec $NS" 29 + 30 + $NSEXE sysctl -w net.ipv4.ping_group_range='0 2147483647' > /dev/null 31 + 32 + # Connectivity 33 + ip -netns $NS link add type dummy 34 + ip -netns $NS link set dev dummy0 up 35 + ip -netns $NS addr add $IP4 dev dummy0 36 + ip -netns $NS addr add $IP6 dev dummy0 37 + 38 + # Test 39 + BAD=0 40 + TOTAL=0 41 + 42 + check_result() { 43 + ((TOTAL++)) 44 + if [ $1 -ne $2 ]; then 45 + echo " Case $3 returned $1, expected $2" 46 + ((BAD++)) 47 + fi 48 + } 49 + 50 + # IPV6_DONTFRAG 51 + for ovr in setsock cmsg both diff; do 52 + for df in 0 1; do 53 + for p in u i r; do 54 + [ $p == "u" ] && prot=UDP 55 + [ $p == "i" ] && prot=ICMP 56 + [ $p == "r" ] && prot=RAW 57 + 58 + [ $ovr == "setsock" ] && m="-F $df" 59 + [ $ovr == "cmsg" ] && m="-f $df" 60 + [ $ovr == "both" ] && m="-F $df -f $df" 61 + [ $ovr == "diff" ] && m="-F $((1 - df)) -f $df" 62 + 63 + $NSEXE ./cmsg_sender -s -S 2000 -6 -p $p $m $TGT6 1234 64 + check_result $? $df "DONTFRAG $prot $ovr" 65 + done 66 + done 67 + done 68 + 69 + # IP_TOS + IPV6_TCLASS 70 + 71 + test_dscp() { 72 + local -r IPVER=$1 73 + local -r TGT=$2 74 + local -r MATCH=$3 75 + 76 + local -r TOS=0x10 77 + local -r TOS2=0x20 78 + local -r ECN=0x3 79 + 80 + ip $IPVER -netns $NS rule add tos $TOS lookup 300 81 + ip $IPVER -netns $NS route add table 300 prohibit any 82 + 83 + for ovr in setsock cmsg both diff; do 84 + for p in u i r; do 85 + [ $p == "u" ] && prot=UDP 86 + [ $p == "i" ] && prot=ICMP 87 + [ $p == "r" ] && prot=RAW 88 + 89 + [ $ovr == "setsock" ] && m="-C" 90 + [ $ovr == "cmsg" ] && m="-c" 91 + [ $ovr == "both" ] && m="-C $((TOS2)) -c" 92 + [ $ovr == "diff" ] && m="-C $((TOS )) -c" 93 + 94 + $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null & 95 + BG=$! 96 + sleep 0.05 97 + 98 + $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS2)) $TGT 1234 99 + check_result $? 0 "$MATCH $prot $ovr - pass" 100 + 101 + while [ -d /proc/$BG ]; do 102 + $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS2)) $TGT 1234 103 + done 104 + 105 + tcpdump -r $TMPF -v 2>&1 | grep "$MATCH $TOS2" >> /dev/null 106 + check_result $? 0 "$MATCH $prot $ovr - packet data" 107 + rm $TMPF 108 + 109 + [ $ovr == "both" ] && m="-C $((TOS )) -c" 110 + [ $ovr == "diff" ] && m="-C $((TOS2)) -c" 111 + 112 + # Match prohibit rule: expect failure 113 + $NSEXE ./cmsg_sender $IPVER -p $p $m $((TOS)) -s $TGT 1234 114 + check_result $? 1 "$MATCH $prot $ovr - rejection" 115 + 116 + # Match prohibit rule: IPv4 masks ECN: expect failure 117 + if [[ "$IPVER" == "-4" ]]; then 118 + $NSEXE ./cmsg_sender $IPVER -p $p $m "$((TOS | ECN))" -s $TGT 1234 119 + check_result $? 1 "$MATCH $prot $ovr - rejection (ECN)" 120 + fi 121 + done 122 + done 123 + } 124 + 125 + test_dscp -4 $TGT4 tos 126 + test_dscp -6 $TGT6 class 127 + 128 + # IP_TTL + IPV6_HOPLIMIT 129 + test_ttl_hoplimit() { 130 + local -r IPVER=$1 131 + local -r TGT=$2 132 + local -r MATCH=$3 133 + 134 + local -r LIM=4 135 + 136 + for ovr in setsock cmsg both diff; do 137 + for p in u i r; do 138 + [ $p == "u" ] && prot=UDP 139 + [ $p == "i" ] && prot=ICMP 140 + [ $p == "r" ] && prot=RAW 141 + 142 + [ $ovr == "setsock" ] && m="-L" 143 + [ $ovr == "cmsg" ] && m="-l" 144 + [ $ovr == "both" ] && m="-L $LIM -l" 145 + [ $ovr == "diff" ] && m="-L $((LIM + 1)) -l" 146 + 147 + $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null & 148 + BG=$! 149 + sleep 0.05 150 + 151 + $NSEXE ./cmsg_sender $IPVER -p $p $m $LIM $TGT 1234 152 + check_result $? 0 "$MATCH $prot $ovr - pass" 153 + 154 + while [ -d /proc/$BG ]; do 155 + $NSEXE ./cmsg_sender $IPVER -p $p $m $LIM $TGT 1234 156 + done 157 + 158 + tcpdump -r $TMPF -v 2>&1 | grep "$MATCH $LIM[^0-9]" >> /dev/null 159 + check_result $? 0 "$MATCH $prot $ovr - packet data" 160 + rm $TMPF 161 + done 162 + done 163 + } 164 + 165 + test_ttl_hoplimit -4 $TGT4 ttl 166 + test_ttl_hoplimit -6 $TGT6 hlim 167 + 168 + # IPV6 exthdr 169 + for p in u i r; do 170 + # Very basic "does it crash" test 171 + for h in h d r; do 172 + $NSEXE ./cmsg_sender -p $p -6 -H $h $TGT6 1234 173 + check_result $? 0 "ExtHdr $prot $ovr - pass" 174 + done 175 + done 176 + 177 + # Summary 178 + if [ $BAD -ne 0 ]; then 179 + echo "FAIL - $BAD/$TOTAL cases failed" 180 + exit 1 181 + else 182 + echo "OK" 183 + exit 0 184 + fi
-154
tools/testing/selftests/net/cmsg_ipv6.sh
··· 1 - #!/bin/bash 2 - # SPDX-License-Identifier: GPL-2.0 3 - 4 - source lib.sh 5 - 6 - IP6=2001:db8:1::1/64 7 - TGT6=2001:db8:1::2 8 - TMPF=$(mktemp --suffix ".pcap") 9 - 10 - cleanup() 11 - { 12 - rm -f $TMPF 13 - cleanup_ns $NS 14 - } 15 - 16 - trap cleanup EXIT 17 - 18 - tcpdump -h | grep immediate-mode >> /dev/null 19 - if [ $? -ne 0 ]; then 20 - echo "SKIP - tcpdump with --immediate-mode option required" 21 - exit $ksft_skip 22 - fi 23 - 24 - # Namespaces 25 - setup_ns NS 26 - NSEXE="ip netns exec $NS" 27 - 28 - $NSEXE sysctl -w net.ipv4.ping_group_range='0 2147483647' > /dev/null 29 - 30 - # Connectivity 31 - ip -netns $NS link add type dummy 32 - ip -netns $NS link set dev dummy0 up 33 - ip -netns $NS addr add $IP6 dev dummy0 34 - 35 - # Test 36 - BAD=0 37 - TOTAL=0 38 - 39 - check_result() { 40 - ((TOTAL++)) 41 - if [ $1 -ne $2 ]; then 42 - echo " Case $3 returned $1, expected $2" 43 - ((BAD++)) 44 - fi 45 - } 46 - 47 - # IPV6_DONTFRAG 48 - for ovr in setsock cmsg both diff; do 49 - for df in 0 1; do 50 - for p in u i r; do 51 - [ $p == "u" ] && prot=UDP 52 - [ $p == "i" ] && prot=ICMP 53 - [ $p == "r" ] && prot=RAW 54 - 55 - [ $ovr == "setsock" ] && m="-F $df" 56 - [ $ovr == "cmsg" ] && m="-f $df" 57 - [ $ovr == "both" ] && m="-F $df -f $df" 58 - [ $ovr == "diff" ] && m="-F $((1 - df)) -f $df" 59 - 60 - $NSEXE ./cmsg_sender -s -S 2000 -6 -p $p $m $TGT6 1234 61 - check_result $? $df "DONTFRAG $prot $ovr" 62 - done 63 - done 64 - done 65 - 66 - # IPV6_TCLASS 67 - TOS=0x10 68 - TOS2=0x20 69 - 70 - ip -6 -netns $NS rule add tos $TOS lookup 300 71 - ip -6 -netns $NS route add table 300 prohibit any 72 - 73 - for ovr in setsock cmsg both diff; do 74 - for p in u i r; do 75 - [ $p == "u" ] && prot=UDP 76 - [ $p == "i" ] && prot=ICMP 77 - [ $p == "r" ] && prot=RAW 78 - 79 - [ $ovr == "setsock" ] && m="-C" 80 - [ $ovr == "cmsg" ] && m="-c" 81 - [ $ovr == "both" ] && m="-C $((TOS2)) -c" 82 - [ $ovr == "diff" ] && m="-C $((TOS )) -c" 83 - 84 - $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null & 85 - BG=$! 86 - sleep 0.05 87 - 88 - $NSEXE ./cmsg_sender -6 -p $p $m $((TOS2)) $TGT6 1234 89 - check_result $? 0 "TCLASS $prot $ovr - pass" 90 - 91 - while [ -d /proc/$BG ]; do 92 - $NSEXE ./cmsg_sender -6 -p $p $m $((TOS2)) $TGT6 1234 93 - done 94 - 95 - tcpdump -r $TMPF -v 2>&1 | grep "class $TOS2" >> /dev/null 96 - check_result $? 0 "TCLASS $prot $ovr - packet data" 97 - rm $TMPF 98 - 99 - [ $ovr == "both" ] && m="-C $((TOS )) -c" 100 - [ $ovr == "diff" ] && m="-C $((TOS2)) -c" 101 - 102 - $NSEXE ./cmsg_sender -6 -p $p $m $((TOS)) -s $TGT6 1234 103 - check_result $? 1 "TCLASS $prot $ovr - rejection" 104 - done 105 - done 106 - 107 - # IPV6_HOPLIMIT 108 - LIM=4 109 - 110 - for ovr in setsock cmsg both diff; do 111 - for p in u i r; do 112 - [ $p == "u" ] && prot=UDP 113 - [ $p == "i" ] && prot=ICMP 114 - [ $p == "r" ] && prot=RAW 115 - 116 - [ $ovr == "setsock" ] && m="-L" 117 - [ $ovr == "cmsg" ] && m="-l" 118 - [ $ovr == "both" ] && m="-L $LIM -l" 119 - [ $ovr == "diff" ] && m="-L $((LIM + 1)) -l" 120 - 121 - $NSEXE nohup tcpdump --immediate-mode -p -ni dummy0 -w $TMPF -c 4 2> /dev/null & 122 - BG=$! 123 - sleep 0.05 124 - 125 - $NSEXE ./cmsg_sender -6 -p $p $m $LIM $TGT6 1234 126 - check_result $? 0 "HOPLIMIT $prot $ovr - pass" 127 - 128 - while [ -d /proc/$BG ]; do 129 - $NSEXE ./cmsg_sender -6 -p $p $m $LIM $TGT6 1234 130 - done 131 - 132 - tcpdump -r $TMPF -v 2>&1 | grep "hlim $LIM[^0-9]" >> /dev/null 133 - check_result $? 0 "HOPLIMIT $prot $ovr - packet data" 134 - rm $TMPF 135 - done 136 - done 137 - 138 - # IPV6 exthdr 139 - for p in u i r; do 140 - # Very basic "does it crash" test 141 - for h in h d r; do 142 - $NSEXE ./cmsg_sender -p $p -6 -H $h $TGT6 1234 143 - check_result $? 0 "ExtHdr $prot $ovr - pass" 144 - done 145 - done 146 - 147 - # Summary 148 - if [ $BAD -ne 0 ]; then 149 - echo "FAIL - $BAD/$TOTAL cases failed" 150 - exit 1 151 - else 152 - echo "OK" 153 - exit 0 154 - fi
+55 -35
tools/testing/selftests/net/cmsg_sender.c
··· 72 72 struct option_cmsg_u32 tclass; 73 73 struct option_cmsg_u32 hlimit; 74 74 struct option_cmsg_u32 exthdr; 75 - } v6; 75 + } cmsg; 76 76 } opt = { 77 77 .size = 13, 78 78 .num_pkt = 1, ··· 104 104 "\t\t-t Enable time stamp reporting\n" 105 105 "\t\t-f val Set don't fragment via cmsg\n" 106 106 "\t\t-F val Set don't fragment via setsockopt\n" 107 - "\t\t-c val Set TCLASS via cmsg\n" 108 - "\t\t-C val Set TCLASS via setsockopt\n" 109 - "\t\t-l val Set HOPLIMIT via cmsg\n" 110 - "\t\t-L val Set HOPLIMIT via setsockopt\n" 107 + "\t\t-c val Set TOS/TCLASS via cmsg\n" 108 + "\t\t-C val Set TOS/TCLASS via setsockopt\n" 109 + "\t\t-l val Set TTL/HOPLIMIT via cmsg\n" 110 + "\t\t-L val Set TTL/HOPLIMIT via setsockopt\n" 111 111 "\t\t-H type Add an IPv6 header option\n" 112 112 "\t\t (h = HOP; d = DST; r = RTDST)" 113 113 ""); ··· 169 169 opt.ts.ena = true; 170 170 break; 171 171 case 'f': 172 - opt.v6.dontfrag.ena = true; 173 - opt.v6.dontfrag.val = atoi(optarg); 172 + opt.cmsg.dontfrag.ena = true; 173 + opt.cmsg.dontfrag.val = atoi(optarg); 174 174 break; 175 175 case 'F': 176 176 opt.sockopt.dontfrag = atoi(optarg); 177 177 break; 178 178 case 'c': 179 - opt.v6.tclass.ena = true; 180 - opt.v6.tclass.val = atoi(optarg); 179 + opt.cmsg.tclass.ena = true; 180 + opt.cmsg.tclass.val = atoi(optarg); 181 181 break; 182 182 case 'C': 183 183 opt.sockopt.tclass = atoi(optarg); 184 184 break; 185 185 case 'l': 186 - opt.v6.hlimit.ena = true; 187 - opt.v6.hlimit.val = atoi(optarg); 186 + opt.cmsg.hlimit.ena = true; 187 + opt.cmsg.hlimit.val = atoi(optarg); 188 188 break; 189 189 case 'L': 190 190 opt.sockopt.hlimit = atoi(optarg); 191 191 break; 192 192 case 'H': 193 - opt.v6.exthdr.ena = true; 193 + opt.cmsg.exthdr.ena = true; 194 194 switch (optarg[0]) { 195 195 case 'h': 196 - opt.v6.exthdr.val = IPV6_HOPOPTS; 196 + opt.cmsg.exthdr.val = IPV6_HOPOPTS; 197 197 break; 198 198 case 'd': 199 - opt.v6.exthdr.val = IPV6_DSTOPTS; 199 + opt.cmsg.exthdr.val = IPV6_DSTOPTS; 200 200 break; 201 201 case 'r': 202 - opt.v6.exthdr.val = IPV6_RTHDRDSTOPTS; 202 + opt.cmsg.exthdr.val = IPV6_RTHDRDSTOPTS; 203 203 break; 204 204 default: 205 205 printf("Error: hdr type: %s\n", optarg); ··· 261 261 SOL_SOCKET, SO_MARK, &opt.mark); 262 262 ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 263 263 SOL_SOCKET, SO_PRIORITY, &opt.priority); 264 - ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 265 - SOL_IPV6, IPV6_DONTFRAG, &opt.v6.dontfrag); 266 - ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 267 - SOL_IPV6, IPV6_TCLASS, &opt.v6.tclass); 268 - ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 269 - SOL_IPV6, IPV6_HOPLIMIT, &opt.v6.hlimit); 264 + 265 + if (opt.sock.family == AF_INET) { 266 + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 267 + SOL_IP, IP_TOS, &opt.cmsg.tclass); 268 + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 269 + SOL_IP, IP_TTL, &opt.cmsg.hlimit); 270 + } else { 271 + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 272 + SOL_IPV6, IPV6_DONTFRAG, &opt.cmsg.dontfrag); 273 + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 274 + SOL_IPV6, IPV6_TCLASS, &opt.cmsg.tclass); 275 + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, 276 + SOL_IPV6, IPV6_HOPLIMIT, &opt.cmsg.hlimit); 277 + } 270 278 271 279 if (opt.txtime.ena) { 272 280 __u64 txtime; ··· 305 297 *(__u32 *)CMSG_DATA(cmsg) = SOF_TIMESTAMPING_TX_SCHED | 306 298 SOF_TIMESTAMPING_TX_SOFTWARE; 307 299 } 308 - if (opt.v6.exthdr.ena) { 300 + if (opt.cmsg.exthdr.ena) { 309 301 cmsg = (struct cmsghdr *)(cbuf + cmsg_len); 310 302 cmsg_len += CMSG_SPACE(8); 311 303 if (cbuf_sz < cmsg_len) 312 304 error(ERN_CMSG_WR, EFAULT, "cmsg buffer too small"); 313 305 314 306 cmsg->cmsg_level = SOL_IPV6; 315 - cmsg->cmsg_type = opt.v6.exthdr.val; 307 + cmsg->cmsg_type = opt.cmsg.exthdr.val; 316 308 cmsg->cmsg_len = CMSG_LEN(8); 317 309 *(__u64 *)CMSG_DATA(cmsg) = 0; 318 310 } ··· 413 405 setsockopt(fd, SOL_SOCKET, SO_MARK, 414 406 &opt.sockopt.mark, sizeof(opt.sockopt.mark))) 415 407 error(ERN_SOCKOPT, errno, "setsockopt SO_MARK"); 416 - if (opt.sockopt.dontfrag && 417 - setsockopt(fd, SOL_IPV6, IPV6_DONTFRAG, 418 - &opt.sockopt.dontfrag, sizeof(opt.sockopt.dontfrag))) 419 - error(ERN_SOCKOPT, errno, "setsockopt IPV6_DONTFRAG"); 420 - if (opt.sockopt.tclass && 421 - setsockopt(fd, SOL_IPV6, IPV6_TCLASS, 422 - &opt.sockopt.tclass, sizeof(opt.sockopt.tclass))) 423 - error(ERN_SOCKOPT, errno, "setsockopt IPV6_TCLASS"); 424 - if (opt.sockopt.hlimit && 425 - setsockopt(fd, SOL_IPV6, IPV6_UNICAST_HOPS, 426 - &opt.sockopt.hlimit, sizeof(opt.sockopt.hlimit))) 427 - error(ERN_SOCKOPT, errno, "setsockopt IPV6_HOPLIMIT"); 428 408 if (opt.sockopt.priority && 429 409 setsockopt(fd, SOL_SOCKET, SO_PRIORITY, 430 410 &opt.sockopt.priority, sizeof(opt.sockopt.priority))) 431 411 error(ERN_SOCKOPT, errno, "setsockopt SO_PRIORITY"); 412 + 413 + if (opt.sock.family == AF_INET) { 414 + if (opt.sockopt.tclass && 415 + setsockopt(fd, SOL_IP, IP_TOS, 416 + &opt.sockopt.tclass, sizeof(opt.sockopt.tclass))) 417 + error(ERN_SOCKOPT, errno, "setsockopt IP_TOS"); 418 + if (opt.sockopt.hlimit && 419 + setsockopt(fd, SOL_IP, IP_TTL, 420 + &opt.sockopt.hlimit, sizeof(opt.sockopt.hlimit))) 421 + error(ERN_SOCKOPT, errno, "setsockopt IP_TTL"); 422 + } else { 423 + if (opt.sockopt.dontfrag && 424 + setsockopt(fd, SOL_IPV6, IPV6_DONTFRAG, 425 + &opt.sockopt.dontfrag, sizeof(opt.sockopt.dontfrag))) 426 + error(ERN_SOCKOPT, errno, "setsockopt IPV6_DONTFRAG"); 427 + if (opt.sockopt.tclass && 428 + setsockopt(fd, SOL_IPV6, IPV6_TCLASS, 429 + &opt.sockopt.tclass, sizeof(opt.sockopt.tclass))) 430 + error(ERN_SOCKOPT, errno, "setsockopt IPV6_TCLASS"); 431 + if (opt.sockopt.hlimit && 432 + setsockopt(fd, SOL_IPV6, IPV6_UNICAST_HOPS, 433 + &opt.sockopt.hlimit, sizeof(opt.sockopt.hlimit))) 434 + error(ERN_SOCKOPT, errno, "setsockopt IPV6_HOPLIMIT"); 435 + } 432 436 433 437 if (opt.txtime.ena) { 434 438 struct sock_txtime so_txtime = {