netfilter: bridge: set skb transport_header before entering NF_INET_PRE_ROUTING [Linux 3.16.72]

This Linux kernel change "netfilter: bridge: set skb transport_header before entering NF_INET_PRE_ROUTING" is included in the Linux 3.16.72 release. This change is authored by Xin Long <lucien.xin [at] gmail.com> on Wed Mar 13 16:33:29 2019 +0800. The commit for this change in Linux stable tree is 5d17c80 (patch) which is from upstream commit e166e4f. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream e166e4f.

netfilter: bridge: set skb transport_header before entering NF_INET_PRE_ROUTING

commit e166e4fdaced850bee3d5ee12a5740258fb30587 upstream.

Since Commit 21d1196a35f5 ("ipv4: set transport header earlier"),
skb->transport_header has been always set before entering INET
netfilter. This patch is to set skb->transport_header for bridge
before entering INET netfilter by bridge-nf-call-iptables.

It also fixes an issue that sctp_error() couldn't compute a right
csum due to unset skb->transport_header.

Fixes: e6d8b64b34aa ("net: sctp: fix and consolidate SCTP checksumming code")
Reported-by: Li Shuang <[email protected]>
Suggested-by: Pablo Neira Ayuso <[email protected]>
Signed-off-by: Xin Long <[email protected]>
Acked-by: Neil Horman <[email protected]>
Acked-by: Florian Westphal <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
[bwh: Backported to 3.16: adjust filenames, context]
Signed-off-by: Ben Hutchings <[email protected]>

There are 3 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/bridge/br_netfilter.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 2cf4e30..7ddb8b3 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -659,6 +659,8 @@ static unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops,
        return NF_DROP;

    skb->protocol = htons(ETH_P_IPV6);
+   skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
+
    NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
        br_nf_pre_routing_finish_ipv6);

@@ -715,6 +717,7 @@ static unsigned int br_nf_pre_routing(const struct nf_hook_ops *ops,
        return NF_DROP;
    store_orig_dstaddr(skb);
    skb->protocol = htons(ETH_P_IP);
+   skb->transport_header = skb->network_header + ip_hdr(skb)->ihl * 4;

    NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
        br_nf_pre_routing_finish);

Leave a Reply

Your email address will not be published. Required fields are marked *