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
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.
13 text data bss dec hex filename
14 2145 208 0 2353 931 net/netfilter/nf_tables_netdev.o
18 text data bss dec hex filename
19 2125 208 0 2333 91d net/netfilter/nf_tables_netdev.o
21 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
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;
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)
35 pkt->tprot_set = false;
37 @@ -63,14 +63,6 @@ static inline void nft_set_pktinfo_proto
41 -static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
42 - struct sk_buff *skb,
43 - const struct nf_hook_state *state)
45 - nft_set_pktinfo(pkt, skb, state);
46 - nft_set_pktinfo_proto_unspec(pkt, skb);
50 * struct nft_verdict - nf_tables verdict
52 --- a/include/net/netfilter/nf_tables_ipv4.h
53 +++ b/include/net/netfilter/nf_tables_ipv4.h
55 #include <net/netfilter/nf_tables.h>
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)
67 - nft_set_pktinfo(pkt, skb, state);
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;
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)
83 struct iphdr *iph, _iph;
85 @@ -52,14 +46,11 @@ __nft_set_pktinfo_ipv4_validate(struct n
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)
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);
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
107 #include <linux/netfilter_ipv6/ip6_tables.h>
108 #include <net/ipv6.h>
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)
117 unsigned int flags = IP6_FH_F_AUTH;
118 int protohdr, thoff = 0;
119 unsigned short frag_off;
121 - nft_set_pktinfo(pkt, skb, state);
123 protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
125 - nft_set_pktinfo_proto_unspec(pkt, skb);
126 + nft_set_pktinfo_unspec(pkt, skb);
130 @@ -28,10 +24,8 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo
131 pkt->xt.fragoff = frag_off;
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)
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
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)
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);
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,
166 struct nft_pktinfo pkt;
168 + nft_set_pktinfo(&pkt, skb, state);
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);
175 case htons(ETH_P_IPV6):
176 - nft_set_pktinfo_ipv6_validate(&pkt, skb, state);
177 + nft_set_pktinfo_ipv6_validate(&pkt, skb);
180 - nft_set_pktinfo_unspec(&pkt, skb, state);
181 + nft_set_pktinfo_unspec(&pkt, skb);
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,
189 struct nft_pktinfo pkt;
191 - nft_set_pktinfo_unspec(&pkt, skb, state);
192 + nft_set_pktinfo(&pkt, skb, state);
193 + nft_set_pktinfo_unspec(&pkt, skb);
195 return nft_do_chain(&pkt, priv);
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
201 struct nft_pktinfo pkt;
203 - nft_set_pktinfo_ipv4(&pkt, skb, state);
204 + nft_set_pktinfo(&pkt, skb, state);
205 + nft_set_pktinfo_ipv4(&pkt, skb);
207 return nft_do_chain(&pkt, priv);
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
213 struct nft_pktinfo pkt;
215 - nft_set_pktinfo_ipv4(&pkt, skb, state);
216 + nft_set_pktinfo(&pkt, skb, state);
217 + nft_set_pktinfo_ipv4(&pkt, skb);
219 return nft_do_chain(&pkt, priv);
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))
227 - nft_set_pktinfo_ipv4(&pkt, skb, state);
228 + nft_set_pktinfo(&pkt, skb, state);
229 + nft_set_pktinfo_ipv4(&pkt, 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
237 struct nft_pktinfo pkt;
239 - nft_set_pktinfo_ipv6(&pkt, skb, state);
240 + nft_set_pktinfo(&pkt, skb, state);
241 + nft_set_pktinfo_ipv6(&pkt, skb);
243 return nft_do_chain(&pkt, priv);
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
249 struct nft_pktinfo pkt;
251 - nft_set_pktinfo_ipv6(&pkt, skb, state);
252 + nft_set_pktinfo(&pkt, skb, state);
253 + nft_set_pktinfo_ipv6(&pkt, skb);
255 return nft_do_chain(&pkt, priv);
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(
263 - nft_set_pktinfo_ipv6(&pkt, skb, state);
264 + nft_set_pktinfo(&pkt, skb, state);
265 + nft_set_pktinfo_ipv6(&pkt, skb);
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
273 struct nft_pktinfo pkt;
275 + nft_set_pktinfo(&pkt, skb, state);
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);
282 case htons(ETH_P_IPV6):
283 - nft_set_pktinfo_ipv6_validate(&pkt, skb, state);
284 + nft_set_pktinfo_ipv6_validate(&pkt, skb);
287 - nft_set_pktinfo_unspec(&pkt, skb, state);
288 + nft_set_pktinfo_unspec(&pkt, skb);