forked from mirrors/linux
		
	net: Add a xfrm validate function to validate_xmit_skb
When we do IPsec offloading, we need a fallback for packets that were targeted to be IPsec offloaded but rerouted to a device that does not support IPsec offload. For that we add a function that checks the offloading features of the sending device and and flags the requirement of a fallback before it calls the IPsec output function. The IPsec output function adds the IPsec trailer and does encryption if needed. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
		
							parent
							
								
									b3859c8ebf
								
							
						
					
					
						commit
						f6e27114a6
					
				
					 3 changed files with 38 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1862,6 +1862,7 @@ static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
 | 
			
		|||
 | 
			
		||||
#ifdef CONFIG_XFRM_OFFLOAD
 | 
			
		||||
void __net_init xfrm_dev_init(void);
 | 
			
		||||
int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features);
 | 
			
		||||
int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
 | 
			
		||||
		       struct xfrm_user_offload *xuo);
 | 
			
		||||
bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
 | 
			
		||||
| 
						 | 
				
			
			@ -1890,6 +1891,11 @@ static inline void __net_init xfrm_dev_init(void)
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2972,6 +2972,9 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
 | 
			
		|||
		    __skb_linearize(skb))
 | 
			
		||||
			goto out_kfree_skb;
 | 
			
		||||
 | 
			
		||||
		if (validate_xmit_xfrm(skb, features))
 | 
			
		||||
			goto out_kfree_skb;
 | 
			
		||||
 | 
			
		||||
		/* If packet is not checksummed and device does not
 | 
			
		||||
		 * support checksumming for this protocol, complete
 | 
			
		||||
		 * checksumming here.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,35 @@
 | 
			
		|||
#include <net/xfrm.h>
 | 
			
		||||
#include <linux/notifier.h>
 | 
			
		||||
 | 
			
		||||
int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
 | 
			
		||||
{
 | 
			
		||||
	int err;
 | 
			
		||||
	struct xfrm_state *x;
 | 
			
		||||
	struct xfrm_offload *xo = xfrm_offload(skb);
 | 
			
		||||
 | 
			
		||||
	if (skb_is_gso(skb))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (xo) {
 | 
			
		||||
		x = skb->sp->xvec[skb->sp->len - 1];
 | 
			
		||||
		if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		x->outer_mode->xmit(x, skb);
 | 
			
		||||
 | 
			
		||||
		err = x->type_offload->xmit(x, skb, features);
 | 
			
		||||
		if (err) {
 | 
			
		||||
			XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR);
 | 
			
		||||
			return err;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		skb_push(skb, skb->data - skb_mac_header(skb));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
 | 
			
		||||
 | 
			
		||||
int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
 | 
			
		||||
		       struct xfrm_user_offload *xuo)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue