Merge tag 'timers-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[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 (nl802154_get_llsec_params(msg, rdev, wpan_dev) < 0)
824                 goto nla_put_failure;
825 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
826
827         genlmsg_end(msg, hdr);
828         return 0;
829
830 nla_put_failure:
831         genlmsg_cancel(msg, hdr);
832         return -EMSGSIZE;
833 }
834
835 static int
836 nl802154_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
837 {
838         int wp_idx = 0;
839         int if_idx = 0;
840         int wp_start = cb->args[0];
841         int if_start = cb->args[1];
842         struct cfg802154_registered_device *rdev;
843         struct wpan_dev *wpan_dev;
844
845         rtnl_lock();
846         list_for_each_entry(rdev, &cfg802154_rdev_list, list) {
847                 if (!net_eq(wpan_phy_net(&rdev->wpan_phy), sock_net(skb->sk)))
848                         continue;
849                 if (wp_idx < wp_start) {
850                         wp_idx++;
851                         continue;
852                 }
853                 if_idx = 0;
854
855                 list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) {
856                         if (if_idx < if_start) {
857                                 if_idx++;
858                                 continue;
859                         }
860                         if (nl802154_send_iface(skb, NETLINK_CB(cb->skb).portid,
861                                                 cb->nlh->nlmsg_seq, NLM_F_MULTI,
862                                                 rdev, wpan_dev) < 0) {
863                                 goto out;
864                         }
865                         if_idx++;
866                 }
867
868                 wp_idx++;
869         }
870 out:
871         rtnl_unlock();
872
873         cb->args[0] = wp_idx;
874         cb->args[1] = if_idx;
875
876         return skb->len;
877 }
878
879 static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info)
880 {
881         struct sk_buff *msg;
882         struct cfg802154_registered_device *rdev = info->user_ptr[0];
883         struct wpan_dev *wdev = info->user_ptr[1];
884
885         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
886         if (!msg)
887                 return -ENOMEM;
888
889         if (nl802154_send_iface(msg, info->snd_portid, info->snd_seq, 0,
890                                 rdev, wdev) < 0) {
891                 nlmsg_free(msg);
892                 return -ENOBUFS;
893         }
894
895         return genlmsg_reply(msg, info);
896 }
897
898 static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
899 {
900         struct cfg802154_registered_device *rdev = info->user_ptr[0];
901         enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC;
902         __le64 extended_addr = cpu_to_le64(0x0000000000000000ULL);
903
904         /* TODO avoid failing a new interface
905          * creation due to pending removal?
906          */
907
908         if (!info->attrs[NL802154_ATTR_IFNAME])
909                 return -EINVAL;
910
911         if (info->attrs[NL802154_ATTR_IFTYPE]) {
912                 type = nla_get_u32(info->attrs[NL802154_ATTR_IFTYPE]);
913                 if (type > NL802154_IFTYPE_MAX ||
914                     !(rdev->wpan_phy.supported.iftypes & BIT(type)))
915                         return -EINVAL;
916         }
917
918         if (info->attrs[NL802154_ATTR_EXTENDED_ADDR])
919                 extended_addr = nla_get_le64(info->attrs[NL802154_ATTR_EXTENDED_ADDR]);
920
921         if (!rdev->ops->add_virtual_intf)
922                 return -EOPNOTSUPP;
923
924         return rdev_add_virtual_intf(rdev,
925                                      nla_data(info->attrs[NL802154_ATTR_IFNAME]),
926                                      NET_NAME_USER, type, extended_addr);
927 }
928
929 static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info)
930 {
931         struct cfg802154_registered_device *rdev = info->user_ptr[0];
932         struct wpan_dev *wpan_dev = info->user_ptr[1];
933
934         if (!rdev->ops->del_virtual_intf)
935                 return -EOPNOTSUPP;
936
937         /* If we remove a wpan device without a netdev then clear
938          * user_ptr[1] so that nl802154_post_doit won't dereference it
939          * to check if it needs to do dev_put(). Otherwise it crashes
940          * since the wpan_dev has been freed, unlike with a netdev where
941          * we need the dev_put() for the netdev to really be freed.
942          */
943         if (!wpan_dev->netdev)
944                 info->user_ptr[1] = NULL;
945
946         return rdev_del_virtual_intf(rdev, wpan_dev);
947 }
948
949 static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
950 {
951         struct cfg802154_registered_device *rdev = info->user_ptr[0];
952         u8 channel, page;
953
954         if (!info->attrs[NL802154_ATTR_PAGE] ||
955             !info->attrs[NL802154_ATTR_CHANNEL])
956                 return -EINVAL;
957
958         page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]);
959         channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]);
960
961         /* check 802.15.4 constraints */
962         if (page > IEEE802154_MAX_PAGE || channel > IEEE802154_MAX_CHANNEL ||
963             !(rdev->wpan_phy.supported.channels[page] & BIT(channel)))
964                 return -EINVAL;
965
966         return rdev_set_channel(rdev, page, channel);
967 }
968
969 static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info)
970 {
971         struct cfg802154_registered_device *rdev = info->user_ptr[0];
972         struct wpan_phy_cca cca;
973
974         if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE))
975                 return -EOPNOTSUPP;
976
977         if (!info->attrs[NL802154_ATTR_CCA_MODE])
978                 return -EINVAL;
979
980         cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]);
981         /* checking 802.15.4 constraints */
982         if (cca.mode < NL802154_CCA_ENERGY ||
983             cca.mode > NL802154_CCA_ATTR_MAX ||
984             !(rdev->wpan_phy.supported.cca_modes & BIT(cca.mode)))
985                 return -EINVAL;
986
987         if (cca.mode == NL802154_CCA_ENERGY_CARRIER) {
988                 if (!info->attrs[NL802154_ATTR_CCA_OPT])
989                         return -EINVAL;
990
991                 cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]);
992                 if (cca.opt > NL802154_CCA_OPT_ATTR_MAX ||
993                     !(rdev->wpan_phy.supported.cca_opts & BIT(cca.opt)))
994                         return -EINVAL;
995         }
996
997         return rdev_set_cca_mode(rdev, &cca);
998 }
999
1000 static int nl802154_set_cca_ed_level(struct sk_buff *skb, struct genl_info *info)
1001 {
1002         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1003         s32 ed_level;
1004         int i;
1005
1006         if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL))
1007                 return -EOPNOTSUPP;
1008
1009         if (!info->attrs[NL802154_ATTR_CCA_ED_LEVEL])
1010                 return -EINVAL;
1011
1012         ed_level = nla_get_s32(info->attrs[NL802154_ATTR_CCA_ED_LEVEL]);
1013
1014         for (i = 0; i < rdev->wpan_phy.supported.cca_ed_levels_size; i++) {
1015                 if (ed_level == rdev->wpan_phy.supported.cca_ed_levels[i])
1016                         return rdev_set_cca_ed_level(rdev, ed_level);
1017         }
1018
1019         return -EINVAL;
1020 }
1021
1022 static int nl802154_set_tx_power(struct sk_buff *skb, struct genl_info *info)
1023 {
1024         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1025         s32 power;
1026         int i;
1027
1028         if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER))
1029                 return -EOPNOTSUPP;
1030
1031         if (!info->attrs[NL802154_ATTR_TX_POWER])
1032                 return -EINVAL;
1033
1034         power = nla_get_s32(info->attrs[NL802154_ATTR_TX_POWER]);
1035
1036         for (i = 0; i < rdev->wpan_phy.supported.tx_powers_size; i++) {
1037                 if (power == rdev->wpan_phy.supported.tx_powers[i])
1038                         return rdev_set_tx_power(rdev, power);
1039         }
1040
1041         return -EINVAL;
1042 }
1043
1044 static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
1045 {
1046         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1047         struct net_device *dev = info->user_ptr[1];
1048         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1049         __le16 pan_id;
1050
1051         /* conflict here while tx/rx calls */
1052         if (netif_running(dev))
1053                 return -EBUSY;
1054
1055         if (wpan_dev->lowpan_dev) {
1056                 if (netif_running(wpan_dev->lowpan_dev))
1057                         return -EBUSY;
1058         }
1059
1060         /* don't change address fields on monitor */
1061         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
1062             !info->attrs[NL802154_ATTR_PAN_ID])
1063                 return -EINVAL;
1064
1065         pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]);
1066
1067         /* TODO
1068          * I am not sure about to check here on broadcast pan_id.
1069          * Broadcast is a valid setting, comment from 802.15.4:
1070          * If this value is 0xffff, the device is not associated.
1071          *
1072          * This could useful to simple deassociate an device.
1073          */
1074         if (pan_id == cpu_to_le16(IEEE802154_PAN_ID_BROADCAST))
1075                 return -EINVAL;
1076
1077         return rdev_set_pan_id(rdev, wpan_dev, pan_id);
1078 }
1079
1080 static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info)
1081 {
1082         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1083         struct net_device *dev = info->user_ptr[1];
1084         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1085         __le16 short_addr;
1086
1087         /* conflict here while tx/rx calls */
1088         if (netif_running(dev))
1089                 return -EBUSY;
1090
1091         if (wpan_dev->lowpan_dev) {
1092                 if (netif_running(wpan_dev->lowpan_dev))
1093                         return -EBUSY;
1094         }
1095
1096         /* don't change address fields on monitor */
1097         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR ||
1098             !info->attrs[NL802154_ATTR_SHORT_ADDR])
1099                 return -EINVAL;
1100
1101         short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]);
1102
1103         /* TODO
1104          * I am not sure about to check here on broadcast short_addr.
1105          * Broadcast is a valid setting, comment from 802.15.4:
1106          * A value of 0xfffe indicates that the device has
1107          * associated but has not been allocated an address. A
1108          * value of 0xffff indicates that the device does not
1109          * have a short address.
1110          *
1111          * I think we should allow to set these settings but
1112          * don't allow to allow socket communication with it.
1113          */
1114         if (short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC) ||
1115             short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST))
1116                 return -EINVAL;
1117
1118         return rdev_set_short_addr(rdev, wpan_dev, short_addr);
1119 }
1120
1121 static int
1122 nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info)
1123 {
1124         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1125         struct net_device *dev = info->user_ptr[1];
1126         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1127         u8 min_be, max_be;
1128
1129         /* should be set on netif open inside phy settings */
1130         if (netif_running(dev))
1131                 return -EBUSY;
1132
1133         if (!info->attrs[NL802154_ATTR_MIN_BE] ||
1134             !info->attrs[NL802154_ATTR_MAX_BE])
1135                 return -EINVAL;
1136
1137         min_be = nla_get_u8(info->attrs[NL802154_ATTR_MIN_BE]);
1138         max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]);
1139
1140         /* check 802.15.4 constraints */
1141         if (min_be < rdev->wpan_phy.supported.min_minbe ||
1142             min_be > rdev->wpan_phy.supported.max_minbe ||
1143             max_be < rdev->wpan_phy.supported.min_maxbe ||
1144             max_be > rdev->wpan_phy.supported.max_maxbe ||
1145             min_be > max_be)
1146                 return -EINVAL;
1147
1148         return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be);
1149 }
1150
1151 static int
1152 nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info)
1153 {
1154         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1155         struct net_device *dev = info->user_ptr[1];
1156         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1157         u8 max_csma_backoffs;
1158
1159         /* conflict here while other running iface settings */
1160         if (netif_running(dev))
1161                 return -EBUSY;
1162
1163         if (!info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS])
1164                 return -EINVAL;
1165
1166         max_csma_backoffs = nla_get_u8(
1167                         info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]);
1168
1169         /* check 802.15.4 constraints */
1170         if (max_csma_backoffs < rdev->wpan_phy.supported.min_csma_backoffs ||
1171             max_csma_backoffs > rdev->wpan_phy.supported.max_csma_backoffs)
1172                 return -EINVAL;
1173
1174         return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs);
1175 }
1176
1177 static int
1178 nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info)
1179 {
1180         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1181         struct net_device *dev = info->user_ptr[1];
1182         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1183         s8 max_frame_retries;
1184
1185         if (netif_running(dev))
1186                 return -EBUSY;
1187
1188         if (!info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES])
1189                 return -EINVAL;
1190
1191         max_frame_retries = nla_get_s8(
1192                         info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]);
1193
1194         /* check 802.15.4 constraints */
1195         if (max_frame_retries < rdev->wpan_phy.supported.min_frame_retries ||
1196             max_frame_retries > rdev->wpan_phy.supported.max_frame_retries)
1197                 return -EINVAL;
1198
1199         return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries);
1200 }
1201
1202 static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
1203 {
1204         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1205         struct net_device *dev = info->user_ptr[1];
1206         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1207         int mode;
1208
1209         if (netif_running(dev))
1210                 return -EBUSY;
1211
1212         if (!info->attrs[NL802154_ATTR_LBT_MODE])
1213                 return -EINVAL;
1214
1215         mode = nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]);
1216
1217         if (mode != 0 && mode != 1)
1218                 return -EINVAL;
1219
1220         if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt))
1221                 return -EINVAL;
1222
1223         return rdev_set_lbt_mode(rdev, wpan_dev, mode);
1224 }
1225
1226 static int
1227 nl802154_set_ackreq_default(struct sk_buff *skb, struct genl_info *info)
1228 {
1229         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1230         struct net_device *dev = info->user_ptr[1];
1231         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1232         int ackreq;
1233
1234         if (netif_running(dev))
1235                 return -EBUSY;
1236
1237         if (!info->attrs[NL802154_ATTR_ACKREQ_DEFAULT])
1238                 return -EINVAL;
1239
1240         ackreq = nla_get_u8(info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]);
1241
1242         if (ackreq != 0 && ackreq != 1)
1243                 return -EINVAL;
1244
1245         return rdev_set_ackreq_default(rdev, wpan_dev, ackreq);
1246 }
1247
1248 static int nl802154_wpan_phy_netns(struct sk_buff *skb, struct genl_info *info)
1249 {
1250         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1251         struct net *net;
1252         int err;
1253
1254         if (info->attrs[NL802154_ATTR_PID]) {
1255                 u32 pid = nla_get_u32(info->attrs[NL802154_ATTR_PID]);
1256
1257                 net = get_net_ns_by_pid(pid);
1258         } else if (info->attrs[NL802154_ATTR_NETNS_FD]) {
1259                 u32 fd = nla_get_u32(info->attrs[NL802154_ATTR_NETNS_FD]);
1260
1261                 net = get_net_ns_by_fd(fd);
1262         } else {
1263                 return -EINVAL;
1264         }
1265
1266         if (IS_ERR(net))
1267                 return PTR_ERR(net);
1268
1269         err = 0;
1270
1271         /* check if anything to do */
1272         if (!net_eq(wpan_phy_net(&rdev->wpan_phy), net))
1273                 err = cfg802154_switch_netns(rdev, net);
1274
1275         put_net(net);
1276         return err;
1277 }
1278
1279 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
1280 static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = {
1281         [NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 },
1282         [NL802154_DEV_ADDR_ATTR_MODE] = { .type = NLA_U32 },
1283         [NL802154_DEV_ADDR_ATTR_SHORT] = { .type = NLA_U16 },
1284         [NL802154_DEV_ADDR_ATTR_EXTENDED] = { .type = NLA_U64 },
1285 };
1286
1287 static int
1288 ieee802154_llsec_parse_dev_addr(struct nlattr *nla,
1289                                 struct ieee802154_addr *addr)
1290 {
1291         struct nlattr *attrs[NL802154_DEV_ADDR_ATTR_MAX + 1];
1292
1293         if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ADDR_ATTR_MAX, nla, nl802154_dev_addr_policy, NULL))
1294                 return -EINVAL;
1295
1296         if (!attrs[NL802154_DEV_ADDR_ATTR_PAN_ID] ||
1297             !attrs[NL802154_DEV_ADDR_ATTR_MODE] ||
1298             !(attrs[NL802154_DEV_ADDR_ATTR_SHORT] ||
1299               attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]))
1300                 return -EINVAL;
1301
1302         addr->pan_id = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_PAN_ID]);
1303         addr->mode = nla_get_u32(attrs[NL802154_DEV_ADDR_ATTR_MODE]);
1304         switch (addr->mode) {
1305         case NL802154_DEV_ADDR_SHORT:
1306                 addr->short_addr = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_SHORT]);
1307                 break;
1308         case NL802154_DEV_ADDR_EXTENDED:
1309                 addr->extended_addr = nla_get_le64(attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]);
1310                 break;
1311         default:
1312                 return -EINVAL;
1313         }
1314
1315         return 0;
1316 }
1317
1318 static const struct nla_policy nl802154_key_id_policy[NL802154_KEY_ID_ATTR_MAX + 1] = {
1319         [NL802154_KEY_ID_ATTR_MODE] = { .type = NLA_U32 },
1320         [NL802154_KEY_ID_ATTR_INDEX] = { .type = NLA_U8 },
1321         [NL802154_KEY_ID_ATTR_IMPLICIT] = { .type = NLA_NESTED },
1322         [NL802154_KEY_ID_ATTR_SOURCE_SHORT] = { .type = NLA_U32 },
1323         [NL802154_KEY_ID_ATTR_SOURCE_EXTENDED] = { .type = NLA_U64 },
1324 };
1325
1326 static int
1327 ieee802154_llsec_parse_key_id(struct nlattr *nla,
1328                               struct ieee802154_llsec_key_id *desc)
1329 {
1330         struct nlattr *attrs[NL802154_KEY_ID_ATTR_MAX + 1];
1331
1332         if (!nla || nla_parse_nested_deprecated(attrs, NL802154_KEY_ID_ATTR_MAX, nla, nl802154_key_id_policy, NULL))
1333                 return -EINVAL;
1334
1335         if (!attrs[NL802154_KEY_ID_ATTR_MODE])
1336                 return -EINVAL;
1337
1338         desc->mode = nla_get_u32(attrs[NL802154_KEY_ID_ATTR_MODE]);
1339         switch (desc->mode) {
1340         case NL802154_KEY_ID_MODE_IMPLICIT:
1341                 if (!attrs[NL802154_KEY_ID_ATTR_IMPLICIT])
1342                         return -EINVAL;
1343
1344                 if (ieee802154_llsec_parse_dev_addr(attrs[NL802154_KEY_ID_ATTR_IMPLICIT],
1345                                                     &desc->device_addr) < 0)
1346                         return -EINVAL;
1347                 break;
1348         case NL802154_KEY_ID_MODE_INDEX:
1349                 break;
1350         case NL802154_KEY_ID_MODE_INDEX_SHORT:
1351                 if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT])
1352                         return -EINVAL;
1353
1354                 desc->short_source = nla_get_le32(attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT]);
1355                 break;
1356         case NL802154_KEY_ID_MODE_INDEX_EXTENDED:
1357                 if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED])
1358                         return -EINVAL;
1359
1360                 desc->extended_source = nla_get_le64(attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED]);
1361                 break;
1362         default:
1363                 return -EINVAL;
1364         }
1365
1366         if (desc->mode != NL802154_KEY_ID_MODE_IMPLICIT) {
1367                 if (!attrs[NL802154_KEY_ID_ATTR_INDEX])
1368                         return -EINVAL;
1369
1370                 /* TODO change id to idx */
1371                 desc->id = nla_get_u8(attrs[NL802154_KEY_ID_ATTR_INDEX]);
1372         }
1373
1374         return 0;
1375 }
1376
1377 static int nl802154_set_llsec_params(struct sk_buff *skb,
1378                                      struct genl_info *info)
1379 {
1380         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1381         struct net_device *dev = info->user_ptr[1];
1382         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1383         struct ieee802154_llsec_params params;
1384         u32 changed = 0;
1385         int ret;
1386
1387         if (info->attrs[NL802154_ATTR_SEC_ENABLED]) {
1388                 u8 enabled;
1389
1390                 enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
1391                 if (enabled != 0 && enabled != 1)
1392                         return -EINVAL;
1393
1394                 params.enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
1395                 changed |= IEEE802154_LLSEC_PARAM_ENABLED;
1396         }
1397
1398         if (info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID]) {
1399                 ret = ieee802154_llsec_parse_key_id(info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID],
1400                                                     &params.out_key);
1401                 if (ret < 0)
1402                         return ret;
1403
1404                 changed |= IEEE802154_LLSEC_PARAM_OUT_KEY;
1405         }
1406
1407         if (info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]) {
1408                 params.out_level = nla_get_u32(info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]);
1409                 if (params.out_level > NL802154_SECLEVEL_MAX)
1410                         return -EINVAL;
1411
1412                 changed |= IEEE802154_LLSEC_PARAM_OUT_LEVEL;
1413         }
1414
1415         if (info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]) {
1416                 params.frame_counter = nla_get_be32(info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]);
1417                 changed |= IEEE802154_LLSEC_PARAM_FRAME_COUNTER;
1418         }
1419
1420         return rdev_set_llsec_params(rdev, wpan_dev, &params, changed);
1421 }
1422
1423 static int nl802154_send_key(struct sk_buff *msg, u32 cmd, u32 portid,
1424                              u32 seq, int flags,
1425                              struct cfg802154_registered_device *rdev,
1426                              struct net_device *dev,
1427                              const struct ieee802154_llsec_key_entry *key)
1428 {
1429         void *hdr;
1430         u32 commands[NL802154_CMD_FRAME_NR_IDS / 32];
1431         struct nlattr *nl_key, *nl_key_id;
1432
1433         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1434         if (!hdr)
1435                 return -1;
1436
1437         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1438                 goto nla_put_failure;
1439
1440         nl_key = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_KEY);
1441         if (!nl_key)
1442                 goto nla_put_failure;
1443
1444         nl_key_id = nla_nest_start_noflag(msg, NL802154_KEY_ATTR_ID);
1445         if (!nl_key_id)
1446                 goto nla_put_failure;
1447
1448         if (ieee802154_llsec_send_key_id(msg, &key->id) < 0)
1449                 goto nla_put_failure;
1450
1451         nla_nest_end(msg, nl_key_id);
1452
1453         if (nla_put_u8(msg, NL802154_KEY_ATTR_USAGE_FRAMES,
1454                        key->key->frame_types))
1455                 goto nla_put_failure;
1456
1457         if (key->key->frame_types & BIT(NL802154_FRAME_CMD)) {
1458                 /* TODO for each nested */
1459                 memset(commands, 0, sizeof(commands));
1460                 commands[7] = key->key->cmd_frame_ids;
1461                 if (nla_put(msg, NL802154_KEY_ATTR_USAGE_CMDS,
1462                             sizeof(commands), commands))
1463                         goto nla_put_failure;
1464         }
1465
1466         if (nla_put(msg, NL802154_KEY_ATTR_BYTES, NL802154_KEY_SIZE,
1467                     key->key->key))
1468                 goto nla_put_failure;
1469
1470         nla_nest_end(msg, nl_key);
1471         genlmsg_end(msg, hdr);
1472
1473         return 0;
1474
1475 nla_put_failure:
1476         genlmsg_cancel(msg, hdr);
1477         return -EMSGSIZE;
1478 }
1479
1480 static int
1481 nl802154_dump_llsec_key(struct sk_buff *skb, struct netlink_callback *cb)
1482 {
1483         struct cfg802154_registered_device *rdev = NULL;
1484         struct ieee802154_llsec_key_entry *key;
1485         struct ieee802154_llsec_table *table;
1486         struct wpan_dev *wpan_dev;
1487         int err;
1488
1489         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1490         if (err)
1491                 return err;
1492
1493         if (!wpan_dev->netdev) {
1494                 err = -EINVAL;
1495                 goto out_err;
1496         }
1497
1498         rdev_lock_llsec_table(rdev, wpan_dev);
1499         rdev_get_llsec_table(rdev, wpan_dev, &table);
1500
1501         /* TODO make it like station dump */
1502         if (cb->args[2])
1503                 goto out;
1504
1505         list_for_each_entry(key, &table->keys, list) {
1506                 if (nl802154_send_key(skb, NL802154_CMD_NEW_SEC_KEY,
1507                                       NETLINK_CB(cb->skb).portid,
1508                                       cb->nlh->nlmsg_seq, NLM_F_MULTI,
1509                                       rdev, wpan_dev->netdev, key) < 0) {
1510                         /* TODO */
1511                         err = -EIO;
1512                         rdev_unlock_llsec_table(rdev, wpan_dev);
1513                         goto out_err;
1514                 }
1515         }
1516
1517         cb->args[2] = 1;
1518
1519 out:
1520         rdev_unlock_llsec_table(rdev, wpan_dev);
1521         err = skb->len;
1522 out_err:
1523         nl802154_finish_wpan_dev_dump(rdev);
1524
1525         return err;
1526 }
1527
1528 static const struct nla_policy nl802154_key_policy[NL802154_KEY_ATTR_MAX + 1] = {
1529         [NL802154_KEY_ATTR_ID] = { NLA_NESTED },
1530         /* TODO handle it as for_each_nested and NLA_FLAG? */
1531         [NL802154_KEY_ATTR_USAGE_FRAMES] = { NLA_U8 },
1532         /* TODO handle it as for_each_nested, not static array? */
1533         [NL802154_KEY_ATTR_USAGE_CMDS] = { .len = NL802154_CMD_FRAME_NR_IDS / 8 },
1534         [NL802154_KEY_ATTR_BYTES] = { .len = NL802154_KEY_SIZE },
1535 };
1536
1537 static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info)
1538 {
1539         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1540         struct net_device *dev = info->user_ptr[1];
1541         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1542         struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
1543         struct ieee802154_llsec_key key = { };
1544         struct ieee802154_llsec_key_id id = { };
1545         u32 commands[NL802154_CMD_FRAME_NR_IDS / 32] = { };
1546
1547         if (nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
1548                 return -EINVAL;
1549
1550         if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] ||
1551             !attrs[NL802154_KEY_ATTR_BYTES])
1552                 return -EINVAL;
1553
1554         if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1555                 return -ENOBUFS;
1556
1557         key.frame_types = nla_get_u8(attrs[NL802154_KEY_ATTR_USAGE_FRAMES]);
1558         if (key.frame_types > BIT(NL802154_FRAME_MAX) ||
1559             ((key.frame_types & BIT(NL802154_FRAME_CMD)) &&
1560              !attrs[NL802154_KEY_ATTR_USAGE_CMDS]))
1561                 return -EINVAL;
1562
1563         if (attrs[NL802154_KEY_ATTR_USAGE_CMDS]) {
1564                 /* TODO for each nested */
1565                 nla_memcpy(commands, attrs[NL802154_KEY_ATTR_USAGE_CMDS],
1566                            NL802154_CMD_FRAME_NR_IDS / 8);
1567
1568                 /* TODO understand the -EINVAL logic here? last condition */
1569                 if (commands[0] || commands[1] || commands[2] || commands[3] ||
1570                     commands[4] || commands[5] || commands[6] ||
1571                     commands[7] > BIT(NL802154_CMD_FRAME_MAX))
1572                         return -EINVAL;
1573
1574                 key.cmd_frame_ids = commands[7];
1575         } else {
1576                 key.cmd_frame_ids = 0;
1577         }
1578
1579         nla_memcpy(key.key, attrs[NL802154_KEY_ATTR_BYTES], NL802154_KEY_SIZE);
1580
1581         if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1582                 return -ENOBUFS;
1583
1584         return rdev_add_llsec_key(rdev, wpan_dev, &id, &key);
1585 }
1586
1587 static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info)
1588 {
1589         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1590         struct net_device *dev = info->user_ptr[1];
1591         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1592         struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
1593         struct ieee802154_llsec_key_id id;
1594
1595         if (nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
1596                 return -EINVAL;
1597
1598         if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1599                 return -ENOBUFS;
1600
1601         return rdev_del_llsec_key(rdev, wpan_dev, &id);
1602 }
1603
1604 static int nl802154_send_device(struct sk_buff *msg, u32 cmd, u32 portid,
1605                                 u32 seq, int flags,
1606                                 struct cfg802154_registered_device *rdev,
1607                                 struct net_device *dev,
1608                                 const struct ieee802154_llsec_device *dev_desc)
1609 {
1610         void *hdr;
1611         struct nlattr *nl_device;
1612
1613         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1614         if (!hdr)
1615                 return -1;
1616
1617         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1618                 goto nla_put_failure;
1619
1620         nl_device = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVICE);
1621         if (!nl_device)
1622                 goto nla_put_failure;
1623
1624         if (nla_put_u32(msg, NL802154_DEV_ATTR_FRAME_COUNTER,
1625                         dev_desc->frame_counter) ||
1626             nla_put_le16(msg, NL802154_DEV_ATTR_PAN_ID, dev_desc->pan_id) ||
1627             nla_put_le16(msg, NL802154_DEV_ATTR_SHORT_ADDR,
1628                          dev_desc->short_addr) ||
1629             nla_put_le64(msg, NL802154_DEV_ATTR_EXTENDED_ADDR,
1630                          dev_desc->hwaddr, NL802154_DEV_ATTR_PAD) ||
1631             nla_put_u8(msg, NL802154_DEV_ATTR_SECLEVEL_EXEMPT,
1632                        dev_desc->seclevel_exempt) ||
1633             nla_put_u32(msg, NL802154_DEV_ATTR_KEY_MODE, dev_desc->key_mode))
1634                 goto nla_put_failure;
1635
1636         nla_nest_end(msg, nl_device);
1637         genlmsg_end(msg, hdr);
1638
1639         return 0;
1640
1641 nla_put_failure:
1642         genlmsg_cancel(msg, hdr);
1643         return -EMSGSIZE;
1644 }
1645
1646 static int
1647 nl802154_dump_llsec_dev(struct sk_buff *skb, struct netlink_callback *cb)
1648 {
1649         struct cfg802154_registered_device *rdev = NULL;
1650         struct ieee802154_llsec_device *dev;
1651         struct ieee802154_llsec_table *table;
1652         struct wpan_dev *wpan_dev;
1653         int err;
1654
1655         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1656         if (err)
1657                 return err;
1658
1659         if (!wpan_dev->netdev) {
1660                 err = -EINVAL;
1661                 goto out_err;
1662         }
1663
1664         rdev_lock_llsec_table(rdev, wpan_dev);
1665         rdev_get_llsec_table(rdev, wpan_dev, &table);
1666
1667         /* TODO make it like station dump */
1668         if (cb->args[2])
1669                 goto out;
1670
1671         list_for_each_entry(dev, &table->devices, list) {
1672                 if (nl802154_send_device(skb, NL802154_CMD_NEW_SEC_LEVEL,
1673                                          NETLINK_CB(cb->skb).portid,
1674                                          cb->nlh->nlmsg_seq, NLM_F_MULTI,
1675                                          rdev, wpan_dev->netdev, dev) < 0) {
1676                         /* TODO */
1677                         err = -EIO;
1678                         rdev_unlock_llsec_table(rdev, wpan_dev);
1679                         goto out_err;
1680                 }
1681         }
1682
1683         cb->args[2] = 1;
1684
1685 out:
1686         rdev_unlock_llsec_table(rdev, wpan_dev);
1687         err = skb->len;
1688 out_err:
1689         nl802154_finish_wpan_dev_dump(rdev);
1690
1691         return err;
1692 }
1693
1694 static const struct nla_policy nl802154_dev_policy[NL802154_DEV_ATTR_MAX + 1] = {
1695         [NL802154_DEV_ATTR_FRAME_COUNTER] = { NLA_U32 },
1696         [NL802154_DEV_ATTR_PAN_ID] = { .type = NLA_U16 },
1697         [NL802154_DEV_ATTR_SHORT_ADDR] = { .type = NLA_U16 },
1698         [NL802154_DEV_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 },
1699         [NL802154_DEV_ATTR_SECLEVEL_EXEMPT] = { NLA_U8 },
1700         [NL802154_DEV_ATTR_KEY_MODE] = { NLA_U32 },
1701 };
1702
1703 static int
1704 ieee802154_llsec_parse_device(struct nlattr *nla,
1705                               struct ieee802154_llsec_device *dev)
1706 {
1707         struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
1708
1709         if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, nla, nl802154_dev_policy, NULL))
1710                 return -EINVAL;
1711
1712         memset(dev, 0, sizeof(*dev));
1713
1714         if (!attrs[NL802154_DEV_ATTR_FRAME_COUNTER] ||
1715             !attrs[NL802154_DEV_ATTR_PAN_ID] ||
1716             !attrs[NL802154_DEV_ATTR_SHORT_ADDR] ||
1717             !attrs[NL802154_DEV_ATTR_EXTENDED_ADDR] ||
1718             !attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT] ||
1719             !attrs[NL802154_DEV_ATTR_KEY_MODE])
1720                 return -EINVAL;
1721
1722         /* TODO be32 */
1723         dev->frame_counter = nla_get_u32(attrs[NL802154_DEV_ATTR_FRAME_COUNTER]);
1724         dev->pan_id = nla_get_le16(attrs[NL802154_DEV_ATTR_PAN_ID]);
1725         dev->short_addr = nla_get_le16(attrs[NL802154_DEV_ATTR_SHORT_ADDR]);
1726         /* TODO rename hwaddr to extended_addr */
1727         dev->hwaddr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
1728         dev->seclevel_exempt = nla_get_u8(attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT]);
1729         dev->key_mode = nla_get_u32(attrs[NL802154_DEV_ATTR_KEY_MODE]);
1730
1731         if (dev->key_mode > NL802154_DEVKEY_MAX ||
1732             (dev->seclevel_exempt != 0 && dev->seclevel_exempt != 1))
1733                 return -EINVAL;
1734
1735         return 0;
1736 }
1737
1738 static int nl802154_add_llsec_dev(struct sk_buff *skb, struct genl_info *info)
1739 {
1740         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1741         struct net_device *dev = info->user_ptr[1];
1742         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1743         struct ieee802154_llsec_device dev_desc;
1744
1745         if (ieee802154_llsec_parse_device(info->attrs[NL802154_ATTR_SEC_DEVICE],
1746                                           &dev_desc) < 0)
1747                 return -EINVAL;
1748
1749         return rdev_add_device(rdev, wpan_dev, &dev_desc);
1750 }
1751
1752 static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info)
1753 {
1754         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1755         struct net_device *dev = info->user_ptr[1];
1756         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1757         struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
1758         __le64 extended_addr;
1759
1760         if (nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVICE], nl802154_dev_policy, info->extack))
1761                 return -EINVAL;
1762
1763         if (!attrs[NL802154_DEV_ATTR_EXTENDED_ADDR])
1764                 return -EINVAL;
1765
1766         extended_addr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
1767         return rdev_del_device(rdev, wpan_dev, extended_addr);
1768 }
1769
1770 static int nl802154_send_devkey(struct sk_buff *msg, u32 cmd, u32 portid,
1771                                 u32 seq, int flags,
1772                                 struct cfg802154_registered_device *rdev,
1773                                 struct net_device *dev, __le64 extended_addr,
1774                                 const struct ieee802154_llsec_device_key *devkey)
1775 {
1776         void *hdr;
1777         struct nlattr *nl_devkey, *nl_key_id;
1778
1779         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1780         if (!hdr)
1781                 return -1;
1782
1783         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1784                 goto nla_put_failure;
1785
1786         nl_devkey = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVKEY);
1787         if (!nl_devkey)
1788                 goto nla_put_failure;
1789
1790         if (nla_put_le64(msg, NL802154_DEVKEY_ATTR_EXTENDED_ADDR,
1791                          extended_addr, NL802154_DEVKEY_ATTR_PAD) ||
1792             nla_put_u32(msg, NL802154_DEVKEY_ATTR_FRAME_COUNTER,
1793                         devkey->frame_counter))
1794                 goto nla_put_failure;
1795
1796         nl_key_id = nla_nest_start_noflag(msg, NL802154_DEVKEY_ATTR_ID);
1797         if (!nl_key_id)
1798                 goto nla_put_failure;
1799
1800         if (ieee802154_llsec_send_key_id(msg, &devkey->key_id) < 0)
1801                 goto nla_put_failure;
1802
1803         nla_nest_end(msg, nl_key_id);
1804         nla_nest_end(msg, nl_devkey);
1805         genlmsg_end(msg, hdr);
1806
1807         return 0;
1808
1809 nla_put_failure:
1810         genlmsg_cancel(msg, hdr);
1811         return -EMSGSIZE;
1812 }
1813
1814 static int
1815 nl802154_dump_llsec_devkey(struct sk_buff *skb, struct netlink_callback *cb)
1816 {
1817         struct cfg802154_registered_device *rdev = NULL;
1818         struct ieee802154_llsec_device_key *kpos;
1819         struct ieee802154_llsec_device *dpos;
1820         struct ieee802154_llsec_table *table;
1821         struct wpan_dev *wpan_dev;
1822         int err;
1823
1824         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1825         if (err)
1826                 return err;
1827
1828         if (!wpan_dev->netdev) {
1829                 err = -EINVAL;
1830                 goto out_err;
1831         }
1832
1833         rdev_lock_llsec_table(rdev, wpan_dev);
1834         rdev_get_llsec_table(rdev, wpan_dev, &table);
1835
1836         /* TODO make it like station dump */
1837         if (cb->args[2])
1838                 goto out;
1839
1840         /* TODO look if remove devkey and do some nested attribute */
1841         list_for_each_entry(dpos, &table->devices, list) {
1842                 list_for_each_entry(kpos, &dpos->keys, list) {
1843                         if (nl802154_send_devkey(skb,
1844                                                  NL802154_CMD_NEW_SEC_LEVEL,
1845                                                  NETLINK_CB(cb->skb).portid,
1846                                                  cb->nlh->nlmsg_seq,
1847                                                  NLM_F_MULTI, rdev,
1848                                                  wpan_dev->netdev,
1849                                                  dpos->hwaddr,
1850                                                  kpos) < 0) {
1851                                 /* TODO */
1852                                 err = -EIO;
1853                                 rdev_unlock_llsec_table(rdev, wpan_dev);
1854                                 goto out_err;
1855                         }
1856                 }
1857         }
1858
1859         cb->args[2] = 1;
1860
1861 out:
1862         rdev_unlock_llsec_table(rdev, wpan_dev);
1863         err = skb->len;
1864 out_err:
1865         nl802154_finish_wpan_dev_dump(rdev);
1866
1867         return err;
1868 }
1869
1870 static const struct nla_policy nl802154_devkey_policy[NL802154_DEVKEY_ATTR_MAX + 1] = {
1871         [NL802154_DEVKEY_ATTR_FRAME_COUNTER] = { NLA_U32 },
1872         [NL802154_DEVKEY_ATTR_EXTENDED_ADDR] = { NLA_U64 },
1873         [NL802154_DEVKEY_ATTR_ID] = { NLA_NESTED },
1874 };
1875
1876 static int nl802154_add_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
1877 {
1878         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1879         struct net_device *dev = info->user_ptr[1];
1880         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1881         struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
1882         struct ieee802154_llsec_device_key key;
1883         __le64 extended_addr;
1884
1885         if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
1886             nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack) < 0)
1887                 return -EINVAL;
1888
1889         if (!attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER] ||
1890             !attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
1891                 return -EINVAL;
1892
1893         /* TODO change key.id ? */
1894         if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
1895                                           &key.key_id) < 0)
1896                 return -ENOBUFS;
1897
1898         /* TODO be32 */
1899         key.frame_counter = nla_get_u32(attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER]);
1900         /* TODO change naming hwaddr -> extended_addr
1901          * check unique identifier short+pan OR extended_addr
1902          */
1903         extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
1904         return rdev_add_devkey(rdev, wpan_dev, extended_addr, &key);
1905 }
1906
1907 static int nl802154_del_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
1908 {
1909         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1910         struct net_device *dev = info->user_ptr[1];
1911         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1912         struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
1913         struct ieee802154_llsec_device_key key;
1914         __le64 extended_addr;
1915
1916         if (nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack))
1917                 return -EINVAL;
1918
1919         if (!attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
1920                 return -EINVAL;
1921
1922         /* TODO change key.id ? */
1923         if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
1924                                           &key.key_id) < 0)
1925                 return -ENOBUFS;
1926
1927         /* TODO change naming hwaddr -> extended_addr
1928          * check unique identifier short+pan OR extended_addr
1929          */
1930         extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
1931         return rdev_del_devkey(rdev, wpan_dev, extended_addr, &key);
1932 }
1933
1934 static int nl802154_send_seclevel(struct sk_buff *msg, u32 cmd, u32 portid,
1935                                   u32 seq, int flags,
1936                                   struct cfg802154_registered_device *rdev,
1937                                   struct net_device *dev,
1938                                   const struct ieee802154_llsec_seclevel *sl)
1939 {
1940         void *hdr;
1941         struct nlattr *nl_seclevel;
1942
1943         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1944         if (!hdr)
1945                 return -1;
1946
1947         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1948                 goto nla_put_failure;
1949
1950         nl_seclevel = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_LEVEL);
1951         if (!nl_seclevel)
1952                 goto nla_put_failure;
1953
1954         if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_FRAME, sl->frame_type) ||
1955             nla_put_u32(msg, NL802154_SECLEVEL_ATTR_LEVELS, sl->sec_levels) ||
1956             nla_put_u8(msg, NL802154_SECLEVEL_ATTR_DEV_OVERRIDE,
1957                        sl->device_override))
1958                 goto nla_put_failure;
1959
1960         if (sl->frame_type == NL802154_FRAME_CMD) {
1961                 if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_CMD_FRAME,
1962                                 sl->cmd_frame_id))
1963                         goto nla_put_failure;
1964         }
1965
1966         nla_nest_end(msg, nl_seclevel);
1967         genlmsg_end(msg, hdr);
1968
1969         return 0;
1970
1971 nla_put_failure:
1972         genlmsg_cancel(msg, hdr);
1973         return -EMSGSIZE;
1974 }
1975
1976 static int
1977 nl802154_dump_llsec_seclevel(struct sk_buff *skb, struct netlink_callback *cb)
1978 {
1979         struct cfg802154_registered_device *rdev = NULL;
1980         struct ieee802154_llsec_seclevel *sl;
1981         struct ieee802154_llsec_table *table;
1982         struct wpan_dev *wpan_dev;
1983         int err;
1984
1985         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1986         if (err)
1987                 return err;
1988
1989         if (!wpan_dev->netdev) {
1990                 err = -EINVAL;
1991                 goto out_err;
1992         }
1993
1994         rdev_lock_llsec_table(rdev, wpan_dev);
1995         rdev_get_llsec_table(rdev, wpan_dev, &table);
1996
1997         /* TODO make it like station dump */
1998         if (cb->args[2])
1999                 goto out;
2000
2001         list_for_each_entry(sl, &table->security_levels, list) {
2002                 if (nl802154_send_seclevel(skb, NL802154_CMD_NEW_SEC_LEVEL,
2003                                            NETLINK_CB(cb->skb).portid,
2004                                            cb->nlh->nlmsg_seq, NLM_F_MULTI,
2005                                            rdev, wpan_dev->netdev, sl) < 0) {
2006                         /* TODO */
2007                         err = -EIO;
2008                         rdev_unlock_llsec_table(rdev, wpan_dev);
2009                         goto out_err;
2010                 }
2011         }
2012
2013         cb->args[2] = 1;
2014
2015 out:
2016         rdev_unlock_llsec_table(rdev, wpan_dev);
2017         err = skb->len;
2018 out_err:
2019         nl802154_finish_wpan_dev_dump(rdev);
2020
2021         return err;
2022 }
2023
2024 static const struct nla_policy nl802154_seclevel_policy[NL802154_SECLEVEL_ATTR_MAX + 1] = {
2025         [NL802154_SECLEVEL_ATTR_LEVELS] = { .type = NLA_U8 },
2026         [NL802154_SECLEVEL_ATTR_FRAME] = { .type = NLA_U32 },
2027         [NL802154_SECLEVEL_ATTR_CMD_FRAME] = { .type = NLA_U32 },
2028         [NL802154_SECLEVEL_ATTR_DEV_OVERRIDE] = { .type = NLA_U8 },
2029 };
2030
2031 static int
2032 llsec_parse_seclevel(struct nlattr *nla, struct ieee802154_llsec_seclevel *sl)
2033 {
2034         struct nlattr *attrs[NL802154_SECLEVEL_ATTR_MAX + 1];
2035
2036         if (!nla || nla_parse_nested_deprecated(attrs, NL802154_SECLEVEL_ATTR_MAX, nla, nl802154_seclevel_policy, NULL))
2037                 return -EINVAL;
2038
2039         memset(sl, 0, sizeof(*sl));
2040
2041         if (!attrs[NL802154_SECLEVEL_ATTR_LEVELS] ||
2042             !attrs[NL802154_SECLEVEL_ATTR_FRAME] ||
2043             !attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE])
2044                 return -EINVAL;
2045
2046         sl->sec_levels = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_LEVELS]);
2047         sl->frame_type = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_FRAME]);
2048         sl->device_override = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE]);
2049         if (sl->frame_type > NL802154_FRAME_MAX ||
2050             (sl->device_override != 0 && sl->device_override != 1))
2051                 return -EINVAL;
2052
2053         if (sl->frame_type == NL802154_FRAME_CMD) {
2054                 if (!attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME])
2055                         return -EINVAL;
2056
2057                 sl->cmd_frame_id = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME]);
2058                 if (sl->cmd_frame_id > NL802154_CMD_FRAME_MAX)
2059                         return -EINVAL;
2060         }
2061
2062         return 0;
2063 }
2064
2065 static int nl802154_add_llsec_seclevel(struct sk_buff *skb,
2066                                        struct genl_info *info)
2067 {
2068         struct cfg802154_registered_device *rdev = info->user_ptr[0];
2069         struct net_device *dev = info->user_ptr[1];
2070         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2071         struct ieee802154_llsec_seclevel sl;
2072
2073         if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
2074                                  &sl) < 0)
2075                 return -EINVAL;
2076
2077         return rdev_add_seclevel(rdev, wpan_dev, &sl);
2078 }
2079
2080 static int nl802154_del_llsec_seclevel(struct sk_buff *skb,
2081                                        struct genl_info *info)
2082 {
2083         struct cfg802154_registered_device *rdev = info->user_ptr[0];
2084         struct net_device *dev = info->user_ptr[1];
2085         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2086         struct ieee802154_llsec_seclevel sl;
2087
2088         if (!info->attrs[NL802154_ATTR_SEC_LEVEL] ||
2089             llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
2090                                  &sl) < 0)
2091                 return -EINVAL;
2092
2093         return rdev_del_seclevel(rdev, wpan_dev, &sl);
2094 }
2095 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2096
2097 #define NL802154_FLAG_NEED_WPAN_PHY     0x01
2098 #define NL802154_FLAG_NEED_NETDEV       0x02
2099 #define NL802154_FLAG_NEED_RTNL         0x04
2100 #define NL802154_FLAG_CHECK_NETDEV_UP   0x08
2101 #define NL802154_FLAG_NEED_NETDEV_UP    (NL802154_FLAG_NEED_NETDEV |\
2102                                          NL802154_FLAG_CHECK_NETDEV_UP)
2103 #define NL802154_FLAG_NEED_WPAN_DEV     0x10
2104 #define NL802154_FLAG_NEED_WPAN_DEV_UP  (NL802154_FLAG_NEED_WPAN_DEV |\
2105                                          NL802154_FLAG_CHECK_NETDEV_UP)
2106
2107 static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
2108                              struct genl_info *info)
2109 {
2110         struct cfg802154_registered_device *rdev;
2111         struct wpan_dev *wpan_dev;
2112         struct net_device *dev;
2113         bool rtnl = ops->internal_flags & NL802154_FLAG_NEED_RTNL;
2114
2115         if (rtnl)
2116                 rtnl_lock();
2117
2118         if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_PHY) {
2119                 rdev = cfg802154_get_dev_from_info(genl_info_net(info), info);
2120                 if (IS_ERR(rdev)) {
2121                         if (rtnl)
2122                                 rtnl_unlock();
2123                         return PTR_ERR(rdev);
2124                 }
2125                 info->user_ptr[0] = rdev;
2126         } else if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV ||
2127                    ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
2128                 ASSERT_RTNL();
2129                 wpan_dev = __cfg802154_wpan_dev_from_attrs(genl_info_net(info),
2130                                                            info->attrs);
2131                 if (IS_ERR(wpan_dev)) {
2132                         if (rtnl)
2133                                 rtnl_unlock();
2134                         return PTR_ERR(wpan_dev);
2135                 }
2136
2137                 dev = wpan_dev->netdev;
2138                 rdev = wpan_phy_to_rdev(wpan_dev->wpan_phy);
2139
2140                 if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV) {
2141                         if (!dev) {
2142                                 if (rtnl)
2143                                         rtnl_unlock();
2144                                 return -EINVAL;
2145                         }
2146
2147                         info->user_ptr[1] = dev;
2148                 } else {
2149                         info->user_ptr[1] = wpan_dev;
2150                 }
2151
2152                 if (dev) {
2153                         if (ops->internal_flags & NL802154_FLAG_CHECK_NETDEV_UP &&
2154                             !netif_running(dev)) {
2155                                 if (rtnl)
2156                                         rtnl_unlock();
2157                                 return -ENETDOWN;
2158                         }
2159
2160                         dev_hold(dev);
2161                 }
2162
2163                 info->user_ptr[0] = rdev;
2164         }
2165
2166         return 0;
2167 }
2168
2169 static void nl802154_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
2170                                struct genl_info *info)
2171 {
2172         if (info->user_ptr[1]) {
2173                 if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
2174                         struct wpan_dev *wpan_dev = info->user_ptr[1];
2175
2176                         if (wpan_dev->netdev)
2177                                 dev_put(wpan_dev->netdev);
2178                 } else {
2179                         dev_put(info->user_ptr[1]);
2180                 }
2181         }
2182
2183         if (ops->internal_flags & NL802154_FLAG_NEED_RTNL)
2184                 rtnl_unlock();
2185 }
2186
2187 static const struct genl_ops nl802154_ops[] = {
2188         {
2189                 .cmd = NL802154_CMD_GET_WPAN_PHY,
2190                 .validate = GENL_DONT_VALIDATE_STRICT |
2191                             GENL_DONT_VALIDATE_DUMP_STRICT,
2192                 .doit = nl802154_get_wpan_phy,
2193                 .dumpit = nl802154_dump_wpan_phy,
2194                 .done = nl802154_dump_wpan_phy_done,
2195                 /* can be retrieved by unprivileged users */
2196                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2197                                   NL802154_FLAG_NEED_RTNL,
2198         },
2199         {
2200                 .cmd = NL802154_CMD_GET_INTERFACE,
2201                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2202                 .doit = nl802154_get_interface,
2203                 .dumpit = nl802154_dump_interface,
2204                 /* can be retrieved by unprivileged users */
2205                 .internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
2206                                   NL802154_FLAG_NEED_RTNL,
2207         },
2208         {
2209                 .cmd = NL802154_CMD_NEW_INTERFACE,
2210                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2211                 .doit = nl802154_new_interface,
2212                 .flags = GENL_ADMIN_PERM,
2213                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2214                                   NL802154_FLAG_NEED_RTNL,
2215         },
2216         {
2217                 .cmd = NL802154_CMD_DEL_INTERFACE,
2218                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2219                 .doit = nl802154_del_interface,
2220                 .flags = GENL_ADMIN_PERM,
2221                 .internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
2222                                   NL802154_FLAG_NEED_RTNL,
2223         },
2224         {
2225                 .cmd = NL802154_CMD_SET_CHANNEL,
2226                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2227                 .doit = nl802154_set_channel,
2228                 .flags = GENL_ADMIN_PERM,
2229                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2230                                   NL802154_FLAG_NEED_RTNL,
2231         },
2232         {
2233                 .cmd = NL802154_CMD_SET_CCA_MODE,
2234                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2235                 .doit = nl802154_set_cca_mode,
2236                 .flags = GENL_ADMIN_PERM,
2237                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2238                                   NL802154_FLAG_NEED_RTNL,
2239         },
2240         {
2241                 .cmd = NL802154_CMD_SET_CCA_ED_LEVEL,
2242                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2243                 .doit = nl802154_set_cca_ed_level,
2244                 .flags = GENL_ADMIN_PERM,
2245                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2246                                   NL802154_FLAG_NEED_RTNL,
2247         },
2248         {
2249                 .cmd = NL802154_CMD_SET_TX_POWER,
2250                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2251                 .doit = nl802154_set_tx_power,
2252                 .flags = GENL_ADMIN_PERM,
2253                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2254                                   NL802154_FLAG_NEED_RTNL,
2255         },
2256         {
2257                 .cmd = NL802154_CMD_SET_WPAN_PHY_NETNS,
2258                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2259                 .doit = nl802154_wpan_phy_netns,
2260                 .flags = GENL_ADMIN_PERM,
2261                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2262                                   NL802154_FLAG_NEED_RTNL,
2263         },
2264         {
2265                 .cmd = NL802154_CMD_SET_PAN_ID,
2266                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2267                 .doit = nl802154_set_pan_id,
2268                 .flags = GENL_ADMIN_PERM,
2269                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2270                                   NL802154_FLAG_NEED_RTNL,
2271         },
2272         {
2273                 .cmd = NL802154_CMD_SET_SHORT_ADDR,
2274                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2275                 .doit = nl802154_set_short_addr,
2276                 .flags = GENL_ADMIN_PERM,
2277                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2278                                   NL802154_FLAG_NEED_RTNL,
2279         },
2280         {
2281                 .cmd = NL802154_CMD_SET_BACKOFF_EXPONENT,
2282                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2283                 .doit = nl802154_set_backoff_exponent,
2284                 .flags = GENL_ADMIN_PERM,
2285                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2286                                   NL802154_FLAG_NEED_RTNL,
2287         },
2288         {
2289                 .cmd = NL802154_CMD_SET_MAX_CSMA_BACKOFFS,
2290                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2291                 .doit = nl802154_set_max_csma_backoffs,
2292                 .flags = GENL_ADMIN_PERM,
2293                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2294                                   NL802154_FLAG_NEED_RTNL,
2295         },
2296         {
2297                 .cmd = NL802154_CMD_SET_MAX_FRAME_RETRIES,
2298                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2299                 .doit = nl802154_set_max_frame_retries,
2300                 .flags = GENL_ADMIN_PERM,
2301                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2302                                   NL802154_FLAG_NEED_RTNL,
2303         },
2304         {
2305                 .cmd = NL802154_CMD_SET_LBT_MODE,
2306                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2307                 .doit = nl802154_set_lbt_mode,
2308                 .flags = GENL_ADMIN_PERM,
2309                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2310                                   NL802154_FLAG_NEED_RTNL,
2311         },
2312         {
2313                 .cmd = NL802154_CMD_SET_ACKREQ_DEFAULT,
2314                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2315                 .doit = nl802154_set_ackreq_default,
2316                 .flags = GENL_ADMIN_PERM,
2317                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2318                                   NL802154_FLAG_NEED_RTNL,
2319         },
2320 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
2321         {
2322                 .cmd = NL802154_CMD_SET_SEC_PARAMS,
2323                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2324                 .doit = nl802154_set_llsec_params,
2325                 .flags = GENL_ADMIN_PERM,
2326                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2327                                   NL802154_FLAG_NEED_RTNL,
2328         },
2329         {
2330                 .cmd = NL802154_CMD_GET_SEC_KEY,
2331                 .validate = GENL_DONT_VALIDATE_STRICT |
2332                             GENL_DONT_VALIDATE_DUMP_STRICT,
2333                 /* TODO .doit by matching key id? */
2334                 .dumpit = nl802154_dump_llsec_key,
2335                 .flags = GENL_ADMIN_PERM,
2336                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2337                                   NL802154_FLAG_NEED_RTNL,
2338         },
2339         {
2340                 .cmd = NL802154_CMD_NEW_SEC_KEY,
2341                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2342                 .doit = nl802154_add_llsec_key,
2343                 .flags = GENL_ADMIN_PERM,
2344                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2345                                   NL802154_FLAG_NEED_RTNL,
2346         },
2347         {
2348                 .cmd = NL802154_CMD_DEL_SEC_KEY,
2349                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2350                 .doit = nl802154_del_llsec_key,
2351                 .flags = GENL_ADMIN_PERM,
2352                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2353                                   NL802154_FLAG_NEED_RTNL,
2354         },
2355         /* TODO unique identifier must short+pan OR extended_addr */
2356         {
2357                 .cmd = NL802154_CMD_GET_SEC_DEV,
2358                 .validate = GENL_DONT_VALIDATE_STRICT |
2359                             GENL_DONT_VALIDATE_DUMP_STRICT,
2360                 /* TODO .doit by matching extended_addr? */
2361                 .dumpit = nl802154_dump_llsec_dev,
2362                 .flags = GENL_ADMIN_PERM,
2363                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2364                                   NL802154_FLAG_NEED_RTNL,
2365         },
2366         {
2367                 .cmd = NL802154_CMD_NEW_SEC_DEV,
2368                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2369                 .doit = nl802154_add_llsec_dev,
2370                 .flags = GENL_ADMIN_PERM,
2371                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2372                                   NL802154_FLAG_NEED_RTNL,
2373         },
2374         {
2375                 .cmd = NL802154_CMD_DEL_SEC_DEV,
2376                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2377                 .doit = nl802154_del_llsec_dev,
2378                 .flags = GENL_ADMIN_PERM,
2379                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2380                                   NL802154_FLAG_NEED_RTNL,
2381         },
2382         /* TODO remove complete devkey, put it as nested? */
2383         {
2384                 .cmd = NL802154_CMD_GET_SEC_DEVKEY,
2385                 .validate = GENL_DONT_VALIDATE_STRICT |
2386                             GENL_DONT_VALIDATE_DUMP_STRICT,
2387                 /* TODO doit by matching ??? */
2388                 .dumpit = nl802154_dump_llsec_devkey,
2389                 .flags = GENL_ADMIN_PERM,
2390                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2391                                   NL802154_FLAG_NEED_RTNL,
2392         },
2393         {
2394                 .cmd = NL802154_CMD_NEW_SEC_DEVKEY,
2395                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2396                 .doit = nl802154_add_llsec_devkey,
2397                 .flags = GENL_ADMIN_PERM,
2398                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2399                                   NL802154_FLAG_NEED_RTNL,
2400         },
2401         {
2402                 .cmd = NL802154_CMD_DEL_SEC_DEVKEY,
2403                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2404                 .doit = nl802154_del_llsec_devkey,
2405                 .flags = GENL_ADMIN_PERM,
2406                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2407                                   NL802154_FLAG_NEED_RTNL,
2408         },
2409         {
2410                 .cmd = NL802154_CMD_GET_SEC_LEVEL,
2411                 .validate = GENL_DONT_VALIDATE_STRICT |
2412                             GENL_DONT_VALIDATE_DUMP_STRICT,
2413                 /* TODO .doit by matching frame_type? */
2414                 .dumpit = nl802154_dump_llsec_seclevel,
2415                 .flags = GENL_ADMIN_PERM,
2416                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2417                                   NL802154_FLAG_NEED_RTNL,
2418         },
2419         {
2420                 .cmd = NL802154_CMD_NEW_SEC_LEVEL,
2421                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2422                 .doit = nl802154_add_llsec_seclevel,
2423                 .flags = GENL_ADMIN_PERM,
2424                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2425                                   NL802154_FLAG_NEED_RTNL,
2426         },
2427         {
2428                 .cmd = NL802154_CMD_DEL_SEC_LEVEL,
2429                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2430                 /* TODO match frame_type only? */
2431                 .doit = nl802154_del_llsec_seclevel,
2432                 .flags = GENL_ADMIN_PERM,
2433                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2434                                   NL802154_FLAG_NEED_RTNL,
2435         },
2436 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2437 };
2438
2439 static struct genl_family nl802154_fam __ro_after_init = {
2440         .name = NL802154_GENL_NAME,     /* have users key off the name instead */
2441         .hdrsize = 0,                   /* no private header */
2442         .version = 1,                   /* no particular meaning now */
2443         .maxattr = NL802154_ATTR_MAX,
2444         .policy = nl802154_policy,
2445         .netnsok = true,
2446         .pre_doit = nl802154_pre_doit,
2447         .post_doit = nl802154_post_doit,
2448         .module = THIS_MODULE,
2449         .ops = nl802154_ops,
2450         .n_ops = ARRAY_SIZE(nl802154_ops),
2451         .mcgrps = nl802154_mcgrps,
2452         .n_mcgrps = ARRAY_SIZE(nl802154_mcgrps),
2453 };
2454
2455 /* initialisation/exit functions */
2456 int __init nl802154_init(void)
2457 {
2458         return genl_register_family(&nl802154_fam);
2459 }
2460
2461 void nl802154_exit(void)
2462 {
2463         genl_unregister_family(&nl802154_fam);
2464 }