e2015e72ac647a8bab0ef600a9983a7909b8fac9
[oweals/openwrt.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Fri, 16 Feb 2018 10:57:23 +0100
3 Subject: [PATCH] netfilter: nf_flow_table: cache mtu in struct
4  flow_offload_tuple
5
6 Reduces the number of cache lines touched in the offload forwarding path
7
8 Signed-off-by: Felix Fietkau <nbd@nbd.name>
9 ---
10
11 --- a/include/net/netfilter/nf_flow_table.h
12 +++ b/include/net/netfilter/nf_flow_table.h
13 @@ -55,6 +55,8 @@ struct flow_offload_tuple {
14  
15         int                             oifidx;
16  
17 +       u16                             mtu;
18 +
19         struct dst_entry                *dst_cache;
20  };
21  
22 --- a/net/ipv4/netfilter/nf_flow_table_ipv4.c
23 +++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c
24 @@ -177,7 +177,7 @@ static int nf_flow_tuple_ip(struct sk_bu
25  }
26  
27  /* Based on ip_exceeds_mtu(). */
28 -static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
29 +static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
30  {
31         if (skb->len <= mtu)
32                 return false;
33 @@ -191,17 +191,6 @@ static bool __nf_flow_exceeds_mtu(const
34         return true;
35  }
36  
37 -static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rtable *rt)
38 -{
39 -       u32 mtu;
40 -
41 -       mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
42 -       if (__nf_flow_exceeds_mtu(skb, mtu))
43 -               return true;
44 -
45 -       return false;
46 -}
47 -
48  unsigned int
49  nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
50                         const struct nf_hook_state *state)
51 @@ -232,9 +221,9 @@ nf_flow_offload_ip_hook(void *priv, stru
52  
53         dir = tuplehash->tuple.dir;
54         flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
55 -
56         rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
57 -       if (unlikely(nf_flow_exceeds_mtu(skb, rt)))
58 +
59 +       if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
60                 return NF_ACCEPT;
61  
62         if (skb_try_make_writable(skb, sizeof(*iph)))
63 --- a/net/ipv6/netfilter/nf_flow_table_ipv6.c
64 +++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c
65 @@ -173,7 +173,7 @@ static int nf_flow_tuple_ipv6(struct sk_
66  }
67  
68  /* Based on ip_exceeds_mtu(). */
69 -static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
70 +static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
71  {
72         if (skb->len <= mtu)
73                 return false;
74 @@ -184,17 +184,6 @@ static bool __nf_flow_exceeds_mtu(const
75         return true;
76  }
77  
78 -static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rt6_info *rt)
79 -{
80 -       u32 mtu;
81 -
82 -       mtu = ip6_dst_mtu_forward(&rt->dst);
83 -       if (__nf_flow_exceeds_mtu(skb, mtu))
84 -               return true;
85 -
86 -       return false;
87 -}
88 -
89  unsigned int
90  nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
91                           const struct nf_hook_state *state)
92 @@ -225,9 +214,9 @@ nf_flow_offload_ipv6_hook(void *priv, st
93  
94         dir = tuplehash->tuple.dir;
95         flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
96 -
97         rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache;
98 -       if (unlikely(nf_flow_exceeds_mtu(skb, rt)))
99 +
100 +       if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
101                 return NF_ACCEPT;
102  
103         if (skb_try_make_writable(skb, sizeof(*ip6h)))
104 --- a/net/netfilter/nf_flow_table.c
105 +++ b/net/netfilter/nf_flow_table.c
106 @@ -4,6 +4,8 @@
107  #include <linux/netfilter.h>
108  #include <linux/rhashtable.h>
109  #include <linux/netdevice.h>
110 +#include <net/ip.h>
111 +#include <net/ip6_route.h>
112  #include <net/netfilter/nf_tables.h>
113  #include <net/netfilter/nf_flow_table.h>
114  #include <net/netfilter/nf_conntrack.h>
115 @@ -23,6 +25,7 @@ flow_offload_fill_dir(struct flow_offloa
116  {
117         struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple;
118         struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple;
119 +       struct dst_entry *dst = route->tuple[dir].dst;
120  
121         ft->dir = dir;
122  
123 @@ -30,10 +33,12 @@ flow_offload_fill_dir(struct flow_offloa
124         case NFPROTO_IPV4:
125                 ft->src_v4 = ctt->src.u3.in;
126                 ft->dst_v4 = ctt->dst.u3.in;
127 +               ft->mtu = ip_dst_mtu_maybe_forward(dst, true);
128                 break;
129         case NFPROTO_IPV6:
130                 ft->src_v6 = ctt->src.u3.in6;
131                 ft->dst_v6 = ctt->dst.u3.in6;
132 +               ft->mtu = ip6_dst_mtu_forward(dst);
133                 break;
134         }
135  
136 @@ -44,8 +49,7 @@ flow_offload_fill_dir(struct flow_offloa
137  
138         ft->iifidx = route->tuple[dir].ifindex;
139         ft->oifidx = route->tuple[!dir].ifindex;
140 -
141 -       ft->dst_cache = route->tuple[dir].dst;
142 +       ft->dst_cache = dst;
143  }
144  
145  struct flow_offload *