diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2011-11-18 02:20:04 +0000 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2015-02-20 00:49:23 +0000 |
commit | 19ad5b89ffb3977fa4b95f56cc8d8256655ae09a (patch) | |
tree | ec45082c68a3b5e42b81abafcdaf5a66012beb7f /net/ipv6/ip6_output.c | |
parent | b3410f43d29c524bc4bdbfe36928ab4190099e64 (diff) | |
download | kernel_samsung_smdk4412-19ad5b89ffb3977fa4b95f56cc8d8256655ae09a.zip kernel_samsung_smdk4412-19ad5b89ffb3977fa4b95f56cc8d8256655ae09a.tar.gz kernel_samsung_smdk4412-19ad5b89ffb3977fa4b95f56cc8d8256655ae09a.tar.bz2 |
ipv6: Remove all uses of LL_ALLOCATED_SPACE
commit a7ae1992248e5cf9dc5bd35695ab846d27efe15f upstream.
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>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 46fc6a3..2215d6b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -623,6 +623,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) struct ipv6hdr *tmp_hdr; struct frag_hdr *fh; unsigned int mtu, hlen, left, len; + int hroom, troom; __be32 frag_id = 0; int ptr, offset = 0, err=0; u8 *prevhdr, nexthdr = 0; @@ -789,6 +790,8 @@ slow_path: */ *prevhdr = NEXTHDR_FRAGMENT; + hroom = LL_RESERVED_SPACE(rt->dst.dev); + troom = rt->dst.dev->needed_tailroom; /* * Keep copying data until we run out. @@ -807,7 +810,8 @@ slow_path: * Allocate buffer. */ - if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->dst.dev), GFP_ATOMIC)) == NULL) { + if ((frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) + + hroom + troom, GFP_ATOMIC)) == NULL) { NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); @@ -820,7 +824,7 @@ slow_path: */ ip6_copy_metadata(frag, skb); - skb_reserve(frag, LL_RESERVED_SPACE(rt->dst.dev)); + skb_reserve(frag, hroom); skb_put(frag, len + hlen + sizeof(struct frag_hdr)); skb_reset_network_header(frag); fh = (struct frag_hdr *)(skb_network_header(frag) + hlen); |