305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. From: Pablo Neira Ayuso <pablo@netfilter.org>
  2. Date: Wed, 20 Dec 2017 16:04:18 +0100
  3. Subject: [PATCH] netfilter: move checksum_partial indirection to struct
  4. nf_ipv6_ops
  5. We cannot make a direct call to nf_ip6_checksum_partial() because that
  6. would result in autoloading the 'ipv6' module because of symbol
  7. dependencies. Therefore, define checksum_partial indirection in
  8. nf_ipv6_ops where this really belongs to.
  9. For IPv4, we can indeed make a direct function call, which is faster,
  10. given IPv4 is built-in in the networking code by default. Still,
  11. CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline
  12. stub for IPv4 in such case.
  13. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  14. ---
  15. --- a/include/linux/netfilter.h
  16. +++ b/include/linux/netfilter.h
  17. @@ -311,11 +311,6 @@ struct nf_queue_entry;
  18. struct nf_afinfo {
  19. unsigned short family;
  20. - __sum16 (*checksum_partial)(struct sk_buff *skb,
  21. - unsigned int hook,
  22. - unsigned int dataoff,
  23. - unsigned int len,
  24. - u_int8_t protocol);
  25. int (*route)(struct net *net, struct dst_entry **dst,
  26. struct flowi *fl, bool strict);
  27. void (*saveroute)(const struct sk_buff *skb,
  28. @@ -335,22 +330,9 @@ __sum16 nf_checksum(struct sk_buff *skb,
  29. unsigned int dataoff, u_int8_t protocol,
  30. unsigned short family);
  31. -static inline __sum16
  32. -nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
  33. - unsigned int dataoff, unsigned int len,
  34. - u_int8_t protocol, unsigned short family)
  35. -{
  36. - const struct nf_afinfo *afinfo;
  37. - __sum16 csum = 0;
  38. -
  39. - rcu_read_lock();
  40. - afinfo = nf_get_afinfo(family);
  41. - if (afinfo)
  42. - csum = afinfo->checksum_partial(skb, hook, dataoff, len,
  43. - protocol);
  44. - rcu_read_unlock();
  45. - return csum;
  46. -}
  47. +__sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
  48. + unsigned int dataoff, unsigned int len,
  49. + u_int8_t protocol, unsigned short family);
  50. int nf_register_afinfo(const struct nf_afinfo *afinfo);
  51. void nf_unregister_afinfo(const struct nf_afinfo *afinfo);
  52. --- a/include/linux/netfilter_ipv4.h
  53. +++ b/include/linux/netfilter_ipv4.h
  54. @@ -11,12 +11,23 @@ int ip_route_me_harder(struct net *net,
  55. #ifdef CONFIG_INET
  56. __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
  57. unsigned int dataoff, u_int8_t protocol);
  58. +__sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
  59. + unsigned int dataoff, unsigned int len,
  60. + u_int8_t protocol);
  61. #else
  62. static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
  63. unsigned int dataoff, u_int8_t protocol)
  64. {
  65. return 0;
  66. }
  67. +static inline __sum16 nf_ip_checksum_partial(struct sk_buff *skb,
  68. + unsigned int hook,
  69. + unsigned int dataoff,
  70. + unsigned int len,
  71. + u_int8_t protocol)
  72. +{
  73. + return 0;
  74. +}
  75. #endif /* CONFIG_INET */
  76. #endif /*__LINUX_IP_NETFILTER_H*/
  77. --- a/include/linux/netfilter_ipv6.h
  78. +++ b/include/linux/netfilter_ipv6.h
  79. @@ -21,6 +21,9 @@ struct nf_ipv6_ops {
  80. int (*output)(struct net *, struct sock *, struct sk_buff *));
  81. __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
  82. unsigned int dataoff, u_int8_t protocol);
  83. + __sum16 (*checksum_partial)(struct sk_buff *skb, unsigned int hook,
  84. + unsigned int dataoff, unsigned int len,
  85. + u_int8_t protocol);
  86. };
  87. #ifdef CONFIG_NETFILTER
  88. --- a/net/bridge/netfilter/nf_tables_bridge.c
  89. +++ b/net/bridge/netfilter/nf_tables_bridge.c
  90. @@ -106,13 +106,6 @@ static int nf_br_reroute(struct net *net
  91. return 0;
  92. }
  93. -static __sum16 nf_br_checksum_partial(struct sk_buff *skb, unsigned int hook,
  94. - unsigned int dataoff, unsigned int len,
  95. - u_int8_t protocol)
  96. -{
  97. - return 0;
  98. -}
  99. -
  100. static int nf_br_route(struct net *net, struct dst_entry **dst,
  101. struct flowi *fl, bool strict __always_unused)
  102. {
  103. @@ -121,7 +114,6 @@ static int nf_br_route(struct net *net,
  104. static const struct nf_afinfo nf_br_afinfo = {
  105. .family = AF_BRIDGE,
  106. - .checksum_partial = nf_br_checksum_partial,
  107. .route = nf_br_route,
  108. .saveroute = nf_br_saveroute,
  109. .reroute = nf_br_reroute,
  110. --- a/net/ipv4/netfilter.c
  111. +++ b/net/ipv4/netfilter.c
  112. @@ -155,9 +155,9 @@ __sum16 nf_ip_checksum(struct sk_buff *s
  113. }
  114. EXPORT_SYMBOL(nf_ip_checksum);
  115. -static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
  116. - unsigned int dataoff, unsigned int len,
  117. - u_int8_t protocol)
  118. +__sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
  119. + unsigned int dataoff, unsigned int len,
  120. + u_int8_t protocol)
  121. {
  122. const struct iphdr *iph = ip_hdr(skb);
  123. __sum16 csum = 0;
  124. @@ -175,6 +175,7 @@ static __sum16 nf_ip_checksum_partial(st
  125. }
  126. return csum;
  127. }
  128. +EXPORT_SYMBOL_GPL(nf_ip_checksum_partial);
  129. static int nf_ip_route(struct net *net, struct dst_entry **dst,
  130. struct flowi *fl, bool strict __always_unused)
  131. @@ -188,7 +189,6 @@ static int nf_ip_route(struct net *net,
  132. static const struct nf_afinfo nf_ip_afinfo = {
  133. .family = AF_INET,
  134. - .checksum_partial = nf_ip_checksum_partial,
  135. .route = nf_ip_route,
  136. .saveroute = nf_ip_saveroute,
  137. .reroute = nf_ip_reroute,
  138. --- a/net/ipv6/netfilter.c
  139. +++ b/net/ipv6/netfilter.c
  140. @@ -194,15 +194,15 @@ static __sum16 nf_ip6_checksum_partial(s
  141. };
  142. static const struct nf_ipv6_ops ipv6ops = {
  143. - .chk_addr = ipv6_chk_addr,
  144. - .route_input = ip6_route_input,
  145. - .fragment = ip6_fragment,
  146. - .checksum = nf_ip6_checksum,
  147. + .chk_addr = ipv6_chk_addr,
  148. + .route_input = ip6_route_input,
  149. + .fragment = ip6_fragment,
  150. + .checksum = nf_ip6_checksum,
  151. + .checksum_partial = nf_ip6_checksum_partial,
  152. };
  153. static const struct nf_afinfo nf_ip6_afinfo = {
  154. .family = AF_INET6,
  155. - .checksum_partial = nf_ip6_checksum_partial,
  156. .route = nf_ip6_route,
  157. .saveroute = nf_ip6_saveroute,
  158. .reroute = nf_ip6_reroute,
  159. --- a/net/netfilter/utils.c
  160. +++ b/net/netfilter/utils.c
  161. @@ -24,3 +24,27 @@ __sum16 nf_checksum(struct sk_buff *skb,
  162. return csum;
  163. }
  164. EXPORT_SYMBOL_GPL(nf_checksum);
  165. +
  166. +__sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
  167. + unsigned int dataoff, unsigned int len,
  168. + u_int8_t protocol, unsigned short family)
  169. +{
  170. + const struct nf_ipv6_ops *v6ops;
  171. + __sum16 csum = 0;
  172. +
  173. + switch (family) {
  174. + case AF_INET:
  175. + csum = nf_ip_checksum_partial(skb, hook, dataoff, len,
  176. + protocol);
  177. + break;
  178. + case AF_INET6:
  179. + v6ops = rcu_dereference(nf_ipv6_ops);
  180. + if (v6ops)
  181. + csum = v6ops->checksum_partial(skb, hook, dataoff, len,
  182. + protocol);
  183. + break;
  184. + }
  185. +
  186. + return csum;
  187. +}
  188. +EXPORT_SYMBOL_GPL(nf_checksum_partial);