summaryrefslogtreecommitdiffstats
path: root/include/net/6lowpan.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/6lowpan.h')
-rw-r--r--include/net/6lowpan.h154
1 files changed, 35 insertions, 119 deletions
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index a2f59ec..07db532 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -61,6 +61,16 @@
#define UIP_PROTO_UDP 17 /* ipv6 next header value for UDP */
#define UIP_FRAGH_LEN 8 /* ipv6 fragment header size */
+#define EUI64_ADDR_LEN 8
+
+#define LOWPAN_NHC_MAX_ID_LEN 1
+/* Max IPHC Header len without IPv6 hdr specific inline data.
+ * Useful for getting the "extra" bytes we need at worst case compression.
+ *
+ * LOWPAN_IPHC + CID + LOWPAN_NHC_MAX_ID_LEN
+ */
+#define LOWPAN_IPHC_MAX_HEADER_LEN (2 + 1 + LOWPAN_NHC_MAX_ID_LEN)
+
/*
* ipv6 address based on mac
* second bit-flip (Universe/Local) is done according RFC2464
@@ -126,13 +136,19 @@
(((a)[6]) == 0xFF) && \
(((a)[7]) == 0xFF))
-#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_IPV6 0x41 /* 01000001 = 65 */
+#define LOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */
+#define LOWPAN_DISPATCH_IPHC_MASK 0xe0
-#define LOWPAN_DISPATCH_MASK 0xf8 /* 11111000 */
+static inline bool lowpan_is_ipv6(u8 dispatch)
+{
+ return dispatch == LOWPAN_DISPATCH_IPV6;
+}
+
+static inline bool lowpan_is_iphc(u8 dispatch)
+{
+ return (dispatch & LOWPAN_DISPATCH_IPHC_MASK) == LOWPAN_DISPATCH_IPHC;
+}
#define LOWPAN_FRAG_TIMEOUT (HZ * 60) /* time-out 60 sec */
@@ -218,6 +234,19 @@ struct lowpan_priv *lowpan_priv(const struct net_device *dev)
return netdev_priv(dev);
}
+struct lowpan_802154_cb {
+ u16 d_tag;
+ unsigned int d_size;
+ u8 d_offset;
+};
+
+static inline
+struct lowpan_802154_cb *lowpan_802154_cb(const struct sk_buff *skb)
+{
+ BUILD_BUG_ON(sizeof(struct lowpan_802154_cb) > sizeof(skb->cb));
+ return (struct lowpan_802154_cb *)skb->cb;
+}
+
#ifdef DEBUG
/* print data in line */
static inline void raw_dump_inline(const char *caller, char *msg,
@@ -280,119 +309,6 @@ static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data,
*hc_ptr += len;
}
-static inline u8 lowpan_addr_mode_size(const u8 addr_mode)
-{
- static const u8 addr_sizes[] = {
- [LOWPAN_IPHC_ADDR_00] = 16,
- [LOWPAN_IPHC_ADDR_01] = 8,
- [LOWPAN_IPHC_ADDR_02] = 2,
- [LOWPAN_IPHC_ADDR_03] = 0,
- };
- return addr_sizes[addr_mode];
-}
-
-static inline u8 lowpan_next_hdr_size(const u8 h_enc, u16 *uncomp_header)
-{
- u8 ret = 1;
-
- if ((h_enc & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
- *uncomp_header += sizeof(struct udphdr);
-
- switch (h_enc & LOWPAN_NHC_UDP_CS_P_11) {
- case LOWPAN_NHC_UDP_CS_P_00:
- ret += 4;
- break;
- case LOWPAN_NHC_UDP_CS_P_01:
- case LOWPAN_NHC_UDP_CS_P_10:
- ret += 3;
- break;
- case LOWPAN_NHC_UDP_CS_P_11:
- ret++;
- break;
- default:
- break;
- }
-
- if (!(h_enc & LOWPAN_NHC_UDP_CS_C))
- ret += 2;
- }
-
- return ret;
-}
-
-/**
- * lowpan_uncompress_size - returns skb->len size with uncompressed header
- * @skb: sk_buff with 6lowpan header inside
- * @datagram_offset: optional to get the datagram_offset value
- *
- * Returns the skb->len with uncompressed header
- */
-static inline u16
-lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
-{
- u16 ret = 2, uncomp_header = sizeof(struct ipv6hdr);
- u8 iphc0, iphc1, h_enc;
-
- iphc0 = skb_network_header(skb)[0];
- iphc1 = skb_network_header(skb)[1];
-
- switch ((iphc0 & LOWPAN_IPHC_TF) >> 3) {
- case 0:
- ret += 4;
- break;
- case 1:
- ret += 3;
- break;
- case 2:
- ret++;
- break;
- default:
- break;
- }
-
- if (!(iphc0 & LOWPAN_IPHC_NH_C))
- ret++;
-
- if (!(iphc0 & 0x03))
- ret++;
-
- ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_SAM) >>
- LOWPAN_IPHC_SAM_BIT);
-
- if (iphc1 & LOWPAN_IPHC_M) {
- switch ((iphc1 & LOWPAN_IPHC_DAM_11) >>
- LOWPAN_IPHC_DAM_BIT) {
- case LOWPAN_IPHC_DAM_00:
- ret += 16;
- break;
- case LOWPAN_IPHC_DAM_01:
- ret += 6;
- break;
- case LOWPAN_IPHC_DAM_10:
- ret += 4;
- break;
- case LOWPAN_IPHC_DAM_11:
- ret++;
- break;
- default:
- break;
- }
- } else {
- ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_DAM_11) >>
- LOWPAN_IPHC_DAM_BIT);
- }
-
- if (iphc0 & LOWPAN_IPHC_NH_C) {
- h_enc = skb_network_header(skb)[ret];
- ret += lowpan_next_hdr_size(h_enc, &uncomp_header);
- }
-
- if (dgram_offset)
- *dgram_offset = uncomp_header;
-
- return skb->len + uncomp_header - ret;
-}
-
void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype);
int
OpenPOWER on IntegriCloud