0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #ifndef __6LOWPAN_H__
0054 #define __6LOWPAN_H__
0055
0056 #include <linux/debugfs.h>
0057
0058 #include <net/ipv6.h>
0059 #include <net/net_namespace.h>
0060
0061
0062 #include <net/mac802154.h>
0063
0064 #define EUI64_ADDR_LEN 8
0065
0066 #define LOWPAN_NHC_MAX_ID_LEN 1
0067
0068
0069
0070 #define LOWPAN_NHC_MAX_HDR_LEN (sizeof(struct udphdr))
0071
0072
0073
0074
0075
0076 #define LOWPAN_IPHC_MAX_HEADER_LEN (2 + 1 + LOWPAN_NHC_MAX_ID_LEN)
0077
0078 #define LOWPAN_IPHC_MAX_HC_BUF_LEN (sizeof(struct ipv6hdr) + \
0079 LOWPAN_IPHC_MAX_HEADER_LEN + \
0080 LOWPAN_NHC_MAX_HDR_LEN)
0081
0082 #define LOWPAN_IPHC_CTX_TABLE_SIZE (1 << 4)
0083
0084 #define LOWPAN_DISPATCH_IPV6 0x41
0085 #define LOWPAN_DISPATCH_IPHC 0x60
0086 #define LOWPAN_DISPATCH_IPHC_MASK 0xe0
0087
0088 static inline bool lowpan_is_ipv6(u8 dispatch)
0089 {
0090 return dispatch == LOWPAN_DISPATCH_IPV6;
0091 }
0092
0093 static inline bool lowpan_is_iphc(u8 dispatch)
0094 {
0095 return (dispatch & LOWPAN_DISPATCH_IPHC_MASK) == LOWPAN_DISPATCH_IPHC;
0096 }
0097
0098 #define LOWPAN_PRIV_SIZE(llpriv_size) \
0099 (sizeof(struct lowpan_dev) + llpriv_size)
0100
0101 enum lowpan_lltypes {
0102 LOWPAN_LLTYPE_BTLE,
0103 LOWPAN_LLTYPE_IEEE802154,
0104 };
0105
0106 enum lowpan_iphc_ctx_flags {
0107 LOWPAN_IPHC_CTX_FLAG_ACTIVE,
0108 LOWPAN_IPHC_CTX_FLAG_COMPRESSION,
0109 };
0110
0111 struct lowpan_iphc_ctx {
0112 u8 id;
0113 struct in6_addr pfx;
0114 u8 plen;
0115 unsigned long flags;
0116 };
0117
0118 struct lowpan_iphc_ctx_table {
0119 spinlock_t lock;
0120 const struct lowpan_iphc_ctx_ops *ops;
0121 struct lowpan_iphc_ctx table[LOWPAN_IPHC_CTX_TABLE_SIZE];
0122 };
0123
0124 static inline bool lowpan_iphc_ctx_is_active(const struct lowpan_iphc_ctx *ctx)
0125 {
0126 return test_bit(LOWPAN_IPHC_CTX_FLAG_ACTIVE, &ctx->flags);
0127 }
0128
0129 static inline bool
0130 lowpan_iphc_ctx_is_compression(const struct lowpan_iphc_ctx *ctx)
0131 {
0132 return test_bit(LOWPAN_IPHC_CTX_FLAG_COMPRESSION, &ctx->flags);
0133 }
0134
0135 struct lowpan_dev {
0136 enum lowpan_lltypes lltype;
0137 struct dentry *iface_debugfs;
0138 struct lowpan_iphc_ctx_table ctx;
0139
0140
0141 u8 priv[] __aligned(sizeof(void *));
0142 };
0143
0144 struct lowpan_802154_neigh {
0145 __le16 short_addr;
0146 };
0147
0148 static inline
0149 struct lowpan_802154_neigh *lowpan_802154_neigh(void *neigh_priv)
0150 {
0151 return neigh_priv;
0152 }
0153
0154 static inline
0155 struct lowpan_dev *lowpan_dev(const struct net_device *dev)
0156 {
0157 return netdev_priv(dev);
0158 }
0159
0160
0161 struct lowpan_802154_dev {
0162 struct net_device *wdev;
0163 u16 fragment_tag;
0164 };
0165
0166 static inline struct
0167 lowpan_802154_dev *lowpan_802154_dev(const struct net_device *dev)
0168 {
0169 return (struct lowpan_802154_dev *)lowpan_dev(dev)->priv;
0170 }
0171
0172 struct lowpan_802154_cb {
0173 u16 d_tag;
0174 unsigned int d_size;
0175 u8 d_offset;
0176 };
0177
0178 static inline
0179 struct lowpan_802154_cb *lowpan_802154_cb(const struct sk_buff *skb)
0180 {
0181 BUILD_BUG_ON(sizeof(struct lowpan_802154_cb) > sizeof(skb->cb));
0182 return (struct lowpan_802154_cb *)skb->cb;
0183 }
0184
0185 static inline void lowpan_iphc_uncompress_eui64_lladdr(struct in6_addr *ipaddr,
0186 const void *lladdr)
0187 {
0188
0189
0190
0191
0192 ipaddr->s6_addr[0] = 0xFE;
0193 ipaddr->s6_addr[1] = 0x80;
0194 memcpy(&ipaddr->s6_addr[8], lladdr, EUI64_ADDR_LEN);
0195
0196
0197
0198 ipaddr->s6_addr[8] ^= 0x02;
0199 }
0200
0201 static inline void lowpan_iphc_uncompress_eui48_lladdr(struct in6_addr *ipaddr,
0202 const void *lladdr)
0203 {
0204
0205
0206
0207
0208 ipaddr->s6_addr[0] = 0xFE;
0209 ipaddr->s6_addr[1] = 0x80;
0210 memcpy(&ipaddr->s6_addr[8], lladdr, 3);
0211 ipaddr->s6_addr[11] = 0xFF;
0212 ipaddr->s6_addr[12] = 0xFE;
0213 memcpy(&ipaddr->s6_addr[13], lladdr + 3, 3);
0214 }
0215
0216 #ifdef DEBUG
0217
0218 static inline void raw_dump_inline(const char *caller, char *msg,
0219 const unsigned char *buf, int len)
0220 {
0221 if (msg)
0222 pr_debug("%s():%s: ", caller, msg);
0223
0224 print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, false);
0225 }
0226
0227
0228
0229
0230
0231
0232
0233 static inline void raw_dump_table(const char *caller, char *msg,
0234 const unsigned char *buf, int len)
0235 {
0236 if (msg)
0237 pr_debug("%s():%s:\n", caller, msg);
0238
0239 print_hex_dump_debug("\t", DUMP_PREFIX_OFFSET, 16, 1, buf, len, false);
0240 }
0241 #else
0242 static inline void raw_dump_table(const char *caller, char *msg,
0243 const unsigned char *buf, int len) { }
0244 static inline void raw_dump_inline(const char *caller, char *msg,
0245 const unsigned char *buf, int len) { }
0246 #endif
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 static inline bool lowpan_fetch_skb(struct sk_buff *skb, void *data,
0261 unsigned int len)
0262 {
0263 if (unlikely(!pskb_may_pull(skb, len)))
0264 return true;
0265
0266 skb_copy_from_linear_data(skb, data, len);
0267 skb_pull(skb, len);
0268
0269 return false;
0270 }
0271
0272 static inline bool lowpan_802154_is_valid_src_short_addr(__le16 addr)
0273 {
0274
0275 return !(addr & cpu_to_le16(0x8000));
0276 }
0277
0278 static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data,
0279 const size_t len)
0280 {
0281 memcpy(*hc_ptr, data, len);
0282 *hc_ptr += len;
0283 }
0284
0285 int lowpan_register_netdevice(struct net_device *dev,
0286 enum lowpan_lltypes lltype);
0287 int lowpan_register_netdev(struct net_device *dev,
0288 enum lowpan_lltypes lltype);
0289 void lowpan_unregister_netdevice(struct net_device *dev);
0290 void lowpan_unregister_netdev(struct net_device *dev);
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,
0309 const void *daddr, const void *saddr);
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
0328 const void *daddr, const void *saddr);
0329
0330 #endif