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