Merge "af_key: unconditionally clone on broadcast"
This commit is contained in:
commit
1ba0161c4d
1 changed files with 15 additions and 25 deletions
|
@ -196,30 +196,22 @@ static int pfkey_release(struct socket *sock)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
|
||||
gfp_t allocation, struct sock *sk)
|
||||
static int pfkey_broadcast_one(struct sk_buff *skb, gfp_t allocation,
|
||||
struct sock *sk)
|
||||
{
|
||||
int err = -ENOBUFS;
|
||||
|
||||
sock_hold(sk);
|
||||
if (*skb2 == NULL) {
|
||||
if (atomic_read(&skb->users) != 1) {
|
||||
*skb2 = skb_clone(skb, allocation);
|
||||
} else {
|
||||
*skb2 = skb;
|
||||
atomic_inc(&skb->users);
|
||||
}
|
||||
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
|
||||
return err;
|
||||
|
||||
skb = skb_clone(skb, allocation);
|
||||
|
||||
if (skb) {
|
||||
skb_set_owner_r(skb, sk);
|
||||
skb_queue_tail(&sk->sk_receive_queue, skb);
|
||||
sk->sk_data_ready(sk);
|
||||
err = 0;
|
||||
}
|
||||
if (*skb2 != NULL) {
|
||||
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) {
|
||||
skb_set_owner_r(*skb2, sk);
|
||||
skb_queue_tail(&sk->sk_receive_queue, *skb2);
|
||||
sk->sk_data_ready(sk);
|
||||
*skb2 = NULL;
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
sock_put(sk);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -234,7 +226,6 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
|
|||
{
|
||||
struct netns_pfkey *net_pfkey = net_generic(net, pfkey_net_id);
|
||||
struct sock *sk;
|
||||
struct sk_buff *skb2 = NULL;
|
||||
int err = -ESRCH;
|
||||
|
||||
/* XXX Do we need something like netlink_overrun? I think
|
||||
|
@ -253,7 +244,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
|
|||
* socket.
|
||||
*/
|
||||
if (pfk->promisc)
|
||||
pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk);
|
||||
pfkey_broadcast_one(skb, GFP_ATOMIC, sk);
|
||||
|
||||
/* the exact target will be processed later */
|
||||
if (sk == one_sk)
|
||||
|
@ -268,7 +259,7 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
|
|||
continue;
|
||||
}
|
||||
|
||||
err2 = pfkey_broadcast_one(skb, &skb2, GFP_ATOMIC, sk);
|
||||
err2 = pfkey_broadcast_one(skb, GFP_ATOMIC, sk);
|
||||
|
||||
/* Error is cleared after successful sending to at least one
|
||||
* registered KM */
|
||||
|
@ -278,9 +269,8 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
|
|||
rcu_read_unlock();
|
||||
|
||||
if (one_sk != NULL)
|
||||
err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk);
|
||||
err = pfkey_broadcast_one(skb, allocation, one_sk);
|
||||
|
||||
kfree_skb(skb2);
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue