[PATCH][linux-bluetooth 3/3] 6lowpan: Refactored lowpan_rcv so it's RFC compliant

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently we support uncompressed IPv6 headers after performing fragmentation.

Signed-off-by: Martin Townsend <martin.townsend@xxxxxxxxxx>
---
 include/net/6lowpan.h         | 17 ++++++++++++
 net/ieee802154/6lowpan_rtnl.c | 63 +++++++++++++++++++++++--------------------
 2 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index d71c062..71b1bf0 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -126,11 +126,28 @@
 	 (((a)[6]) == 0xFF) &&	\
 	 (((a)[7]) == 0xFF))
 
+#define lowpan_dispatch_is_nalp(a)	\
+	(((a) & LOWPAN_DISPATCH_MAJOR) == 0x00)
+
+#define lowpan_dispatch_is_mesh(a)	\
+	(((a) & LOWPAN_DISPATCH_MAJOR) == 0x80)
+
+#define lowpan_dispatch_is_broadcast(a)	\
+	((a) == LOWPAN_DISPATCH_BCAST)
+
+#define lowpan_dispatch_is_frag(a)	\
+	(((a) & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1 || \
+	 ((a) & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAGN)
+
+#define LOWPAN_DISPATCH_MAJOR	0xc0
+#define LOWPAN_DISPATCH_MINOR	0x3f
+
 #define LOWPAN_DISPATCH_IPV6	0x41 /* 01000001 = 65 */
 #define LOWPAN_DISPATCH_HC1	0x42 /* 01000010 = 66 */
 #define LOWPAN_DISPATCH_IPHC	0x60 /* 011xxxxx = ... */
 #define LOWPAN_DISPATCH_FRAG1	0xc0 /* 11000xxx */
 #define LOWPAN_DISPATCH_FRAGN	0xe0 /* 11100xxx */
+#define LOWPAN_DISPATCH_BCAST	0x50 /* 01010000 */
 
 #define LOWPAN_DISPATCH_MASK	0xf8 /* 11111000 */
 
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 4f4b02d..1557ece 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -477,41 +477,46 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
 	if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
 		goto drop_skb;
 
-	/* check that it's our buffer */
+	/* First off if frame is Not A LoWPAN Packet (NALP) then chuck away */
+	if (lowpan_dispatch_is_nalp(skb->data[0]))
+		goto drop_skb;
+
+	/* The 6LoWPAN header stack comprimises of the following (in order)
+	 *   Mesh
+	 *   Broadcast
+	 *   Fragmentation
+	 */
+	if (lowpan_dispatch_is_mesh(skb->data[0]))
+		/* Not supported */
+		goto drop_skb;
+
+	if (lowpan_dispatch_is_broadcast(skb->data[0]))
+		/* Not supported */
+		goto drop_skb;
+
+	if (lowpan_dispatch_is_frag(skb->data[0])) {
+		u8 frag_dispatch = skb->data[0] & 0xe0;
+
+		ret = lowpan_frag_rcv(skb, frag_dispatch);
+		if (ret != 1) {
+			/* more frags to process */
+			return NET_RX_SUCCESS;
+		}
+	}
+
+	/* We should now have an IPv6 Header (Compressed or Uncompressed) */
 	if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
-		/* Pull off the 1-byte of 6lowpan header. */
+		/* Uncompressed, Pull off the dispatch byte */
 		skb_pull(skb, 1);
-
-		ret = NET_RX_SUCCESS;
 	} else {
-		switch (skb->data[0] & 0xe0) {
-		case LOWPAN_DISPATCH_IPHC:	/* ipv6 datagram */
+		if ((skb->data[0] & 0xe0) == LOWPAN_DISPATCH_IPHC) {
+			/* Compressed with IPHC - RFC 6282 */
 			ret = iphc_uncompress_hdr(&skb, &hdr);
 			if (ret < 0)
 				goto drop;
-			break;
-		case LOWPAN_DISPATCH_FRAG1:	/* first fragment header */
-			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
-			if (ret == 1) {
-				ret = iphc_uncompress_hdr(&skb, &hdr);
-				if (ret < 0)
-					goto drop;
-			} else {
-				return NET_RX_SUCCESS;
-			}
-			break;
-		case LOWPAN_DISPATCH_FRAGN:	/* next fragments headers */
-			ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
-			if (ret == 1) {
-				ret = iphc_uncompress_hdr(&skb, &hdr);
-				if (ret < 0)
-					goto drop;
-			} else {
-				return NET_RX_SUCCESS;
-			}
-			break;
-		default:
-			break;
+		} else {
+			/* TODO: other compression formats to follow */
+			goto drop_skb;
 		}
 	}
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux