]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - include/net/6lowpan.h
6lowpan: remove lowpan_fetch_skb_u8
[mirror_ubuntu-artful-kernel.git] / include / net / 6lowpan.h
index a2f59ec98d24a1af1e8de056305b563b2ff94df7..4afdbb3ab6d800bad32dde913742ad4ffb9a21c8 100644 (file)
 #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
+/* Maximum next header compression length which we currently support inclusive
+ * possible inline data.
+ */
+#define LOWPAN_NHC_MAX_HDR_LEN (sizeof(struct udphdr))
+/* 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)
+/* Maximum worst case IPHC header buffer size */
+#define LOWPAN_IPHC_MAX_HC_BUF_LEN     (sizeof(struct ipv6hdr) +       \
+                                        LOWPAN_IPHC_MAX_HEADER_LEN +   \
+                                        LOWPAN_NHC_MAX_HDR_LEN)
+
 /*
  * ipv6 address based on mac
  * second bit-flip (Universe/Local) is done according RFC2464
         (((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,10 +242,23 @@ 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,
-                                  unsigned char *buf, int len)
+                                  const unsigned char *buf, int len)
 {
        if (msg)
                pr_debug("%s():%s: ", caller, msg);
@@ -236,7 +273,7 @@ static inline void raw_dump_inline(const char *caller, char *msg,
  * ...
  */
 static inline void raw_dump_table(const char *caller, char *msg,
-                                 unsigned char *buf, int len)
+                                 const unsigned char *buf, int len)
 {
        if (msg)
                pr_debug("%s():%s:\n", caller, msg);
@@ -245,24 +282,25 @@ static inline void raw_dump_table(const char *caller, char *msg,
 }
 #else
 static inline void raw_dump_table(const char *caller, char *msg,
-                                 unsigned char *buf, int len) { }
+                                 const unsigned char *buf, int len) { }
 static inline void raw_dump_inline(const char *caller, char *msg,
-                                  unsigned char *buf, int len) { }
+                                  const unsigned char *buf, int len) { }
 #endif
 
-static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val)
-{
-       if (unlikely(!pskb_may_pull(skb, 1)))
-               return -EINVAL;
-
-       *val = skb->data[0];
-       skb_pull(skb, 1);
-
-       return 0;
-}
-
-static inline bool lowpan_fetch_skb(struct sk_buff *skb,
-               void *data, const unsigned int len)
+/**
+ * lowpan_fetch_skb - getting inline data from 6LoWPAN header
+ *
+ * This function will pull data from sk buffer and put it into data to
+ * remove the 6LoWPAN inline data. This function returns true if the
+ * sk buffer is too small to pull the amount of data which is specified
+ * by len.
+ *
+ * @skb: the buffer where the inline data should be pulled from.
+ * @data: destination buffer for the inline data.
+ * @len: amount of data which should be pulled in bytes.
+ */
+static inline bool lowpan_fetch_skb(struct sk_buff *skb, void *data,
+                                   unsigned int len)
 {
        if (unlikely(!pskb_may_pull(skb, len)))
                return true;
@@ -280,129 +318,44 @@ 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;
-}
+void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype);
 
 /**
- *     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
+ * lowpan_header_decompress - replace 6LoWPAN header with IPv6 header
+ *
+ * This function replaces the IPHC 6LoWPAN header which should be pointed at
+ * skb->data and skb_network_header, with the IPv6 header.
+ * It would be nice that the caller have the necessary headroom of IPv6 header
+ * and greatest Transport layer header, this would reduce the overhead for
+ * reallocate headroom.
  *
- *     Returns the skb->len with uncompressed header
+ * @skb: the buffer which should be manipulate.
+ * @dev: the lowpan net device pointer.
+ * @daddr: destination lladdr of mac header which is used for compression
+ *     methods.
+ * @saddr: source lladdr of mac header which is used for compression
+ *     methods.
  */
-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 lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,
+                            const void *daddr, const void *saddr);
 
-int
-lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
-                        const u8 *saddr, const u8 saddr_type,
-                        const u8 saddr_len, const u8 *daddr,
-                        const u8 daddr_type, const u8 daddr_len,
-                        u8 iphc0, u8 iphc1);
-int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
-                       unsigned short type, const void *_daddr,
-                       const void *_saddr, unsigned int len);
+/**
+ * lowpan_header_compress - replace IPv6 header with 6LoWPAN header
+ *
+ * This function replaces the IPv6 header which should be pointed at
+ * skb->data and skb_network_header, with the IPHC 6LoWPAN header.
+ * The caller need to be sure that the sk buffer is not shared and at have
+ * at least a headroom which is smaller or equal LOWPAN_IPHC_MAX_HEADER_LEN,
+ * which is the IPHC "more bytes than IPv6 header" at worst case.
+ *
+ * @skb: the buffer which should be manipulate.
+ * @dev: the lowpan net device pointer.
+ * @daddr: destination lladdr of mac header which is used for compression
+ *     methods.
+ * @saddr: source lladdr of mac header which is used for compression
+ *     methods.
+ */
+int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
+                          const void *daddr, const void *saddr);
 
 #endif /* __6LOWPAN_H__ */