diff options
-rw-r--r-- | net/netlink/af_netlink.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 26779c24b1d4..58b9025978fa 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -119,6 +119,20 @@ static void netlink_consume_callback(struct netlink_callback *cb) | |||
119 | kfree(cb); | 119 | kfree(cb); |
120 | } | 120 | } |
121 | 121 | ||
122 | static void netlink_skb_destructor(struct sk_buff *skb) | ||
123 | { | ||
124 | sock_rfree(skb); | ||
125 | } | ||
126 | |||
127 | static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk) | ||
128 | { | ||
129 | WARN_ON(skb->sk != NULL); | ||
130 | skb->sk = sk; | ||
131 | skb->destructor = netlink_skb_destructor; | ||
132 | atomic_add(skb->truesize, &sk->sk_rmem_alloc); | ||
133 | sk_mem_charge(sk, skb->truesize); | ||
134 | } | ||
135 | |||
122 | static void netlink_sock_destruct(struct sock *sk) | 136 | static void netlink_sock_destruct(struct sock *sk) |
123 | { | 137 | { |
124 | struct netlink_sock *nlk = nlk_sk(sk); | 138 | struct netlink_sock *nlk = nlk_sk(sk); |
@@ -820,7 +834,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, | |||
820 | } | 834 | } |
821 | return 1; | 835 | return 1; |
822 | } | 836 | } |
823 | skb_set_owner_r(skb, sk); | 837 | netlink_skb_set_owner_r(skb, sk); |
824 | return 0; | 838 | return 0; |
825 | } | 839 | } |
826 | 840 | ||
@@ -890,7 +904,7 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb, | |||
890 | ret = -ECONNREFUSED; | 904 | ret = -ECONNREFUSED; |
891 | if (nlk->netlink_rcv != NULL) { | 905 | if (nlk->netlink_rcv != NULL) { |
892 | ret = skb->len; | 906 | ret = skb->len; |
893 | skb_set_owner_r(skb, sk); | 907 | netlink_skb_set_owner_r(skb, sk); |
894 | NETLINK_CB(skb).sk = ssk; | 908 | NETLINK_CB(skb).sk = ssk; |
895 | nlk->netlink_rcv(skb); | 909 | nlk->netlink_rcv(skb); |
896 | consume_skb(skb); | 910 | consume_skb(skb); |
@@ -962,7 +976,7 @@ static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb) | |||
962 | 976 | ||
963 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && | 977 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && |
964 | !test_bit(NETLINK_CONGESTED, &nlk->state)) { | 978 | !test_bit(NETLINK_CONGESTED, &nlk->state)) { |
965 | skb_set_owner_r(skb, sk); | 979 | netlink_skb_set_owner_r(skb, sk); |
966 | __netlink_sendskb(sk, skb); | 980 | __netlink_sendskb(sk, skb); |
967 | return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1); | 981 | return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1); |
968 | } | 982 | } |