]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - include/net/ieee802154_netdev.h
xfrm: dst_entries_init() per-net dst_ops
[karo-tx-linux.git] / include / net / ieee802154_netdev.h
1 /*
2  * An interface between IEEE802.15.4 device and rest of the kernel.
3  *
4  * Copyright (C) 2007-2012 Siemens AG
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * Written by:
16  * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
17  * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
18  * Maxim Osipov <maxim.osipov@siemens.com>
19  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
20  * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
21  */
22
23 #ifndef IEEE802154_NETDEVICE_H
24 #define IEEE802154_NETDEVICE_H
25
26 #include <net/af_ieee802154.h>
27 #include <linux/netdevice.h>
28 #include <linux/skbuff.h>
29 #include <linux/ieee802154.h>
30
31 #include <net/cfg802154.h>
32
33 struct ieee802154_sechdr {
34 #if defined(__LITTLE_ENDIAN_BITFIELD)
35         u8 level:3,
36            key_id_mode:2,
37            reserved:3;
38 #elif defined(__BIG_ENDIAN_BITFIELD)
39         u8 reserved:3,
40            key_id_mode:2,
41            level:3;
42 #else
43 #error  "Please fix <asm/byteorder.h>"
44 #endif
45         u8 key_id;
46         __le32 frame_counter;
47         union {
48                 __le32 short_src;
49                 __le64 extended_src;
50         };
51 };
52
53 struct ieee802154_addr {
54         u8 mode;
55         __le16 pan_id;
56         union {
57                 __le16 short_addr;
58                 __le64 extended_addr;
59         };
60 };
61
62 struct ieee802154_hdr_fc {
63 #if defined(__LITTLE_ENDIAN_BITFIELD)
64         u16 type:3,
65             security_enabled:1,
66             frame_pending:1,
67             ack_request:1,
68             intra_pan:1,
69             reserved:3,
70             dest_addr_mode:2,
71             version:2,
72             source_addr_mode:2;
73 #elif defined(__BIG_ENDIAN_BITFIELD)
74         u16 reserved:1,
75             intra_pan:1,
76             ack_request:1,
77             frame_pending:1,
78             security_enabled:1,
79             type:3,
80             source_addr_mode:2,
81             version:2,
82             dest_addr_mode:2,
83             reserved2:2;
84 #else
85 #error  "Please fix <asm/byteorder.h>"
86 #endif
87 };
88
89 struct ieee802154_hdr {
90         struct ieee802154_hdr_fc fc;
91         u8 seq;
92         struct ieee802154_addr source;
93         struct ieee802154_addr dest;
94         struct ieee802154_sechdr sec;
95 };
96
97 /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
98  * the contents of hdr will be, and the actual value of those bits in
99  * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
100  * version, if SECEN is set.
101  */
102 int ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr);
103
104 /* pulls the entire 802.15.4 header off of the skb, including the security
105  * header, and performs pan id decompression
106  */
107 int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr);
108
109 /* parses the frame control, sequence number of address fields in a given skb
110  * and stores them into hdr, performing pan id decompression and length checks
111  * to be suitable for use in header_ops.parse
112  */
113 int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
114                               struct ieee802154_hdr *hdr);
115
116 /* parses the full 802.15.4 header a given skb and stores them into hdr,
117  * performing pan id decompression and length checks to be suitable for use in
118  * header_ops.parse
119  */
120 int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
121
122 int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
123
124 static inline int
125 ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec)
126 {
127         switch (sec->level) {
128         case IEEE802154_SCF_SECLEVEL_MIC32:
129         case IEEE802154_SCF_SECLEVEL_ENC_MIC32:
130                 return 4;
131         case IEEE802154_SCF_SECLEVEL_MIC64:
132         case IEEE802154_SCF_SECLEVEL_ENC_MIC64:
133                 return 8;
134         case IEEE802154_SCF_SECLEVEL_MIC128:
135         case IEEE802154_SCF_SECLEVEL_ENC_MIC128:
136                 return 16;
137         case IEEE802154_SCF_SECLEVEL_NONE:
138         case IEEE802154_SCF_SECLEVEL_ENC:
139         default:
140                 return 0;
141         }
142 }
143
144 static inline int ieee802154_hdr_length(struct sk_buff *skb)
145 {
146         struct ieee802154_hdr hdr;
147         int len = ieee802154_hdr_pull(skb, &hdr);
148
149         if (len > 0)
150                 skb_push(skb, len);
151
152         return len;
153 }
154
155 static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1,
156                                          const struct ieee802154_addr *a2)
157 {
158         if (a1->pan_id != a2->pan_id || a1->mode != a2->mode)
159                 return false;
160
161         if ((a1->mode == IEEE802154_ADDR_LONG &&
162              a1->extended_addr != a2->extended_addr) ||
163             (a1->mode == IEEE802154_ADDR_SHORT &&
164              a1->short_addr != a2->short_addr))
165                 return false;
166
167         return true;
168 }
169
170 static inline __le64 ieee802154_devaddr_from_raw(const void *raw)
171 {
172         u64 temp;
173
174         memcpy(&temp, raw, IEEE802154_ADDR_LEN);
175         return (__force __le64)swab64(temp);
176 }
177
178 static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
179 {
180         u64 temp = swab64((__force u64)addr);
181
182         memcpy(raw, &temp, IEEE802154_ADDR_LEN);
183 }
184
185 static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
186                                            const struct ieee802154_addr_sa *sa)
187 {
188         a->mode = sa->addr_type;
189         a->pan_id = cpu_to_le16(sa->pan_id);
190
191         switch (a->mode) {
192         case IEEE802154_ADDR_SHORT:
193                 a->short_addr = cpu_to_le16(sa->short_addr);
194                 break;
195         case IEEE802154_ADDR_LONG:
196                 a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr);
197                 break;
198         }
199 }
200
201 static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa,
202                                          const struct ieee802154_addr *a)
203 {
204         sa->addr_type = a->mode;
205         sa->pan_id = le16_to_cpu(a->pan_id);
206
207         switch (a->mode) {
208         case IEEE802154_ADDR_SHORT:
209                 sa->short_addr = le16_to_cpu(a->short_addr);
210                 break;
211         case IEEE802154_ADDR_LONG:
212                 ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr);
213                 break;
214         }
215 }
216
217 /*
218  * A control block of skb passed between the ARPHRD_IEEE802154 device
219  * and other stack parts.
220  */
221 struct ieee802154_mac_cb {
222         u8 lqi;
223         u8 type;
224         bool ackreq;
225         bool secen;
226         bool secen_override;
227         u8 seclevel;
228         bool seclevel_override;
229         struct ieee802154_addr source;
230         struct ieee802154_addr dest;
231 };
232
233 static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
234 {
235         return (struct ieee802154_mac_cb *)skb->cb;
236 }
237
238 static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb)
239 {
240         BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb));
241
242         memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb));
243         return mac_cb(skb);
244 }
245
246 #define IEEE802154_LLSEC_KEY_SIZE 16
247
248 struct ieee802154_llsec_key_id {
249         u8 mode;
250         u8 id;
251         union {
252                 struct ieee802154_addr device_addr;
253                 __le32 short_source;
254                 __le64 extended_source;
255         };
256 };
257
258 struct ieee802154_llsec_key {
259         u8 frame_types;
260         u32 cmd_frame_ids;
261         u8 key[IEEE802154_LLSEC_KEY_SIZE];
262 };
263
264 struct ieee802154_llsec_key_entry {
265         struct list_head list;
266
267         struct ieee802154_llsec_key_id id;
268         struct ieee802154_llsec_key *key;
269 };
270
271 struct ieee802154_llsec_device_key {
272         struct list_head list;
273
274         struct ieee802154_llsec_key_id key_id;
275         u32 frame_counter;
276 };
277
278 enum {
279         IEEE802154_LLSEC_DEVKEY_IGNORE,
280         IEEE802154_LLSEC_DEVKEY_RESTRICT,
281         IEEE802154_LLSEC_DEVKEY_RECORD,
282
283         __IEEE802154_LLSEC_DEVKEY_MAX,
284 };
285
286 struct ieee802154_llsec_device {
287         struct list_head list;
288
289         __le16 pan_id;
290         __le16 short_addr;
291         __le64 hwaddr;
292         u32 frame_counter;
293         bool seclevel_exempt;
294
295         u8 key_mode;
296         struct list_head keys;
297 };
298
299 struct ieee802154_llsec_seclevel {
300         struct list_head list;
301
302         u8 frame_type;
303         u8 cmd_frame_id;
304         bool device_override;
305         u32 sec_levels;
306 };
307
308 struct ieee802154_llsec_params {
309         bool enabled;
310
311         __be32 frame_counter;
312         u8 out_level;
313         struct ieee802154_llsec_key_id out_key;
314
315         __le64 default_key_source;
316
317         __le16 pan_id;
318         __le64 hwaddr;
319         __le64 coord_hwaddr;
320         __le16 coord_shortaddr;
321 };
322
323 struct ieee802154_llsec_table {
324         struct list_head keys;
325         struct list_head devices;
326         struct list_head security_levels;
327 };
328
329 #define IEEE802154_MAC_SCAN_ED          0
330 #define IEEE802154_MAC_SCAN_ACTIVE      1
331 #define IEEE802154_MAC_SCAN_PASSIVE     2
332 #define IEEE802154_MAC_SCAN_ORPHAN      3
333
334 struct ieee802154_mac_params {
335         s8 transmit_power;
336         u8 min_be;
337         u8 max_be;
338         u8 csma_retries;
339         s8 frame_retries;
340
341         bool lbt;
342         struct wpan_phy_cca cca;
343         s32 cca_ed_level;
344 };
345
346 struct wpan_phy;
347
348 enum {
349         IEEE802154_LLSEC_PARAM_ENABLED          = BIT(0),
350         IEEE802154_LLSEC_PARAM_FRAME_COUNTER    = BIT(1),
351         IEEE802154_LLSEC_PARAM_OUT_LEVEL        = BIT(2),
352         IEEE802154_LLSEC_PARAM_OUT_KEY          = BIT(3),
353         IEEE802154_LLSEC_PARAM_KEY_SOURCE       = BIT(4),
354         IEEE802154_LLSEC_PARAM_PAN_ID           = BIT(5),
355         IEEE802154_LLSEC_PARAM_HWADDR           = BIT(6),
356         IEEE802154_LLSEC_PARAM_COORD_HWADDR     = BIT(7),
357         IEEE802154_LLSEC_PARAM_COORD_SHORTADDR  = BIT(8),
358 };
359
360 struct ieee802154_llsec_ops {
361         int (*get_params)(struct net_device *dev,
362                           struct ieee802154_llsec_params *params);
363         int (*set_params)(struct net_device *dev,
364                           const struct ieee802154_llsec_params *params,
365                           int changed);
366
367         int (*add_key)(struct net_device *dev,
368                        const struct ieee802154_llsec_key_id *id,
369                        const struct ieee802154_llsec_key *key);
370         int (*del_key)(struct net_device *dev,
371                        const struct ieee802154_llsec_key_id *id);
372
373         int (*add_dev)(struct net_device *dev,
374                        const struct ieee802154_llsec_device *llsec_dev);
375         int (*del_dev)(struct net_device *dev, __le64 dev_addr);
376
377         int (*add_devkey)(struct net_device *dev,
378                           __le64 device_addr,
379                           const struct ieee802154_llsec_device_key *key);
380         int (*del_devkey)(struct net_device *dev,
381                           __le64 device_addr,
382                           const struct ieee802154_llsec_device_key *key);
383
384         int (*add_seclevel)(struct net_device *dev,
385                             const struct ieee802154_llsec_seclevel *sl);
386         int (*del_seclevel)(struct net_device *dev,
387                             const struct ieee802154_llsec_seclevel *sl);
388
389         void (*lock_table)(struct net_device *dev);
390         void (*get_table)(struct net_device *dev,
391                           struct ieee802154_llsec_table **t);
392         void (*unlock_table)(struct net_device *dev);
393 };
394 /*
395  * This should be located at net_device->ml_priv
396  *
397  * get_phy should increment the reference counting on returned phy.
398  * Use wpan_wpy_put to put that reference.
399  */
400 struct ieee802154_mlme_ops {
401         /* The following fields are optional (can be NULL). */
402
403         int (*assoc_req)(struct net_device *dev,
404                         struct ieee802154_addr *addr,
405                         u8 channel, u8 page, u8 cap);
406         int (*assoc_resp)(struct net_device *dev,
407                         struct ieee802154_addr *addr,
408                         __le16 short_addr, u8 status);
409         int (*disassoc_req)(struct net_device *dev,
410                         struct ieee802154_addr *addr,
411                         u8 reason);
412         int (*start_req)(struct net_device *dev,
413                         struct ieee802154_addr *addr,
414                         u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
415                         u8 pan_coord, u8 blx, u8 coord_realign);
416         int (*scan_req)(struct net_device *dev,
417                         u8 type, u32 channels, u8 page, u8 duration);
418
419         int (*set_mac_params)(struct net_device *dev,
420                               const struct ieee802154_mac_params *params);
421         void (*get_mac_params)(struct net_device *dev,
422                                struct ieee802154_mac_params *params);
423
424         struct ieee802154_llsec_ops *llsec;
425 };
426
427 static inline struct ieee802154_mlme_ops *
428 ieee802154_mlme_ops(const struct net_device *dev)
429 {
430         return dev->ml_priv;
431 }
432
433 #endif