aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2011-11-17 21:20:04 -0500
committerDavid S. Miller <davem@davemloft.net>2011-11-18 14:37:09 -0500
commita7ae1992248e5cf9dc5bd35695ab846d27efe15f (patch)
treeed3f450a41ca5975aecae2850105ca22f98ca318
parent660882432909dbe611f1792eda158188065cb9f1 (diff)
ipv6: Remove all uses of LL_ALLOCATED_SPACE
ipv6: Remove all uses of LL_ALLOCATED_SPACE The macro LL_ALLOCATED_SPACE was ill-conceived. It applies the alignment to the sum of needed_headroom and needed_tailroom. As the amount that is then reserved for head room is needed_headroom with alignment, this means that the tail room left may be too small. This patch replaces all uses of LL_ALLOCATED_SPACE in net/ipv6 with the macro LL_RESERVED_SPACE and direct reference to needed_tailroom. This also fixes the problem with needed_headroom changing between allocating the skb and reserving the head room. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/ip6_output.c8
-rw-r--r--net/ipv6/mcast.c12
-rw-r--r--net/ipv6/ndisc.c13
-rw-r--r--net/ipv6/raw.c6
4 files changed, 27 insertions, 12 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 84d0bd5cac93..68ef97f353b6 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -631,6 +631,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
631 struct ipv6hdr *tmp_hdr; 631 struct ipv6hdr *tmp_hdr;
632 struct frag_hdr *fh; 632 struct frag_hdr *fh;
633 unsigned int mtu, hlen, left, len; 633 unsigned int mtu, hlen, left, len;
634 int hroom, troom;
634 __be32 frag_id = 0; 635 __be32 frag_id = 0;
635 int ptr, offset = 0, err=0; 636 int ptr, offset = 0, err=0;
636 u8 *prevhdr, nexthdr = 0; 637 u8 *prevhdr, nexthdr = 0;
@@ -797,6 +798,8 @@ slow_path:
797 */ 798 */
798 799
799 *prevhdr = NEXTHDR_FRAGMENT; 800 *prevhdr = NEXTHDR_FRAGMENT;
801 hroom = LL_RESERVED_SPACE(rt->dst.dev);
802 troom = rt->dst.dev->needed_tailroom;
800 803
801 /* 804 /*
802 * Keep copying data until we run out. 805 * Keep copying data until we run out.
@@ -815,7 +818,8 @@ slow_path:
815 * Allocate buffer. 818 * Allocate buffer.
816 */ 819 */
817 820
818 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->dst.dev), GFP_ATOMIC)) == NULL) { 821 if ((frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) +
822 hroom + troom, GFP_ATOMIC)) == NULL) {
819 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); 823 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
820 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), 824 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
821 IPSTATS_MIB_FRAGFAILS); 825 IPSTATS_MIB_FRAGFAILS);
@@ -828,7 +832,7 @@ slow_path:
828 */ 832 */
829 833
830 ip6_copy_metadata(frag, skb); 834 ip6_copy_metadata(frag, skb);
831 skb_reserve(frag, LL_RESERVED_SPACE(rt->dst.dev)); 835 skb_reserve(frag, hroom);
832 skb_put(frag, len + hlen + sizeof(struct frag_hdr)); 836 skb_put(frag, len + hlen + sizeof(struct frag_hdr));
833 skb_reset_network_header(frag); 837 skb_reset_network_header(frag);
834 fh = (struct frag_hdr *)(skb_network_header(frag) + hlen); 838 fh = (struct frag_hdr *)(skb_network_header(frag) + hlen);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index ee7839f4d6e3..7b94bebb73b1 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1343,13 +1343,15 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1343 struct mld2_report *pmr; 1343 struct mld2_report *pmr;
1344 struct in6_addr addr_buf; 1344 struct in6_addr addr_buf;
1345 const struct in6_addr *saddr; 1345 const struct in6_addr *saddr;
1346 int hlen = LL_RESERVED_SPACE(dev);
1347 int tlen = dev->needed_tailroom;
1346 int err; 1348 int err;
1347 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1349 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1348 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1350 IPV6_TLV_ROUTERALERT, 2, 0, 0,
1349 IPV6_TLV_PADN, 0 }; 1351 IPV6_TLV_PADN, 0 };
1350 1352
1351 /* we assume size > sizeof(ra) here */ 1353 /* we assume size > sizeof(ra) here */
1352 size += LL_ALLOCATED_SPACE(dev); 1354 size += hlen + tlen;
1353 /* limit our allocations to order-0 page */ 1355 /* limit our allocations to order-0 page */
1354 size = min_t(int, size, SKB_MAX_ORDER(0, 0)); 1356 size = min_t(int, size, SKB_MAX_ORDER(0, 0));
1355 skb = sock_alloc_send_skb(sk, size, 1, &err); 1357 skb = sock_alloc_send_skb(sk, size, 1, &err);
@@ -1357,7 +1359,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1357 if (!skb) 1359 if (!skb)
1358 return NULL; 1360 return NULL;
1359 1361
1360 skb_reserve(skb, LL_RESERVED_SPACE(dev)); 1362 skb_reserve(skb, hlen);
1361 1363
1362 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { 1364 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
1363 /* <draft-ietf-magma-mld-source-05.txt>: 1365 /* <draft-ietf-magma-mld-source-05.txt>:
@@ -1723,6 +1725,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1723 struct mld_msg *hdr; 1725 struct mld_msg *hdr;
1724 const struct in6_addr *snd_addr, *saddr; 1726 const struct in6_addr *snd_addr, *saddr;
1725 struct in6_addr addr_buf; 1727 struct in6_addr addr_buf;
1728 int hlen = LL_RESERVED_SPACE(dev);
1729 int tlen = dev->needed_tailroom;
1726 int err, len, payload_len, full_len; 1730 int err, len, payload_len, full_len;
1727 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1731 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1728 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1732 IPV6_TLV_ROUTERALERT, 2, 0, 0,
@@ -1744,7 +1748,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1744 IPSTATS_MIB_OUT, full_len); 1748 IPSTATS_MIB_OUT, full_len);
1745 rcu_read_unlock(); 1749 rcu_read_unlock();
1746 1750
1747 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); 1751 skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
1748 1752
1749 if (skb == NULL) { 1753 if (skb == NULL) {
1750 rcu_read_lock(); 1754 rcu_read_lock();
@@ -1754,7 +1758,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1754 return; 1758 return;
1755 } 1759 }
1756 1760
1757 skb_reserve(skb, LL_RESERVED_SPACE(dev)); 1761 skb_reserve(skb, hlen);
1758 1762
1759 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { 1763 if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
1760 /* <draft-ietf-magma-mld-source-05.txt>: 1764 /* <draft-ietf-magma-mld-source-05.txt>:
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 4a2098222625..d699ddcad4ce 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -446,6 +446,8 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
446 struct sock *sk = net->ipv6.ndisc_sk; 446 struct sock *sk = net->ipv6.ndisc_sk;
447 struct sk_buff *skb; 447 struct sk_buff *skb;
448 struct icmp6hdr *hdr; 448 struct icmp6hdr *hdr;
449 int hlen = LL_RESERVED_SPACE(dev);
450 int tlen = dev->needed_tailroom;
449 int len; 451 int len;
450 int err; 452 int err;
451 u8 *opt; 453 u8 *opt;
@@ -459,7 +461,7 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
459 461
460 skb = sock_alloc_send_skb(sk, 462 skb = sock_alloc_send_skb(sk,
461 (MAX_HEADER + sizeof(struct ipv6hdr) + 463 (MAX_HEADER + sizeof(struct ipv6hdr) +
462 len + LL_ALLOCATED_SPACE(dev)), 464 len + hlen + tlen),
463 1, &err); 465 1, &err);
464 if (!skb) { 466 if (!skb) {
465 ND_PRINTK0(KERN_ERR 467 ND_PRINTK0(KERN_ERR
@@ -468,7 +470,7 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
468 return NULL; 470 return NULL;
469 } 471 }
470 472
471 skb_reserve(skb, LL_RESERVED_SPACE(dev)); 473 skb_reserve(skb, hlen);
472 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len); 474 ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
473 475
474 skb->transport_header = skb->tail; 476 skb->transport_header = skb->tail;
@@ -1533,6 +1535,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1533 struct inet6_dev *idev; 1535 struct inet6_dev *idev;
1534 struct flowi6 fl6; 1536 struct flowi6 fl6;
1535 u8 *opt; 1537 u8 *opt;
1538 int hlen, tlen;
1536 int rd_len; 1539 int rd_len;
1537 int err; 1540 int err;
1538 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; 1541 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
@@ -1590,9 +1593,11 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1590 rd_len &= ~0x7; 1593 rd_len &= ~0x7;
1591 len += rd_len; 1594 len += rd_len;
1592 1595
1596 hlen = LL_RESERVED_SPACE(dev);
1597 tlen = dev->needed_tailroom;
1593 buff = sock_alloc_send_skb(sk, 1598 buff = sock_alloc_send_skb(sk,
1594 (MAX_HEADER + sizeof(struct ipv6hdr) + 1599 (MAX_HEADER + sizeof(struct ipv6hdr) +
1595 len + LL_ALLOCATED_SPACE(dev)), 1600 len + hlen + tlen),
1596 1, &err); 1601 1, &err);
1597 if (buff == NULL) { 1602 if (buff == NULL) {
1598 ND_PRINTK0(KERN_ERR 1603 ND_PRINTK0(KERN_ERR
@@ -1601,7 +1606,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1601 goto release; 1606 goto release;
1602 } 1607 }
1603 1608
1604 skb_reserve(buff, LL_RESERVED_SPACE(dev)); 1609 skb_reserve(buff, hlen);
1605 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr, 1610 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
1606 IPPROTO_ICMPV6, len); 1611 IPPROTO_ICMPV6, len);
1607 1612
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 204f2e833f04..a1aa869a9ce7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -611,6 +611,8 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
611 struct sk_buff *skb; 611 struct sk_buff *skb;
612 int err; 612 int err;
613 struct rt6_info *rt = (struct rt6_info *)*dstp; 613 struct rt6_info *rt = (struct rt6_info *)*dstp;
614 int hlen = LL_RESERVED_SPACE(rt->dst.dev);
615 int tlen = rt->dst.dev->needed_tailroom;
614 616
615 if (length > rt->dst.dev->mtu) { 617 if (length > rt->dst.dev->mtu) {
616 ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); 618 ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
@@ -620,11 +622,11 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
620 goto out; 622 goto out;
621 623
622 skb = sock_alloc_send_skb(sk, 624 skb = sock_alloc_send_skb(sk,
623 length + LL_ALLOCATED_SPACE(rt->dst.dev) + 15, 625 length + hlen + tlen + 15,
624 flags & MSG_DONTWAIT, &err); 626 flags & MSG_DONTWAIT, &err);
625 if (skb == NULL) 627 if (skb == NULL)
626 goto error; 628 goto error;
627 skb_reserve(skb, LL_RESERVED_SPACE(rt->dst.dev)); 629 skb_reserve(skb, hlen);
628 630
629 skb->priority = sk->sk_priority; 631 skb->priority = sk->sk_priority;
630 skb->mark = sk->sk_mark; 632 skb->mark = sk->sk_mark;