Commit 62e69776 authored by Alexander Aring's avatar Alexander Aring Committed by David S. Miller

ipv6: rpl: fix full address compression

This patch makes it impossible that cmpri or cmpre values are set to the
value 16 which is not possible, because these are 4 bit values. We
currently run in an overflow when assigning the value 16 to it.

According to the standard a value of 16 can be interpreted as a full
elided address which isn't possible to set as compression value. A reason
why this cannot be set is that the current ipv6 header destination address
should never show up inside the segments of the rpl header. In this case we
run in a overflow and the address will have no compression at all. Means
cmpri or compre is set to 0.

As we handle cmpri and cmpre sometimes as unsigned char or 4 bit value
inside the rpl header the current behaviour ends in an invalid header
format. This patch simple use the best compression method if we ever run
into the case that the destination address is showed up inside the rpl
segments. We avoid the overflow handling and the rpl header is still valid,
even when we have the destination address inside the rpl segments.
Signed-off-by: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 91a2559c
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <net/rpl.h> #include <net/rpl.h>
#define IPV6_PFXTAIL_LEN(x) (sizeof(struct in6_addr) - (x)) #define IPV6_PFXTAIL_LEN(x) (sizeof(struct in6_addr) - (x))
#define IPV6_RPL_BEST_ADDR_COMPRESSION 15
static void ipv6_rpl_addr_decompress(struct in6_addr *dst, static void ipv6_rpl_addr_decompress(struct in6_addr *dst,
const struct in6_addr *daddr, const struct in6_addr *daddr,
...@@ -73,7 +74,7 @@ static unsigned char ipv6_rpl_srh_calc_cmpri(const struct ipv6_rpl_sr_hdr *inhdr ...@@ -73,7 +74,7 @@ static unsigned char ipv6_rpl_srh_calc_cmpri(const struct ipv6_rpl_sr_hdr *inhdr
} }
} }
return plen; return IPV6_RPL_BEST_ADDR_COMPRESSION;
} }
static unsigned char ipv6_rpl_srh_calc_cmpre(const struct in6_addr *daddr, static unsigned char ipv6_rpl_srh_calc_cmpre(const struct in6_addr *daddr,
...@@ -83,10 +84,10 @@ static unsigned char ipv6_rpl_srh_calc_cmpre(const struct in6_addr *daddr, ...@@ -83,10 +84,10 @@ static unsigned char ipv6_rpl_srh_calc_cmpre(const struct in6_addr *daddr,
for (plen = 0; plen < sizeof(*daddr); plen++) { for (plen = 0; plen < sizeof(*daddr); plen++) {
if (daddr->s6_addr[plen] != last_segment->s6_addr[plen]) if (daddr->s6_addr[plen] != last_segment->s6_addr[plen])
break; return plen;
} }
return plen; return IPV6_RPL_BEST_ADDR_COMPRESSION;
} }
void ipv6_rpl_srh_compress(struct ipv6_rpl_sr_hdr *outhdr, void ipv6_rpl_srh_compress(struct ipv6_rpl_sr_hdr *outhdr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment