Commit 0bafedc5 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says:

====================
pull request (net): ipsec 2022-09-29

1) Use the inner instead of the outer protocol for GSO on inter
   address family tunnels. This fixes the GSO case for address
   family tunnels. From Sabrina Dubroca.

2) Reset ipcomp_scratches with NULL when freed, otherwise
   it holds obsolete address. From Khalid Masum.

3) Reinject transport-mode packets through workqueue
   instead of a tasklet. The tasklet might take too
   long to finish. From Liu Jian.

Please pull or let me know if there are problems.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f4ce91ce 4f492066
...@@ -110,7 +110,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x, ...@@ -110,7 +110,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
struct sk_buff *skb, struct sk_buff *skb,
netdev_features_t features) netdev_features_t features)
{ {
return skb_eth_gso_segment(skb, features, htons(ETH_P_IP)); __be16 type = x->inner_mode.family == AF_INET6 ? htons(ETH_P_IPV6)
: htons(ETH_P_IP);
return skb_eth_gso_segment(skb, features, type);
} }
static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x, static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
......
...@@ -145,7 +145,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x, ...@@ -145,7 +145,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
struct sk_buff *skb, struct sk_buff *skb,
netdev_features_t features) netdev_features_t features)
{ {
return skb_eth_gso_segment(skb, features, htons(ETH_P_IPV6)); __be16 type = x->inner_mode.family == AF_INET ? htons(ETH_P_IP)
: htons(ETH_P_IPV6);
return skb_eth_gso_segment(skb, features, type);
} }
static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x, static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
#include "xfrm_inout.h" #include "xfrm_inout.h"
struct xfrm_trans_tasklet { struct xfrm_trans_tasklet {
struct tasklet_struct tasklet; struct work_struct work;
spinlock_t queue_lock;
struct sk_buff_head queue; struct sk_buff_head queue;
}; };
...@@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr) ...@@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
} }
EXPORT_SYMBOL(xfrm_input_resume); EXPORT_SYMBOL(xfrm_input_resume);
static void xfrm_trans_reinject(struct tasklet_struct *t) static void xfrm_trans_reinject(struct work_struct *work)
{ {
struct xfrm_trans_tasklet *trans = from_tasklet(trans, t, tasklet); struct xfrm_trans_tasklet *trans = container_of(work, struct xfrm_trans_tasklet, work);
struct sk_buff_head queue; struct sk_buff_head queue;
struct sk_buff *skb; struct sk_buff *skb;
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
spin_lock_bh(&trans->queue_lock);
skb_queue_splice_init(&trans->queue, &queue); skb_queue_splice_init(&trans->queue, &queue);
spin_unlock_bh(&trans->queue_lock);
local_bh_disable();
while ((skb = __skb_dequeue(&queue))) while ((skb = __skb_dequeue(&queue)))
XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net, XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
NULL, skb); NULL, skb);
local_bh_enable();
} }
int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb, int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
...@@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb, ...@@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
XFRM_TRANS_SKB_CB(skb)->finish = finish; XFRM_TRANS_SKB_CB(skb)->finish = finish;
XFRM_TRANS_SKB_CB(skb)->net = net; XFRM_TRANS_SKB_CB(skb)->net = net;
spin_lock_bh(&trans->queue_lock);
__skb_queue_tail(&trans->queue, skb); __skb_queue_tail(&trans->queue, skb);
tasklet_schedule(&trans->tasklet); spin_unlock_bh(&trans->queue_lock);
schedule_work(&trans->work);
return 0; return 0;
} }
EXPORT_SYMBOL(xfrm_trans_queue_net); EXPORT_SYMBOL(xfrm_trans_queue_net);
...@@ -817,7 +824,8 @@ void __init xfrm_input_init(void) ...@@ -817,7 +824,8 @@ void __init xfrm_input_init(void)
struct xfrm_trans_tasklet *trans; struct xfrm_trans_tasklet *trans;
trans = &per_cpu(xfrm_trans_tasklet, i); trans = &per_cpu(xfrm_trans_tasklet, i);
spin_lock_init(&trans->queue_lock);
__skb_queue_head_init(&trans->queue); __skb_queue_head_init(&trans->queue);
tasklet_setup(&trans->tasklet, xfrm_trans_reinject); INIT_WORK(&trans->work, xfrm_trans_reinject);
} }
} }
...@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void) ...@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void)
vfree(*per_cpu_ptr(scratches, i)); vfree(*per_cpu_ptr(scratches, i));
free_percpu(scratches); free_percpu(scratches);
ipcomp_scratches = NULL;
} }
static void * __percpu *ipcomp_alloc_scratches(void) static void * __percpu *ipcomp_alloc_scratches(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment