diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2011-11-17 21:20:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-18 14:37:08 -0500 |
commit | 660882432909dbe611f1792eda158188065cb9f1 (patch) | |
tree | 101be8ad6357197cff3dcd6daf573dadab2cdd6b /net/ipv4 | |
parent | 505a467b66233fd08ac32fca943100130928bf89 (diff) |
ipv4: Remove all uses of LL_ALLOCATED_SPACE
ipv4: 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/ipv4
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>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/arp.c | 6 | ||||
-rw-r--r-- | net/ipv4/igmp.c | 13 | ||||
-rw-r--r-- | net/ipv4/ipconfig.c | 6 | ||||
-rw-r--r-- | net/ipv4/raw.c | 7 |
4 files changed, 22 insertions, 10 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index d732827b32b9..5c29ac5b0c3a 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -592,16 +592,18 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, | |||
592 | struct sk_buff *skb; | 592 | struct sk_buff *skb; |
593 | struct arphdr *arp; | 593 | struct arphdr *arp; |
594 | unsigned char *arp_ptr; | 594 | unsigned char *arp_ptr; |
595 | int hlen = LL_RESERVED_SPACE(dev); | ||
596 | int tlen = dev->needed_tailroom; | ||
595 | 597 | ||
596 | /* | 598 | /* |
597 | * Allocate a buffer | 599 | * Allocate a buffer |
598 | */ | 600 | */ |
599 | 601 | ||
600 | skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); | 602 | skb = alloc_skb(arp_hdr_len(dev) + hlen + tlen, GFP_ATOMIC); |
601 | if (skb == NULL) | 603 | if (skb == NULL) |
602 | return NULL; | 604 | return NULL; |
603 | 605 | ||
604 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 606 | skb_reserve(skb, hlen); |
605 | skb_reset_network_header(skb); | 607 | skb_reset_network_header(skb); |
606 | arp = (struct arphdr *) skb_put(skb, arp_hdr_len(dev)); | 608 | arp = (struct arphdr *) skb_put(skb, arp_hdr_len(dev)); |
607 | skb->dev = dev; | 609 | skb->dev = dev; |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index c7472eff2d51..fbc53767bf35 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -304,9 +304,11 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
304 | struct igmpv3_report *pig; | 304 | struct igmpv3_report *pig; |
305 | struct net *net = dev_net(dev); | 305 | struct net *net = dev_net(dev); |
306 | struct flowi4 fl4; | 306 | struct flowi4 fl4; |
307 | int hlen = LL_RESERVED_SPACE(dev); | ||
308 | int tlen = dev->needed_tailroom; | ||
307 | 309 | ||
308 | while (1) { | 310 | while (1) { |
309 | skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), | 311 | skb = alloc_skb(size + hlen + tlen, |
310 | GFP_ATOMIC | __GFP_NOWARN); | 312 | GFP_ATOMIC | __GFP_NOWARN); |
311 | if (skb) | 313 | if (skb) |
312 | break; | 314 | break; |
@@ -327,7 +329,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
327 | skb_dst_set(skb, &rt->dst); | 329 | skb_dst_set(skb, &rt->dst); |
328 | skb->dev = dev; | 330 | skb->dev = dev; |
329 | 331 | ||
330 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 332 | skb_reserve(skb, hlen); |
331 | 333 | ||
332 | skb_reset_network_header(skb); | 334 | skb_reset_network_header(skb); |
333 | pip = ip_hdr(skb); | 335 | pip = ip_hdr(skb); |
@@ -647,6 +649,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
647 | __be32 group = pmc ? pmc->multiaddr : 0; | 649 | __be32 group = pmc ? pmc->multiaddr : 0; |
648 | struct flowi4 fl4; | 650 | struct flowi4 fl4; |
649 | __be32 dst; | 651 | __be32 dst; |
652 | int hlen, tlen; | ||
650 | 653 | ||
651 | if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) | 654 | if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) |
652 | return igmpv3_send_report(in_dev, pmc); | 655 | return igmpv3_send_report(in_dev, pmc); |
@@ -661,7 +664,9 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
661 | if (IS_ERR(rt)) | 664 | if (IS_ERR(rt)) |
662 | return -1; | 665 | return -1; |
663 | 666 | ||
664 | skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); | 667 | hlen = LL_RESERVED_SPACE(dev); |
668 | tlen = dev->needed_tailroom; | ||
669 | skb = alloc_skb(IGMP_SIZE + hlen + tlen, GFP_ATOMIC); | ||
665 | if (skb == NULL) { | 670 | if (skb == NULL) { |
666 | ip_rt_put(rt); | 671 | ip_rt_put(rt); |
667 | return -1; | 672 | return -1; |
@@ -669,7 +674,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
669 | 674 | ||
670 | skb_dst_set(skb, &rt->dst); | 675 | skb_dst_set(skb, &rt->dst); |
671 | 676 | ||
672 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 677 | skb_reserve(skb, hlen); |
673 | 678 | ||
674 | skb_reset_network_header(skb); | 679 | skb_reset_network_header(skb); |
675 | iph = ip_hdr(skb); | 680 | iph = ip_hdr(skb); |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 7f17ba8b0318..915eb5265b2e 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -763,13 +763,15 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d | |||
763 | struct sk_buff *skb; | 763 | struct sk_buff *skb; |
764 | struct bootp_pkt *b; | 764 | struct bootp_pkt *b; |
765 | struct iphdr *h; | 765 | struct iphdr *h; |
766 | int hlen = LL_RESERVED_SPACE(dev); | ||
767 | int tlen = dev->needed_tailroom; | ||
766 | 768 | ||
767 | /* Allocate packet */ | 769 | /* Allocate packet */ |
768 | skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15, | 770 | skb = alloc_skb(sizeof(struct bootp_pkt) + hlen + tlen + 15, |
769 | GFP_KERNEL); | 771 | GFP_KERNEL); |
770 | if (!skb) | 772 | if (!skb) |
771 | return; | 773 | return; |
772 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 774 | skb_reserve(skb, hlen); |
773 | b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt)); | 775 | b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt)); |
774 | memset(b, 0, sizeof(struct bootp_pkt)); | 776 | memset(b, 0, sizeof(struct bootp_pkt)); |
775 | 777 | ||
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 7a8410d1b4b1..3ccda5ae8a27 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -328,6 +328,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, | |||
328 | unsigned int iphlen; | 328 | unsigned int iphlen; |
329 | int err; | 329 | int err; |
330 | struct rtable *rt = *rtp; | 330 | struct rtable *rt = *rtp; |
331 | int hlen, tlen; | ||
331 | 332 | ||
332 | if (length > rt->dst.dev->mtu) { | 333 | if (length > rt->dst.dev->mtu) { |
333 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, | 334 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, |
@@ -337,12 +338,14 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, | |||
337 | if (flags&MSG_PROBE) | 338 | if (flags&MSG_PROBE) |
338 | goto out; | 339 | goto out; |
339 | 340 | ||
341 | hlen = LL_RESERVED_SPACE(rt->dst.dev); | ||
342 | tlen = rt->dst.dev->needed_tailroom; | ||
340 | skb = sock_alloc_send_skb(sk, | 343 | skb = sock_alloc_send_skb(sk, |
341 | length + LL_ALLOCATED_SPACE(rt->dst.dev) + 15, | 344 | length + hlen + tlen + 15, |
342 | flags & MSG_DONTWAIT, &err); | 345 | flags & MSG_DONTWAIT, &err); |
343 | if (skb == NULL) | 346 | if (skb == NULL) |
344 | goto error; | 347 | goto error; |
345 | skb_reserve(skb, LL_RESERVED_SPACE(rt->dst.dev)); | 348 | skb_reserve(skb, hlen); |
346 | 349 | ||
347 | skb->priority = sk->sk_priority; | 350 | skb->priority = sk->sk_priority; |
348 | skb->mark = sk->sk_mark; | 351 | skb->mark = sk->sk_mark; |