xref: /linux/include/net/ieee802154_netdev.h (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
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
434