6lowpan: Use netdev addr_len to determine lladdr len
This allow technologies such as Bluetooth to use its native lladdr which is eui48 instead of eui64 which was expected by functions like lowpan_header_decompress and lowpan_header_compress. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Reviewed-by: Stefan Schmidt <stefan@osg.samsung.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:

committed by
Marcel Holtmann

parent
8a7a4b4767
commit
fa09ae661f
@@ -278,6 +278,23 @@ lowpan_iphc_ctx_get_by_mcast_addr(const struct net_device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lowpan_iphc_uncompress_lladdr(const struct net_device *dev,
|
||||
struct in6_addr *ipaddr,
|
||||
const void *lladdr)
|
||||
{
|
||||
switch (dev->addr_len) {
|
||||
case ETH_ALEN:
|
||||
lowpan_iphc_uncompress_eui48_lladdr(ipaddr, lladdr);
|
||||
break;
|
||||
case EUI64_ADDR_LEN:
|
||||
lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Uncompress address function for source and
|
||||
* destination address(non-multicast).
|
||||
*
|
||||
@@ -320,7 +337,7 @@ static int lowpan_iphc_uncompress_addr(struct sk_buff *skb,
|
||||
lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr);
|
||||
break;
|
||||
default:
|
||||
lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr);
|
||||
lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -381,7 +398,7 @@ static int lowpan_iphc_uncompress_ctx_addr(struct sk_buff *skb,
|
||||
lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr);
|
||||
break;
|
||||
default:
|
||||
lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr);
|
||||
lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr);
|
||||
break;
|
||||
}
|
||||
ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen);
|
||||
@@ -810,6 +827,21 @@ lowpan_iphc_compress_ctx_802154_lladdr(const struct in6_addr *ipaddr,
|
||||
return lladdr_compress;
|
||||
}
|
||||
|
||||
static bool lowpan_iphc_addr_equal(const struct net_device *dev,
|
||||
const struct lowpan_iphc_ctx *ctx,
|
||||
const struct in6_addr *ipaddr,
|
||||
const void *lladdr)
|
||||
{
|
||||
struct in6_addr tmp = {};
|
||||
|
||||
lowpan_iphc_uncompress_lladdr(dev, &tmp, lladdr);
|
||||
|
||||
if (ctx)
|
||||
ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
|
||||
|
||||
return ipv6_addr_equal(&tmp, ipaddr);
|
||||
}
|
||||
|
||||
static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct net_device *dev,
|
||||
const struct in6_addr *ipaddr,
|
||||
const struct lowpan_iphc_ctx *ctx,
|
||||
@@ -827,13 +859,7 @@ static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct net_device *dev,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* check for SAM/DAM = 11 */
|
||||
memcpy(&tmp.s6_addr[8], lladdr, EUI64_ADDR_LEN);
|
||||
/* second bit-flip (Universe/Local) is done according RFC2464 */
|
||||
tmp.s6_addr[8] ^= 0x02;
|
||||
/* context information are always used */
|
||||
ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
|
||||
if (ipv6_addr_equal(&tmp, ipaddr)) {
|
||||
if (lowpan_iphc_addr_equal(dev, ctx, ipaddr, lladdr)) {
|
||||
dam = LOWPAN_IPHC_DAM_11;
|
||||
goto out;
|
||||
}
|
||||
@@ -929,11 +955,12 @@ static u8 lowpan_compress_addr_64(u8 **hc_ptr, const struct net_device *dev,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (is_addr_mac_addr_based(ipaddr, lladdr)) {
|
||||
dam = LOWPAN_IPHC_DAM_11; /* 0-bits */
|
||||
if (lowpan_iphc_addr_equal(dev, NULL, ipaddr, lladdr)) {
|
||||
dam = LOWPAN_IPHC_DAM_11;
|
||||
pr_debug("address compression 0 bits\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user