aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ndisc.c
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>2013-01-21 01:48:14 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-21 13:33:15 -0500
commitde09334b9326632bbf1a74bfd8b01866cbbf2f61 (patch)
treefcdf6af7a7d1f529d41dbdd1d785c7f1337b1553 /net/ipv6/ndisc.c
parent9c86dafe94f03679b77d85915e65da1304005a7c (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.c52
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
369static 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
369static struct sk_buff *ndisc_build_skb(struct net_device *dev, 392static 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