diff options
author | YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> | 2013-01-21 01:48:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-21 13:33:15 -0500 |
commit | de09334b9326632bbf1a74bfd8b01866cbbf2f61 (patch) | |
tree | fcdf6af7a7d1f529d41dbdd1d785c7f1337b1553 /net/ipv6/ndisc.c | |
parent | 9c86dafe94f03679b77d85915e65da1304005a7c (diff) |
ndisc: Introduce ndisc_alloc_skb() helper.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r-- | net/ipv6/ndisc.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 53a545f32625..1776a0deee7f 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -366,6 +366,29 @@ static void pndisc_destructor(struct pneigh_entry *n) | |||
366 | ipv6_dev_mc_dec(dev, &maddr); | 366 | ipv6_dev_mc_dec(dev, &maddr); |
367 | } | 367 | } |
368 | 368 | ||
369 | static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, | ||
370 | int len) | ||
371 | { | ||
372 | int hlen = LL_RESERVED_SPACE(dev); | ||
373 | int tlen = dev->needed_tailroom; | ||
374 | struct sock *sk = dev_net(dev)->ipv6.ndisc_sk; | ||
375 | struct sk_buff *skb; | ||
376 | int err; | ||
377 | |||
378 | skb = sock_alloc_send_skb(sk, | ||
379 | hlen + sizeof(struct ipv6hdr) + len + tlen, | ||
380 | 1, &err); | ||
381 | if (!skb) { | ||
382 | ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb, err=%d\n", | ||
383 | __func__, err); | ||
384 | return NULL; | ||
385 | } | ||
386 | |||
387 | skb_reserve(skb, hlen); | ||
388 | |||
389 | return skb; | ||
390 | } | ||
391 | |||
369 | static struct sk_buff *ndisc_build_skb(struct net_device *dev, | 392 | static struct sk_buff *ndisc_build_skb(struct net_device *dev, |
370 | const struct in6_addr *daddr, | 393 | const struct in6_addr *daddr, |
371 | const struct in6_addr *saddr, | 394 | const struct in6_addr *saddr, |
@@ -377,10 +400,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
377 | struct sock *sk = net->ipv6.ndisc_sk; | 400 | struct sock *sk = net->ipv6.ndisc_sk; |
378 | struct sk_buff *skb; | 401 | struct sk_buff *skb; |
379 | struct icmp6hdr *hdr; | 402 | struct icmp6hdr *hdr; |
380 | int hlen = LL_RESERVED_SPACE(dev); | ||
381 | int tlen = dev->needed_tailroom; | ||
382 | int len; | 403 | int len; |
383 | int err; | ||
384 | u8 *opt; | 404 | u8 *opt; |
385 | 405 | ||
386 | if (!dev->addr_len) | 406 | if (!dev->addr_len) |
@@ -390,17 +410,10 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
390 | if (llinfo) | 410 | if (llinfo) |
391 | len += ndisc_opt_addr_space(dev); | 411 | len += ndisc_opt_addr_space(dev); |
392 | 412 | ||
393 | skb = sock_alloc_send_skb(sk, | 413 | skb = ndisc_alloc_skb(dev, len); |
394 | (sizeof(struct ipv6hdr) + | 414 | if (!skb) |
395 | len + hlen + tlen), | ||
396 | 1, &err); | ||
397 | if (!skb) { | ||
398 | ND_PRINTK(0, err, "ND: %s failed to allocate an skb, err=%d\n", | ||
399 | __func__, err); | ||
400 | return NULL; | 415 | return NULL; |
401 | } | ||
402 | 416 | ||
403 | skb_reserve(skb, hlen); | ||
404 | ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len); | 417 | ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len); |
405 | 418 | ||
406 | skb->transport_header = skb->tail; | 419 | skb->transport_header = skb->tail; |
@@ -1369,7 +1382,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | |||
1369 | struct inet6_dev *idev; | 1382 | struct inet6_dev *idev; |
1370 | struct flowi6 fl6; | 1383 | struct flowi6 fl6; |
1371 | u8 *opt; | 1384 | u8 *opt; |
1372 | int hlen, tlen; | ||
1373 | int rd_len; | 1385 | int rd_len; |
1374 | int err; | 1386 | int err; |
1375 | u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; | 1387 | u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; |
@@ -1439,20 +1451,10 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | |||
1439 | rd_len &= ~0x7; | 1451 | rd_len &= ~0x7; |
1440 | len += rd_len; | 1452 | len += rd_len; |
1441 | 1453 | ||
1442 | hlen = LL_RESERVED_SPACE(dev); | 1454 | buff = ndisc_alloc_skb(dev, len); |
1443 | tlen = dev->needed_tailroom; | 1455 | if (!buff) |
1444 | buff = sock_alloc_send_skb(sk, | ||
1445 | (sizeof(struct ipv6hdr) + | ||
1446 | len + hlen + tlen), | ||
1447 | 1, &err); | ||
1448 | if (buff == NULL) { | ||
1449 | ND_PRINTK(0, err, | ||
1450 | "Redirect: %s failed to allocate an skb, err=%d\n", | ||
1451 | __func__, err); | ||
1452 | goto release; | 1456 | goto release; |
1453 | } | ||
1454 | 1457 | ||
1455 | skb_reserve(buff, hlen); | ||
1456 | ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr, | 1458 | ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr, |
1457 | IPPROTO_ICMPV6, len); | 1459 | IPPROTO_ICMPV6, len); |
1458 | 1460 | ||