forked from mirrors/linux
		
	xfrm: remove output_finish indirection from xfrm_state_afinfo
There are only two implementaions, one for ipv4 and one for ipv6. Both are almost identical, they clear skb->cb[], set the TRANSFORMED flag in IP(6)CB and then call the common xfrm_output() function. By placing the IPCB handling into the common function, we avoid the need for the output_finish indirection as the output functions can simply use xfrm_output(). Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
		
							parent
							
								
									f3075f48dd
								
							
						
					
					
						commit
						2ab6096db2
					
				
					 6 changed files with 19 additions and 57 deletions
				
			
		|  | @ -361,7 +361,6 @@ struct xfrm_state_afinfo { | |||
| 	const struct xfrm_type		*type_dstopts; | ||||
| 
 | ||||
| 	int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb); | ||||
| 	int			(*output_finish)(struct sock *sk, struct sk_buff *skb); | ||||
| 	int			(*transport_finish)(struct sk_buff *skb, | ||||
| 						    int async); | ||||
| 	void			(*local_error)(struct sk_buff *skb, u32 mtu); | ||||
|  |  | |||
|  | @ -14,22 +14,9 @@ | |||
| #include <net/xfrm.h> | ||||
| #include <net/icmp.h> | ||||
| 
 | ||||
| int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb) | ||||
| { | ||||
| 	memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | ||||
| 
 | ||||
| #ifdef CONFIG_NETFILTER | ||||
| 	IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; | ||||
| #endif | ||||
| 
 | ||||
| 	return xfrm_output(sk, skb); | ||||
| } | ||||
| 
 | ||||
| static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) | ||||
| { | ||||
| 	struct xfrm_state *x = skb_dst(skb)->xfrm; | ||||
| 	const struct xfrm_state_afinfo *afinfo; | ||||
| 	int ret = -EAFNOSUPPORT; | ||||
| 
 | ||||
| #ifdef CONFIG_NETFILTER | ||||
| 	if (!x) { | ||||
|  | @ -38,15 +25,7 @@ static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	rcu_read_lock(); | ||||
| 	afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family); | ||||
| 	if (likely(afinfo)) | ||||
| 		ret = afinfo->output_finish(sk, skb); | ||||
| 	else | ||||
| 		kfree_skb(skb); | ||||
| 	rcu_read_unlock(); | ||||
| 
 | ||||
| 	return ret; | ||||
| 	return xfrm_output(sk, skb); | ||||
| } | ||||
| 
 | ||||
| int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) | ||||
|  |  | |||
|  | @ -14,7 +14,6 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = { | |||
| 	.family			= AF_INET, | ||||
| 	.proto			= IPPROTO_IPIP, | ||||
| 	.output			= xfrm4_output, | ||||
| 	.output_finish		= xfrm4_output_finish, | ||||
| 	.transport_finish	= xfrm4_transport_finish, | ||||
| 	.local_error		= xfrm4_local_error, | ||||
| }; | ||||
|  |  | |||
|  | @ -47,39 +47,9 @@ void xfrm6_local_error(struct sk_buff *skb, u32 mtu) | |||
| 	ipv6_local_error(sk, EMSGSIZE, &fl6, mtu); | ||||
| } | ||||
| 
 | ||||
| int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb) | ||||
| { | ||||
| 	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | ||||
| 
 | ||||
| #ifdef CONFIG_NETFILTER | ||||
| 	IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | ||||
| #endif | ||||
| 
 | ||||
| 	return xfrm_output(sk, skb); | ||||
| } | ||||
| 
 | ||||
| static int __xfrm6_output_state_finish(struct xfrm_state *x, struct sock *sk, | ||||
| 				       struct sk_buff *skb) | ||||
| { | ||||
| 	const struct xfrm_state_afinfo *afinfo; | ||||
| 	int ret = -EAFNOSUPPORT; | ||||
| 
 | ||||
| 	rcu_read_lock(); | ||||
| 	afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family); | ||||
| 	if (likely(afinfo)) | ||||
| 		ret = afinfo->output_finish(sk, skb); | ||||
| 	else | ||||
| 		kfree_skb(skb); | ||||
| 	rcu_read_unlock(); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | ||||
| { | ||||
| 	struct xfrm_state *x = skb_dst(skb)->xfrm; | ||||
| 
 | ||||
| 	return __xfrm6_output_state_finish(x, sk, skb); | ||||
| 	return xfrm_output(sk, skb); | ||||
| } | ||||
| 
 | ||||
| static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | ||||
|  | @ -121,7 +91,7 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 				    __xfrm6_output_finish); | ||||
| 
 | ||||
| skip_frag: | ||||
| 	return __xfrm6_output_state_finish(x, sk, skb); | ||||
| 	return xfrm_output(sk, skb); | ||||
| } | ||||
| 
 | ||||
| int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { | |||
| 	.family			= AF_INET6, | ||||
| 	.proto			= IPPROTO_IPV6, | ||||
| 	.output			= xfrm6_output, | ||||
| 	.output_finish		= xfrm6_output_finish, | ||||
| 	.transport_finish	= xfrm6_transport_finish, | ||||
| 	.local_error		= xfrm6_local_error, | ||||
| }; | ||||
|  |  | |||
|  | @ -571,6 +571,22 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb) | |||
| 	struct xfrm_state *x = skb_dst(skb)->xfrm; | ||||
| 	int err; | ||||
| 
 | ||||
| 	switch (x->outer_mode.family) { | ||||
| 	case AF_INET: | ||||
| 		memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | ||||
| #ifdef CONFIG_NETFILTER | ||||
| 		IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; | ||||
| #endif | ||||
| 		break; | ||||
| 	case AF_INET6: | ||||
| 		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | ||||
| 
 | ||||
| #ifdef CONFIG_NETFILTER | ||||
| 		IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | ||||
| #endif | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	secpath_reset(skb); | ||||
| 
 | ||||
| 	if (xfrm_dev_offload_ok(skb, x)) { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Florian Westphal
						Florian Westphal