aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2013-08-27 19:07:25 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-29 16:01:05 -0400
commit1f324e38870cc09659cf23bc626f1b8869e201f2 (patch)
tree703e667d870347854baf534e7186771b0ad74353
parentc27c9322d015dc1d9dfdf31724fca71c0476c4d1 (diff)
ipv6: Don't depend on per socket memory for neighbour discovery messages
Allocating skbs when sending out neighbour discovery messages currently uses sock_alloc_send_skb() based on a per net namespace socket and thus share a socket wmem buffer space. If a netdevice is temporarily unable to transmit due to carrier loss or for other reasons, the queued up ndisc messages will cosnume all of the wmem space and will thus prevent from any more skbs to be allocated even for netdevices that are able to transmit packets. The number of neighbour discovery messages sent is very limited, simply use alloc_skb() and don't depend on any socket wmem space any longer. This patch has orginally been posted by Eric Dumazet in a modified form. Signed-off-by: Thomas Graf <tgraf@suug.ch> Cc: Eric Dumazet <eric.dumazet@gmail.com> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/ndisc.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 04d31c2fbef1..5cb98df966c2 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -370,16 +370,12 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
370{ 370{
371 int hlen = LL_RESERVED_SPACE(dev); 371 int hlen = LL_RESERVED_SPACE(dev);
372 int tlen = dev->needed_tailroom; 372 int tlen = dev->needed_tailroom;
373 struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
374 struct sk_buff *skb; 373 struct sk_buff *skb;
375 int err;
376 374
377 skb = sock_alloc_send_skb(sk, 375 skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
378 hlen + sizeof(struct ipv6hdr) + len + tlen,
379 1, &err);
380 if (!skb) { 376 if (!skb) {
381 ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb, err=%d\n", 377 ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
382 __func__, err); 378 __func__);
383 return NULL; 379 return NULL;
384 } 380 }
385 381