You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
4.0 KiB
146 lines
4.0 KiB
7 years ago
|
From: Felix Fietkau <nbd@nbd.name>
|
||
|
Date: Fri, 16 Feb 2018 10:57:23 +0100
|
||
|
Subject: [PATCH] netfilter: nf_flow_table: cache mtu in struct
|
||
|
flow_offload_tuple
|
||
|
|
||
|
Reduces the number of cache lines touched in the offload forwarding path
|
||
|
|
||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||
|
---
|
||
|
|
||
|
--- a/include/net/netfilter/nf_flow_table.h
|
||
|
+++ b/include/net/netfilter/nf_flow_table.h
|
||
|
@@ -55,6 +55,8 @@ struct flow_offload_tuple {
|
||
|
|
||
|
int oifidx;
|
||
|
|
||
|
+ u16 mtu;
|
||
|
+
|
||
|
struct dst_entry *dst_cache;
|
||
|
};
|
||
|
|
||
|
--- a/net/ipv4/netfilter/nf_flow_table_ipv4.c
|
||
|
+++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c
|
||
|
@@ -177,7 +177,7 @@ static int nf_flow_tuple_ip(struct sk_bu
|
||
|
}
|
||
|
|
||
|
/* Based on ip_exceeds_mtu(). */
|
||
|
-static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
|
||
|
+static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
|
||
|
{
|
||
|
if (skb->len <= mtu)
|
||
|
return false;
|
||
|
@@ -191,17 +191,6 @@ static bool __nf_flow_exceeds_mtu(const
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
-static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rtable *rt)
|
||
|
-{
|
||
|
- u32 mtu;
|
||
|
-
|
||
|
- mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
|
||
|
- if (__nf_flow_exceeds_mtu(skb, mtu))
|
||
|
- return true;
|
||
|
-
|
||
|
- return false;
|
||
|
-}
|
||
|
-
|
||
|
unsigned int
|
||
|
nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
|
||
|
const struct nf_hook_state *state)
|
||
|
@@ -232,9 +221,9 @@ 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;
|
||
|
- if (unlikely(nf_flow_exceeds_mtu(skb, rt)))
|
||
|
+
|
||
|
+ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
|
||
|
return NF_ACCEPT;
|
||
|
|
||
|
if (skb_try_make_writable(skb, sizeof(*iph)))
|
||
|
--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c
|
||
|
+++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c
|
||
|
@@ -173,7 +173,7 @@ static int nf_flow_tuple_ipv6(struct sk_
|
||
|
}
|
||
|
|
||
|
/* Based on ip_exceeds_mtu(). */
|
||
|
-static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
|
||
|
+static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
|
||
|
{
|
||
|
if (skb->len <= mtu)
|
||
|
return false;
|
||
|
@@ -184,17 +184,6 @@ static bool __nf_flow_exceeds_mtu(const
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
-static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rt6_info *rt)
|
||
|
-{
|
||
|
- u32 mtu;
|
||
|
-
|
||
|
- mtu = ip6_dst_mtu_forward(&rt->dst);
|
||
|
- if (__nf_flow_exceeds_mtu(skb, mtu))
|
||
|
- return true;
|
||
|
-
|
||
|
- return false;
|
||
|
-}
|
||
|
-
|
||
|
unsigned int
|
||
|
nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
|
||
|
const struct nf_hook_state *state)
|
||
|
@@ -225,9 +214,9 @@ 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;
|
||
|
- if (unlikely(nf_flow_exceeds_mtu(skb, rt)))
|
||
|
+
|
||
|
+ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
|
||
|
return NF_ACCEPT;
|
||
|
|
||
|
if (skb_try_make_writable(skb, sizeof(*ip6h)))
|
||
|
--- a/net/netfilter/nf_flow_table.c
|
||
|
+++ b/net/netfilter/nf_flow_table.c
|
||
|
@@ -4,6 +4,8 @@
|
||
|
#include <linux/netfilter.h>
|
||
|
#include <linux/rhashtable.h>
|
||
|
#include <linux/netdevice.h>
|
||
|
+#include <net/ip.h>
|
||
|
+#include <net/ip6_route.h>
|
||
|
#include <net/netfilter/nf_tables.h>
|
||
|
#include <net/netfilter/nf_flow_table.h>
|
||
|
#include <net/netfilter/nf_conntrack.h>
|
||
|
@@ -23,6 +25,7 @@ flow_offload_fill_dir(struct flow_offloa
|
||
|
{
|
||
|
struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple;
|
||
|
struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple;
|
||
|
+ struct dst_entry *dst = route->tuple[dir].dst;
|
||
|
|
||
|
ft->dir = dir;
|
||
|
|
||
|
@@ -30,10 +33,12 @@ flow_offload_fill_dir(struct flow_offloa
|
||
|
case NFPROTO_IPV4:
|
||
|
ft->src_v4 = ctt->src.u3.in;
|
||
|
ft->dst_v4 = ctt->dst.u3.in;
|
||
|
+ ft->mtu = ip_dst_mtu_maybe_forward(dst, true);
|
||
|
break;
|
||
|
case NFPROTO_IPV6:
|
||
|
ft->src_v6 = ctt->src.u3.in6;
|
||
|
ft->dst_v6 = ctt->dst.u3.in6;
|
||
|
+ ft->mtu = ip6_dst_mtu_forward(dst);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
@@ -44,8 +49,7 @@ flow_offload_fill_dir(struct flow_offloa
|
||
|
|
||
|
ft->iifidx = route->tuple[dir].ifindex;
|
||
|
ft->oifidx = route->tuple[!dir].ifindex;
|
||
|
-
|
||
|
- ft->dst_cache = route->tuple[dir].dst;
|
||
|
+ ft->dst_cache = dst;
|
||
|
}
|
||
|
|
||
|
struct flow_offload *
|