diff options
author | Simon Horman <horms@verge.net.au> | 2013-05-28 16:34:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-29 02:49:07 -0400 |
commit | 29a3cad5c6ae9e7fbf1509d01d39c3c3c38f11f9 (patch) | |
tree | fd6436d8a820801843ca257807c8af0f36425291 /net/ipv6/ndisc.c | |
parent | ced14f6804a979d1972415bc23f2f8ddb18595dd (diff) |
ipv6: Correct comparisons and calculations using skb->tail and skb-transport_header
This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that comparisons and calculations are always made using pointers.
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r-- | net/ipv6/ndisc.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index a0962697a257..781dd3c99680 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -693,7 +693,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
693 | const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr; | 693 | const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr; |
694 | const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; | 694 | const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; |
695 | u8 *lladdr = NULL; | 695 | u8 *lladdr = NULL; |
696 | u32 ndoptlen = skb->tail - (skb->transport_header + | 696 | u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) + |
697 | offsetof(struct nd_msg, opt)); | 697 | offsetof(struct nd_msg, opt)); |
698 | struct ndisc_options ndopts; | 698 | struct ndisc_options ndopts; |
699 | struct net_device *dev = skb->dev; | 699 | struct net_device *dev = skb->dev; |
@@ -853,7 +853,7 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
853 | const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr; | 853 | const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr; |
854 | const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; | 854 | const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; |
855 | u8 *lladdr = NULL; | 855 | u8 *lladdr = NULL; |
856 | u32 ndoptlen = skb->tail - (skb->transport_header + | 856 | u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) + |
857 | offsetof(struct nd_msg, opt)); | 857 | offsetof(struct nd_msg, opt)); |
858 | struct ndisc_options ndopts; | 858 | struct ndisc_options ndopts; |
859 | struct net_device *dev = skb->dev; | 859 | struct net_device *dev = skb->dev; |
@@ -1069,7 +1069,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1069 | 1069 | ||
1070 | __u8 * opt = (__u8 *)(ra_msg + 1); | 1070 | __u8 * opt = (__u8 *)(ra_msg + 1); |
1071 | 1071 | ||
1072 | optlen = (skb->tail - skb->transport_header) - sizeof(struct ra_msg); | 1072 | optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) - |
1073 | sizeof(struct ra_msg); | ||
1073 | 1074 | ||
1074 | if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { | 1075 | if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { |
1075 | ND_PRINTK(2, warn, "RA: source address is not link-local\n"); | 1076 | ND_PRINTK(2, warn, "RA: source address is not link-local\n"); |
@@ -1346,7 +1347,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
1346 | u8 *hdr; | 1347 | u8 *hdr; |
1347 | struct ndisc_options ndopts; | 1348 | struct ndisc_options ndopts; |
1348 | struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb); | 1349 | struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb); |
1349 | u32 ndoptlen = skb->tail - (skb->transport_header + | 1350 | u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) + |
1350 | offsetof(struct rd_msg, opt)); | 1351 | offsetof(struct rd_msg, opt)); |
1351 | 1352 | ||
1352 | #ifdef CONFIG_IPV6_NDISC_NODETYPE | 1353 | #ifdef CONFIG_IPV6_NDISC_NODETYPE |