xref: /openbmc/linux/net/ieee802154/nl802154.c (revision c699ce1a)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *
4  * Authors:
5  * Alexander Aring <aar@pengutronix.de>
6  *
7  * Based on: net/wireless/nl80211.c
8  */
9 
10 #include <linux/rtnetlink.h>
11 
12 #include <net/cfg802154.h>
13 #include <net/genetlink.h>
14 #include <net/mac802154.h>
15 #include <net/netlink.h>
16 #include <net/nl802154.h>
17 #include <net/sock.h>
18 
19 #include "nl802154.h"
20 #include "rdev-ops.h"
21 #include "core.h"
22 
23 /* the netlink family */
24 static struct genl_family nl802154_fam;
25 
26 /* multicast groups */
27 enum nl802154_multicast_groups {
28 	NL802154_MCGRP_CONFIG,
29 	NL802154_MCGRP_SCAN,
30 };
31 
32 static const struct genl_multicast_group nl802154_mcgrps[] = {
33 	[NL802154_MCGRP_CONFIG] = { .name = "config", },
34 	[NL802154_MCGRP_SCAN] = { .name = "scan", },
35 };
36 
37 /* returns ERR_PTR values */
38 static struct wpan_dev *
39 __cfg802154_wpan_dev_from_attrs(struct net *netns, struct nlattr **attrs)
40 {
41 	struct cfg802154_registered_device *rdev;
42 	struct wpan_dev *result = NULL;
43 	bool have_ifidx = attrs[NL802154_ATTR_IFINDEX];
44 	bool have_wpan_dev_id = attrs[NL802154_ATTR_WPAN_DEV];
45 	u64 wpan_dev_id;
46 	int wpan_phy_idx = -1;
47 	int ifidx = -1;
48 
49 	ASSERT_RTNL();
50 
51 	if (!have_ifidx && !have_wpan_dev_id)
52 		return ERR_PTR(-EINVAL);
53 
54 	if (have_ifidx)
55 		ifidx = nla_get_u32(attrs[NL802154_ATTR_IFINDEX]);
56 	if (have_wpan_dev_id) {
57 		wpan_dev_id = nla_get_u64(attrs[NL802154_ATTR_WPAN_DEV]);
58 		wpan_phy_idx = wpan_dev_id >> 32;
59 	}
60 
61 	list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
62 		struct wpan_dev *wpan_dev;
63 
64 		if (wpan_phy_net(&rdev->wpan_phy) != netns)
65 			continue;
66 
67 		if (have_wpan_dev_id && rdev->wpan_phy_idx != wpan_phy_idx)
68 			continue;
69 
70 		list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) {
71 			if (have_ifidx && wpan_dev->netdev &&
72 			    wpan_dev->netdev->ifindex == ifidx) {
73 				result = wpan_dev;
74 				break;
75 			}
76 			if (have_wpan_dev_id &&
77 			    wpan_dev->identifier == (u32)wpan_dev_id) {
78 				result = wpan_dev;
79 				break;
80 			}
81 		}
82 
83 		if (result)
84 			break;
85 	}
86 
87 	if (result)
88 		return result;
89 
90 	return ERR_PTR(-ENODEV);
91 }
92 
93 static struct cfg802154_registered_device *
94 __cfg802154_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
95 {
96 	struct cfg802154_registered_device *rdev = NULL, *tmp;
97 	struct net_device *netdev;
98 
99 	ASSERT_RTNL();
100 
101 	if (!attrs[NL802154_ATTR_WPAN_PHY] &&
102 	    !attrs[NL802154_ATTR_IFINDEX] &&
103 	    !attrs[NL802154_ATTR_WPAN_DEV])
104 		return ERR_PTR(-EINVAL);
105 
106 	if (attrs[NL802154_ATTR_WPAN_PHY])
107 		rdev = cfg802154_rdev_by_wpan_phy_idx(
108 				nla_get_u32(attrs[NL802154_ATTR_WPAN_PHY]));
109 
110 	if (attrs[NL802154_ATTR_WPAN_DEV]) {
111 		u64 wpan_dev_id = nla_get_u64(attrs[NL802154_ATTR_WPAN_DEV]);
112 		struct wpan_dev *wpan_dev;
113 		bool found = false;
114 
115 		tmp = cfg802154_rdev_by_wpan_phy_idx(wpan_dev_id >> 32);
116 		if (tmp) {
117 			/* make sure wpan_dev exists */
118 			list_for_each_entry(wpan_dev, &tmp->wpan_dev_list, list) {
119 				if (wpan_dev->identifier != (u32)wpan_dev_id)
120 					continue;
121 				found = true;
122 				break;
123 			}
124 
125 			if (!found)
126 				tmp = NULL;
127 
128 			if (rdev && tmp != rdev)
129 				return ERR_PTR(-EINVAL);
130 			rdev = tmp;
131 		}
132 	}
133 
134 	if (attrs[NL802154_ATTR_IFINDEX]) {
135 		int ifindex = nla_get_u32(attrs[NL802154_ATTR_IFINDEX]);
136 
137 		netdev = __dev_get_by_index(netns, ifindex);
138 		if (netdev) {
139 			if (netdev->ieee802154_ptr)
140 				tmp = wpan_phy_to_rdev(
141 						netdev->ieee802154_ptr->wpan_phy);
142 			else
143 				tmp = NULL;
144 
145 			/* not wireless device -- return error */
146 			if (!tmp)
147 				return ERR_PTR(-EINVAL);
148 
149 			/* mismatch -- return error */
150 			if (rdev && tmp != rdev)
151 				return ERR_PTR(-EINVAL);
152 
153 			rdev = tmp;
154 		}
155 	}
156 
157 	if (!rdev)
158 		return ERR_PTR(-ENODEV);
159 
160 	if (netns != wpan_phy_net(&rdev->wpan_phy))
161 		return ERR_PTR(-ENODEV);
162 
163 	return rdev;
164 }
165 
166 /* This function returns a pointer to the driver
167  * that the genl_info item that is passed refers to.
168  *
169  * The result of this can be a PTR_ERR and hence must
170  * be checked with IS_ERR() for errors.
171  */
172 static struct cfg802154_registered_device *
173 cfg802154_get_dev_from_info(struct net *netns, struct genl_info *info)
174 {
175 	return __cfg802154_rdev_from_attrs(netns, info->attrs);
176 }
177 
178 /* policy for the attributes */
179 static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
180 	[NL802154_ATTR_WPAN_PHY] = { .type = NLA_U32 },
181 	[NL802154_ATTR_WPAN_PHY_NAME] = { .type = NLA_NUL_STRING,
182 					  .len = 20-1 },
183 
184 	[NL802154_ATTR_IFINDEX] = { .type = NLA_U32 },
185 	[NL802154_ATTR_IFTYPE] = { .type = NLA_U32 },
186 	[NL802154_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
187 
188 	[NL802154_ATTR_WPAN_DEV] = { .type = NLA_U64 },
189 
190 	[NL802154_ATTR_PAGE] = { .type = NLA_U8, },
191 	[NL802154_ATTR_CHANNEL] = { .type = NLA_U8, },
192 
193 	[NL802154_ATTR_TX_POWER] = { .type = NLA_S32, },
194 
195 	[NL802154_ATTR_CCA_MODE] = { .type = NLA_U32, },
196 	[NL802154_ATTR_CCA_OPT] = { .type = NLA_U32, },
197 	[NL802154_ATTR_CCA_ED_LEVEL] = { .type = NLA_S32, },
198 
199 	[NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, },
200 
201 	[NL802154_ATTR_PAN_ID] = { .type = NLA_U16, },
202 	[NL802154_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 },
203 	[NL802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
204 
205 	[NL802154_ATTR_MIN_BE] = { .type = NLA_U8, },
206 	[NL802154_ATTR_MAX_BE] = { .type = NLA_U8, },
207 	[NL802154_ATTR_MAX_CSMA_BACKOFFS] = { .type = NLA_U8, },
208 
209 	[NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, },
210 
211 	[NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, },
212 
213 	[NL802154_ATTR_WPAN_PHY_CAPS] = { .type = NLA_NESTED },
214 
215 	[NL802154_ATTR_SUPPORTED_COMMANDS] = { .type = NLA_NESTED },
216 
217 	[NL802154_ATTR_ACKREQ_DEFAULT] = { .type = NLA_U8 },
218 
219 	[NL802154_ATTR_PID] = { .type = NLA_U32 },
220 	[NL802154_ATTR_NETNS_FD] = { .type = NLA_U32 },
221 
222 	[NL802154_ATTR_COORDINATOR] = { .type = NLA_NESTED },
223 
224 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
225 	[NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, },
226 	[NL802154_ATTR_SEC_OUT_LEVEL] = { .type = NLA_U32, },
227 	[NL802154_ATTR_SEC_OUT_KEY_ID] = { .type = NLA_NESTED, },
228 	[NL802154_ATTR_SEC_FRAME_COUNTER] = { .type = NLA_U32 },
229 
230 	[NL802154_ATTR_SEC_LEVEL] = { .type = NLA_NESTED },
231 	[NL802154_ATTR_SEC_DEVICE] = { .type = NLA_NESTED },
232 	[NL802154_ATTR_SEC_DEVKEY] = { .type = NLA_NESTED },
233 	[NL802154_ATTR_SEC_KEY] = { .type = NLA_NESTED },
234 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
235 };
236 
237 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
238 static int
239 nl802154_prepare_wpan_dev_dump(struct sk_buff *skb,
240 			       struct netlink_callback *cb,
241 			       struct cfg802154_registered_device **rdev,
242 			       struct wpan_dev **wpan_dev)
243 {
244 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
245 	int err;
246 
247 	rtnl_lock();
248 
249 	if (!cb->args[0]) {
250 		*wpan_dev = __cfg802154_wpan_dev_from_attrs(sock_net(skb->sk),
251 							    info->attrs);
252 		if (IS_ERR(*wpan_dev)) {
253 			err = PTR_ERR(*wpan_dev);
254 			goto out_unlock;
255 		}
256 		*rdev = wpan_phy_to_rdev((*wpan_dev)->wpan_phy);
257 		/* 0 is the first index - add 1 to parse only once */
258 		cb->args[0] = (*rdev)->wpan_phy_idx + 1;
259 		cb->args[1] = (*wpan_dev)->identifier;
260 	} else {
261 		/* subtract the 1 again here */
262 		struct wpan_phy *wpan_phy = wpan_phy_idx_to_wpan_phy(cb->args[0] - 1);
263 		struct wpan_dev *tmp;
264 
265 		if (!wpan_phy) {
266 			err = -ENODEV;
267 			goto out_unlock;
268 		}
269 		*rdev = wpan_phy_to_rdev(wpan_phy);
270 		*wpan_dev = NULL;
271 
272 		list_for_each_entry(tmp, &(*rdev)->wpan_dev_list, list) {
273 			if (tmp->identifier == cb->args[1]) {
274 				*wpan_dev = tmp;
275 				break;
276 			}
277 		}
278 
279 		if (!*wpan_dev) {
280 			err = -ENODEV;
281 			goto out_unlock;
282 		}
283 	}
284 
285 	return 0;
286  out_unlock:
287 	rtnl_unlock();
288 	return err;
289 }
290 
291 static void
292 nl802154_finish_wpan_dev_dump(struct cfg802154_registered_device *rdev)
293 {
294 	rtnl_unlock();
295 }
296 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
297 
298 /* message building helper */
299 static inline void *nl802154hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
300 				    int flags, u8 cmd)
301 {
302 	/* since there is no private header just add the generic one */
303 	return genlmsg_put(skb, portid, seq, &nl802154_fam, flags, cmd);
304 }
305 
306 static int
307 nl802154_put_flags(struct sk_buff *msg, int attr, u32 mask)
308 {
309 	struct nlattr *nl_flags = nla_nest_start_noflag(msg, attr);
310 	int i;
311 
312 	if (!nl_flags)
313 		return -ENOBUFS;
314 
315 	i = 0;
316 	while (mask) {
317 		if ((mask & 1) && nla_put_flag(msg, i))
318 			return -ENOBUFS;
319 
320 		mask >>= 1;
321 		i++;
322 	}
323 
324 	nla_nest_end(msg, nl_flags);
325 	return 0;
326 }
327 
328 static int
329 nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev,
330 				struct sk_buff *msg)
331 {
332 	struct nlattr *nl_page;
333 	unsigned long page;
334 
335 	nl_page = nla_nest_start_noflag(msg, NL802154_ATTR_CHANNELS_SUPPORTED);
336 	if (!nl_page)
337 		return -ENOBUFS;
338 
339 	for (page = 0; page <= IEEE802154_MAX_PAGE; page++) {
340 		if (nla_put_u32(msg, NL802154_ATTR_SUPPORTED_CHANNEL,
341 				rdev->wpan_phy.supported.channels[page]))
342 			return -ENOBUFS;
343 	}
344 	nla_nest_end(msg, nl_page);
345 
346 	return 0;
347 }
348 
349 static int
350 nl802154_put_capabilities(struct sk_buff *msg,
351 			  struct cfg802154_registered_device *rdev)
352 {
353 	const struct wpan_phy_supported *caps = &rdev->wpan_phy.supported;
354 	struct nlattr *nl_caps, *nl_channels;
355 	int i;
356 
357 	nl_caps = nla_nest_start_noflag(msg, NL802154_ATTR_WPAN_PHY_CAPS);
358 	if (!nl_caps)
359 		return -ENOBUFS;
360 
361 	nl_channels = nla_nest_start_noflag(msg, NL802154_CAP_ATTR_CHANNELS);
362 	if (!nl_channels)
363 		return -ENOBUFS;
364 
365 	for (i = 0; i <= IEEE802154_MAX_PAGE; i++) {
366 		if (caps->channels[i]) {
367 			if (nl802154_put_flags(msg, i, caps->channels[i]))
368 				return -ENOBUFS;
369 		}
370 	}
371 
372 	nla_nest_end(msg, nl_channels);
373 
374 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) {
375 		struct nlattr *nl_ed_lvls;
376 
377 		nl_ed_lvls = nla_nest_start_noflag(msg,
378 						   NL802154_CAP_ATTR_CCA_ED_LEVELS);
379 		if (!nl_ed_lvls)
380 			return -ENOBUFS;
381 
382 		for (i = 0; i < caps->cca_ed_levels_size; i++) {
383 			if (nla_put_s32(msg, i, caps->cca_ed_levels[i]))
384 				return -ENOBUFS;
385 		}
386 
387 		nla_nest_end(msg, nl_ed_lvls);
388 	}
389 
390 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) {
391 		struct nlattr *nl_tx_pwrs;
392 
393 		nl_tx_pwrs = nla_nest_start_noflag(msg,
394 						   NL802154_CAP_ATTR_TX_POWERS);
395 		if (!nl_tx_pwrs)
396 			return -ENOBUFS;
397 
398 		for (i = 0; i < caps->tx_powers_size; i++) {
399 			if (nla_put_s32(msg, i, caps->tx_powers[i]))
400 				return -ENOBUFS;
401 		}
402 
403 		nla_nest_end(msg, nl_tx_pwrs);
404 	}
405 
406 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) {
407 		if (nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_MODES,
408 				       caps->cca_modes) ||
409 		    nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_OPTS,
410 				       caps->cca_opts))
411 			return -ENOBUFS;
412 	}
413 
414 	if (nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MINBE, caps->min_minbe) ||
415 	    nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MINBE, caps->max_minbe) ||
416 	    nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MAXBE, caps->min_maxbe) ||
417 	    nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MAXBE, caps->max_maxbe) ||
418 	    nla_put_u8(msg, NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS,
419 		       caps->min_csma_backoffs) ||
420 	    nla_put_u8(msg, NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS,
421 		       caps->max_csma_backoffs) ||
422 	    nla_put_s8(msg, NL802154_CAP_ATTR_MIN_FRAME_RETRIES,
423 		       caps->min_frame_retries) ||
424 	    nla_put_s8(msg, NL802154_CAP_ATTR_MAX_FRAME_RETRIES,
425 		       caps->max_frame_retries) ||
426 	    nl802154_put_flags(msg, NL802154_CAP_ATTR_IFTYPES,
427 			       caps->iftypes) ||
428 	    nla_put_u32(msg, NL802154_CAP_ATTR_LBT, caps->lbt))
429 		return -ENOBUFS;
430 
431 	nla_nest_end(msg, nl_caps);
432 
433 	return 0;
434 }
435 
436 static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev,
437 				  enum nl802154_commands cmd,
438 				  struct sk_buff *msg, u32 portid, u32 seq,
439 				  int flags)
440 {
441 	struct nlattr *nl_cmds;
442 	void *hdr;
443 	int i;
444 
445 	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
446 	if (!hdr)
447 		return -ENOBUFS;
448 
449 	if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) ||
450 	    nla_put_string(msg, NL802154_ATTR_WPAN_PHY_NAME,
451 			   wpan_phy_name(&rdev->wpan_phy)) ||
452 	    nla_put_u32(msg, NL802154_ATTR_GENERATION,
453 			cfg802154_rdev_list_generation))
454 		goto nla_put_failure;
455 
456 	if (cmd != NL802154_CMD_NEW_WPAN_PHY)
457 		goto finish;
458 
459 	/* DUMP PHY PIB */
460 
461 	/* current channel settings */
462 	if (nla_put_u8(msg, NL802154_ATTR_PAGE,
463 		       rdev->wpan_phy.current_page) ||
464 	    nla_put_u8(msg, NL802154_ATTR_CHANNEL,
465 		       rdev->wpan_phy.current_channel))
466 		goto nla_put_failure;
467 
468 	/* TODO remove this behaviour, we still keep support it for a while
469 	 * so users can change the behaviour to the new one.
470 	 */
471 	if (nl802154_send_wpan_phy_channels(rdev, msg))
472 		goto nla_put_failure;
473 
474 	/* cca mode */
475 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) {
476 		if (nla_put_u32(msg, NL802154_ATTR_CCA_MODE,
477 				rdev->wpan_phy.cca.mode))
478 			goto nla_put_failure;
479 
480 		if (rdev->wpan_phy.cca.mode == NL802154_CCA_ENERGY_CARRIER) {
481 			if (nla_put_u32(msg, NL802154_ATTR_CCA_OPT,
482 					rdev->wpan_phy.cca.opt))
483 				goto nla_put_failure;
484 		}
485 	}
486 
487 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) {
488 		if (nla_put_s32(msg, NL802154_ATTR_TX_POWER,
489 				rdev->wpan_phy.transmit_power))
490 			goto nla_put_failure;
491 	}
492 
493 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) {
494 		if (nla_put_s32(msg, NL802154_ATTR_CCA_ED_LEVEL,
495 				rdev->wpan_phy.cca_ed_level))
496 			goto nla_put_failure;
497 	}
498 
499 	if (nl802154_put_capabilities(msg, rdev))
500 		goto nla_put_failure;
501 
502 	nl_cmds = nla_nest_start_noflag(msg, NL802154_ATTR_SUPPORTED_COMMANDS);
503 	if (!nl_cmds)
504 		goto nla_put_failure;
505 
506 	i = 0;
507 #define CMD(op, n)							\
508 	do {								\
509 		if (rdev->ops->op) {					\
510 			i++;						\
511 			if (nla_put_u32(msg, i, NL802154_CMD_ ## n))	\
512 				goto nla_put_failure;			\
513 		}							\
514 	} while (0)
515 
516 	CMD(add_virtual_intf, NEW_INTERFACE);
517 	CMD(del_virtual_intf, DEL_INTERFACE);
518 	CMD(set_channel, SET_CHANNEL);
519 	CMD(set_pan_id, SET_PAN_ID);
520 	CMD(set_short_addr, SET_SHORT_ADDR);
521 	CMD(set_backoff_exponent, SET_BACKOFF_EXPONENT);
522 	CMD(set_max_csma_backoffs, SET_MAX_CSMA_BACKOFFS);
523 	CMD(set_max_frame_retries, SET_MAX_FRAME_RETRIES);
524 	CMD(set_lbt_mode, SET_LBT_MODE);
525 	CMD(set_ackreq_default, SET_ACKREQ_DEFAULT);
526 
527 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER)
528 		CMD(set_tx_power, SET_TX_POWER);
529 
530 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL)
531 		CMD(set_cca_ed_level, SET_CCA_ED_LEVEL);
532 
533 	if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE)
534 		CMD(set_cca_mode, SET_CCA_MODE);
535 
536 #undef CMD
537 	nla_nest_end(msg, nl_cmds);
538 
539 finish:
540 	genlmsg_end(msg, hdr);
541 	return 0;
542 
543 nla_put_failure:
544 	genlmsg_cancel(msg, hdr);
545 	return -EMSGSIZE;
546 }
547 
548 struct nl802154_dump_wpan_phy_state {
549 	s64 filter_wpan_phy;
550 	long start;
551 
552 };
553 
554 static int nl802154_dump_wpan_phy_parse(struct sk_buff *skb,
555 					struct netlink_callback *cb,
556 					struct nl802154_dump_wpan_phy_state *state)
557 {
558 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
559 	struct nlattr **tb = info->attrs;
560 
561 	if (tb[NL802154_ATTR_WPAN_PHY])
562 		state->filter_wpan_phy = nla_get_u32(tb[NL802154_ATTR_WPAN_PHY]);
563 	if (tb[NL802154_ATTR_WPAN_DEV])
564 		state->filter_wpan_phy = nla_get_u64(tb[NL802154_ATTR_WPAN_DEV]) >> 32;
565 	if (tb[NL802154_ATTR_IFINDEX]) {
566 		struct net_device *netdev;
567 		struct cfg802154_registered_device *rdev;
568 		int ifidx = nla_get_u32(tb[NL802154_ATTR_IFINDEX]);
569 
570 		netdev = __dev_get_by_index(&init_net, ifidx);
571 		if (!netdev)
572 			return -ENODEV;
573 		if (netdev->ieee802154_ptr) {
574 			rdev = wpan_phy_to_rdev(
575 					netdev->ieee802154_ptr->wpan_phy);
576 			state->filter_wpan_phy = rdev->wpan_phy_idx;
577 		}
578 	}
579 
580 	return 0;
581 }
582 
583 static int
584 nl802154_dump_wpan_phy(struct sk_buff *skb, struct netlink_callback *cb)
585 {
586 	int idx = 0, ret;
587 	struct nl802154_dump_wpan_phy_state *state = (void *)cb->args[0];
588 	struct cfg802154_registered_device *rdev;
589 
590 	rtnl_lock();
591 	if (!state) {
592 		state = kzalloc(sizeof(*state), GFP_KERNEL);
593 		if (!state) {
594 			rtnl_unlock();
595 			return -ENOMEM;
596 		}
597 		state->filter_wpan_phy = -1;
598 		ret = nl802154_dump_wpan_phy_parse(skb, cb, state);
599 		if (ret) {
600 			kfree(state);
601 			rtnl_unlock();
602 			return ret;
603 		}
604 		cb->args[0] = (long)state;
605 	}
606 
607 	list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
608 		if (!net_eq(wpan_phy_net(&rdev->wpan_phy), sock_net(skb->sk)))
609 			continue;
610 		if (++idx <= state->start)
611 			continue;
612 		if (state->filter_wpan_phy != -1 &&
613 		    state->filter_wpan_phy != rdev->wpan_phy_idx)
614 			continue;
615 		/* attempt to fit multiple wpan_phy data chunks into the skb */
616 		ret = nl802154_send_wpan_phy(rdev,
617 					     NL802154_CMD_NEW_WPAN_PHY,
618 					     skb,
619 					     NETLINK_CB(cb->skb).portid,
620 					     cb->nlh->nlmsg_seq, NLM_F_MULTI);
621 		if (ret < 0) {
622 			if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
623 			    !skb->len && cb->min_dump_alloc < 4096) {
624 				cb->min_dump_alloc = 4096;
625 				rtnl_unlock();
626 				return 1;
627 			}
628 			idx--;
629 			break;
630 		}
631 		break;
632 	}
633 	rtnl_unlock();
634 
635 	state->start = idx;
636 
637 	return skb->len;
638 }
639 
640 static int nl802154_dump_wpan_phy_done(struct netlink_callback *cb)
641 {
642 	kfree((void *)cb->args[0]);
643 	return 0;
644 }
645 
646 static int nl802154_get_wpan_phy(struct sk_buff *skb, struct genl_info *info)
647 {
648 	struct sk_buff *msg;
649 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
650 
651 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
652 	if (!msg)
653 		return -ENOMEM;
654 
655 	if (nl802154_send_wpan_phy(rdev, NL802154_CMD_NEW_WPAN_PHY, msg,
656 				   info->snd_portid, info->snd_seq, 0) < 0) {
657 		nlmsg_free(msg);
658 		return -ENOBUFS;
659 	}
660 
661 	return genlmsg_reply(msg, info);
662 }
663 
664 static inline u64 wpan_dev_id(struct wpan_dev *wpan_dev)
665 {
666 	return (u64)wpan_dev->identifier |
667 	       ((u64)wpan_phy_to_rdev(wpan_dev->wpan_phy)->wpan_phy_idx << 32);
668 }
669 
670 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
671 #include <net/ieee802154_netdev.h>
672 
673 static int
674 ieee802154_llsec_send_key_id(struct sk_buff *msg,
675 			     const struct ieee802154_llsec_key_id *desc)
676 {
677 	struct nlattr *nl_dev_addr;
678 
679 	if (nla_put_u32(msg, NL802154_KEY_ID_ATTR_MODE, desc->mode))
680 		return -ENOBUFS;
681 
682 	switch (desc->mode) {
683 	case NL802154_KEY_ID_MODE_IMPLICIT:
684 		nl_dev_addr = nla_nest_start_noflag(msg,
685 						    NL802154_KEY_ID_ATTR_IMPLICIT);
686 		if (!nl_dev_addr)
687 			return -ENOBUFS;
688 
689 		if (nla_put_le16(msg, NL802154_DEV_ADDR_ATTR_PAN_ID,
690 				 desc->device_addr.pan_id) ||
691 		    nla_put_u32(msg,  NL802154_DEV_ADDR_ATTR_MODE,
692 				desc->device_addr.mode))
693 			return -ENOBUFS;
694 
695 		switch (desc->device_addr.mode) {
696 		case NL802154_DEV_ADDR_SHORT:
697 			if (nla_put_le16(msg, NL802154_DEV_ADDR_ATTR_SHORT,
698 					 desc->device_addr.short_addr))
699 				return -ENOBUFS;
700 			break;
701 		case NL802154_DEV_ADDR_EXTENDED:
702 			if (nla_put_le64(msg, NL802154_DEV_ADDR_ATTR_EXTENDED,
703 					 desc->device_addr.extended_addr,
704 					 NL802154_DEV_ADDR_ATTR_PAD))
705 				return -ENOBUFS;
706 			break;
707 		default:
708 			/* userspace should handle unknown */
709 			break;
710 		}
711 
712 		nla_nest_end(msg, nl_dev_addr);
713 		break;
714 	case NL802154_KEY_ID_MODE_INDEX:
715 		break;
716 	case NL802154_KEY_ID_MODE_INDEX_SHORT:
717 		/* TODO renmae short_source? */
718 		if (nla_put_le32(msg, NL802154_KEY_ID_ATTR_SOURCE_SHORT,
719 				 desc->short_source))
720 			return -ENOBUFS;
721 		break;
722 	case NL802154_KEY_ID_MODE_INDEX_EXTENDED:
723 		if (nla_put_le64(msg, NL802154_KEY_ID_ATTR_SOURCE_EXTENDED,
724 				 desc->extended_source,
725 				 NL802154_KEY_ID_ATTR_PAD))
726 			return -ENOBUFS;
727 		break;
728 	default:
729 		/* userspace should handle unknown */
730 		break;
731 	}
732 
733 	/* TODO key_id to key_idx ? Check naming */
734 	if (desc->mode != NL802154_KEY_ID_MODE_IMPLICIT) {
735 		if (nla_put_u8(msg, NL802154_KEY_ID_ATTR_INDEX, desc->id))
736 			return -ENOBUFS;
737 	}
738 
739 	return 0;
740 }
741 
742 static int nl802154_get_llsec_params(struct sk_buff *msg,
743 				     struct cfg802154_registered_device *rdev,
744 				     struct wpan_dev *wpan_dev)
745 {
746 	struct nlattr *nl_key_id;
747 	struct ieee802154_llsec_params params;
748 	int ret;
749 
750 	ret = rdev_get_llsec_params(rdev, wpan_dev, &params);
751 	if (ret < 0)
752 		return ret;
753 
754 	if (nla_put_u8(msg, NL802154_ATTR_SEC_ENABLED, params.enabled) ||
755 	    nla_put_u32(msg, NL802154_ATTR_SEC_OUT_LEVEL, params.out_level) ||
756 	    nla_put_be32(msg, NL802154_ATTR_SEC_FRAME_COUNTER,
757 			 params.frame_counter))
758 		return -ENOBUFS;
759 
760 	nl_key_id = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_OUT_KEY_ID);
761 	if (!nl_key_id)
762 		return -ENOBUFS;
763 
764 	ret = ieee802154_llsec_send_key_id(msg, &params.out_key);
765 	if (ret < 0)
766 		return ret;
767 
768 	nla_nest_end(msg, nl_key_id);
769 
770 	return 0;
771 }
772 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
773 
774 static int
775 nl802154_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
776 		    struct cfg802154_registered_device *rdev,
777 		    struct wpan_dev *wpan_dev)
778 {
779 	struct net_device *dev = wpan_dev->netdev;
780 	void *hdr;
781 
782 	hdr = nl802154hdr_put(msg, portid, seq, flags,
783 			      NL802154_CMD_NEW_INTERFACE);
784 	if (!hdr)
785 		return -1;
786 
787 	if (dev &&
788 	    (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex) ||
789 	     nla_put_string(msg, NL802154_ATTR_IFNAME, dev->name)))
790 		goto nla_put_failure;
791 
792 	if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) ||
793 	    nla_put_u32(msg, NL802154_ATTR_IFTYPE, wpan_dev->iftype) ||
794 	    nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV,
795 			      wpan_dev_id(wpan_dev), NL802154_ATTR_PAD) ||
796 	    nla_put_u32(msg, NL802154_ATTR_GENERATION,
797 			rdev->devlist_generation ^
798 			(cfg802154_rdev_list_generation << 2)))
799 		goto nla_put_failure;
800 
801 	/* address settings */
802 	if (nla_put_le64(msg, NL802154_ATTR_EXTENDED_ADDR,
803 			 wpan_dev->extended_addr,
804 			 NL802154_ATTR_PAD) ||
805 	    nla_put_le16(msg, NL802154_ATTR_SHORT_ADDR,
806 			 wpan_dev->short_addr) ||
807 	    nla_put_le16(msg, NL802154_ATTR_PAN_ID, wpan_dev->pan_id))
808 		goto nla_put_failure;
809 
810 	/* ARET handling */
811 	if (nla_put_s8(msg, NL802154_ATTR_MAX_FRAME_RETRIES,
812 		       wpan_dev->frame_retries) ||
813 	    nla_put_u8(msg, NL802154_ATTR_MAX_BE, wpan_dev->max_be) ||
814 	    nla_put_u8(msg, NL802154_ATTR_MAX_CSMA_BACKOFFS,
815 		       wpan_dev->csma_retries) ||
816 	    nla_put_u8(msg, NL802154_ATTR_MIN_BE, wpan_dev->min_be))
817 		goto nla_put_failure;
818 
819 	/* listen before transmit */
820 	if (nla_put_u8(msg, NL802154_ATTR_LBT_MODE, wpan_dev->lbt))
821 		goto nla_put_failure;
822 
823 	/* ackreq default behaviour */
824 	if (nla_put_u8(msg, NL802154_ATTR_ACKREQ_DEFAULT, wpan_dev->ackreq))
825 		goto nla_put_failure;
826 
827 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
828 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
829 		goto out;
830 
831 	if (nl802154_get_llsec_params(msg, rdev, wpan_dev) < 0)
832 		goto nla_put_failure;
833 
834 out:
835 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
836 
837 	genlmsg_end(msg, hdr);
838 	return 0;
839 
840 nla_put_failure:
841 	genlmsg_cancel(msg, hdr);
842 	return -EMSGSIZE;
843 }
844 
845 static int
846 nl802154_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
847 {
848 	int wp_idx = 0;
849 	int if_idx = 0;
850 	int wp_start = cb->args[0];
851 	int if_start = cb->args[1];
852 	struct cfg802154_registered_device *rdev;
853 	struct wpan_dev *wpan_dev;
854 
855 	rtnl_lock();
856 	list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
857 		if (!net_eq(wpan_phy_net(&rdev->wpan_phy), sock_net(skb->sk)))
858 			continue;
859 		if (wp_idx < wp_start) {
860 			wp_idx++;
861 			continue;
862 		}
863 		if_idx = 0;
864 
865 		list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) {
866 			if (if_idx < if_start) {
867 				if_idx++;
868 				continue;
869 			}
870 			if (nl802154_send_iface(skb, NETLINK_CB(cb->skb).portid,
871 						cb->nlh->nlmsg_seq, NLM_F_MULTI,
872 						rdev, wpan_dev) < 0) {
873 				goto out;
874 			}
875 			if_idx++;
876 		}
877 
878 		wp_idx++;
879 	}
880 out:
881 	rtnl_unlock();
882 
883 	cb->args[0] = wp_idx;
884 	cb->args[1] = if_idx;
885 
886 	return skb->len;
887 }
888 
889 static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info)
890 {
891 	struct sk_buff *msg;
892 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
893 	struct wpan_dev *wdev = info->user_ptr[1];
894 
895 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
896 	if (!msg)
897 		return -ENOMEM;
898 
899 	if (nl802154_send_iface(msg, info->snd_portid, info->snd_seq, 0,
900 				rdev, wdev) < 0) {
901 		nlmsg_free(msg);
902 		return -ENOBUFS;
903 	}
904 
905 	return genlmsg_reply(msg, info);
906 }
907 
908 static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
909 {
910 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
911 	enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC;
912 	__le64 extended_addr = cpu_to_le64(0x0000000000000000ULL);
913 
914 	/* TODO avoid failing a new interface
915 	 * creation due to pending removal?
916 	 */
917 
918 	if (!info->attrs[NL802154_ATTR_IFNAME])
919 		return -EINVAL;
920 
921 	if (info->attrs[NL802154_ATTR_IFTYPE]) {
922 		type = nla_get_u32(info->attrs[NL802154_ATTR_IFTYPE]);
923 		if (type > NL802154_IFTYPE_MAX ||
924 		    !(rdev->wpan_phy.supported.iftypes & BIT(type)))
925 			return -EINVAL;
926 	}
927 
928 	if (info->attrs[NL802154_ATTR_EXTENDED_ADDR])
929 		extended_addr = nla_get_le64(info->attrs[NL802154_ATTR_EXTENDED_ADDR]);
930 
931 	if (!rdev->ops->add_virtual_intf)
932 		return -EOPNOTSUPP;
933 
934 	return rdev_add_virtual_intf(rdev,
935 				     nla_data(info->attrs[NL802154_ATTR_IFNAME]),
936 				     NET_NAME_USER, type, extended_addr);
937 }
938 
939 static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info)
940 {
941 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
942 	struct wpan_dev *wpan_dev = info->user_ptr[1];
943 
944 	if (!rdev->ops->del_virtual_intf)
945 		return -EOPNOTSUPP;
946 
947 	/* If we remove a wpan device without a netdev then clear
948 	 * user_ptr[1] so that nl802154_post_doit won't dereference it
949 	 * to check if it needs to do dev_put(). Otherwise it crashes
950 	 * since the wpan_dev has been freed, unlike with a netdev where
951 	 * we need the dev_put() for the netdev to really be freed.
952 	 */
953 	if (!wpan_dev->netdev)
954 		info->user_ptr[1] = NULL;
955 
956 	return rdev_del_virtual_intf(rdev, wpan_dev);
957 }
958 
959 static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
960 {
961 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
962 	u8 channel, page;
963 
964 	if (!info->attrs[NL802154_ATTR_PAGE] ||
965 	    !info->attrs[NL802154_ATTR_CHANNEL])
966 		return -EINVAL;
967 
968 	page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]);
969 	channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]);
970 
971 	/* check 802.15.4 constraints */
972 	if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL ||
973 	    !(rdev->wpan_phy.supported.channels[page] & BIT(channel)))
974 		return -EINVAL;
975 
976 	return rdev_set_channel(rdev, page, channel);
977 }
978 
979 static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
980 {
981 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
982 	struct wpan_phy_cca cca;
983 
984 	if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE))
985 		return -EOPNOTSUPP;
986 
987 	if (!info->attrs[NL802154_ATTR_CCA_MODE])
988 		return -EINVAL;
989 
990 	cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]);
991 	/* checking 802.15.4 constraints */
992 	if (cca.mode < NL802154_CCA_ENERGY ||
993 	    cca.mode > NL802154_CCA_ATTR_MAX ||
994 	    !(rdev->wpan_phy.supported.cca_modes & BIT(cca.mode)))
995 		return -EINVAL;
996 
997 	if (cca.mode == NL802154_CCA_ENERGY_CARRIER) {
998 		if (!info->attrs[NL802154_ATTR_CCA_OPT])
999 			return -EINVAL;
1000 
1001 		cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]);
1002 		if (cca.opt > NL802154_CCA_OPT_ATTR_MAX ||
1003 		    !(rdev->wpan_phy.supported.cca_opts & BIT(cca.opt)))
1004 			return -EINVAL;
1005 	}
1006 
1007 	return rdev_set_cca_mode(rdev, &cca);
1008 }
1009 
1010 static int nl802154_set_cca_ed_level(struct sk_buff *skb, struct genl_info *info)
1011 {
1012 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1013 	s32 ed_level;
1014 	int i;
1015 
1016 	if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL))
1017 		return -EOPNOTSUPP;
1018 
1019 	if (!info->attrs[NL802154_ATTR_CCA_ED_LEVEL])
1020 		return -EINVAL;
1021 
1022 	ed_level = nla_get_s32(info->attrs[NL802154_ATTR_CCA_ED_LEVEL]);
1023 
1024 	for (i = 0; i < rdev->wpan_phy.supported.cca_ed_levels_size; i++) {
1025 		if (ed_level == rdev->wpan_phy.supported.cca_ed_levels[i])
1026 			return rdev_set_cca_ed_level(rdev, ed_level);
1027 	}
1028 
1029 	return -EINVAL;
1030 }
1031 
1032 static int nl802154_set_tx_power(struct sk_buff *skb, struct genl_info *info)
1033 {
1034 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1035 	s32 power;
1036 	int i;
1037 
1038 	if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER))
1039 		return -EOPNOTSUPP;
1040 
1041 	if (!info->attrs[NL802154_ATTR_TX_POWER])
1042 		return -EINVAL;
1043 
1044 	power = nla_get_s32(info->attrs[NL802154_ATTR_TX_POWER]);
1045 
1046 	for (i = 0; i < rdev->wpan_phy.supported.tx_powers_size; i++) {
1047 		if (power == rdev->wpan_phy.supported.tx_powers[i])
1048 			return rdev_set_tx_power(rdev, power);
1049 	}
1050 
1051 	return -EINVAL;
1052 }
1053 
1054 static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
1055 {
1056 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1057 	struct net_device *dev = info->user_ptr[1];
1058 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1059 	__le16 pan_id;
1060 
1061 	/* conflict here while tx/rx calls */
1062 	if (netif_running(dev))
1063 		return -EBUSY;
1064 
1065 	if (wpan_dev->lowpan_dev) {
1066 		if (netif_running(wpan_dev->lowpan_dev))
1067 			return -EBUSY;
1068 	}
1069 
1070 	/* don't change address fields on monitor */
1071 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
1072 	    !info->attrs[NL802154_ATTR_PAN_ID])
1073 		return -EINVAL;
1074 
1075 	pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]);
1076 
1077 	/* TODO
1078 	 * I am not sure about to check here on broadcast pan_id.
1079 	 * Broadcast is a valid setting, comment from 802.15.4:
1080 	 * If this value is 0xffff, the device is not associated.
1081 	 *
1082 	 * This could useful to simple deassociate an device.
1083 	 */
1084 	if (pan_id == cpu_to_le16(IEEE802154_PAN_ID_BROADCAST))
1085 		return -EINVAL;
1086 
1087 	return rdev_set_pan_id(rdev, wpan_dev, pan_id);
1088 }
1089 
1090 static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info)
1091 {
1092 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1093 	struct net_device *dev = info->user_ptr[1];
1094 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1095 	__le16 short_addr;
1096 
1097 	/* conflict here while tx/rx calls */
1098 	if (netif_running(dev))
1099 		return -EBUSY;
1100 
1101 	if (wpan_dev->lowpan_dev) {
1102 		if (netif_running(wpan_dev->lowpan_dev))
1103 			return -EBUSY;
1104 	}
1105 
1106 	/* don't change address fields on monitor */
1107 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
1108 	    !info->attrs[NL802154_ATTR_SHORT_ADDR])
1109 		return -EINVAL;
1110 
1111 	short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]);
1112 
1113 	/* TODO
1114 	 * I am not sure about to check here on broadcast short_addr.
1115 	 * Broadcast is a valid setting, comment from 802.15.4:
1116 	 * A value of 0xfffe indicates that the device has
1117 	 * associated but has not been allocated an address. A
1118 	 * value of 0xffff indicates that the device does not
1119 	 * have a short address.
1120 	 *
1121 	 * I think we should allow to set these settings but
1122 	 * don't allow to allow socket communication with it.
1123 	 */
1124 	if (short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC) ||
1125 	    short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST))
1126 		return -EINVAL;
1127 
1128 	return rdev_set_short_addr(rdev, wpan_dev, short_addr);
1129 }
1130 
1131 static int
1132 nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info)
1133 {
1134 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1135 	struct net_device *dev = info->user_ptr[1];
1136 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1137 	u8 min_be, max_be;
1138 
1139 	/* should be set on netif open inside phy settings */
1140 	if (netif_running(dev))
1141 		return -EBUSY;
1142 
1143 	if (!info->attrs[NL802154_ATTR_MIN_BE] ||
1144 	    !info->attrs[NL802154_ATTR_MAX_BE])
1145 		return -EINVAL;
1146 
1147 	min_be = nla_get_u8(info->attrs[NL802154_ATTR_MIN_BE]);
1148 	max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]);
1149 
1150 	/* check 802.15.4 constraints */
1151 	if (min_be < rdev->wpan_phy.supported.min_minbe ||
1152 	    min_be > rdev->wpan_phy.supported.max_minbe ||
1153 	    max_be < rdev->wpan_phy.supported.min_maxbe ||
1154 	    max_be > rdev->wpan_phy.supported.max_maxbe ||
1155 	    min_be > max_be)
1156 		return -EINVAL;
1157 
1158 	return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be);
1159 }
1160 
1161 static int
1162 nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info)
1163 {
1164 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1165 	struct net_device *dev = info->user_ptr[1];
1166 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1167 	u8 max_csma_backoffs;
1168 
1169 	/* conflict here while other running iface settings */
1170 	if (netif_running(dev))
1171 		return -EBUSY;
1172 
1173 	if (!info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS])
1174 		return -EINVAL;
1175 
1176 	max_csma_backoffs = nla_get_u8(
1177 			info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]);
1178 
1179 	/* check 802.15.4 constraints */
1180 	if (max_csma_backoffs < rdev->wpan_phy.supported.min_csma_backoffs ||
1181 	    max_csma_backoffs > rdev->wpan_phy.supported.max_csma_backoffs)
1182 		return -EINVAL;
1183 
1184 	return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs);
1185 }
1186 
1187 static int
1188 nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info)
1189 {
1190 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1191 	struct net_device *dev = info->user_ptr[1];
1192 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1193 	s8 max_frame_retries;
1194 
1195 	if (netif_running(dev))
1196 		return -EBUSY;
1197 
1198 	if (!info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES])
1199 		return -EINVAL;
1200 
1201 	max_frame_retries = nla_get_s8(
1202 			info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]);
1203 
1204 	/* check 802.15.4 constraints */
1205 	if (max_frame_retries < rdev->wpan_phy.supported.min_frame_retries ||
1206 	    max_frame_retries > rdev->wpan_phy.supported.max_frame_retries)
1207 		return -EINVAL;
1208 
1209 	return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries);
1210 }
1211 
1212 static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
1213 {
1214 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1215 	struct net_device *dev = info->user_ptr[1];
1216 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1217 	int mode;
1218 
1219 	if (netif_running(dev))
1220 		return -EBUSY;
1221 
1222 	if (!info->attrs[NL802154_ATTR_LBT_MODE])
1223 		return -EINVAL;
1224 
1225 	mode = nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]);
1226 
1227 	if (mode != 0 && mode != 1)
1228 		return -EINVAL;
1229 
1230 	if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt))
1231 		return -EINVAL;
1232 
1233 	return rdev_set_lbt_mode(rdev, wpan_dev, mode);
1234 }
1235 
1236 static int
1237 nl802154_set_ackreq_default(struct sk_buff *skb, struct genl_info *info)
1238 {
1239 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1240 	struct net_device *dev = info->user_ptr[1];
1241 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1242 	int ackreq;
1243 
1244 	if (netif_running(dev))
1245 		return -EBUSY;
1246 
1247 	if (!info->attrs[NL802154_ATTR_ACKREQ_DEFAULT])
1248 		return -EINVAL;
1249 
1250 	ackreq = nla_get_u8(info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]);
1251 
1252 	if (ackreq != 0 && ackreq != 1)
1253 		return -EINVAL;
1254 
1255 	return rdev_set_ackreq_default(rdev, wpan_dev, ackreq);
1256 }
1257 
1258 static int nl802154_wpan_phy_netns(struct sk_buff *skb, struct genl_info *info)
1259 {
1260 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1261 	struct net *net;
1262 	int err;
1263 
1264 	if (info->attrs[NL802154_ATTR_PID]) {
1265 		u32 pid = nla_get_u32(info->attrs[NL802154_ATTR_PID]);
1266 
1267 		net = get_net_ns_by_pid(pid);
1268 	} else if (info->attrs[NL802154_ATTR_NETNS_FD]) {
1269 		u32 fd = nla_get_u32(info->attrs[NL802154_ATTR_NETNS_FD]);
1270 
1271 		net = get_net_ns_by_fd(fd);
1272 	} else {
1273 		return -EINVAL;
1274 	}
1275 
1276 	if (IS_ERR(net))
1277 		return PTR_ERR(net);
1278 
1279 	err = 0;
1280 
1281 	/* check if anything to do */
1282 	if (!net_eq(wpan_phy_net(&rdev->wpan_phy), net))
1283 		err = cfg802154_switch_netns(rdev, net);
1284 
1285 	put_net(net);
1286 	return err;
1287 }
1288 
1289 static int nl802154_prep_scan_event_msg(struct sk_buff *msg,
1290 					struct cfg802154_registered_device *rdev,
1291 					struct wpan_dev *wpan_dev,
1292 					u32 portid, u32 seq, int flags, u8 cmd,
1293 					struct ieee802154_coord_desc *desc)
1294 {
1295 	struct nlattr *nla;
1296 	void *hdr;
1297 
1298 	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1299 	if (!hdr)
1300 		return -ENOBUFS;
1301 
1302 	if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx))
1303 		goto nla_put_failure;
1304 
1305 	if (wpan_dev->netdev &&
1306 	    nla_put_u32(msg, NL802154_ATTR_IFINDEX, wpan_dev->netdev->ifindex))
1307 		goto nla_put_failure;
1308 
1309 	if (nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV,
1310 			      wpan_dev_id(wpan_dev), NL802154_ATTR_PAD))
1311 		goto nla_put_failure;
1312 
1313 	nla = nla_nest_start_noflag(msg, NL802154_ATTR_COORDINATOR);
1314 	if (!nla)
1315 		goto nla_put_failure;
1316 
1317 	if (nla_put(msg, NL802154_COORD_PANID, IEEE802154_PAN_ID_LEN,
1318 		    &desc->addr.pan_id))
1319 		goto nla_put_failure;
1320 
1321 	if (desc->addr.mode == IEEE802154_ADDR_SHORT) {
1322 		if (nla_put(msg, NL802154_COORD_ADDR,
1323 			    IEEE802154_SHORT_ADDR_LEN,
1324 			    &desc->addr.short_addr))
1325 			goto nla_put_failure;
1326 	} else {
1327 		if (nla_put(msg, NL802154_COORD_ADDR,
1328 			    IEEE802154_EXTENDED_ADDR_LEN,
1329 			    &desc->addr.extended_addr))
1330 			goto nla_put_failure;
1331 	}
1332 
1333 	if (nla_put_u8(msg, NL802154_COORD_CHANNEL, desc->channel))
1334 		goto nla_put_failure;
1335 
1336 	if (nla_put_u8(msg, NL802154_COORD_PAGE, desc->page))
1337 		goto nla_put_failure;
1338 
1339 	if (nla_put_u16(msg, NL802154_COORD_SUPERFRAME_SPEC,
1340 			desc->superframe_spec))
1341 		goto nla_put_failure;
1342 
1343 	if (nla_put_u8(msg, NL802154_COORD_LINK_QUALITY, desc->link_quality))
1344 		goto nla_put_failure;
1345 
1346 	if (desc->gts_permit && nla_put_flag(msg, NL802154_COORD_GTS_PERMIT))
1347 		goto nla_put_failure;
1348 
1349 	/* TODO: NL802154_COORD_PAYLOAD_DATA if any */
1350 
1351 	nla_nest_end(msg, nla);
1352 
1353 	genlmsg_end(msg, hdr);
1354 
1355 	return 0;
1356 
1357  nla_put_failure:
1358 	genlmsg_cancel(msg, hdr);
1359 
1360 	return -EMSGSIZE;
1361 }
1362 
1363 int nl802154_scan_event(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
1364 			struct ieee802154_coord_desc *desc)
1365 {
1366 	struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(wpan_phy);
1367 	struct sk_buff *msg;
1368 	int ret;
1369 
1370 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
1371 	if (!msg)
1372 		return -ENOMEM;
1373 
1374 	ret = nl802154_prep_scan_event_msg(msg, rdev, wpan_dev, 0, 0, 0,
1375 					   NL802154_CMD_SCAN_EVENT,
1376 					   desc);
1377 	if (ret < 0) {
1378 		nlmsg_free(msg);
1379 		return ret;
1380 	}
1381 
1382 	return genlmsg_multicast_netns(&nl802154_fam, wpan_phy_net(wpan_phy),
1383 				       msg, 0, NL802154_MCGRP_SCAN, GFP_ATOMIC);
1384 }
1385 EXPORT_SYMBOL_GPL(nl802154_scan_event);
1386 
1387 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
1388 static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = {
1389 	[NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 },
1390 	[NL802154_DEV_ADDR_ATTR_MODE] = { .type = NLA_U32 },
1391 	[NL802154_DEV_ADDR_ATTR_SHORT] = { .type = NLA_U16 },
1392 	[NL802154_DEV_ADDR_ATTR_EXTENDED] = { .type = NLA_U64 },
1393 };
1394 
1395 static int
1396 ieee802154_llsec_parse_dev_addr(struct nlattr *nla,
1397 				struct ieee802154_addr *addr)
1398 {
1399 	struct nlattr *attrs[NL802154_DEV_ADDR_ATTR_MAX + 1];
1400 
1401 	if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ADDR_ATTR_MAX, nla, nl802154_dev_addr_policy, NULL))
1402 		return -EINVAL;
1403 
1404 	if (!attrs[NL802154_DEV_ADDR_ATTR_PAN_ID] || !attrs[NL802154_DEV_ADDR_ATTR_MODE])
1405 		return -EINVAL;
1406 
1407 	addr->pan_id = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_PAN_ID]);
1408 	addr->mode = nla_get_u32(attrs[NL802154_DEV_ADDR_ATTR_MODE]);
1409 	switch (addr->mode) {
1410 	case NL802154_DEV_ADDR_SHORT:
1411 		if (!attrs[NL802154_DEV_ADDR_ATTR_SHORT])
1412 			return -EINVAL;
1413 		addr->short_addr = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_SHORT]);
1414 		break;
1415 	case NL802154_DEV_ADDR_EXTENDED:
1416 		if (!attrs[NL802154_DEV_ADDR_ATTR_EXTENDED])
1417 			return -EINVAL;
1418 		addr->extended_addr = nla_get_le64(attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]);
1419 		break;
1420 	default:
1421 		return -EINVAL;
1422 	}
1423 
1424 	return 0;
1425 }
1426 
1427 static const struct nla_policy nl802154_key_id_policy[NL802154_KEY_ID_ATTR_MAX + 1] = {
1428 	[NL802154_KEY_ID_ATTR_MODE] = { .type = NLA_U32 },
1429 	[NL802154_KEY_ID_ATTR_INDEX] = { .type = NLA_U8 },
1430 	[NL802154_KEY_ID_ATTR_IMPLICIT] = { .type = NLA_NESTED },
1431 	[NL802154_KEY_ID_ATTR_SOURCE_SHORT] = { .type = NLA_U32 },
1432 	[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED] = { .type = NLA_U64 },
1433 };
1434 
1435 static int
1436 ieee802154_llsec_parse_key_id(struct nlattr *nla,
1437 			      struct ieee802154_llsec_key_id *desc)
1438 {
1439 	struct nlattr *attrs[NL802154_KEY_ID_ATTR_MAX + 1];
1440 
1441 	if (!nla || nla_parse_nested_deprecated(attrs, NL802154_KEY_ID_ATTR_MAX, nla, nl802154_key_id_policy, NULL))
1442 		return -EINVAL;
1443 
1444 	if (!attrs[NL802154_KEY_ID_ATTR_MODE])
1445 		return -EINVAL;
1446 
1447 	desc->mode = nla_get_u32(attrs[NL802154_KEY_ID_ATTR_MODE]);
1448 	switch (desc->mode) {
1449 	case NL802154_KEY_ID_MODE_IMPLICIT:
1450 		if (!attrs[NL802154_KEY_ID_ATTR_IMPLICIT])
1451 			return -EINVAL;
1452 
1453 		if (ieee802154_llsec_parse_dev_addr(attrs[NL802154_KEY_ID_ATTR_IMPLICIT],
1454 						    &desc->device_addr) < 0)
1455 			return -EINVAL;
1456 		break;
1457 	case NL802154_KEY_ID_MODE_INDEX:
1458 		break;
1459 	case NL802154_KEY_ID_MODE_INDEX_SHORT:
1460 		if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT])
1461 			return -EINVAL;
1462 
1463 		desc->short_source = nla_get_le32(attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT]);
1464 		break;
1465 	case NL802154_KEY_ID_MODE_INDEX_EXTENDED:
1466 		if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED])
1467 			return -EINVAL;
1468 
1469 		desc->extended_source = nla_get_le64(attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED]);
1470 		break;
1471 	default:
1472 		return -EINVAL;
1473 	}
1474 
1475 	if (desc->mode != NL802154_KEY_ID_MODE_IMPLICIT) {
1476 		if (!attrs[NL802154_KEY_ID_ATTR_INDEX])
1477 			return -EINVAL;
1478 
1479 		/* TODO change id to idx */
1480 		desc->id = nla_get_u8(attrs[NL802154_KEY_ID_ATTR_INDEX]);
1481 	}
1482 
1483 	return 0;
1484 }
1485 
1486 static int nl802154_set_llsec_params(struct sk_buff *skb,
1487 				     struct genl_info *info)
1488 {
1489 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1490 	struct net_device *dev = info->user_ptr[1];
1491 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1492 	struct ieee802154_llsec_params params;
1493 	u32 changed = 0;
1494 	int ret;
1495 
1496 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1497 		return -EOPNOTSUPP;
1498 
1499 	if (info->attrs[NL802154_ATTR_SEC_ENABLED]) {
1500 		u8 enabled;
1501 
1502 		enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
1503 		if (enabled != 0 && enabled != 1)
1504 			return -EINVAL;
1505 
1506 		params.enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
1507 		changed |= IEEE802154_LLSEC_PARAM_ENABLED;
1508 	}
1509 
1510 	if (info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID]) {
1511 		ret = ieee802154_llsec_parse_key_id(info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID],
1512 						    &params.out_key);
1513 		if (ret < 0)
1514 			return ret;
1515 
1516 		changed |= IEEE802154_LLSEC_PARAM_OUT_KEY;
1517 	}
1518 
1519 	if (info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]) {
1520 		params.out_level = nla_get_u32(info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]);
1521 		if (params.out_level > NL802154_SECLEVEL_MAX)
1522 			return -EINVAL;
1523 
1524 		changed |= IEEE802154_LLSEC_PARAM_OUT_LEVEL;
1525 	}
1526 
1527 	if (info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]) {
1528 		params.frame_counter = nla_get_be32(info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]);
1529 		changed |= IEEE802154_LLSEC_PARAM_FRAME_COUNTER;
1530 	}
1531 
1532 	return rdev_set_llsec_params(rdev, wpan_dev, &params, changed);
1533 }
1534 
1535 static int nl802154_send_key(struct sk_buff *msg, u32 cmd, u32 portid,
1536 			     u32 seq, int flags,
1537 			     struct cfg802154_registered_device *rdev,
1538 			     struct net_device *dev,
1539 			     const struct ieee802154_llsec_key_entry *key)
1540 {
1541 	void *hdr;
1542 	u32 commands[NL802154_CMD_FRAME_NR_IDS / 32];
1543 	struct nlattr *nl_key, *nl_key_id;
1544 
1545 	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1546 	if (!hdr)
1547 		return -ENOBUFS;
1548 
1549 	if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1550 		goto nla_put_failure;
1551 
1552 	nl_key = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_KEY);
1553 	if (!nl_key)
1554 		goto nla_put_failure;
1555 
1556 	nl_key_id = nla_nest_start_noflag(msg, NL802154_KEY_ATTR_ID);
1557 	if (!nl_key_id)
1558 		goto nla_put_failure;
1559 
1560 	if (ieee802154_llsec_send_key_id(msg, &key->id) < 0)
1561 		goto nla_put_failure;
1562 
1563 	nla_nest_end(msg, nl_key_id);
1564 
1565 	if (nla_put_u8(msg, NL802154_KEY_ATTR_USAGE_FRAMES,
1566 		       key->key->frame_types))
1567 		goto nla_put_failure;
1568 
1569 	if (key->key->frame_types & BIT(NL802154_FRAME_CMD)) {
1570 		/* TODO for each nested */
1571 		memset(commands, 0, sizeof(commands));
1572 		commands[7] = key->key->cmd_frame_ids;
1573 		if (nla_put(msg, NL802154_KEY_ATTR_USAGE_CMDS,
1574 			    sizeof(commands), commands))
1575 			goto nla_put_failure;
1576 	}
1577 
1578 	if (nla_put(msg, NL802154_KEY_ATTR_BYTES, NL802154_KEY_SIZE,
1579 		    key->key->key))
1580 		goto nla_put_failure;
1581 
1582 	nla_nest_end(msg, nl_key);
1583 	genlmsg_end(msg, hdr);
1584 
1585 	return 0;
1586 
1587 nla_put_failure:
1588 	genlmsg_cancel(msg, hdr);
1589 	return -EMSGSIZE;
1590 }
1591 
1592 static int
1593 nl802154_dump_llsec_key(struct sk_buff *skb, struct netlink_callback *cb)
1594 {
1595 	struct cfg802154_registered_device *rdev = NULL;
1596 	struct ieee802154_llsec_key_entry *key;
1597 	struct ieee802154_llsec_table *table;
1598 	struct wpan_dev *wpan_dev;
1599 	int err;
1600 
1601 	err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1602 	if (err)
1603 		return err;
1604 
1605 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
1606 		err = skb->len;
1607 		goto out_err;
1608 	}
1609 
1610 	if (!wpan_dev->netdev) {
1611 		err = -EINVAL;
1612 		goto out_err;
1613 	}
1614 
1615 	rdev_lock_llsec_table(rdev, wpan_dev);
1616 	rdev_get_llsec_table(rdev, wpan_dev, &table);
1617 
1618 	/* TODO make it like station dump */
1619 	if (cb->args[2])
1620 		goto out;
1621 
1622 	list_for_each_entry(key, &table->keys, list) {
1623 		if (nl802154_send_key(skb, NL802154_CMD_NEW_SEC_KEY,
1624 				      NETLINK_CB(cb->skb).portid,
1625 				      cb->nlh->nlmsg_seq, NLM_F_MULTI,
1626 				      rdev, wpan_dev->netdev, key) < 0) {
1627 			/* TODO */
1628 			err = -EIO;
1629 			rdev_unlock_llsec_table(rdev, wpan_dev);
1630 			goto out_err;
1631 		}
1632 	}
1633 
1634 	cb->args[2] = 1;
1635 
1636 out:
1637 	rdev_unlock_llsec_table(rdev, wpan_dev);
1638 	err = skb->len;
1639 out_err:
1640 	nl802154_finish_wpan_dev_dump(rdev);
1641 
1642 	return err;
1643 }
1644 
1645 static const struct nla_policy nl802154_key_policy[NL802154_KEY_ATTR_MAX + 1] = {
1646 	[NL802154_KEY_ATTR_ID] = { NLA_NESTED },
1647 	/* TODO handle it as for_each_nested and NLA_FLAG? */
1648 	[NL802154_KEY_ATTR_USAGE_FRAMES] = { NLA_U8 },
1649 	/* TODO handle it as for_each_nested, not static array? */
1650 	[NL802154_KEY_ATTR_USAGE_CMDS] = { .len = NL802154_CMD_FRAME_NR_IDS / 8 },
1651 	[NL802154_KEY_ATTR_BYTES] = { .len = NL802154_KEY_SIZE },
1652 };
1653 
1654 static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info)
1655 {
1656 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1657 	struct net_device *dev = info->user_ptr[1];
1658 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1659 	struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
1660 	struct ieee802154_llsec_key key = { };
1661 	struct ieee802154_llsec_key_id id = { };
1662 	u32 commands[NL802154_CMD_FRAME_NR_IDS / 32] = { };
1663 
1664 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1665 		return -EOPNOTSUPP;
1666 
1667 	if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
1668 	    nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
1669 		return -EINVAL;
1670 
1671 	if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] ||
1672 	    !attrs[NL802154_KEY_ATTR_BYTES])
1673 		return -EINVAL;
1674 
1675 	if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1676 		return -ENOBUFS;
1677 
1678 	key.frame_types = nla_get_u8(attrs[NL802154_KEY_ATTR_USAGE_FRAMES]);
1679 	if (key.frame_types > BIT(NL802154_FRAME_MAX) ||
1680 	    ((key.frame_types & BIT(NL802154_FRAME_CMD)) &&
1681 	     !attrs[NL802154_KEY_ATTR_USAGE_CMDS]))
1682 		return -EINVAL;
1683 
1684 	if (attrs[NL802154_KEY_ATTR_USAGE_CMDS]) {
1685 		/* TODO for each nested */
1686 		nla_memcpy(commands, attrs[NL802154_KEY_ATTR_USAGE_CMDS],
1687 			   NL802154_CMD_FRAME_NR_IDS / 8);
1688 
1689 		/* TODO understand the -EINVAL logic here? last condition */
1690 		if (commands[0] || commands[1] || commands[2] || commands[3] ||
1691 		    commands[4] || commands[5] || commands[6] ||
1692 		    commands[7] > BIT(NL802154_CMD_FRAME_MAX))
1693 			return -EINVAL;
1694 
1695 		key.cmd_frame_ids = commands[7];
1696 	} else {
1697 		key.cmd_frame_ids = 0;
1698 	}
1699 
1700 	nla_memcpy(key.key, attrs[NL802154_KEY_ATTR_BYTES], NL802154_KEY_SIZE);
1701 
1702 	if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1703 		return -ENOBUFS;
1704 
1705 	return rdev_add_llsec_key(rdev, wpan_dev, &id, &key);
1706 }
1707 
1708 static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info)
1709 {
1710 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1711 	struct net_device *dev = info->user_ptr[1];
1712 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1713 	struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
1714 	struct ieee802154_llsec_key_id id;
1715 
1716 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1717 		return -EOPNOTSUPP;
1718 
1719 	if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
1720 	    nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
1721 		return -EINVAL;
1722 
1723 	if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1724 		return -ENOBUFS;
1725 
1726 	return rdev_del_llsec_key(rdev, wpan_dev, &id);
1727 }
1728 
1729 static int nl802154_send_device(struct sk_buff *msg, u32 cmd, u32 portid,
1730 				u32 seq, int flags,
1731 				struct cfg802154_registered_device *rdev,
1732 				struct net_device *dev,
1733 				const struct ieee802154_llsec_device *dev_desc)
1734 {
1735 	void *hdr;
1736 	struct nlattr *nl_device;
1737 
1738 	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1739 	if (!hdr)
1740 		return -ENOBUFS;
1741 
1742 	if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1743 		goto nla_put_failure;
1744 
1745 	nl_device = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVICE);
1746 	if (!nl_device)
1747 		goto nla_put_failure;
1748 
1749 	if (nla_put_u32(msg, NL802154_DEV_ATTR_FRAME_COUNTER,
1750 			dev_desc->frame_counter) ||
1751 	    nla_put_le16(msg, NL802154_DEV_ATTR_PAN_ID, dev_desc->pan_id) ||
1752 	    nla_put_le16(msg, NL802154_DEV_ATTR_SHORT_ADDR,
1753 			 dev_desc->short_addr) ||
1754 	    nla_put_le64(msg, NL802154_DEV_ATTR_EXTENDED_ADDR,
1755 			 dev_desc->hwaddr, NL802154_DEV_ATTR_PAD) ||
1756 	    nla_put_u8(msg, NL802154_DEV_ATTR_SECLEVEL_EXEMPT,
1757 		       dev_desc->seclevel_exempt) ||
1758 	    nla_put_u32(msg, NL802154_DEV_ATTR_KEY_MODE, dev_desc->key_mode))
1759 		goto nla_put_failure;
1760 
1761 	nla_nest_end(msg, nl_device);
1762 	genlmsg_end(msg, hdr);
1763 
1764 	return 0;
1765 
1766 nla_put_failure:
1767 	genlmsg_cancel(msg, hdr);
1768 	return -EMSGSIZE;
1769 }
1770 
1771 static int
1772 nl802154_dump_llsec_dev(struct sk_buff *skb, struct netlink_callback *cb)
1773 {
1774 	struct cfg802154_registered_device *rdev = NULL;
1775 	struct ieee802154_llsec_device *dev;
1776 	struct ieee802154_llsec_table *table;
1777 	struct wpan_dev *wpan_dev;
1778 	int err;
1779 
1780 	err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1781 	if (err)
1782 		return err;
1783 
1784 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
1785 		err = skb->len;
1786 		goto out_err;
1787 	}
1788 
1789 	if (!wpan_dev->netdev) {
1790 		err = -EINVAL;
1791 		goto out_err;
1792 	}
1793 
1794 	rdev_lock_llsec_table(rdev, wpan_dev);
1795 	rdev_get_llsec_table(rdev, wpan_dev, &table);
1796 
1797 	/* TODO make it like station dump */
1798 	if (cb->args[2])
1799 		goto out;
1800 
1801 	list_for_each_entry(dev, &table->devices, list) {
1802 		if (nl802154_send_device(skb, NL802154_CMD_NEW_SEC_LEVEL,
1803 					 NETLINK_CB(cb->skb).portid,
1804 					 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1805 					 rdev, wpan_dev->netdev, dev) < 0) {
1806 			/* TODO */
1807 			err = -EIO;
1808 			rdev_unlock_llsec_table(rdev, wpan_dev);
1809 			goto out_err;
1810 		}
1811 	}
1812 
1813 	cb->args[2] = 1;
1814 
1815 out:
1816 	rdev_unlock_llsec_table(rdev, wpan_dev);
1817 	err = skb->len;
1818 out_err:
1819 	nl802154_finish_wpan_dev_dump(rdev);
1820 
1821 	return err;
1822 }
1823 
1824 static const struct nla_policy nl802154_dev_policy[NL802154_DEV_ATTR_MAX + 1] = {
1825 	[NL802154_DEV_ATTR_FRAME_COUNTER] = { NLA_U32 },
1826 	[NL802154_DEV_ATTR_PAN_ID] = { .type = NLA_U16 },
1827 	[NL802154_DEV_ATTR_SHORT_ADDR] = { .type = NLA_U16 },
1828 	[NL802154_DEV_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 },
1829 	[NL802154_DEV_ATTR_SECLEVEL_EXEMPT] = { NLA_U8 },
1830 	[NL802154_DEV_ATTR_KEY_MODE] = { NLA_U32 },
1831 };
1832 
1833 static int
1834 ieee802154_llsec_parse_device(struct nlattr *nla,
1835 			      struct ieee802154_llsec_device *dev)
1836 {
1837 	struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
1838 
1839 	if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, nla, nl802154_dev_policy, NULL))
1840 		return -EINVAL;
1841 
1842 	memset(dev, 0, sizeof(*dev));
1843 
1844 	if (!attrs[NL802154_DEV_ATTR_FRAME_COUNTER] ||
1845 	    !attrs[NL802154_DEV_ATTR_PAN_ID] ||
1846 	    !attrs[NL802154_DEV_ATTR_SHORT_ADDR] ||
1847 	    !attrs[NL802154_DEV_ATTR_EXTENDED_ADDR] ||
1848 	    !attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT] ||
1849 	    !attrs[NL802154_DEV_ATTR_KEY_MODE])
1850 		return -EINVAL;
1851 
1852 	/* TODO be32 */
1853 	dev->frame_counter = nla_get_u32(attrs[NL802154_DEV_ATTR_FRAME_COUNTER]);
1854 	dev->pan_id = nla_get_le16(attrs[NL802154_DEV_ATTR_PAN_ID]);
1855 	dev->short_addr = nla_get_le16(attrs[NL802154_DEV_ATTR_SHORT_ADDR]);
1856 	/* TODO rename hwaddr to extended_addr */
1857 	dev->hwaddr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
1858 	dev->seclevel_exempt = nla_get_u8(attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT]);
1859 	dev->key_mode = nla_get_u32(attrs[NL802154_DEV_ATTR_KEY_MODE]);
1860 
1861 	if (dev->key_mode > NL802154_DEVKEY_MAX ||
1862 	    (dev->seclevel_exempt != 0 && dev->seclevel_exempt != 1))
1863 		return -EINVAL;
1864 
1865 	return 0;
1866 }
1867 
1868 static int nl802154_add_llsec_dev(struct sk_buff *skb, struct genl_info *info)
1869 {
1870 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1871 	struct net_device *dev = info->user_ptr[1];
1872 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1873 	struct ieee802154_llsec_device dev_desc;
1874 
1875 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1876 		return -EOPNOTSUPP;
1877 
1878 	if (ieee802154_llsec_parse_device(info->attrs[NL802154_ATTR_SEC_DEVICE],
1879 					  &dev_desc) < 0)
1880 		return -EINVAL;
1881 
1882 	return rdev_add_device(rdev, wpan_dev, &dev_desc);
1883 }
1884 
1885 static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info)
1886 {
1887 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
1888 	struct net_device *dev = info->user_ptr[1];
1889 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1890 	struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
1891 	__le64 extended_addr;
1892 
1893 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1894 		return -EOPNOTSUPP;
1895 
1896 	if (!info->attrs[NL802154_ATTR_SEC_DEVICE] ||
1897 	    nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVICE], nl802154_dev_policy, info->extack))
1898 		return -EINVAL;
1899 
1900 	if (!attrs[NL802154_DEV_ATTR_EXTENDED_ADDR])
1901 		return -EINVAL;
1902 
1903 	extended_addr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
1904 	return rdev_del_device(rdev, wpan_dev, extended_addr);
1905 }
1906 
1907 static int nl802154_send_devkey(struct sk_buff *msg, u32 cmd, u32 portid,
1908 				u32 seq, int flags,
1909 				struct cfg802154_registered_device *rdev,
1910 				struct net_device *dev, __le64 extended_addr,
1911 				const struct ieee802154_llsec_device_key *devkey)
1912 {
1913 	void *hdr;
1914 	struct nlattr *nl_devkey, *nl_key_id;
1915 
1916 	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1917 	if (!hdr)
1918 		return -ENOBUFS;
1919 
1920 	if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1921 		goto nla_put_failure;
1922 
1923 	nl_devkey = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVKEY);
1924 	if (!nl_devkey)
1925 		goto nla_put_failure;
1926 
1927 	if (nla_put_le64(msg, NL802154_DEVKEY_ATTR_EXTENDED_ADDR,
1928 			 extended_addr, NL802154_DEVKEY_ATTR_PAD) ||
1929 	    nla_put_u32(msg, NL802154_DEVKEY_ATTR_FRAME_COUNTER,
1930 			devkey->frame_counter))
1931 		goto nla_put_failure;
1932 
1933 	nl_key_id = nla_nest_start_noflag(msg, NL802154_DEVKEY_ATTR_ID);
1934 	if (!nl_key_id)
1935 		goto nla_put_failure;
1936 
1937 	if (ieee802154_llsec_send_key_id(msg, &devkey->key_id) < 0)
1938 		goto nla_put_failure;
1939 
1940 	nla_nest_end(msg, nl_key_id);
1941 	nla_nest_end(msg, nl_devkey);
1942 	genlmsg_end(msg, hdr);
1943 
1944 	return 0;
1945 
1946 nla_put_failure:
1947 	genlmsg_cancel(msg, hdr);
1948 	return -EMSGSIZE;
1949 }
1950 
1951 static int
1952 nl802154_dump_llsec_devkey(struct sk_buff *skb, struct netlink_callback *cb)
1953 {
1954 	struct cfg802154_registered_device *rdev = NULL;
1955 	struct ieee802154_llsec_device_key *kpos;
1956 	struct ieee802154_llsec_device *dpos;
1957 	struct ieee802154_llsec_table *table;
1958 	struct wpan_dev *wpan_dev;
1959 	int err;
1960 
1961 	err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1962 	if (err)
1963 		return err;
1964 
1965 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
1966 		err = skb->len;
1967 		goto out_err;
1968 	}
1969 
1970 	if (!wpan_dev->netdev) {
1971 		err = -EINVAL;
1972 		goto out_err;
1973 	}
1974 
1975 	rdev_lock_llsec_table(rdev, wpan_dev);
1976 	rdev_get_llsec_table(rdev, wpan_dev, &table);
1977 
1978 	/* TODO make it like station dump */
1979 	if (cb->args[2])
1980 		goto out;
1981 
1982 	/* TODO look if remove devkey and do some nested attribute */
1983 	list_for_each_entry(dpos, &table->devices, list) {
1984 		list_for_each_entry(kpos, &dpos->keys, list) {
1985 			if (nl802154_send_devkey(skb,
1986 						 NL802154_CMD_NEW_SEC_LEVEL,
1987 						 NETLINK_CB(cb->skb).portid,
1988 						 cb->nlh->nlmsg_seq,
1989 						 NLM_F_MULTI, rdev,
1990 						 wpan_dev->netdev,
1991 						 dpos->hwaddr,
1992 						 kpos) < 0) {
1993 				/* TODO */
1994 				err = -EIO;
1995 				rdev_unlock_llsec_table(rdev, wpan_dev);
1996 				goto out_err;
1997 			}
1998 		}
1999 	}
2000 
2001 	cb->args[2] = 1;
2002 
2003 out:
2004 	rdev_unlock_llsec_table(rdev, wpan_dev);
2005 	err = skb->len;
2006 out_err:
2007 	nl802154_finish_wpan_dev_dump(rdev);
2008 
2009 	return err;
2010 }
2011 
2012 static const struct nla_policy nl802154_devkey_policy[NL802154_DEVKEY_ATTR_MAX + 1] = {
2013 	[NL802154_DEVKEY_ATTR_FRAME_COUNTER] = { NLA_U32 },
2014 	[NL802154_DEVKEY_ATTR_EXTENDED_ADDR] = { NLA_U64 },
2015 	[NL802154_DEVKEY_ATTR_ID] = { NLA_NESTED },
2016 };
2017 
2018 static int nl802154_add_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
2019 {
2020 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
2021 	struct net_device *dev = info->user_ptr[1];
2022 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2023 	struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
2024 	struct ieee802154_llsec_device_key key;
2025 	__le64 extended_addr;
2026 
2027 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
2028 		return -EOPNOTSUPP;
2029 
2030 	if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
2031 	    nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack) < 0)
2032 		return -EINVAL;
2033 
2034 	if (!attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER] ||
2035 	    !attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
2036 		return -EINVAL;
2037 
2038 	/* TODO change key.id ? */
2039 	if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
2040 					  &key.key_id) < 0)
2041 		return -ENOBUFS;
2042 
2043 	/* TODO be32 */
2044 	key.frame_counter = nla_get_u32(attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER]);
2045 	/* TODO change naming hwaddr -> extended_addr
2046 	 * check unique identifier short+pan OR extended_addr
2047 	 */
2048 	extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
2049 	return rdev_add_devkey(rdev, wpan_dev, extended_addr, &key);
2050 }
2051 
2052 static int nl802154_del_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
2053 {
2054 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
2055 	struct net_device *dev = info->user_ptr[1];
2056 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2057 	struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
2058 	struct ieee802154_llsec_device_key key;
2059 	__le64 extended_addr;
2060 
2061 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
2062 		return -EOPNOTSUPP;
2063 
2064 	if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
2065 	    nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack))
2066 		return -EINVAL;
2067 
2068 	if (!attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
2069 		return -EINVAL;
2070 
2071 	/* TODO change key.id ? */
2072 	if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
2073 					  &key.key_id) < 0)
2074 		return -ENOBUFS;
2075 
2076 	/* TODO change naming hwaddr -> extended_addr
2077 	 * check unique identifier short+pan OR extended_addr
2078 	 */
2079 	extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
2080 	return rdev_del_devkey(rdev, wpan_dev, extended_addr, &key);
2081 }
2082 
2083 static int nl802154_send_seclevel(struct sk_buff *msg, u32 cmd, u32 portid,
2084 				  u32 seq, int flags,
2085 				  struct cfg802154_registered_device *rdev,
2086 				  struct net_device *dev,
2087 				  const struct ieee802154_llsec_seclevel *sl)
2088 {
2089 	void *hdr;
2090 	struct nlattr *nl_seclevel;
2091 
2092 	hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
2093 	if (!hdr)
2094 		return -ENOBUFS;
2095 
2096 	if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
2097 		goto nla_put_failure;
2098 
2099 	nl_seclevel = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_LEVEL);
2100 	if (!nl_seclevel)
2101 		goto nla_put_failure;
2102 
2103 	if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_FRAME, sl->frame_type) ||
2104 	    nla_put_u32(msg, NL802154_SECLEVEL_ATTR_LEVELS, sl->sec_levels) ||
2105 	    nla_put_u8(msg, NL802154_SECLEVEL_ATTR_DEV_OVERRIDE,
2106 		       sl->device_override))
2107 		goto nla_put_failure;
2108 
2109 	if (sl->frame_type == NL802154_FRAME_CMD) {
2110 		if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_CMD_FRAME,
2111 				sl->cmd_frame_id))
2112 			goto nla_put_failure;
2113 	}
2114 
2115 	nla_nest_end(msg, nl_seclevel);
2116 	genlmsg_end(msg, hdr);
2117 
2118 	return 0;
2119 
2120 nla_put_failure:
2121 	genlmsg_cancel(msg, hdr);
2122 	return -EMSGSIZE;
2123 }
2124 
2125 static int
2126 nl802154_dump_llsec_seclevel(struct sk_buff *skb, struct netlink_callback *cb)
2127 {
2128 	struct cfg802154_registered_device *rdev = NULL;
2129 	struct ieee802154_llsec_seclevel *sl;
2130 	struct ieee802154_llsec_table *table;
2131 	struct wpan_dev *wpan_dev;
2132 	int err;
2133 
2134 	err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
2135 	if (err)
2136 		return err;
2137 
2138 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
2139 		err = skb->len;
2140 		goto out_err;
2141 	}
2142 
2143 	if (!wpan_dev->netdev) {
2144 		err = -EINVAL;
2145 		goto out_err;
2146 	}
2147 
2148 	rdev_lock_llsec_table(rdev, wpan_dev);
2149 	rdev_get_llsec_table(rdev, wpan_dev, &table);
2150 
2151 	/* TODO make it like station dump */
2152 	if (cb->args[2])
2153 		goto out;
2154 
2155 	list_for_each_entry(sl, &table->security_levels, list) {
2156 		if (nl802154_send_seclevel(skb, NL802154_CMD_NEW_SEC_LEVEL,
2157 					   NETLINK_CB(cb->skb).portid,
2158 					   cb->nlh->nlmsg_seq, NLM_F_MULTI,
2159 					   rdev, wpan_dev->netdev, sl) < 0) {
2160 			/* TODO */
2161 			err = -EIO;
2162 			rdev_unlock_llsec_table(rdev, wpan_dev);
2163 			goto out_err;
2164 		}
2165 	}
2166 
2167 	cb->args[2] = 1;
2168 
2169 out:
2170 	rdev_unlock_llsec_table(rdev, wpan_dev);
2171 	err = skb->len;
2172 out_err:
2173 	nl802154_finish_wpan_dev_dump(rdev);
2174 
2175 	return err;
2176 }
2177 
2178 static const struct nla_policy nl802154_seclevel_policy[NL802154_SECLEVEL_ATTR_MAX + 1] = {
2179 	[NL802154_SECLEVEL_ATTR_LEVELS] = { .type = NLA_U8 },
2180 	[NL802154_SECLEVEL_ATTR_FRAME] = { .type = NLA_U32 },
2181 	[NL802154_SECLEVEL_ATTR_CMD_FRAME] = { .type = NLA_U32 },
2182 	[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE] = { .type = NLA_U8 },
2183 };
2184 
2185 static int
2186 llsec_parse_seclevel(struct nlattr *nla, struct ieee802154_llsec_seclevel *sl)
2187 {
2188 	struct nlattr *attrs[NL802154_SECLEVEL_ATTR_MAX + 1];
2189 
2190 	if (!nla || nla_parse_nested_deprecated(attrs, NL802154_SECLEVEL_ATTR_MAX, nla, nl802154_seclevel_policy, NULL))
2191 		return -EINVAL;
2192 
2193 	memset(sl, 0, sizeof(*sl));
2194 
2195 	if (!attrs[NL802154_SECLEVEL_ATTR_LEVELS] ||
2196 	    !attrs[NL802154_SECLEVEL_ATTR_FRAME] ||
2197 	    !attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE])
2198 		return -EINVAL;
2199 
2200 	sl->sec_levels = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_LEVELS]);
2201 	sl->frame_type = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_FRAME]);
2202 	sl->device_override = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE]);
2203 	if (sl->frame_type > NL802154_FRAME_MAX ||
2204 	    (sl->device_override != 0 && sl->device_override != 1))
2205 		return -EINVAL;
2206 
2207 	if (sl->frame_type == NL802154_FRAME_CMD) {
2208 		if (!attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME])
2209 			return -EINVAL;
2210 
2211 		sl->cmd_frame_id = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME]);
2212 		if (sl->cmd_frame_id > NL802154_CMD_FRAME_MAX)
2213 			return -EINVAL;
2214 	}
2215 
2216 	return 0;
2217 }
2218 
2219 static int nl802154_add_llsec_seclevel(struct sk_buff *skb,
2220 				       struct genl_info *info)
2221 {
2222 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
2223 	struct net_device *dev = info->user_ptr[1];
2224 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2225 	struct ieee802154_llsec_seclevel sl;
2226 
2227 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
2228 		return -EOPNOTSUPP;
2229 
2230 	if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
2231 				 &sl) < 0)
2232 		return -EINVAL;
2233 
2234 	return rdev_add_seclevel(rdev, wpan_dev, &sl);
2235 }
2236 
2237 static int nl802154_del_llsec_seclevel(struct sk_buff *skb,
2238 				       struct genl_info *info)
2239 {
2240 	struct cfg802154_registered_device *rdev = info->user_ptr[0];
2241 	struct net_device *dev = info->user_ptr[1];
2242 	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2243 	struct ieee802154_llsec_seclevel sl;
2244 
2245 	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
2246 		return -EOPNOTSUPP;
2247 
2248 	if (!info->attrs[NL802154_ATTR_SEC_LEVEL] ||
2249 	    llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
2250 				 &sl) < 0)
2251 		return -EINVAL;
2252 
2253 	return rdev_del_seclevel(rdev, wpan_dev, &sl);
2254 }
2255 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2256 
2257 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
2258 #define NL802154_FLAG_NEED_NETDEV	0x02
2259 #define NL802154_FLAG_NEED_RTNL		0x04
2260 #define NL802154_FLAG_CHECK_NETDEV_UP	0x08
2261 #define NL802154_FLAG_NEED_WPAN_DEV	0x10
2262 
2263 static int nl802154_pre_doit(const struct genl_split_ops *ops,
2264 			     struct sk_buff *skb,
2265 			     struct genl_info *info)
2266 {
2267 	struct cfg802154_registered_device *rdev;
2268 	struct wpan_dev *wpan_dev;
2269 	struct net_device *dev;
2270 	bool rtnl = ops->internal_flags & NL802154_FLAG_NEED_RTNL;
2271 
2272 	if (rtnl)
2273 		rtnl_lock();
2274 
2275 	if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_PHY) {
2276 		rdev = cfg802154_get_dev_from_info(genl_info_net(info), info);
2277 		if (IS_ERR(rdev)) {
2278 			if (rtnl)
2279 				rtnl_unlock();
2280 			return PTR_ERR(rdev);
2281 		}
2282 		info->user_ptr[0] = rdev;
2283 	} else if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV ||
2284 		   ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
2285 		ASSERT_RTNL();
2286 		wpan_dev = __cfg802154_wpan_dev_from_attrs(genl_info_net(info),
2287 							   info->attrs);
2288 		if (IS_ERR(wpan_dev)) {
2289 			if (rtnl)
2290 				rtnl_unlock();
2291 			return PTR_ERR(wpan_dev);
2292 		}
2293 
2294 		dev = wpan_dev->netdev;
2295 		rdev = wpan_phy_to_rdev(wpan_dev->wpan_phy);
2296 
2297 		if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV) {
2298 			if (!dev) {
2299 				if (rtnl)
2300 					rtnl_unlock();
2301 				return -EINVAL;
2302 			}
2303 
2304 			info->user_ptr[1] = dev;
2305 		} else {
2306 			info->user_ptr[1] = wpan_dev;
2307 		}
2308 
2309 		if (dev) {
2310 			if (ops->internal_flags & NL802154_FLAG_CHECK_NETDEV_UP &&
2311 			    !netif_running(dev)) {
2312 				if (rtnl)
2313 					rtnl_unlock();
2314 				return -ENETDOWN;
2315 			}
2316 
2317 			dev_hold(dev);
2318 		}
2319 
2320 		info->user_ptr[0] = rdev;
2321 	}
2322 
2323 	return 0;
2324 }
2325 
2326 static void nl802154_post_doit(const struct genl_split_ops *ops,
2327 			       struct sk_buff *skb,
2328 			       struct genl_info *info)
2329 {
2330 	if (info->user_ptr[1]) {
2331 		if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
2332 			struct wpan_dev *wpan_dev = info->user_ptr[1];
2333 
2334 			dev_put(wpan_dev->netdev);
2335 		} else {
2336 			dev_put(info->user_ptr[1]);
2337 		}
2338 	}
2339 
2340 	if (ops->internal_flags & NL802154_FLAG_NEED_RTNL)
2341 		rtnl_unlock();
2342 }
2343 
2344 static const struct genl_ops nl802154_ops[] = {
2345 	{
2346 		.cmd = NL802154_CMD_GET_WPAN_PHY,
2347 		.validate = GENL_DONT_VALIDATE_STRICT |
2348 			    GENL_DONT_VALIDATE_DUMP_STRICT,
2349 		.doit = nl802154_get_wpan_phy,
2350 		.dumpit = nl802154_dump_wpan_phy,
2351 		.done = nl802154_dump_wpan_phy_done,
2352 		/* can be retrieved by unprivileged users */
2353 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2354 				  NL802154_FLAG_NEED_RTNL,
2355 	},
2356 	{
2357 		.cmd = NL802154_CMD_GET_INTERFACE,
2358 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2359 		.doit = nl802154_get_interface,
2360 		.dumpit = nl802154_dump_interface,
2361 		/* can be retrieved by unprivileged users */
2362 		.internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
2363 				  NL802154_FLAG_NEED_RTNL,
2364 	},
2365 	{
2366 		.cmd = NL802154_CMD_NEW_INTERFACE,
2367 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2368 		.doit = nl802154_new_interface,
2369 		.flags = GENL_ADMIN_PERM,
2370 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2371 				  NL802154_FLAG_NEED_RTNL,
2372 	},
2373 	{
2374 		.cmd = NL802154_CMD_DEL_INTERFACE,
2375 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2376 		.doit = nl802154_del_interface,
2377 		.flags = GENL_ADMIN_PERM,
2378 		.internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
2379 				  NL802154_FLAG_NEED_RTNL,
2380 	},
2381 	{
2382 		.cmd = NL802154_CMD_SET_CHANNEL,
2383 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2384 		.doit = nl802154_set_channel,
2385 		.flags = GENL_ADMIN_PERM,
2386 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2387 				  NL802154_FLAG_NEED_RTNL,
2388 	},
2389 	{
2390 		.cmd = NL802154_CMD_SET_CCA_MODE,
2391 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2392 		.doit = nl802154_set_cca_mode,
2393 		.flags = GENL_ADMIN_PERM,
2394 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2395 				  NL802154_FLAG_NEED_RTNL,
2396 	},
2397 	{
2398 		.cmd = NL802154_CMD_SET_CCA_ED_LEVEL,
2399 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2400 		.doit = nl802154_set_cca_ed_level,
2401 		.flags = GENL_ADMIN_PERM,
2402 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2403 				  NL802154_FLAG_NEED_RTNL,
2404 	},
2405 	{
2406 		.cmd = NL802154_CMD_SET_TX_POWER,
2407 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2408 		.doit = nl802154_set_tx_power,
2409 		.flags = GENL_ADMIN_PERM,
2410 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2411 				  NL802154_FLAG_NEED_RTNL,
2412 	},
2413 	{
2414 		.cmd = NL802154_CMD_SET_WPAN_PHY_NETNS,
2415 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2416 		.doit = nl802154_wpan_phy_netns,
2417 		.flags = GENL_ADMIN_PERM,
2418 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2419 				  NL802154_FLAG_NEED_RTNL,
2420 	},
2421 	{
2422 		.cmd = NL802154_CMD_SET_PAN_ID,
2423 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2424 		.doit = nl802154_set_pan_id,
2425 		.flags = GENL_ADMIN_PERM,
2426 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2427 				  NL802154_FLAG_NEED_RTNL,
2428 	},
2429 	{
2430 		.cmd = NL802154_CMD_SET_SHORT_ADDR,
2431 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2432 		.doit = nl802154_set_short_addr,
2433 		.flags = GENL_ADMIN_PERM,
2434 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2435 				  NL802154_FLAG_NEED_RTNL,
2436 	},
2437 	{
2438 		.cmd = NL802154_CMD_SET_BACKOFF_EXPONENT,
2439 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2440 		.doit = nl802154_set_backoff_exponent,
2441 		.flags = GENL_ADMIN_PERM,
2442 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2443 				  NL802154_FLAG_NEED_RTNL,
2444 	},
2445 	{
2446 		.cmd = NL802154_CMD_SET_MAX_CSMA_BACKOFFS,
2447 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2448 		.doit = nl802154_set_max_csma_backoffs,
2449 		.flags = GENL_ADMIN_PERM,
2450 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2451 				  NL802154_FLAG_NEED_RTNL,
2452 	},
2453 	{
2454 		.cmd = NL802154_CMD_SET_MAX_FRAME_RETRIES,
2455 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2456 		.doit = nl802154_set_max_frame_retries,
2457 		.flags = GENL_ADMIN_PERM,
2458 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2459 				  NL802154_FLAG_NEED_RTNL,
2460 	},
2461 	{
2462 		.cmd = NL802154_CMD_SET_LBT_MODE,
2463 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2464 		.doit = nl802154_set_lbt_mode,
2465 		.flags = GENL_ADMIN_PERM,
2466 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2467 				  NL802154_FLAG_NEED_RTNL,
2468 	},
2469 	{
2470 		.cmd = NL802154_CMD_SET_ACKREQ_DEFAULT,
2471 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2472 		.doit = nl802154_set_ackreq_default,
2473 		.flags = GENL_ADMIN_PERM,
2474 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2475 				  NL802154_FLAG_NEED_RTNL,
2476 	},
2477 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
2478 	{
2479 		.cmd = NL802154_CMD_SET_SEC_PARAMS,
2480 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2481 		.doit = nl802154_set_llsec_params,
2482 		.flags = GENL_ADMIN_PERM,
2483 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2484 				  NL802154_FLAG_NEED_RTNL,
2485 	},
2486 	{
2487 		.cmd = NL802154_CMD_GET_SEC_KEY,
2488 		.validate = GENL_DONT_VALIDATE_STRICT |
2489 			    GENL_DONT_VALIDATE_DUMP_STRICT,
2490 		/* TODO .doit by matching key id? */
2491 		.dumpit = nl802154_dump_llsec_key,
2492 		.flags = GENL_ADMIN_PERM,
2493 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2494 				  NL802154_FLAG_NEED_RTNL,
2495 	},
2496 	{
2497 		.cmd = NL802154_CMD_NEW_SEC_KEY,
2498 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2499 		.doit = nl802154_add_llsec_key,
2500 		.flags = GENL_ADMIN_PERM,
2501 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2502 				  NL802154_FLAG_NEED_RTNL,
2503 	},
2504 	{
2505 		.cmd = NL802154_CMD_DEL_SEC_KEY,
2506 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2507 		.doit = nl802154_del_llsec_key,
2508 		.flags = GENL_ADMIN_PERM,
2509 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2510 				  NL802154_FLAG_NEED_RTNL,
2511 	},
2512 	/* TODO unique identifier must short+pan OR extended_addr */
2513 	{
2514 		.cmd = NL802154_CMD_GET_SEC_DEV,
2515 		.validate = GENL_DONT_VALIDATE_STRICT |
2516 			    GENL_DONT_VALIDATE_DUMP_STRICT,
2517 		/* TODO .doit by matching extended_addr? */
2518 		.dumpit = nl802154_dump_llsec_dev,
2519 		.flags = GENL_ADMIN_PERM,
2520 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2521 				  NL802154_FLAG_NEED_RTNL,
2522 	},
2523 	{
2524 		.cmd = NL802154_CMD_NEW_SEC_DEV,
2525 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2526 		.doit = nl802154_add_llsec_dev,
2527 		.flags = GENL_ADMIN_PERM,
2528 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2529 				  NL802154_FLAG_NEED_RTNL,
2530 	},
2531 	{
2532 		.cmd = NL802154_CMD_DEL_SEC_DEV,
2533 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2534 		.doit = nl802154_del_llsec_dev,
2535 		.flags = GENL_ADMIN_PERM,
2536 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2537 				  NL802154_FLAG_NEED_RTNL,
2538 	},
2539 	/* TODO remove complete devkey, put it as nested? */
2540 	{
2541 		.cmd = NL802154_CMD_GET_SEC_DEVKEY,
2542 		.validate = GENL_DONT_VALIDATE_STRICT |
2543 			    GENL_DONT_VALIDATE_DUMP_STRICT,
2544 		/* TODO doit by matching ??? */
2545 		.dumpit = nl802154_dump_llsec_devkey,
2546 		.flags = GENL_ADMIN_PERM,
2547 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2548 				  NL802154_FLAG_NEED_RTNL,
2549 	},
2550 	{
2551 		.cmd = NL802154_CMD_NEW_SEC_DEVKEY,
2552 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2553 		.doit = nl802154_add_llsec_devkey,
2554 		.flags = GENL_ADMIN_PERM,
2555 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2556 				  NL802154_FLAG_NEED_RTNL,
2557 	},
2558 	{
2559 		.cmd = NL802154_CMD_DEL_SEC_DEVKEY,
2560 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2561 		.doit = nl802154_del_llsec_devkey,
2562 		.flags = GENL_ADMIN_PERM,
2563 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2564 				  NL802154_FLAG_NEED_RTNL,
2565 	},
2566 	{
2567 		.cmd = NL802154_CMD_GET_SEC_LEVEL,
2568 		.validate = GENL_DONT_VALIDATE_STRICT |
2569 			    GENL_DONT_VALIDATE_DUMP_STRICT,
2570 		/* TODO .doit by matching frame_type? */
2571 		.dumpit = nl802154_dump_llsec_seclevel,
2572 		.flags = GENL_ADMIN_PERM,
2573 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2574 				  NL802154_FLAG_NEED_RTNL,
2575 	},
2576 	{
2577 		.cmd = NL802154_CMD_NEW_SEC_LEVEL,
2578 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2579 		.doit = nl802154_add_llsec_seclevel,
2580 		.flags = GENL_ADMIN_PERM,
2581 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2582 				  NL802154_FLAG_NEED_RTNL,
2583 	},
2584 	{
2585 		.cmd = NL802154_CMD_DEL_SEC_LEVEL,
2586 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2587 		/* TODO match frame_type only? */
2588 		.doit = nl802154_del_llsec_seclevel,
2589 		.flags = GENL_ADMIN_PERM,
2590 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
2591 				  NL802154_FLAG_NEED_RTNL,
2592 	},
2593 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2594 };
2595 
2596 static struct genl_family nl802154_fam __ro_after_init = {
2597 	.name = NL802154_GENL_NAME,	/* have users key off the name instead */
2598 	.hdrsize = 0,			/* no private header */
2599 	.version = 1,			/* no particular meaning now */
2600 	.maxattr = NL802154_ATTR_MAX,
2601 	.policy = nl802154_policy,
2602 	.netnsok = true,
2603 	.pre_doit = nl802154_pre_doit,
2604 	.post_doit = nl802154_post_doit,
2605 	.module = THIS_MODULE,
2606 	.ops = nl802154_ops,
2607 	.n_ops = ARRAY_SIZE(nl802154_ops),
2608 	.resv_start_op = NL802154_CMD_DEL_SEC_LEVEL + 1,
2609 	.mcgrps = nl802154_mcgrps,
2610 	.n_mcgrps = ARRAY_SIZE(nl802154_mcgrps),
2611 };
2612 
2613 /* initialisation/exit functions */
2614 int __init nl802154_init(void)
2615 {
2616 	return genl_register_family(&nl802154_fam);
2617 }
2618 
2619 void nl802154_exit(void)
2620 {
2621 	genl_unregister_family(&nl802154_fam);
2622 }
2623