300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch 8.3 KB

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