Commit f6ac85a1 authored by Jakub Kicinski's avatar Jakub Kicinski

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.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2e64fe46 b06ada6d
......@@ -736,9 +736,8 @@ config NF_FLOW_TABLE
config NF_FLOW_TABLE_PROCFS
bool "Supply flow table statistics in procfs"
default y
depends on NF_FLOW_TABLE
depends on PROC_FS
depends on SYSCTL
help
This option enables for the flow table offload statistics
to be shown in procfs under net/netfilter/nf_flowtable.
......
......@@ -34,25 +34,23 @@ static noinline void __nft_trace_packet(struct nft_traceinfo *info,
nft_trace_notify(info);
}
static inline void nft_trace_packet(struct nft_traceinfo *info,
static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
struct nft_traceinfo *info,
const struct nft_chain *chain,
const struct nft_rule_dp *rule,
enum nft_trace_types type)
{
if (static_branch_unlikely(&nft_trace_enabled)) {
const struct nft_pktinfo *pkt = info->pkt;
info->nf_trace = pkt->skb->nf_trace;
info->rule = rule;
__nft_trace_packet(info, chain, type);
}
}
static inline void nft_trace_copy_nftrace(struct nft_traceinfo *info)
static inline void nft_trace_copy_nftrace(const struct nft_pktinfo *pkt,
struct nft_traceinfo *info)
{
if (static_branch_unlikely(&nft_trace_enabled)) {
const struct nft_pktinfo *pkt = info->pkt;
if (info->trace)
info->nf_trace = pkt->skb->nf_trace;
}
......@@ -96,7 +94,6 @@ static noinline void __nft_trace_verdict(struct nft_traceinfo *info,
const struct nft_chain *chain,
const struct nft_regs *regs)
{
const struct nft_pktinfo *pkt = info->pkt;
enum nft_trace_types type;
switch (regs->verdict.code) {
......@@ -110,7 +107,9 @@ static noinline void __nft_trace_verdict(struct nft_traceinfo *info,
break;
default:
type = NFT_TRACETYPE_RULE;
info->nf_trace = pkt->skb->nf_trace;
if (info->trace)
info->nf_trace = info->pkt->skb->nf_trace;
break;
}
......@@ -271,10 +270,10 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
switch (regs.verdict.code) {
case NFT_BREAK:
regs.verdict.code = NFT_CONTINUE;
nft_trace_copy_nftrace(&info);
nft_trace_copy_nftrace(pkt, &info);
continue;
case NFT_CONTINUE:
nft_trace_packet(&info, chain, rule,
nft_trace_packet(pkt, &info, chain, rule,
NFT_TRACETYPE_RULE);
continue;
}
......@@ -318,7 +317,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
goto next_rule;
}
nft_trace_packet(&info, basechain, NULL, NFT_TRACETYPE_POLICY);
nft_trace_packet(pkt, &info, basechain, NULL, NFT_TRACETYPE_POLICY);
if (static_branch_unlikely(&nft_counters_enabled))
nft_update_chain_stats(basechain, pkt);
......
......@@ -9,8 +9,27 @@
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
testns=testns1
testns=testns-$(mktemp -u "XXXXXXXX")
tables="foo bar baz quux"
global_ret=0
eret=0
lret=0
check_result()
{
local r=$1
local OK="PASS"
if [ $r -ne 0 ] ;then
OK="FAIL"
global_ret=$r
fi
echo "$OK: nft $2 test returned $r"
eret=0
}
nft --version > /dev/null 2>&1
if [ $? -ne 0 ];then
......@@ -59,16 +78,66 @@ done)
sleep 1
ip netns exec "$testns" nft -f "$tmp"
for i in $(seq 1 10) ; do ip netns exec "$testns" nft -f "$tmp" & done
for table in $tables;do
randsleep=$((RANDOM%10))
randsleep=$((RANDOM%2))
sleep $randsleep
ip netns exec "$testns" nft delete table inet $table 2>/dev/null
ip netns exec "$testns" nft delete table inet $table
lret=$?
if [ $lret -ne 0 ]; then
eret=$lret
fi
done
randsleep=$((RANDOM%10))
sleep $randsleep
check_result $eret "add/delete"
for i in $(seq 1 10) ; do
(echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin
lret=$?
if [ $lret -ne 0 ]; then
eret=$lret
fi
done
check_result $eret "reload"
for i in $(seq 1 10) ; do
(echo "flush ruleset"; cat "$tmp"
echo "insert rule inet foo INPUT meta nftrace set 1"
echo "insert rule inet foo OUTPUT meta nftrace set 1"
) | ip netns exec "$testns" nft -f /dev/stdin
lret=$?
if [ $lret -ne 0 ]; then
eret=$lret
fi
(echo "flush ruleset"; cat "$tmp"
) | ip netns exec "$testns" nft -f /dev/stdin
lret=$?
if [ $lret -ne 0 ]; then
eret=$lret
fi
done
check_result $eret "add/delete with nftrace enabled"
echo "insert rule inet foo INPUT meta nftrace set 1" >> $tmp
echo "insert rule inet foo OUTPUT meta nftrace set 1" >> $tmp
for i in $(seq 1 10) ; do
(echo "flush ruleset"; cat "$tmp") | ip netns exec "$testns" nft -f /dev/stdin
lret=$?
if [ $lret -ne 0 ]; then
eret=1
fi
done
check_result $lret "add/delete with nftrace enabled"
pkill -9 ping
......@@ -76,3 +145,5 @@ wait
rm -f "$tmp"
ip netns del "$testns"
exit $global_ret
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment