[PATCH 4.17 01/15] netfilter: nf_flow_table: attach dst to skbs

From: Greg Kroah-Hartman
Date: Sat Jun 09 2018 - 11:30:57 EST


4.17-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jason A. Donenfeld <Jason@xxxxxxxxx>

commit 2a79fd3908acd88e6cb0e620c314d7b1fee56a02 upstream.

Some drivers, such as vxlan and wireguard, use the skb's dst in order to
determine things like PMTU. They therefore loose functionality when flow
offloading is enabled. So, we ensure the skb has it before xmit'ing it
in the offloading path.

Signed-off-by: Jason A. Donenfeld <Jason@xxxxxxxxx>
Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>


---
net/ipv4/netfilter/nf_flow_table_ipv4.c | 5 +++--
net/ipv6/netfilter/nf_flow_table_ipv6.c | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)

--- a/net/ipv4/netfilter/nf_flow_table_ipv4.c
+++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c
@@ -213,7 +213,7 @@ nf_flow_offload_ip_hook(void *priv, stru
enum flow_offload_tuple_dir dir;
struct flow_offload *flow;
struct net_device *outdev;
- const struct rtable *rt;
+ struct rtable *rt;
struct iphdr *iph;
__be32 nexthop;

@@ -234,7 +234,7 @@ nf_flow_offload_ip_hook(void *priv, stru
dir = tuplehash->tuple.dir;
flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);

- rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
+ rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
if (unlikely(nf_flow_exceeds_mtu(skb, rt)))
return NF_ACCEPT;

@@ -251,6 +251,7 @@ nf_flow_offload_ip_hook(void *priv, stru

skb->dev = outdev;
nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
+ skb_dst_set_noref(skb, &rt->dst);
neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb);

return NF_STOLEN;
--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c
+++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c
@@ -243,6 +243,7 @@ nf_flow_offload_ipv6_hook(void *priv, st

skb->dev = outdev;
nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
+ skb_dst_set_noref(skb, &rt->dst);
neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb);

return NF_STOLEN;