da77b9c2f1
Deleted (reverse-appliable): generic/pending-5.10/110-perf-jevents-fix-getting-maximum-number-of-fds.patch Manually refreshed: ramips/patches-5.10/835-asoc-add-mt7620-support.patch Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
148 lines
4.5 KiB
Diff
148 lines
4.5 KiB
Diff
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
Date: Wed, 24 Mar 2021 02:30:38 +0100
|
|
Subject: [PATCH] netfilter: flowtable: add xmit path types
|
|
|
|
Add the xmit_type field that defines the two supported xmit paths in the
|
|
flowtable data plane, which are the neighbour and the xfrm xmit paths.
|
|
This patch prepares for new flowtable xmit path types to come.
|
|
|
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
---
|
|
|
|
--- a/include/net/netfilter/nf_flow_table.h
|
|
+++ b/include/net/netfilter/nf_flow_table.h
|
|
@@ -89,6 +89,11 @@ enum flow_offload_tuple_dir {
|
|
};
|
|
#define FLOW_OFFLOAD_DIR_MAX IP_CT_DIR_MAX
|
|
|
|
+enum flow_offload_xmit_type {
|
|
+ FLOW_OFFLOAD_XMIT_NEIGH = 0,
|
|
+ FLOW_OFFLOAD_XMIT_XFRM,
|
|
+};
|
|
+
|
|
struct flow_offload_tuple {
|
|
union {
|
|
struct in_addr src_v4;
|
|
@@ -111,7 +116,8 @@ struct flow_offload_tuple {
|
|
/* All members above are keys for lookups, see flow_offload_hash(). */
|
|
struct { } __hash;
|
|
|
|
- u8 dir;
|
|
+ u8 dir:6,
|
|
+ xmit_type:2;
|
|
|
|
u16 mtu;
|
|
|
|
@@ -157,7 +163,8 @@ static inline __s32 nf_flow_timeout_delt
|
|
|
|
struct nf_flow_route {
|
|
struct {
|
|
- struct dst_entry *dst;
|
|
+ struct dst_entry *dst;
|
|
+ enum flow_offload_xmit_type xmit_type;
|
|
} tuple[FLOW_OFFLOAD_DIR_MAX];
|
|
};
|
|
|
|
--- a/net/netfilter/nf_flow_table_core.c
|
|
+++ b/net/netfilter/nf_flow_table_core.c
|
|
@@ -95,6 +95,7 @@ static int flow_offload_fill_route(struc
|
|
}
|
|
|
|
flow_tuple->iifidx = other_dst->dev->ifindex;
|
|
+ flow_tuple->xmit_type = route->tuple[dir].xmit_type;
|
|
flow_tuple->dst_cache = dst;
|
|
|
|
return 0;
|
|
--- a/net/netfilter/nf_flow_table_ip.c
|
|
+++ b/net/netfilter/nf_flow_table_ip.c
|
|
@@ -235,8 +235,6 @@ nf_flow_offload_ip_hook(void *priv, stru
|
|
|
|
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;
|
|
@@ -265,13 +263,16 @@ nf_flow_offload_ip_hook(void *priv, stru
|
|
if (flow_table->flags & NF_FLOWTABLE_COUNTER)
|
|
nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
|
|
|
|
- if (unlikely(dst_xfrm(&rt->dst))) {
|
|
+ rt = (struct rtable *)tuplehash->tuple.dst_cache;
|
|
+
|
|
+ if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
|
|
memset(skb->cb, 0, sizeof(struct inet_skb_parm));
|
|
IPCB(skb)->iif = skb->dev->ifindex;
|
|
IPCB(skb)->flags = IPSKB_FORWARDED;
|
|
return nf_flow_xmit_xfrm(skb, state, &rt->dst);
|
|
}
|
|
|
|
+ outdev = rt->dst.dev;
|
|
skb->dev = outdev;
|
|
nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
|
|
skb_dst_set_noref(skb, &rt->dst);
|
|
@@ -456,8 +457,6 @@ nf_flow_offload_ipv6_hook(void *priv, st
|
|
|
|
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;
|
|
@@ -485,13 +484,16 @@ nf_flow_offload_ipv6_hook(void *priv, st
|
|
if (flow_table->flags & NF_FLOWTABLE_COUNTER)
|
|
nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
|
|
|
|
- if (unlikely(dst_xfrm(&rt->dst))) {
|
|
+ rt = (struct rt6_info *)tuplehash->tuple.dst_cache;
|
|
+
|
|
+ if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
|
|
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
|
|
IP6CB(skb)->iif = skb->dev->ifindex;
|
|
IP6CB(skb)->flags = IP6SKB_FORWARDED;
|
|
return nf_flow_xmit_xfrm(skb, state, &rt->dst);
|
|
}
|
|
|
|
+ outdev = rt->dst.dev;
|
|
skb->dev = outdev;
|
|
nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
|
|
skb_dst_set_noref(skb, &rt->dst);
|
|
--- a/net/netfilter/nft_flow_offload.c
|
|
+++ b/net/netfilter/nft_flow_offload.c
|
|
@@ -19,6 +19,22 @@ struct nft_flow_offload {
|
|
struct nft_flowtable *flowtable;
|
|
};
|
|
|
|
+static enum flow_offload_xmit_type nft_xmit_type(struct dst_entry *dst)
|
|
+{
|
|
+ if (dst_xfrm(dst))
|
|
+ return FLOW_OFFLOAD_XMIT_XFRM;
|
|
+
|
|
+ return FLOW_OFFLOAD_XMIT_NEIGH;
|
|
+}
|
|
+
|
|
+static void nft_default_forward_path(struct nf_flow_route *route,
|
|
+ struct dst_entry *dst_cache,
|
|
+ enum ip_conntrack_dir dir)
|
|
+{
|
|
+ route->tuple[dir].dst = dst_cache;
|
|
+ route->tuple[dir].xmit_type = nft_xmit_type(dst_cache);
|
|
+}
|
|
+
|
|
static int nft_flow_route(const struct nft_pktinfo *pkt,
|
|
const struct nf_conn *ct,
|
|
struct nf_flow_route *route,
|
|
@@ -44,8 +60,8 @@ static int nft_flow_route(const struct n
|
|
if (!other_dst)
|
|
return -ENOENT;
|
|
|
|
- route->tuple[dir].dst = this_dst;
|
|
- route->tuple[!dir].dst = other_dst;
|
|
+ nft_default_forward_path(route, this_dst, dir);
|
|
+ nft_default_forward_path(route, other_dst, !dir);
|
|
|
|
return 0;
|
|
}
|