diff options
author | Alexander Aring <alex.aring@gmail.com> | 2013-08-16 21:59:59 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-20 13:23:12 -0700 |
commit | 65d892c8ac8f131f668edd55db291a7c68f8338f (patch) | |
tree | 34b01006d0a2c3991ebdcfaba5f08d47b6d126d0 /net/ieee802154 | |
parent | ce2463b283a0cb63e0e4de5e7d971b4c92be542a (diff) |
6lowpan: handle context based source address
Handle context based address when an unspecified address is given.
For other context based address we print a warning and drop the packet
because we don't support it right now.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Reviewed-by: Werner Almesberger <werner@almesberger.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee802154')
-rw-r--r-- | net/ieee802154/6lowpan.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 5ef9157c5f1..c85e71e0c7f 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -242,6 +242,40 @@ lowpan_uncompress_addr(struct sk_buff *skb, return 0; } +/* Uncompress address function for source context + * based address(non-multicast). + */ +static int +lowpan_uncompress_context_based_src_addr(struct sk_buff *skb, + struct in6_addr *ipaddr, + const u8 sam) +{ + switch (sam) { + case LOWPAN_IPHC_ADDR_00: + /* unspec address :: + * Do nothing, address is already :: + */ + break; + case LOWPAN_IPHC_ADDR_01: + /* TODO */ + case LOWPAN_IPHC_ADDR_02: + /* TODO */ + case LOWPAN_IPHC_ADDR_03: + /* TODO */ + netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam); + return -EINVAL; + default: + pr_debug("Invalid sam value: 0x%x\n", sam); + return -EINVAL; + } + + lowpan_raw_dump_inline(NULL, + "Reconstructed context based ipv6 src addr is:\n", + ipaddr->s6_addr, 16); + + return 0; +} + /* Uncompress function for multicast destination address, * when M bit is set. */ @@ -970,9 +1004,18 @@ lowpan_process_data(struct sk_buff *skb) /* Extract SAM to the tmp variable */ tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; - /* Source address uncompression */ - pr_debug("source address stateless compression\n"); - err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr); + if (iphc1 & LOWPAN_IPHC_SAC) { + /* Source address context based uncompression */ + pr_debug("SAC bit is set. Handle context based source address.\n"); + err = lowpan_uncompress_context_based_src_addr( + skb, &hdr.saddr, tmp); + } else { + /* Source address uncompression */ + pr_debug("source address stateless compression\n"); + err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr); + } + + /* Check on error of previous branch */ if (err) goto drop; |