This patch drop the pre and postcount calculation from the
lowpan_uncompress_addr function.

We use instead a switch case over address_mode value, it's easier
to understand what's going on there.

Signed-off-by: Alexander Aring <alex.ar...@gmail.com>
---
 net/ieee802154/6lowpan.c | 123 ++++++++++++++++++++++-------------------------
 net/ieee802154/6lowpan.h |   8 +--
 2 files changed, 62 insertions(+), 69 deletions(-)

diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 14e29d8..84f05c4 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -67,30 +67,6 @@ static const u8 lowpan_ttl_values[] = {0, 1, 64, 255};
 
 static LIST_HEAD(lowpan_devices);
 
-/*
- * Uncompression of linklocal:
- *   0 -> 16 bytes from packet
- *   1 -> 2  bytes from prefix - bunch of zeroes and 8 from packet
- *   2 -> 2  bytes from prefix - zeroes + 2 from packet
- *   3 -> 2  bytes from prefix - infer 8 bytes from lladdr
- *
- *  NOTE: => the uncompress function does change 0xf to 0x10
- *  NOTE: 0x00 => no-autoconfig => unspecified
- */
-static const u8 lowpan_unc_llconf[] = {0x0f, 0x28, 0x22, 0x20};
-
-/*
- * Uncompression of ctx-based:
- *   0 -> 0 bits  from packet [unspecified / reserved]
- *   1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet
- *   2 -> 8 bytes from prefix - zeroes + 2 from packet
- *   3 -> 8 bytes from prefix - infer 8 bytes from lladdr
- */
-static const u8 lowpan_unc_ctxconf[] = {0x00, 0x88, 0x82, 0x80};
-
-/* Link local prefix */
-static const u8 lowpan_llprefix[] = {0xfe, 0x80};
-
 /* private device info */
 struct lowpan_dev_info {
        struct net_device       *real_dev; /* real WPAN device ptr */
@@ -182,50 +158,67 @@ lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, const 
struct in6_addr *ipaddr,
        return rol8(val, shift);
 }
 
-static void
-lowpan_uip_ds6_set_addr_iid(struct in6_addr *ipaddr, unsigned char *lladdr)
-{
-       memcpy(&ipaddr->s6_addr[8], lladdr, IEEE802154_ADDR_LEN);
-       /* second bit-flip (Universe/Local) is done according RFC2464 */
-       ipaddr->s6_addr[8] ^= 0x02;
-}
-
 /*
- * Uncompress addresses based on a prefix and a postfix with zeroes in
- * between. If the postfix is zero in length it will use the link address
- * to configure the IP address (autoconf style).
- * pref_post_count takes a byte where the first nibble specify prefix count
- * and the second postfix count (NOTE: 15/0xf => 16 bytes copy).
+ * Uncompress address function for source and
+ * destination address(non-multicast).
+ *
+ * address_mode is sam value or dam value.
  */
 static int
-lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr,
-       u8 const *prefix, u8 pref_post_count, unsigned char *lladdr)
+lowpan_uncompress_addr(struct sk_buff *skb,
+               struct in6_addr *ipaddr,
+               const u8 address_mode,
+               const u8 *layer_addr)
 {
-       u8 prefcount = pref_post_count >> 4;
-       u8 postcount = pref_post_count & 0x0f;
-
-       /* full nibble 15 => 16 */
-       prefcount = (prefcount == 15 ? 16 : prefcount);
-       postcount = (postcount == 15 ? 16 : postcount);
-
-       if (lladdr)
-               lowpan_raw_dump_inline(__func__, "linklocal address",
-                                               lladdr, IEEE802154_ADDR_LEN);
-       if (prefcount > 0)
-               memcpy(ipaddr, prefix, prefcount);
-
-       if (postcount > 0) {
-               memcpy(&ipaddr->s6_addr[16 - postcount], skb->data, postcount);
-               skb_pull(skb, postcount);
-       } else if (prefcount > 0) {
-               if (lladdr == NULL)
-                       return -EINVAL;
-
-               /* no IID based configuration if no prefix and no data */
-               lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr);
+       switch (address_mode) {
+       case LOWPAN_IPHC_ADDR_00:
+               /*
+                * for global link addresses
+                */
+               memcpy(ipaddr->s6_addr, skb->data, 16);
+               skb_pull(skb, 16);
+               break;
+       case LOWPAN_IPHC_ADDR_01:
+               /*
+                * fe:80::XXXX:XXXX:XXXX:XXXX
+                */
+               memset(&ipaddr->s6_addr[0], 0xFE, 1);
+               memset(&ipaddr->s6_addr[1], 0x80, 1);
+               memcpy(&ipaddr->s6_addr[8], skb->data, 8);
+               skb_pull(skb, 8);
+               break;
+       case LOWPAN_IPHC_ADDR_02:
+               /*
+                * fe:80::ff:fe00:XXXX
+                */
+               memset(&ipaddr->s6_addr[0], 0xFE, 1);
+               memset(&ipaddr->s6_addr[1], 0x80, 1);
+               memset(&ipaddr->s6_addr[11], 0xFF, 1);
+               memset(&ipaddr->s6_addr[12], 0xFE, 1);
+               memcpy(&ipaddr->s6_addr[14], skb->data, 2);
+               skb_pull(skb, 2);
+               break;
+       case LOWPAN_IPHC_ADDR_03:
+               /*
+                * fe:80::XXXX:XXXX:XXXX:XXXX
+                *        \_________________/
+                *             layer_addr
+                */
+               memset(&ipaddr->s6_addr[0], 0xFE, 1);
+               memset(&ipaddr->s6_addr[1], 0x80, 1);
+               memcpy(&ipaddr->s6_addr[8], layer_addr, IEEE802154_ADDR_LEN);
+               /*
+                * second bit-flip (Universe/Local)
+                * is done according RFC2464
+                */
+               ipaddr->s6_addr[8] ^= 0x02;
+               break;
+       default:
+               pr_debug("Invalid address mode value: 0x%x\n", address_mode);
+               return -EINVAL;
        }
 
-       pr_debug("uncompressing %d + %d => ", prefcount, postcount);
+       pr_debug("Reconstructed ipv6 addr is:\n");
        lowpan_raw_dump_inline(NULL, NULL, ipaddr->s6_addr, 16);
 
        return 0;
@@ -960,8 +953,7 @@ lowpan_process_data(struct sk_buff *skb)
 
        /* Source address uncompression */
        pr_debug("source address stateless compression\n");
-       err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix,
-                               lowpan_unc_llconf[tmp], _saddr);
+       err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr);
        if (err)
                goto drop;
 
@@ -981,8 +973,7 @@ lowpan_process_data(struct sk_buff *skb)
                }
        } else {
                pr_debug("dest: stateless compression\n");
-               err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix,
-                               lowpan_unc_llconf[tmp], _daddr);
+               err = lowpan_uncompress_addr(skb, &hdr.daddr, tmp, _daddr);
                if (err)
                        goto drop;
        }
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h
index 4b8f917..3b64644 100644
--- a/net/ieee802154/6lowpan.h
+++ b/net/ieee802154/6lowpan.h
@@ -193,10 +193,12 @@
 /* Values of fields within the IPHC encoding second byte */
 #define LOWPAN_IPHC_CID                0x80
 
+#define LOWPAN_IPHC_ADDR_00    0x00
+#define LOWPAN_IPHC_ADDR_01    0x01
+#define LOWPAN_IPHC_ADDR_02    0x02
+#define LOWPAN_IPHC_ADDR_03    0x03
+
 #define LOWPAN_IPHC_SAC                0x40
-#define LOWPAN_IPHC_SAM_00     0x00
-#define LOWPAN_IPHC_SAM_01     0x10
-#define LOWPAN_IPHC_SAM_10     0x20
 #define LOWPAN_IPHC_SAM                0x30
 
 #define LOWPAN_IPHC_SAM_BIT    4
-- 
1.8.3.2


------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to