mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 06:23:42 -04:00
netfilter: nf_flow_table: attach dst to skbs
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@zx2c4.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
committed by
Pablo Neira Ayuso
parent
a654de8fdc
commit
2a79fd3908
@@ -220,7 +220,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
|
|||||||
enum flow_offload_tuple_dir dir;
|
enum flow_offload_tuple_dir dir;
|
||||||
struct flow_offload *flow;
|
struct flow_offload *flow;
|
||||||
struct net_device *outdev;
|
struct net_device *outdev;
|
||||||
const struct rtable *rt;
|
struct rtable *rt;
|
||||||
unsigned int thoff;
|
unsigned int thoff;
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
__be32 nexthop;
|
__be32 nexthop;
|
||||||
@@ -241,7 +241,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
|
|||||||
|
|
||||||
dir = tuplehash->tuple.dir;
|
dir = tuplehash->tuple.dir;
|
||||||
flow = container_of(tuplehash, struct flow_offload, tuplehash[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, flow->tuplehash[dir].tuple.mtu)) &&
|
if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)) &&
|
||||||
(ip_hdr(skb)->frag_off & htons(IP_DF)) != 0)
|
(ip_hdr(skb)->frag_off & htons(IP_DF)) != 0)
|
||||||
@@ -264,6 +264,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
|
|||||||
|
|
||||||
skb->dev = outdev;
|
skb->dev = outdev;
|
||||||
nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
|
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);
|
neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb);
|
||||||
|
|
||||||
return NF_STOLEN;
|
return NF_STOLEN;
|
||||||
@@ -480,6 +481,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
|
|||||||
|
|
||||||
skb->dev = outdev;
|
skb->dev = outdev;
|
||||||
nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
|
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);
|
neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb);
|
||||||
|
|
||||||
return NF_STOLEN;
|
return NF_STOLEN;
|
||||||
|
|||||||
Reference in New Issue
Block a user