aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
authorHideo Aoki <haoki@redhat.com>2007-12-31 03:29:24 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:00:19 -0500
commit95766fff6b9a78d11fc2d3812dd035381690b55d (patch)
treec1ec9386a3d9a76a9f74bd230d3e7d4ee8059c51 /net/ipv6/udp.c
parent3ab224be6d69de912ee21302745ea45a99274dbc (diff)
[UDP]: Add memory accounting.
Signed-off-by: Takahiro Yasui <tyasui@redhat.com> Signed-off-by: Hideo Aoki <haoki@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index c9a97b405511..bf58acab2064 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -204,13 +204,17 @@ try_again:
204 err = ulen; 204 err = ulen;
205 205
206out_free: 206out_free:
207 lock_sock(sk);
207 skb_free_datagram(sk, skb); 208 skb_free_datagram(sk, skb);
209 release_sock(sk);
208out: 210out:
209 return err; 211 return err;
210 212
211csum_copy_err: 213csum_copy_err:
214 lock_sock(sk);
212 if (!skb_kill_datagram(sk, skb, flags)) 215 if (!skb_kill_datagram(sk, skb, flags))
213 UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); 216 UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
217 release_sock(sk);
214 218
215 if (flags & MSG_DONTWAIT) 219 if (flags & MSG_DONTWAIT)
216 return -EAGAIN; 220 return -EAGAIN;
@@ -366,10 +370,21 @@ static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
366 while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr, 370 while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr,
367 uh->source, saddr, dif))) { 371 uh->source, saddr, dif))) {
368 struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); 372 struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
369 if (buff) 373 if (buff) {
370 udpv6_queue_rcv_skb(sk2, buff); 374 bh_lock_sock_nested(sk2);
375 if (!sock_owned_by_user(sk2))
376 udpv6_queue_rcv_skb(sk2, buff);
377 else
378 sk_add_backlog(sk2, buff);
379 bh_unlock_sock(sk2);
380 }
371 } 381 }
372 udpv6_queue_rcv_skb(sk, skb); 382 bh_lock_sock_nested(sk);
383 if (!sock_owned_by_user(sk))
384 udpv6_queue_rcv_skb(sk, skb);
385 else
386 sk_add_backlog(sk, skb);
387 bh_unlock_sock(sk);
373out: 388out:
374 read_unlock(&udp_hash_lock); 389 read_unlock(&udp_hash_lock);
375 return 0; 390 return 0;
@@ -482,7 +497,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
482 497
483 /* deliver */ 498 /* deliver */
484 499
485 udpv6_queue_rcv_skb(sk, skb); 500 bh_lock_sock_nested(sk);
501 if (!sock_owned_by_user(sk))
502 udpv6_queue_rcv_skb(sk, skb);
503 else
504 sk_add_backlog(sk, skb);
505 bh_unlock_sock(sk);
486 sock_put(sk); 506 sock_put(sk);
487 return 0; 507 return 0;
488 508
@@ -994,6 +1014,10 @@ struct proto udpv6_prot = {
994 .hash = udp_lib_hash, 1014 .hash = udp_lib_hash,
995 .unhash = udp_lib_unhash, 1015 .unhash = udp_lib_unhash,
996 .get_port = udp_v6_get_port, 1016 .get_port = udp_v6_get_port,
1017 .memory_allocated = &udp_memory_allocated,
1018 .sysctl_mem = sysctl_udp_mem,
1019 .sysctl_wmem = &sysctl_udp_wmem_min,
1020 .sysctl_rmem = &sysctl_udp_rmem_min,
997 .obj_size = sizeof(struct udp6_sock), 1021 .obj_size = sizeof(struct udp6_sock),
998#ifdef CONFIG_COMPAT 1022#ifdef CONFIG_COMPAT
999 .compat_setsockopt = compat_udpv6_setsockopt, 1023 .compat_setsockopt = compat_udpv6_setsockopt,