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