]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
netfilter: nat: really support inet nat without l3 address
authorFlorian Westphal <fw@strlen.de>
Wed, 1 Jun 2022 08:47:35 +0000 (10:47 +0200)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 26 Aug 2022 08:52:56 +0000 (10:52 +0200)
BugLink: https://bugs.launchpad.net/bugs/1982968
[ Upstream commit 282e5f8fe907dc3f2fbf9f2103b0e62ffc3a68a5 ]

When no l3 address is given, priv->family is set to NFPROTO_INET and
the evaluation function isn't called.

Call it too so l4-only rewrite can work.
Also add a test case for this.

Fixes: a33f387ecd5aa ("netfilter: nft_nat: allow to specify layer 4 protocol NAT only")
Reported-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
net/netfilter/nft_nat.c
tools/testing/selftests/netfilter/nft_nat.sh

index be1595d6979d8107098921a9cc6675c38b53e3b2..db8f9116eeb434c16cb9cb97e588a2ac78eb458f 100644 (file)
@@ -334,7 +334,8 @@ static void nft_nat_inet_eval(const struct nft_expr *expr,
 {
        const struct nft_nat *priv = nft_expr_priv(expr);
 
-       if (priv->family == nft_pf(pkt))
+       if (priv->family == nft_pf(pkt) ||
+           priv->family == NFPROTO_INET)
                nft_nat_eval(expr, regs, pkt);
 }
 
index 781fa2d9ea9d52c4a908d7111ba30e9a0e1010b1..032f2de6e14e0933879b96d9eea2071f240cfbf4 100755 (executable)
@@ -374,6 +374,45 @@ EOF
        return $lret
 }
 
+test_local_dnat_portonly()
+{
+       local family=$1
+       local daddr=$2
+       local lret=0
+       local sr_s
+       local sr_r
+
+ip netns exec "$ns0" nft -f /dev/stdin <<EOF
+table $family nat {
+       chain output {
+               type nat hook output priority 0; policy accept;
+               meta l4proto tcp dnat to :2000
+
+       }
+}
+EOF
+       if [ $? -ne 0 ]; then
+               if [ $family = "inet" ];then
+                       echo "SKIP: inet port test"
+                       test_inet_nat=false
+                       return
+               fi
+               echo "SKIP: Could not add $family dnat hook"
+               return
+       fi
+
+       echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 &
+       sc_s=$!
+
+       result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT)
+
+       if [ "$result" = "SERVER-inet" ];then
+               echo "PASS: inet port rewrite without l3 address"
+       else
+               echo "ERROR: inet port rewrite"
+               ret=1
+       fi
+}
 
 test_masquerade6()
 {
@@ -1135,6 +1174,10 @@ fi
 reset_counters
 test_local_dnat ip
 test_local_dnat6 ip6
+
+reset_counters
+test_local_dnat_portonly inet 10.0.1.99
+
 reset_counters
 $test_inet_nat && test_local_dnat inet
 $test_inet_nat && test_local_dnat6 inet