aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_user.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 52b5843937c5..dab112f1dd8a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1008,17 +1008,24 @@ static int xfrm_user_rcv_skb(struct sk_buff *skb)
1008 1008
1009static void xfrm_netlink_rcv(struct sock *sk, int len) 1009static void xfrm_netlink_rcv(struct sock *sk, int len)
1010{ 1010{
1011 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
1012
1011 do { 1013 do {
1012 struct sk_buff *skb; 1014 struct sk_buff *skb;
1013 1015
1014 down(&xfrm_cfg_sem); 1016 down(&xfrm_cfg_sem);
1015 1017
1016 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 1018 if (qlen > skb_queue_len(&sk->sk_receive_queue))
1019 qlen = skb_queue_len(&sk->sk_receive_queue);
1020
1021 while (qlen--) {
1022 skb = skb_dequeue(&sk->sk_receive_queue);
1017 if (xfrm_user_rcv_skb(skb)) { 1023 if (xfrm_user_rcv_skb(skb)) {
1018 if (skb->len) 1024 if (skb->len) {
1019 skb_queue_head(&sk->sk_receive_queue, 1025 skb_queue_head(&sk->sk_receive_queue,
1020 skb); 1026 skb);
1021 else 1027 qlen++;
1028 } else
1022 kfree_skb(skb); 1029 kfree_skb(skb);
1023 break; 1030 break;
1024 } 1031 }
@@ -1027,7 +1034,7 @@ static void xfrm_netlink_rcv(struct sock *sk, int len)
1027 1034
1028 up(&xfrm_cfg_sem); 1035 up(&xfrm_cfg_sem);
1029 1036
1030 } while (xfrm_nl && xfrm_nl->sk_receive_queue.qlen); 1037 } while (qlen);
1031} 1038}
1032 1039
1033static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) 1040static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard)