netfilter: move checksum indirection to struct nf_ipv6_ops
We cannot make a direct call to nf_ip6_checksum() because that would result in autoloading the 'ipv6' module because of symbol dependencies. Therefore, define checksum 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>
This commit is contained in:
		
							parent
							
								
									625c556118
								
							
						
					
					
						commit
						ef71fe27ec
					
				| @ -311,8 +311,6 @@ struct nf_queue_entry; | ||||
| 
 | ||||
| struct nf_afinfo { | ||||
| 	unsigned short	family; | ||||
| 	__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, | ||||
| @ -333,20 +331,9 @@ static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family) | ||||
| 	return rcu_dereference(nf_afinfo[family]); | ||||
| } | ||||
| 
 | ||||
| static inline __sum16 | ||||
| nf_checksum(struct sk_buff *skb, unsigned int hook, unsigned int dataoff, | ||||
| 	    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(skb, hook, dataoff, protocol); | ||||
| 	rcu_read_unlock(); | ||||
| 	return csum; | ||||
| } | ||||
| __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, | ||||
| 		    unsigned int dataoff, u_int8_t protocol, | ||||
| 		    unsigned short family); | ||||
| 
 | ||||
| static inline __sum16 | ||||
| nf_checksum_partial(struct sk_buff *skb, unsigned int hook, | ||||
|  | ||||
| @ -7,6 +7,16 @@ | ||||
| #include <uapi/linux/netfilter_ipv4.h> | ||||
| 
 | ||||
| int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned addr_type); | ||||
| 
 | ||||
| #ifdef CONFIG_INET | ||||
| __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, | ||||
| 		       unsigned int dataoff, 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; | ||||
| } | ||||
| #endif /* CONFIG_INET */ | ||||
| 
 | ||||
| #endif /*__LINUX_IP_NETFILTER_H*/ | ||||
|  | ||||
| @ -19,6 +19,8 @@ struct nf_ipv6_ops { | ||||
| 	void (*route_input)(struct sk_buff *skb); | ||||
| 	int (*fragment)(struct net *net, struct sock *sk, struct sk_buff *skb, | ||||
| 			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); | ||||
| }; | ||||
| 
 | ||||
| #ifdef CONFIG_NETFILTER | ||||
|  | ||||
| @ -106,12 +106,6 @@ static int nf_br_reroute(struct net *net, struct sk_buff *skb, | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static __sum16 nf_br_checksum(struct sk_buff *skb, unsigned int hook, | ||||
| 			      unsigned int dataoff, u_int8_t protocol) | ||||
| { | ||||
| 	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) | ||||
| @ -127,7 +121,6 @@ static int nf_br_route(struct net *net, struct dst_entry **dst, | ||||
| 
 | ||||
| static const struct nf_afinfo nf_br_afinfo = { | ||||
| 	.family                 = AF_BRIDGE, | ||||
| 	.checksum               = nf_br_checksum, | ||||
| 	.checksum_partial       = nf_br_checksum_partial, | ||||
| 	.route                  = nf_br_route, | ||||
| 	.saveroute              = nf_br_saveroute, | ||||
|  | ||||
| @ -188,7 +188,6 @@ static int nf_ip_route(struct net *net, struct dst_entry **dst, | ||||
| 
 | ||||
| static const struct nf_afinfo nf_ip_afinfo = { | ||||
| 	.family			= AF_INET, | ||||
| 	.checksum		= nf_ip_checksum, | ||||
| 	.checksum_partial	= nf_ip_checksum_partial, | ||||
| 	.route			= nf_ip_route, | ||||
| 	.saveroute		= nf_ip_saveroute, | ||||
|  | ||||
| @ -192,12 +192,12 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook, | ||||
| static const struct nf_ipv6_ops ipv6ops = { | ||||
| 	.chk_addr	= ipv6_chk_addr, | ||||
| 	.route_input    = ip6_route_input, | ||||
| 	.fragment	= ip6_fragment | ||||
| 	.fragment	= ip6_fragment, | ||||
| 	.checksum	= nf_ip6_checksum, | ||||
| }; | ||||
| 
 | ||||
| static const struct nf_afinfo nf_ip6_afinfo = { | ||||
| 	.family			= AF_INET6, | ||||
| 	.checksum		= nf_ip6_checksum, | ||||
| 	.checksum_partial	= nf_ip6_checksum_partial, | ||||
| 	.route			= nf_ip6_route, | ||||
| 	.saveroute		= nf_ip6_saveroute, | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| # SPDX-License-Identifier: GPL-2.0
 | ||||
| netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o | ||||
| netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o utils.o | ||||
| 
 | ||||
| nf_conntrack-y	:= nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack_seqadj.o | ||||
| nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o | ||||
|  | ||||
							
								
								
									
										26
									
								
								net/netfilter/utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								net/netfilter/utils.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/netfilter.h> | ||||
| #include <linux/netfilter_ipv4.h> | ||||
| #include <linux/netfilter_ipv6.h> | ||||
| 
 | ||||
| __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, | ||||
| 		    unsigned int dataoff, 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(skb, hook, dataoff, protocol); | ||||
| 		break; | ||||
| 	case AF_INET6: | ||||
| 		v6ops = rcu_dereference(nf_ipv6_ops); | ||||
| 		if (v6ops) | ||||
| 			csum = v6ops->checksum(skb, hook, dataoff, protocol); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	return csum; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(nf_checksum); | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user