]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: replace skb_try_make_writable() by skb_ensure_writable()
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 27 Apr 2026 12:34:45 +0000 (14:34 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 29 Apr 2026 22:57:42 +0000 (00:57 +0200)
skb_try_make_writable() only works on clones and uncloned packets might
have their network header in paged fragments.

nft_fwd needs to work for the ingress and egress hooks, but the egress
hook where skb->data points to the mac header, use skb_network_offset()
to include the mac header. The flowtable is fine since it already uses
the transport offset.

Fixes: d32de98ea70f ("netfilter: nft_fwd_netdev: allow to forward packets via neighbour layer")
Fixes: 7d2086871762 ("netfilter: nf_flow_table: move ipv4 offload hook code to nf_flow_table")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_flow_table_ip.c
net/netfilter/nft_fwd_netdev.c

index fd56d663cb5b02e77480672452b238ee19f67f23..dbd7644fdbebeb594dae19b194e02917eb068e03 100644 (file)
@@ -524,7 +524,7 @@ static int nf_flow_offload_forward(struct nf_flowtable_ctx *ctx,
                return 0;
        }
 
-       if (skb_try_make_writable(skb, thoff + ctx->hdrsize))
+       if (skb_ensure_writable(skb, thoff + ctx->hdrsize))
                return -1;
 
        flow_offload_refresh(flow_table, flow, false);
@@ -1037,7 +1037,7 @@ static int nf_flow_offload_ipv6_forward(struct nf_flowtable_ctx *ctx,
                return 0;
        }
 
-       if (skb_try_make_writable(skb, thoff + ctx->hdrsize))
+       if (skb_ensure_writable(skb, thoff + ctx->hdrsize))
                return -1;
 
        flow_offload_refresh(flow_table, flow, false);
index 4bce36c3a6a070deeadd24de6737a557b0217d96..2cc809303ce81d931dae6b52e5c0b8da076f78d6 100644 (file)
@@ -100,6 +100,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr,
        int oif = regs->data[priv->sreg_dev];
        unsigned int verdict = NF_STOLEN;
        struct sk_buff *skb = pkt->skb;
+       int nhoff = skb_network_offset(skb);
        struct net_device *dev;
        int neigh_table;
 
@@ -111,7 +112,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr,
                        verdict = NFT_BREAK;
                        goto out;
                }
-               if (skb_try_make_writable(skb, sizeof(*iph))) {
+               if (skb_ensure_writable(skb, nhoff + sizeof(*iph))) {
                        verdict = NF_DROP;
                        goto out;
                }
@@ -132,7 +133,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr,
                        verdict = NFT_BREAK;
                        goto out;
                }
-               if (skb_try_make_writable(skb, sizeof(*ip6h))) {
+               if (skb_ensure_writable(skb, nhoff + sizeof(*ip6h))) {
                        verdict = NF_DROP;
                        goto out;
                }