diff options
author | Alexander Aring <aar@pengutronix.de> | 2016-03-16 08:52:41 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2016-04-08 13:28:13 -0400 |
commit | feb2add3235ca81dc5cd5d975490c707a24c9889 (patch) | |
tree | 403717eb115afc4ce01d1d6c0889ce3b2d683871 /net/6lowpan | |
parent | 13407376b255325fa817798800117a839f3aa055 (diff) |
6lowpan: iphc: fix handling of link-local compression
This patch fixes handling in case of link-local address compression. A
IPv6 link-local address is defined as fe80::/10 prefix which is also
what ipv6_addr_type checks for link-local addresses.
But IPHC compression for link-local addresses are for fe80::/64 types
only. This patch adds additional checks for zero padded bits in case of
link-local address compression to match on a fe80::/64 address only.
Signed-off-by: Alexander Aring <aar@pengutronix.de>
Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Reviewed-by: Stefan Schmidt <stefan@osg.samsung.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/6lowpan')
-rw-r--r-- | net/6lowpan/iphc.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index 99bb22aea346..68c80f3c9add 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c | |||
@@ -148,6 +148,11 @@ | |||
148 | (((a)->s6_addr16[6]) == 0) && \ | 148 | (((a)->s6_addr16[6]) == 0) && \ |
149 | (((a)->s6_addr[14]) == 0)) | 149 | (((a)->s6_addr[14]) == 0)) |
150 | 150 | ||
151 | #define lowpan_is_linklocal_zero_padded(a) \ | ||
152 | (!(hdr->saddr.s6_addr[1] & 0x3f) && \ | ||
153 | !hdr->saddr.s6_addr16[1] && \ | ||
154 | !hdr->saddr.s6_addr32[1]) | ||
155 | |||
151 | #define LOWPAN_IPHC_CID_DCI(cid) (cid & 0x0f) | 156 | #define LOWPAN_IPHC_CID_DCI(cid) (cid & 0x0f) |
152 | #define LOWPAN_IPHC_CID_SCI(cid) ((cid & 0xf0) >> 4) | 157 | #define LOWPAN_IPHC_CID_SCI(cid) ((cid & 0xf0) >> 4) |
153 | 158 | ||
@@ -1101,7 +1106,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev, | |||
1101 | true); | 1106 | true); |
1102 | iphc1 |= LOWPAN_IPHC_SAC; | 1107 | iphc1 |= LOWPAN_IPHC_SAC; |
1103 | } else { | 1108 | } else { |
1104 | if (ipv6_saddr_type & IPV6_ADDR_LINKLOCAL) { | 1109 | if (ipv6_saddr_type & IPV6_ADDR_LINKLOCAL && |
1110 | lowpan_is_linklocal_zero_padded(hdr->saddr)) { | ||
1105 | iphc1 |= lowpan_compress_addr_64(&hc_ptr, | 1111 | iphc1 |= lowpan_compress_addr_64(&hc_ptr, |
1106 | &hdr->saddr, | 1112 | &hdr->saddr, |
1107 | saddr, true); | 1113 | saddr, true); |
@@ -1135,7 +1141,8 @@ int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev, | |||
1135 | false); | 1141 | false); |
1136 | iphc1 |= LOWPAN_IPHC_DAC; | 1142 | iphc1 |= LOWPAN_IPHC_DAC; |
1137 | } else { | 1143 | } else { |
1138 | if (ipv6_daddr_type & IPV6_ADDR_LINKLOCAL) { | 1144 | if (ipv6_daddr_type & IPV6_ADDR_LINKLOCAL && |
1145 | lowpan_is_linklocal_zero_padded(hdr->daddr)) { | ||
1139 | iphc1 |= lowpan_compress_addr_64(&hc_ptr, | 1146 | iphc1 |= lowpan_compress_addr_64(&hc_ptr, |
1140 | &hdr->daddr, | 1147 | &hdr->daddr, |
1141 | daddr, false); | 1148 | daddr, false); |