123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- From: Pablo Neira Ayuso <pablo@netfilter.org>
- Date: Wed, 20 Dec 2017 16:04:18 +0100
- Subject: [PATCH] netfilter: move checksum_partial indirection to struct
- nf_ipv6_ops
- We cannot make a direct call to nf_ip6_checksum_partial() because that
- would result in autoloading the 'ipv6' module because of symbol
- dependencies. Therefore, define checksum_partial indirection in
- nf_ipv6_ops where this really belongs to.
- For IPv4, we can indeed make a direct function call, which is faster,
- given IPv4 is built-in in the networking code by default. Still,
- CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline
- stub for IPv4 in such case.
- Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
- ---
- --- a/include/linux/netfilter.h
- +++ b/include/linux/netfilter.h
- @@ -311,11 +311,6 @@ struct nf_queue_entry;
-
- struct nf_afinfo {
- unsigned short family;
- - __sum16 (*checksum_partial)(struct sk_buff *skb,
- - unsigned int hook,
- - unsigned int dataoff,
- - unsigned int len,
- - u_int8_t protocol);
- int (*route)(struct net *net, struct dst_entry **dst,
- struct flowi *fl, bool strict);
- void (*saveroute)(const struct sk_buff *skb,
- @@ -335,22 +330,9 @@ __sum16 nf_checksum(struct sk_buff *skb,
- unsigned int dataoff, u_int8_t protocol,
- unsigned short family);
-
- -static inline __sum16
- -nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
- - unsigned int dataoff, unsigned int len,
- - u_int8_t protocol, unsigned short family)
- -{
- - const struct nf_afinfo *afinfo;
- - __sum16 csum = 0;
- -
- - rcu_read_lock();
- - afinfo = nf_get_afinfo(family);
- - if (afinfo)
- - csum = afinfo->checksum_partial(skb, hook, dataoff, len,
- - protocol);
- - rcu_read_unlock();
- - return csum;
- -}
- +__sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
- + unsigned int dataoff, unsigned int len,
- + u_int8_t protocol, unsigned short family);
-
- int nf_register_afinfo(const struct nf_afinfo *afinfo);
- void nf_unregister_afinfo(const struct nf_afinfo *afinfo);
- --- a/include/linux/netfilter_ipv4.h
- +++ b/include/linux/netfilter_ipv4.h
- @@ -11,12 +11,23 @@ int ip_route_me_harder(struct net *net,
- #ifdef CONFIG_INET
- __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
- unsigned int dataoff, u_int8_t protocol);
- +__sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
- + unsigned int dataoff, unsigned int len,
- + u_int8_t protocol);
- #else
- static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
- unsigned int dataoff, u_int8_t protocol)
- {
- return 0;
- }
- +static inline __sum16 nf_ip_checksum_partial(struct sk_buff *skb,
- + unsigned int hook,
- + unsigned int dataoff,
- + unsigned int len,
- + u_int8_t protocol)
- +{
- + return 0;
- +}
- #endif /* CONFIG_INET */
-
- #endif /*__LINUX_IP_NETFILTER_H*/
- --- a/include/linux/netfilter_ipv6.h
- +++ b/include/linux/netfilter_ipv6.h
- @@ -21,6 +21,9 @@ struct nf_ipv6_ops {
- int (*output)(struct net *, struct sock *, struct sk_buff *));
- __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
- unsigned int dataoff, u_int8_t protocol);
- + __sum16 (*checksum_partial)(struct sk_buff *skb, unsigned int hook,
- + unsigned int dataoff, unsigned int len,
- + u_int8_t protocol);
- };
-
- #ifdef CONFIG_NETFILTER
- --- a/net/bridge/netfilter/nf_tables_bridge.c
- +++ b/net/bridge/netfilter/nf_tables_bridge.c
- @@ -106,13 +106,6 @@ static int nf_br_reroute(struct net *net
- return 0;
- }
-
- -static __sum16 nf_br_checksum_partial(struct sk_buff *skb, unsigned int hook,
- - unsigned int dataoff, unsigned int len,
- - u_int8_t protocol)
- -{
- - return 0;
- -}
- -
- static int nf_br_route(struct net *net, struct dst_entry **dst,
- struct flowi *fl, bool strict __always_unused)
- {
- @@ -121,7 +114,6 @@ static int nf_br_route(struct net *net,
-
- static const struct nf_afinfo nf_br_afinfo = {
- .family = AF_BRIDGE,
- - .checksum_partial = nf_br_checksum_partial,
- .route = nf_br_route,
- .saveroute = nf_br_saveroute,
- .reroute = nf_br_reroute,
- --- a/net/ipv4/netfilter.c
- +++ b/net/ipv4/netfilter.c
- @@ -155,9 +155,9 @@ __sum16 nf_ip_checksum(struct sk_buff *s
- }
- EXPORT_SYMBOL(nf_ip_checksum);
-
- -static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
- - unsigned int dataoff, unsigned int len,
- - u_int8_t protocol)
- +__sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
- + unsigned int dataoff, unsigned int len,
- + u_int8_t protocol)
- {
- const struct iphdr *iph = ip_hdr(skb);
- __sum16 csum = 0;
- @@ -175,6 +175,7 @@ static __sum16 nf_ip_checksum_partial(st
- }
- return csum;
- }
- +EXPORT_SYMBOL_GPL(nf_ip_checksum_partial);
-
- static int nf_ip_route(struct net *net, struct dst_entry **dst,
- struct flowi *fl, bool strict __always_unused)
- @@ -188,7 +189,6 @@ static int nf_ip_route(struct net *net,
-
- static const struct nf_afinfo nf_ip_afinfo = {
- .family = AF_INET,
- - .checksum_partial = nf_ip_checksum_partial,
- .route = nf_ip_route,
- .saveroute = nf_ip_saveroute,
- .reroute = nf_ip_reroute,
- --- a/net/ipv6/netfilter.c
- +++ b/net/ipv6/netfilter.c
- @@ -194,15 +194,15 @@ static __sum16 nf_ip6_checksum_partial(s
- };
-
- static const struct nf_ipv6_ops ipv6ops = {
- - .chk_addr = ipv6_chk_addr,
- - .route_input = ip6_route_input,
- - .fragment = ip6_fragment,
- - .checksum = nf_ip6_checksum,
- + .chk_addr = ipv6_chk_addr,
- + .route_input = ip6_route_input,
- + .fragment = ip6_fragment,
- + .checksum = nf_ip6_checksum,
- + .checksum_partial = nf_ip6_checksum_partial,
- };
-
- static const struct nf_afinfo nf_ip6_afinfo = {
- .family = AF_INET6,
- - .checksum_partial = nf_ip6_checksum_partial,
- .route = nf_ip6_route,
- .saveroute = nf_ip6_saveroute,
- .reroute = nf_ip6_reroute,
- --- a/net/netfilter/utils.c
- +++ b/net/netfilter/utils.c
- @@ -24,3 +24,27 @@ __sum16 nf_checksum(struct sk_buff *skb,
- return csum;
- }
- EXPORT_SYMBOL_GPL(nf_checksum);
- +
- +__sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
- + unsigned int dataoff, unsigned int len,
- + u_int8_t protocol, unsigned short family)
- +{
- + const struct nf_ipv6_ops *v6ops;
- + __sum16 csum = 0;
- +
- + switch (family) {
- + case AF_INET:
- + csum = nf_ip_checksum_partial(skb, hook, dataoff, len,
- + protocol);
- + break;
- + case AF_INET6:
- + v6ops = rcu_dereference(nf_ipv6_ops);
- + if (v6ops)
- + csum = v6ops->checksum_partial(skb, hook, dataoff, len,
- + protocol);
- + break;
- + }
- +
- + return csum;
- +}
- +EXPORT_SYMBOL_GPL(nf_checksum_partial);
|