[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201015163038.26992-7-pablo@netfilter.org>
Date: Thu, 15 Oct 2020 18:30:35 +0200
From: Pablo Neira Ayuso <pablo@...filter.org>
To: netfilter-devel@...r.kernel.org
Cc: davem@...emloft.net, netdev@...r.kernel.org, kuba@...nel.org
Subject: [PATCH net-next,v2 6/9] netfilter: flowtable: use dev_fill_forward_path() to obtain egress device
The egress device in the tuple is obtained from route. Use
dev_fill_forward_path() instead to provide the real ingress device for
this flow whenever this is available.
Signed-off-by: Pablo Neira Ayuso <pablo@...filter.org>
---
v2: no changes.
include/net/netfilter/nf_flow_table.h | 4 ++++
net/netfilter/nf_flow_table_core.c | 1 +
net/netfilter/nf_flow_table_ip.c | 25 +++++++++++++++++++++++--
net/netfilter/nft_flow_offload.c | 1 +
4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index ecb84d4358cc..fe225e881cc7 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -117,6 +117,7 @@ struct flow_offload_tuple {
u8 dir;
enum flow_offload_xmit_type xmit_type:8;
u16 mtu;
+ u32 oifidx;
struct dst_entry *dst_cache;
};
@@ -164,6 +165,9 @@ struct nf_flow_route {
struct {
u32 ifindex;
} in;
+ struct {
+ u32 ifindex;
+ } out;
struct dst_entry *dst;
} tuple[FLOW_OFFLOAD_DIR_MAX];
};
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index 66abc7f287a3..99f01f08c550 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -94,6 +94,7 @@ static int flow_offload_fill_route(struct flow_offload *flow,
}
flow_tuple->iifidx = route->tuple[dir].in.ifindex;
+ flow_tuple->oifidx = route->tuple[dir].out.ifindex;
if (dst_xfrm(dst))
flow_tuple->xmit_type = FLOW_OFFLOAD_XMIT_XFRM;
diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c
index e215c79e6777..92f444db8d9f 100644
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -228,6 +228,15 @@ static int nf_flow_offload_dst_check(struct dst_entry *dst)
return 0;
}
+static struct net_device *nf_flow_outdev_lookup(struct net *net, int oifidx,
+ struct net_device *dev)
+{
+ if (oifidx == dev->ifindex)
+ return dev;
+
+ return dev_get_by_index_rcu(net, oifidx);
+}
+
static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
const struct nf_hook_state *state,
struct dst_entry *dst)
@@ -267,7 +276,6 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
dir = tuplehash->tuple.dir;
flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
- outdev = rt->dst.dev;
if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
return NF_ACCEPT;
@@ -286,6 +294,13 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
return NF_ACCEPT;
}
+ outdev = nf_flow_outdev_lookup(state->net, tuplehash->tuple.oifidx,
+ rt->dst.dev);
+ if (!outdev) {
+ flow_offload_teardown(flow);
+ return NF_ACCEPT;
+ }
+
if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0)
return NF_DROP;
@@ -517,7 +532,6 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
dir = tuplehash->tuple.dir;
flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache;
- outdev = rt->dst.dev;
if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
return NF_ACCEPT;
@@ -533,6 +547,13 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
return NF_ACCEPT;
}
+ outdev = nf_flow_outdev_lookup(state->net, tuplehash->tuple.oifidx,
+ rt->dst.dev);
+ if (!outdev) {
+ flow_offload_teardown(flow);
+ return NF_ACCEPT;
+ }
+
if (skb_try_make_writable(skb, sizeof(*ip6h)))
return NF_DROP;
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 4b476b0a3c88..6a6633e2ceeb 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -84,6 +84,7 @@ static int nft_dev_forward_path(struct nf_flow_route *route,
}
route->tuple[!dir].in.ifindex = info.iifindex;
+ route->tuple[dir].out.ifindex = info.iifindex;
return 0;
}
--
2.20.1
Powered by blists - more mailing lists