v1.5 branch refresh based upon upstream master @ c8677ca89e53e3be7988d54280fce166cc894a7e
[librecmc/librecmc.git] / target / linux / generic / backport-4.14 / 300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch
1 From: Pablo Neira Ayuso <pablo@netfilter.org>
2 Date: Sun, 10 Dec 2017 01:43:14 +0100
3 Subject: [PATCH] netfilter: nf_tables: explicit nft_set_pktinfo() call from
4  hook path
5
6 Instead of calling this function from the family specific variant, this
7 reduces the code size in the fast path for the netdev, bridge and inet
8 families. After this change, we must call nft_set_pktinfo() upfront from
9 the chain hook indirection.
10
11 Before:
12
13    text    data     bss     dec     hex filename
14    2145     208       0    2353     931 net/netfilter/nf_tables_netdev.o
15
16 After:
17
18    text    data     bss     dec     hex filename
19    2125     208       0    2333     91d net/netfilter/nf_tables_netdev.o
20
21 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
22 ---
23
24 --- a/include/net/netfilter/nf_tables.h
25 +++ b/include/net/netfilter/nf_tables.h
26 @@ -54,8 +54,8 @@ static inline void nft_set_pktinfo(struc
27         pkt->xt.state = state;
28  }
29  
30 -static inline void nft_set_pktinfo_proto_unspec(struct nft_pktinfo *pkt,
31 -                                               struct sk_buff *skb)
32 +static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
33 +                                         struct sk_buff *skb)
34  {
35         pkt->tprot_set = false;
36         pkt->tprot = 0;
37 @@ -63,14 +63,6 @@ static inline void nft_set_pktinfo_proto
38         pkt->xt.fragoff = 0;
39  }
40  
41 -static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
42 -                                         struct sk_buff *skb,
43 -                                         const struct nf_hook_state *state)
44 -{
45 -       nft_set_pktinfo(pkt, skb, state);
46 -       nft_set_pktinfo_proto_unspec(pkt, skb);
47 -}
48 -
49  /**
50   *     struct nft_verdict - nf_tables verdict
51   *
52 --- a/include/net/netfilter/nf_tables_ipv4.h
53 +++ b/include/net/netfilter/nf_tables_ipv4.h
54 @@ -5,15 +5,11 @@
55  #include <net/netfilter/nf_tables.h>
56  #include <net/ip.h>
57  
58 -static inline void
59 -nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
60 -                    struct sk_buff *skb,
61 -                    const struct nf_hook_state *state)
62 +static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
63 +                                       struct sk_buff *skb)
64  {
65         struct iphdr *ip;
66  
67 -       nft_set_pktinfo(pkt, skb, state);
68 -
69         ip = ip_hdr(pkt->skb);
70         pkt->tprot_set = true;
71         pkt->tprot = ip->protocol;
72 @@ -21,10 +17,8 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo
73         pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
74  }
75  
76 -static inline int
77 -__nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
78 -                               struct sk_buff *skb,
79 -                               const struct nf_hook_state *state)
80 +static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
81 +                                                 struct sk_buff *skb)
82  {
83         struct iphdr *iph, _iph;
84         u32 len, thoff;
85 @@ -52,14 +46,11 @@ __nft_set_pktinfo_ipv4_validate(struct n
86         return 0;
87  }
88  
89 -static inline void
90 -nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
91 -                             struct sk_buff *skb,
92 -                             const struct nf_hook_state *state)
93 +static inline void nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
94 +                                                struct sk_buff *skb)
95  {
96 -       nft_set_pktinfo(pkt, skb, state);
97 -       if (__nft_set_pktinfo_ipv4_validate(pkt, skb, state) < 0)
98 -               nft_set_pktinfo_proto_unspec(pkt, skb);
99 +       if (__nft_set_pktinfo_ipv4_validate(pkt, skb) < 0)
100 +               nft_set_pktinfo_unspec(pkt, skb);
101  }
102  
103  extern struct nft_af_info nft_af_ipv4;
104 --- a/include/net/netfilter/nf_tables_ipv6.h
105 +++ b/include/net/netfilter/nf_tables_ipv6.h
106 @@ -5,20 +5,16 @@
107  #include <linux/netfilter_ipv6/ip6_tables.h>
108  #include <net/ipv6.h>
109  
110 -static inline void
111 -nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
112 -                    struct sk_buff *skb,
113 -                    const struct nf_hook_state *state)
114 +static inline void nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
115 +                                       struct sk_buff *skb)
116  {
117         unsigned int flags = IP6_FH_F_AUTH;
118         int protohdr, thoff = 0;
119         unsigned short frag_off;
120  
121 -       nft_set_pktinfo(pkt, skb, state);
122 -
123         protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
124         if (protohdr < 0) {
125 -               nft_set_pktinfo_proto_unspec(pkt, skb);
126 +               nft_set_pktinfo_unspec(pkt, skb);
127                 return;
128         }
129  
130 @@ -28,10 +24,8 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo
131         pkt->xt.fragoff = frag_off;
132  }
133  
134 -static inline int
135 -__nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
136 -                               struct sk_buff *skb,
137 -                               const struct nf_hook_state *state)
138 +static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
139 +                                                 struct sk_buff *skb)
140  {
141  #if IS_ENABLED(CONFIG_IPV6)
142         unsigned int flags = IP6_FH_F_AUTH;
143 @@ -68,14 +62,11 @@ __nft_set_pktinfo_ipv6_validate(struct n
144  #endif
145  }
146  
147 -static inline void
148 -nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
149 -                             struct sk_buff *skb,
150 -                             const struct nf_hook_state *state)
151 +static inline void nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
152 +                                                struct sk_buff *skb)
153  {
154 -       nft_set_pktinfo(pkt, skb, state);
155 -       if (__nft_set_pktinfo_ipv6_validate(pkt, skb, state) < 0)
156 -               nft_set_pktinfo_proto_unspec(pkt, skb);
157 +       if (__nft_set_pktinfo_ipv6_validate(pkt, skb) < 0)
158 +               nft_set_pktinfo_unspec(pkt, skb);
159  }
160  
161  extern struct nft_af_info nft_af_ipv6;
162 --- a/net/bridge/netfilter/nf_tables_bridge.c
163 +++ b/net/bridge/netfilter/nf_tables_bridge.c
164 @@ -25,15 +25,17 @@ nft_do_chain_bridge(void *priv,
165  {
166         struct nft_pktinfo pkt;
167  
168 +       nft_set_pktinfo(&pkt, skb, state);
169 +
170         switch (eth_hdr(skb)->h_proto) {
171         case htons(ETH_P_IP):
172 -               nft_set_pktinfo_ipv4_validate(&pkt, skb, state);
173 +               nft_set_pktinfo_ipv4_validate(&pkt, skb);
174                 break;
175         case htons(ETH_P_IPV6):
176 -               nft_set_pktinfo_ipv6_validate(&pkt, skb, state);
177 +               nft_set_pktinfo_ipv6_validate(&pkt, skb);
178                 break;
179         default:
180 -               nft_set_pktinfo_unspec(&pkt, skb, state);
181 +               nft_set_pktinfo_unspec(&pkt, skb);
182                 break;
183         }
184  
185 --- a/net/ipv4/netfilter/nf_tables_arp.c
186 +++ b/net/ipv4/netfilter/nf_tables_arp.c
187 @@ -21,7 +21,8 @@ nft_do_chain_arp(void *priv,
188  {
189         struct nft_pktinfo pkt;
190  
191 -       nft_set_pktinfo_unspec(&pkt, skb, state);
192 +       nft_set_pktinfo(&pkt, skb, state);
193 +       nft_set_pktinfo_unspec(&pkt, skb);
194  
195         return nft_do_chain(&pkt, priv);
196  }
197 --- a/net/ipv4/netfilter/nf_tables_ipv4.c
198 +++ b/net/ipv4/netfilter/nf_tables_ipv4.c
199 @@ -24,7 +24,8 @@ static unsigned int nft_do_chain_ipv4(vo
200  {
201         struct nft_pktinfo pkt;
202  
203 -       nft_set_pktinfo_ipv4(&pkt, skb, state);
204 +       nft_set_pktinfo(&pkt, skb, state);
205 +       nft_set_pktinfo_ipv4(&pkt, skb);
206  
207         return nft_do_chain(&pkt, priv);
208  }
209 --- a/net/ipv4/netfilter/nft_chain_nat_ipv4.c
210 +++ b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
211 @@ -33,7 +33,8 @@ static unsigned int nft_nat_do_chain(voi
212  {
213         struct nft_pktinfo pkt;
214  
215 -       nft_set_pktinfo_ipv4(&pkt, skb, state);
216 +       nft_set_pktinfo(&pkt, skb, state);
217 +       nft_set_pktinfo_ipv4(&pkt, skb);
218  
219         return nft_do_chain(&pkt, priv);
220  }
221 --- a/net/ipv4/netfilter/nft_chain_route_ipv4.c
222 +++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c
223 @@ -38,7 +38,8 @@ static unsigned int nf_route_table_hook(
224             ip_hdrlen(skb) < sizeof(struct iphdr))
225                 return NF_ACCEPT;
226  
227 -       nft_set_pktinfo_ipv4(&pkt, skb, state);
228 +       nft_set_pktinfo(&pkt, skb, state);
229 +       nft_set_pktinfo_ipv4(&pkt, skb);
230  
231         mark = skb->mark;
232         iph = ip_hdr(skb);
233 --- a/net/ipv6/netfilter/nf_tables_ipv6.c
234 +++ b/net/ipv6/netfilter/nf_tables_ipv6.c
235 @@ -22,7 +22,8 @@ static unsigned int nft_do_chain_ipv6(vo
236  {
237         struct nft_pktinfo pkt;
238  
239 -       nft_set_pktinfo_ipv6(&pkt, skb, state);
240 +       nft_set_pktinfo(&pkt, skb, state);
241 +       nft_set_pktinfo_ipv6(&pkt, skb);
242  
243         return nft_do_chain(&pkt, priv);
244  }
245 --- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
246 +++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
247 @@ -31,7 +31,8 @@ static unsigned int nft_nat_do_chain(voi
248  {
249         struct nft_pktinfo pkt;
250  
251 -       nft_set_pktinfo_ipv6(&pkt, skb, state);
252 +       nft_set_pktinfo(&pkt, skb, state);
253 +       nft_set_pktinfo_ipv6(&pkt, skb);
254  
255         return nft_do_chain(&pkt, priv);
256  }
257 --- a/net/ipv6/netfilter/nft_chain_route_ipv6.c
258 +++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c
259 @@ -33,7 +33,8 @@ static unsigned int nf_route_table_hook(
260         u32 mark, flowlabel;
261         int err;
262  
263 -       nft_set_pktinfo_ipv6(&pkt, skb, state);
264 +       nft_set_pktinfo(&pkt, skb, state);
265 +       nft_set_pktinfo_ipv6(&pkt, skb);
266  
267         /* save source/dest address, mark, hoplimit, flowlabel, priority */
268         memcpy(&saddr, &ipv6_hdr(skb)->saddr, sizeof(saddr));
269 --- a/net/netfilter/nf_tables_netdev.c
270 +++ b/net/netfilter/nf_tables_netdev.c
271 @@ -21,15 +21,17 @@ nft_do_chain_netdev(void *priv, struct s
272  {
273         struct nft_pktinfo pkt;
274  
275 +       nft_set_pktinfo(&pkt, skb, state);
276 +
277         switch (skb->protocol) {
278         case htons(ETH_P_IP):
279 -               nft_set_pktinfo_ipv4_validate(&pkt, skb, state);
280 +               nft_set_pktinfo_ipv4_validate(&pkt, skb);
281                 break;
282         case htons(ETH_P_IPV6):
283 -               nft_set_pktinfo_ipv6_validate(&pkt, skb, state);
284 +               nft_set_pktinfo_ipv6_validate(&pkt, skb);
285                 break;
286         default:
287 -               nft_set_pktinfo_unspec(&pkt, skb, state);
288 +               nft_set_pktinfo_unspec(&pkt, skb);
289                 break;
290         }
291