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

Merge branch 'netfilter-followup-fixes-for-net'

Florian Westphal says:

====================
netfilter followup fixes for net

Regressions, since 5.19:
Fix crash when packet tracing is enabled via 'meta nftrace set 1' rule.
Also comes with a test case.

Regressions, this cycle:
Fix Kconfig dependency for the flowtable /proc interface, we want this
to be off by default.
====================

Link: https://lore.kernel.org/r/20220804172629.29748-1-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+87 -18
+1 -2
net/netfilter/Kconfig
··· 736 736 737 737 config NF_FLOW_TABLE_PROCFS 738 738 bool "Supply flow table statistics in procfs" 739 - default y 739 + depends on NF_FLOW_TABLE 740 740 depends on PROC_FS 741 - depends on SYSCTL 742 741 help 743 742 This option enables for the flow table offload statistics 744 743 to be shown in procfs under net/netfilter/nf_flowtable.
+10 -11
net/netfilter/nf_tables_core.c
··· 34 34 nft_trace_notify(info); 35 35 } 36 36 37 - static inline void nft_trace_packet(struct nft_traceinfo *info, 37 + static inline void nft_trace_packet(const struct nft_pktinfo *pkt, 38 + struct nft_traceinfo *info, 38 39 const struct nft_chain *chain, 39 40 const struct nft_rule_dp *rule, 40 41 enum nft_trace_types type) 41 42 { 42 43 if (static_branch_unlikely(&nft_trace_enabled)) { 43 - const struct nft_pktinfo *pkt = info->pkt; 44 - 45 44 info->nf_trace = pkt->skb->nf_trace; 46 45 info->rule = rule; 47 46 __nft_trace_packet(info, chain, type); 48 47 } 49 48 } 50 49 51 - static inline void nft_trace_copy_nftrace(struct nft_traceinfo *info) 50 + static inline void nft_trace_copy_nftrace(const struct nft_pktinfo *pkt, 51 + struct nft_traceinfo *info) 52 52 { 53 53 if (static_branch_unlikely(&nft_trace_enabled)) { 54 - const struct nft_pktinfo *pkt = info->pkt; 55 - 56 54 if (info->trace) 57 55 info->nf_trace = pkt->skb->nf_trace; 58 56 } ··· 94 96 const struct nft_chain *chain, 95 97 const struct nft_regs *regs) 96 98 { 97 - const struct nft_pktinfo *pkt = info->pkt; 98 99 enum nft_trace_types type; 99 100 100 101 switch (regs->verdict.code) { ··· 107 110 break; 108 111 default: 109 112 type = NFT_TRACETYPE_RULE; 110 - info->nf_trace = pkt->skb->nf_trace; 113 + 114 + if (info->trace) 115 + info->nf_trace = info->pkt->skb->nf_trace; 111 116 break; 112 117 } 113 118 ··· 270 271 switch (regs.verdict.code) { 271 272 case NFT_BREAK: 272 273 regs.verdict.code = NFT_CONTINUE; 273 - nft_trace_copy_nftrace(&info); 274 + nft_trace_copy_nftrace(pkt, &info); 274 275 continue; 275 276 case NFT_CONTINUE: 276 - nft_trace_packet(&info, chain, rule, 277 + nft_trace_packet(pkt, &info, chain, rule, 277 278 NFT_TRACETYPE_RULE); 278 279 continue; 279 280 } ··· 317 318 goto next_rule; 318 319 } 319 320 320 - nft_trace_packet(&info, basechain, NULL, NFT_TRACETYPE_POLICY); 321 + nft_trace_packet(pkt, &info, basechain, NULL, NFT_TRACETYPE_POLICY); 321 322 322 323 if (static_branch_unlikely(&nft_counters_enabled)) 323 324 nft_update_chain_stats(basechain, pkt);
+76 -5
tools/testing/selftests/netfilter/nft_trans_stress.sh
··· 9 9 # Kselftest framework requirement - SKIP code is 4. 10 10 ksft_skip=4 11 11 12 - testns=testns1 12 + testns=testns-$(mktemp -u "XXXXXXXX") 13 + 13 14 tables="foo bar baz quux" 15 + global_ret=0 16 + eret=0 17 + lret=0 18 + 19 + check_result() 20 + { 21 + local r=$1 22 + local OK="PASS" 23 + 24 + if [ $r -ne 0 ] ;then 25 + OK="FAIL" 26 + global_ret=$r 27 + fi 28 + 29 + echo "$OK: nft $2 test returned $r" 30 + 31 + eret=0 32 + } 14 33 15 34 nft --version > /dev/null 2>&1 16 35 if [ $? -ne 0 ];then ··· 78 59 79 60 sleep 1 80 61 62 + ip netns exec "$testns" nft -f "$tmp" 81 63 for i in $(seq 1 10) ; do ip netns exec "$testns" nft -f "$tmp" & done 82 64 83 65 for table in $tables;do 84 - randsleep=$((RANDOM%10)) 66 + randsleep=$((RANDOM%2)) 85 67 sleep $randsleep 86 - ip netns exec "$testns" nft delete table inet $table 2>/dev/null 68 + ip netns exec "$testns" nft delete table inet $table 69 + lret=$? 70 + if [ $lret -ne 0 ]; then 71 + eret=$lret 72 + fi 87 73 done 88 74 89 - randsleep=$((RANDOM%10)) 90 - sleep $randsleep 75 + check_result $eret "add/delete" 76 + 77 + for i in $(seq 1 10) ; do 78 + (echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin 79 + 80 + lret=$? 81 + if [ $lret -ne 0 ]; then 82 + eret=$lret 83 + fi 84 + done 85 + 86 + check_result $eret "reload" 87 + 88 + for i in $(seq 1 10) ; do 89 + (echo "flush ruleset"; cat "$tmp" 90 + echo "insert rule inet foo INPUT meta nftrace set 1" 91 + echo "insert rule inet foo OUTPUT meta nftrace set 1" 92 + ) | ip netns exec "$testns" nft -f /dev/stdin 93 + lret=$? 94 + if [ $lret -ne 0 ]; then 95 + eret=$lret 96 + fi 97 + 98 + (echo "flush ruleset"; cat "$tmp" 99 + ) | ip netns exec "$testns" nft -f /dev/stdin 100 + 101 + lret=$? 102 + if [ $lret -ne 0 ]; then 103 + eret=$lret 104 + fi 105 + done 106 + 107 + check_result $eret "add/delete with nftrace enabled" 108 + 109 + echo "insert rule inet foo INPUT meta nftrace set 1" >> $tmp 110 + echo "insert rule inet foo OUTPUT meta nftrace set 1" >> $tmp 111 + 112 + for i in $(seq 1 10) ; do 113 + (echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin 114 + 115 + lret=$? 116 + if [ $lret -ne 0 ]; then 117 + eret=1 118 + fi 119 + done 120 + 121 + check_result $lret "add/delete with nftrace enabled" 91 122 92 123 pkill -9 ping 93 124 ··· 145 76 146 77 rm -f "$tmp" 147 78 ip netns del "$testns" 79 + 80 + exit $global_ret