c0cb5bbebae0a6fc99b2bb1b97589ab3c39d4695
[openwrt/staging/hauke.git] /
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