net: ieee802154: forbid monitor for del llsec seclevel
[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 (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1388                 return -EOPNOTSUPP;
1389
1390         if (info->attrs[NL802154_ATTR_SEC_ENABLED]) {
1391                 u8 enabled;
1392
1393                 enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
1394                 if (enabled != 0 && enabled != 1)
1395                         return -EINVAL;
1396
1397                 params.enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]);
1398                 changed |= IEEE802154_LLSEC_PARAM_ENABLED;
1399         }
1400
1401         if (info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID]) {
1402                 ret = ieee802154_llsec_parse_key_id(info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID],
1403                                                     &params.out_key);
1404                 if (ret < 0)
1405                         return ret;
1406
1407                 changed |= IEEE802154_LLSEC_PARAM_OUT_KEY;
1408         }
1409
1410         if (info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]) {
1411                 params.out_level = nla_get_u32(info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]);
1412                 if (params.out_level > NL802154_SECLEVEL_MAX)
1413                         return -EINVAL;
1414
1415                 changed |= IEEE802154_LLSEC_PARAM_OUT_LEVEL;
1416         }
1417
1418         if (info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]) {
1419                 params.frame_counter = nla_get_be32(info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]);
1420                 changed |= IEEE802154_LLSEC_PARAM_FRAME_COUNTER;
1421         }
1422
1423         return rdev_set_llsec_params(rdev, wpan_dev, &params, changed);
1424 }
1425
1426 static int nl802154_send_key(struct sk_buff *msg, u32 cmd, u32 portid,
1427                              u32 seq, int flags,
1428                              struct cfg802154_registered_device *rdev,
1429                              struct net_device *dev,
1430                              const struct ieee802154_llsec_key_entry *key)
1431 {
1432         void *hdr;
1433         u32 commands[NL802154_CMD_FRAME_NR_IDS / 32];
1434         struct nlattr *nl_key, *nl_key_id;
1435
1436         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1437         if (!hdr)
1438                 return -1;
1439
1440         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1441                 goto nla_put_failure;
1442
1443         nl_key = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_KEY);
1444         if (!nl_key)
1445                 goto nla_put_failure;
1446
1447         nl_key_id = nla_nest_start_noflag(msg, NL802154_KEY_ATTR_ID);
1448         if (!nl_key_id)
1449                 goto nla_put_failure;
1450
1451         if (ieee802154_llsec_send_key_id(msg, &key->id) < 0)
1452                 goto nla_put_failure;
1453
1454         nla_nest_end(msg, nl_key_id);
1455
1456         if (nla_put_u8(msg, NL802154_KEY_ATTR_USAGE_FRAMES,
1457                        key->key->frame_types))
1458                 goto nla_put_failure;
1459
1460         if (key->key->frame_types & BIT(NL802154_FRAME_CMD)) {
1461                 /* TODO for each nested */
1462                 memset(commands, 0, sizeof(commands));
1463                 commands[7] = key->key->cmd_frame_ids;
1464                 if (nla_put(msg, NL802154_KEY_ATTR_USAGE_CMDS,
1465                             sizeof(commands), commands))
1466                         goto nla_put_failure;
1467         }
1468
1469         if (nla_put(msg, NL802154_KEY_ATTR_BYTES, NL802154_KEY_SIZE,
1470                     key->key->key))
1471                 goto nla_put_failure;
1472
1473         nla_nest_end(msg, nl_key);
1474         genlmsg_end(msg, hdr);
1475
1476         return 0;
1477
1478 nla_put_failure:
1479         genlmsg_cancel(msg, hdr);
1480         return -EMSGSIZE;
1481 }
1482
1483 static int
1484 nl802154_dump_llsec_key(struct sk_buff *skb, struct netlink_callback *cb)
1485 {
1486         struct cfg802154_registered_device *rdev = NULL;
1487         struct ieee802154_llsec_key_entry *key;
1488         struct ieee802154_llsec_table *table;
1489         struct wpan_dev *wpan_dev;
1490         int err;
1491
1492         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1493         if (err)
1494                 return err;
1495
1496         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
1497                 err = skb->len;
1498                 goto out_err;
1499         }
1500
1501         if (!wpan_dev->netdev) {
1502                 err = -EINVAL;
1503                 goto out_err;
1504         }
1505
1506         rdev_lock_llsec_table(rdev, wpan_dev);
1507         rdev_get_llsec_table(rdev, wpan_dev, &table);
1508
1509         /* TODO make it like station dump */
1510         if (cb->args[2])
1511                 goto out;
1512
1513         list_for_each_entry(key, &table->keys, list) {
1514                 if (nl802154_send_key(skb, NL802154_CMD_NEW_SEC_KEY,
1515                                       NETLINK_CB(cb->skb).portid,
1516                                       cb->nlh->nlmsg_seq, NLM_F_MULTI,
1517                                       rdev, wpan_dev->netdev, key) < 0) {
1518                         /* TODO */
1519                         err = -EIO;
1520                         rdev_unlock_llsec_table(rdev, wpan_dev);
1521                         goto out_err;
1522                 }
1523         }
1524
1525         cb->args[2] = 1;
1526
1527 out:
1528         rdev_unlock_llsec_table(rdev, wpan_dev);
1529         err = skb->len;
1530 out_err:
1531         nl802154_finish_wpan_dev_dump(rdev);
1532
1533         return err;
1534 }
1535
1536 static const struct nla_policy nl802154_key_policy[NL802154_KEY_ATTR_MAX + 1] = {
1537         [NL802154_KEY_ATTR_ID] = { NLA_NESTED },
1538         /* TODO handle it as for_each_nested and NLA_FLAG? */
1539         [NL802154_KEY_ATTR_USAGE_FRAMES] = { NLA_U8 },
1540         /* TODO handle it as for_each_nested, not static array? */
1541         [NL802154_KEY_ATTR_USAGE_CMDS] = { .len = NL802154_CMD_FRAME_NR_IDS / 8 },
1542         [NL802154_KEY_ATTR_BYTES] = { .len = NL802154_KEY_SIZE },
1543 };
1544
1545 static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info)
1546 {
1547         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1548         struct net_device *dev = info->user_ptr[1];
1549         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1550         struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
1551         struct ieee802154_llsec_key key = { };
1552         struct ieee802154_llsec_key_id id = { };
1553         u32 commands[NL802154_CMD_FRAME_NR_IDS / 32] = { };
1554
1555         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1556                 return -EOPNOTSUPP;
1557
1558         if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
1559             nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
1560                 return -EINVAL;
1561
1562         if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] ||
1563             !attrs[NL802154_KEY_ATTR_BYTES])
1564                 return -EINVAL;
1565
1566         if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1567                 return -ENOBUFS;
1568
1569         key.frame_types = nla_get_u8(attrs[NL802154_KEY_ATTR_USAGE_FRAMES]);
1570         if (key.frame_types > BIT(NL802154_FRAME_MAX) ||
1571             ((key.frame_types & BIT(NL802154_FRAME_CMD)) &&
1572              !attrs[NL802154_KEY_ATTR_USAGE_CMDS]))
1573                 return -EINVAL;
1574
1575         if (attrs[NL802154_KEY_ATTR_USAGE_CMDS]) {
1576                 /* TODO for each nested */
1577                 nla_memcpy(commands, attrs[NL802154_KEY_ATTR_USAGE_CMDS],
1578                            NL802154_CMD_FRAME_NR_IDS / 8);
1579
1580                 /* TODO understand the -EINVAL logic here? last condition */
1581                 if (commands[0] || commands[1] || commands[2] || commands[3] ||
1582                     commands[4] || commands[5] || commands[6] ||
1583                     commands[7] > BIT(NL802154_CMD_FRAME_MAX))
1584                         return -EINVAL;
1585
1586                 key.cmd_frame_ids = commands[7];
1587         } else {
1588                 key.cmd_frame_ids = 0;
1589         }
1590
1591         nla_memcpy(key.key, attrs[NL802154_KEY_ATTR_BYTES], NL802154_KEY_SIZE);
1592
1593         if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1594                 return -ENOBUFS;
1595
1596         return rdev_add_llsec_key(rdev, wpan_dev, &id, &key);
1597 }
1598
1599 static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info)
1600 {
1601         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1602         struct net_device *dev = info->user_ptr[1];
1603         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1604         struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
1605         struct ieee802154_llsec_key_id id;
1606
1607         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1608                 return -EOPNOTSUPP;
1609
1610         if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
1611             nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
1612                 return -EINVAL;
1613
1614         if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0)
1615                 return -ENOBUFS;
1616
1617         return rdev_del_llsec_key(rdev, wpan_dev, &id);
1618 }
1619
1620 static int nl802154_send_device(struct sk_buff *msg, u32 cmd, u32 portid,
1621                                 u32 seq, int flags,
1622                                 struct cfg802154_registered_device *rdev,
1623                                 struct net_device *dev,
1624                                 const struct ieee802154_llsec_device *dev_desc)
1625 {
1626         void *hdr;
1627         struct nlattr *nl_device;
1628
1629         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1630         if (!hdr)
1631                 return -1;
1632
1633         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1634                 goto nla_put_failure;
1635
1636         nl_device = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVICE);
1637         if (!nl_device)
1638                 goto nla_put_failure;
1639
1640         if (nla_put_u32(msg, NL802154_DEV_ATTR_FRAME_COUNTER,
1641                         dev_desc->frame_counter) ||
1642             nla_put_le16(msg, NL802154_DEV_ATTR_PAN_ID, dev_desc->pan_id) ||
1643             nla_put_le16(msg, NL802154_DEV_ATTR_SHORT_ADDR,
1644                          dev_desc->short_addr) ||
1645             nla_put_le64(msg, NL802154_DEV_ATTR_EXTENDED_ADDR,
1646                          dev_desc->hwaddr, NL802154_DEV_ATTR_PAD) ||
1647             nla_put_u8(msg, NL802154_DEV_ATTR_SECLEVEL_EXEMPT,
1648                        dev_desc->seclevel_exempt) ||
1649             nla_put_u32(msg, NL802154_DEV_ATTR_KEY_MODE, dev_desc->key_mode))
1650                 goto nla_put_failure;
1651
1652         nla_nest_end(msg, nl_device);
1653         genlmsg_end(msg, hdr);
1654
1655         return 0;
1656
1657 nla_put_failure:
1658         genlmsg_cancel(msg, hdr);
1659         return -EMSGSIZE;
1660 }
1661
1662 static int
1663 nl802154_dump_llsec_dev(struct sk_buff *skb, struct netlink_callback *cb)
1664 {
1665         struct cfg802154_registered_device *rdev = NULL;
1666         struct ieee802154_llsec_device *dev;
1667         struct ieee802154_llsec_table *table;
1668         struct wpan_dev *wpan_dev;
1669         int err;
1670
1671         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1672         if (err)
1673                 return err;
1674
1675         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
1676                 err = skb->len;
1677                 goto out_err;
1678         }
1679
1680         if (!wpan_dev->netdev) {
1681                 err = -EINVAL;
1682                 goto out_err;
1683         }
1684
1685         rdev_lock_llsec_table(rdev, wpan_dev);
1686         rdev_get_llsec_table(rdev, wpan_dev, &table);
1687
1688         /* TODO make it like station dump */
1689         if (cb->args[2])
1690                 goto out;
1691
1692         list_for_each_entry(dev, &table->devices, list) {
1693                 if (nl802154_send_device(skb, NL802154_CMD_NEW_SEC_LEVEL,
1694                                          NETLINK_CB(cb->skb).portid,
1695                                          cb->nlh->nlmsg_seq, NLM_F_MULTI,
1696                                          rdev, wpan_dev->netdev, dev) < 0) {
1697                         /* TODO */
1698                         err = -EIO;
1699                         rdev_unlock_llsec_table(rdev, wpan_dev);
1700                         goto out_err;
1701                 }
1702         }
1703
1704         cb->args[2] = 1;
1705
1706 out:
1707         rdev_unlock_llsec_table(rdev, wpan_dev);
1708         err = skb->len;
1709 out_err:
1710         nl802154_finish_wpan_dev_dump(rdev);
1711
1712         return err;
1713 }
1714
1715 static const struct nla_policy nl802154_dev_policy[NL802154_DEV_ATTR_MAX + 1] = {
1716         [NL802154_DEV_ATTR_FRAME_COUNTER] = { NLA_U32 },
1717         [NL802154_DEV_ATTR_PAN_ID] = { .type = NLA_U16 },
1718         [NL802154_DEV_ATTR_SHORT_ADDR] = { .type = NLA_U16 },
1719         [NL802154_DEV_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 },
1720         [NL802154_DEV_ATTR_SECLEVEL_EXEMPT] = { NLA_U8 },
1721         [NL802154_DEV_ATTR_KEY_MODE] = { NLA_U32 },
1722 };
1723
1724 static int
1725 ieee802154_llsec_parse_device(struct nlattr *nla,
1726                               struct ieee802154_llsec_device *dev)
1727 {
1728         struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
1729
1730         if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, nla, nl802154_dev_policy, NULL))
1731                 return -EINVAL;
1732
1733         memset(dev, 0, sizeof(*dev));
1734
1735         if (!attrs[NL802154_DEV_ATTR_FRAME_COUNTER] ||
1736             !attrs[NL802154_DEV_ATTR_PAN_ID] ||
1737             !attrs[NL802154_DEV_ATTR_SHORT_ADDR] ||
1738             !attrs[NL802154_DEV_ATTR_EXTENDED_ADDR] ||
1739             !attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT] ||
1740             !attrs[NL802154_DEV_ATTR_KEY_MODE])
1741                 return -EINVAL;
1742
1743         /* TODO be32 */
1744         dev->frame_counter = nla_get_u32(attrs[NL802154_DEV_ATTR_FRAME_COUNTER]);
1745         dev->pan_id = nla_get_le16(attrs[NL802154_DEV_ATTR_PAN_ID]);
1746         dev->short_addr = nla_get_le16(attrs[NL802154_DEV_ATTR_SHORT_ADDR]);
1747         /* TODO rename hwaddr to extended_addr */
1748         dev->hwaddr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
1749         dev->seclevel_exempt = nla_get_u8(attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT]);
1750         dev->key_mode = nla_get_u32(attrs[NL802154_DEV_ATTR_KEY_MODE]);
1751
1752         if (dev->key_mode > NL802154_DEVKEY_MAX ||
1753             (dev->seclevel_exempt != 0 && dev->seclevel_exempt != 1))
1754                 return -EINVAL;
1755
1756         return 0;
1757 }
1758
1759 static int nl802154_add_llsec_dev(struct sk_buff *skb, struct genl_info *info)
1760 {
1761         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1762         struct net_device *dev = info->user_ptr[1];
1763         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1764         struct ieee802154_llsec_device dev_desc;
1765
1766         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1767                 return -EOPNOTSUPP;
1768
1769         if (ieee802154_llsec_parse_device(info->attrs[NL802154_ATTR_SEC_DEVICE],
1770                                           &dev_desc) < 0)
1771                 return -EINVAL;
1772
1773         return rdev_add_device(rdev, wpan_dev, &dev_desc);
1774 }
1775
1776 static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info)
1777 {
1778         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1779         struct net_device *dev = info->user_ptr[1];
1780         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1781         struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
1782         __le64 extended_addr;
1783
1784         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1785                 return -EOPNOTSUPP;
1786
1787         if (!info->attrs[NL802154_ATTR_SEC_DEVICE] ||
1788             nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVICE], nl802154_dev_policy, info->extack))
1789                 return -EINVAL;
1790
1791         if (!attrs[NL802154_DEV_ATTR_EXTENDED_ADDR])
1792                 return -EINVAL;
1793
1794         extended_addr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]);
1795         return rdev_del_device(rdev, wpan_dev, extended_addr);
1796 }
1797
1798 static int nl802154_send_devkey(struct sk_buff *msg, u32 cmd, u32 portid,
1799                                 u32 seq, int flags,
1800                                 struct cfg802154_registered_device *rdev,
1801                                 struct net_device *dev, __le64 extended_addr,
1802                                 const struct ieee802154_llsec_device_key *devkey)
1803 {
1804         void *hdr;
1805         struct nlattr *nl_devkey, *nl_key_id;
1806
1807         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1808         if (!hdr)
1809                 return -1;
1810
1811         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1812                 goto nla_put_failure;
1813
1814         nl_devkey = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVKEY);
1815         if (!nl_devkey)
1816                 goto nla_put_failure;
1817
1818         if (nla_put_le64(msg, NL802154_DEVKEY_ATTR_EXTENDED_ADDR,
1819                          extended_addr, NL802154_DEVKEY_ATTR_PAD) ||
1820             nla_put_u32(msg, NL802154_DEVKEY_ATTR_FRAME_COUNTER,
1821                         devkey->frame_counter))
1822                 goto nla_put_failure;
1823
1824         nl_key_id = nla_nest_start_noflag(msg, NL802154_DEVKEY_ATTR_ID);
1825         if (!nl_key_id)
1826                 goto nla_put_failure;
1827
1828         if (ieee802154_llsec_send_key_id(msg, &devkey->key_id) < 0)
1829                 goto nla_put_failure;
1830
1831         nla_nest_end(msg, nl_key_id);
1832         nla_nest_end(msg, nl_devkey);
1833         genlmsg_end(msg, hdr);
1834
1835         return 0;
1836
1837 nla_put_failure:
1838         genlmsg_cancel(msg, hdr);
1839         return -EMSGSIZE;
1840 }
1841
1842 static int
1843 nl802154_dump_llsec_devkey(struct sk_buff *skb, struct netlink_callback *cb)
1844 {
1845         struct cfg802154_registered_device *rdev = NULL;
1846         struct ieee802154_llsec_device_key *kpos;
1847         struct ieee802154_llsec_device *dpos;
1848         struct ieee802154_llsec_table *table;
1849         struct wpan_dev *wpan_dev;
1850         int err;
1851
1852         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
1853         if (err)
1854                 return err;
1855
1856         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
1857                 err = skb->len;
1858                 goto out_err;
1859         }
1860
1861         if (!wpan_dev->netdev) {
1862                 err = -EINVAL;
1863                 goto out_err;
1864         }
1865
1866         rdev_lock_llsec_table(rdev, wpan_dev);
1867         rdev_get_llsec_table(rdev, wpan_dev, &table);
1868
1869         /* TODO make it like station dump */
1870         if (cb->args[2])
1871                 goto out;
1872
1873         /* TODO look if remove devkey and do some nested attribute */
1874         list_for_each_entry(dpos, &table->devices, list) {
1875                 list_for_each_entry(kpos, &dpos->keys, list) {
1876                         if (nl802154_send_devkey(skb,
1877                                                  NL802154_CMD_NEW_SEC_LEVEL,
1878                                                  NETLINK_CB(cb->skb).portid,
1879                                                  cb->nlh->nlmsg_seq,
1880                                                  NLM_F_MULTI, rdev,
1881                                                  wpan_dev->netdev,
1882                                                  dpos->hwaddr,
1883                                                  kpos) < 0) {
1884                                 /* TODO */
1885                                 err = -EIO;
1886                                 rdev_unlock_llsec_table(rdev, wpan_dev);
1887                                 goto out_err;
1888                         }
1889                 }
1890         }
1891
1892         cb->args[2] = 1;
1893
1894 out:
1895         rdev_unlock_llsec_table(rdev, wpan_dev);
1896         err = skb->len;
1897 out_err:
1898         nl802154_finish_wpan_dev_dump(rdev);
1899
1900         return err;
1901 }
1902
1903 static const struct nla_policy nl802154_devkey_policy[NL802154_DEVKEY_ATTR_MAX + 1] = {
1904         [NL802154_DEVKEY_ATTR_FRAME_COUNTER] = { NLA_U32 },
1905         [NL802154_DEVKEY_ATTR_EXTENDED_ADDR] = { NLA_U64 },
1906         [NL802154_DEVKEY_ATTR_ID] = { NLA_NESTED },
1907 };
1908
1909 static int nl802154_add_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
1910 {
1911         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1912         struct net_device *dev = info->user_ptr[1];
1913         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1914         struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
1915         struct ieee802154_llsec_device_key key;
1916         __le64 extended_addr;
1917
1918         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1919                 return -EOPNOTSUPP;
1920
1921         if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
1922             nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack) < 0)
1923                 return -EINVAL;
1924
1925         if (!attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER] ||
1926             !attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
1927                 return -EINVAL;
1928
1929         /* TODO change key.id ? */
1930         if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
1931                                           &key.key_id) < 0)
1932                 return -ENOBUFS;
1933
1934         /* TODO be32 */
1935         key.frame_counter = nla_get_u32(attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER]);
1936         /* TODO change naming hwaddr -> extended_addr
1937          * check unique identifier short+pan OR extended_addr
1938          */
1939         extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
1940         return rdev_add_devkey(rdev, wpan_dev, extended_addr, &key);
1941 }
1942
1943 static int nl802154_del_llsec_devkey(struct sk_buff *skb, struct genl_info *info)
1944 {
1945         struct cfg802154_registered_device *rdev = info->user_ptr[0];
1946         struct net_device *dev = info->user_ptr[1];
1947         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
1948         struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1];
1949         struct ieee802154_llsec_device_key key;
1950         __le64 extended_addr;
1951
1952         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
1953                 return -EOPNOTSUPP;
1954
1955         if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
1956             nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack))
1957                 return -EINVAL;
1958
1959         if (!attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR])
1960                 return -EINVAL;
1961
1962         /* TODO change key.id ? */
1963         if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID],
1964                                           &key.key_id) < 0)
1965                 return -ENOBUFS;
1966
1967         /* TODO change naming hwaddr -> extended_addr
1968          * check unique identifier short+pan OR extended_addr
1969          */
1970         extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]);
1971         return rdev_del_devkey(rdev, wpan_dev, extended_addr, &key);
1972 }
1973
1974 static int nl802154_send_seclevel(struct sk_buff *msg, u32 cmd, u32 portid,
1975                                   u32 seq, int flags,
1976                                   struct cfg802154_registered_device *rdev,
1977                                   struct net_device *dev,
1978                                   const struct ieee802154_llsec_seclevel *sl)
1979 {
1980         void *hdr;
1981         struct nlattr *nl_seclevel;
1982
1983         hdr = nl802154hdr_put(msg, portid, seq, flags, cmd);
1984         if (!hdr)
1985                 return -1;
1986
1987         if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex))
1988                 goto nla_put_failure;
1989
1990         nl_seclevel = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_LEVEL);
1991         if (!nl_seclevel)
1992                 goto nla_put_failure;
1993
1994         if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_FRAME, sl->frame_type) ||
1995             nla_put_u32(msg, NL802154_SECLEVEL_ATTR_LEVELS, sl->sec_levels) ||
1996             nla_put_u8(msg, NL802154_SECLEVEL_ATTR_DEV_OVERRIDE,
1997                        sl->device_override))
1998                 goto nla_put_failure;
1999
2000         if (sl->frame_type == NL802154_FRAME_CMD) {
2001                 if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_CMD_FRAME,
2002                                 sl->cmd_frame_id))
2003                         goto nla_put_failure;
2004         }
2005
2006         nla_nest_end(msg, nl_seclevel);
2007         genlmsg_end(msg, hdr);
2008
2009         return 0;
2010
2011 nla_put_failure:
2012         genlmsg_cancel(msg, hdr);
2013         return -EMSGSIZE;
2014 }
2015
2016 static int
2017 nl802154_dump_llsec_seclevel(struct sk_buff *skb, struct netlink_callback *cb)
2018 {
2019         struct cfg802154_registered_device *rdev = NULL;
2020         struct ieee802154_llsec_seclevel *sl;
2021         struct ieee802154_llsec_table *table;
2022         struct wpan_dev *wpan_dev;
2023         int err;
2024
2025         err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev);
2026         if (err)
2027                 return err;
2028
2029         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
2030                 err = skb->len;
2031                 goto out_err;
2032         }
2033
2034         if (!wpan_dev->netdev) {
2035                 err = -EINVAL;
2036                 goto out_err;
2037         }
2038
2039         rdev_lock_llsec_table(rdev, wpan_dev);
2040         rdev_get_llsec_table(rdev, wpan_dev, &table);
2041
2042         /* TODO make it like station dump */
2043         if (cb->args[2])
2044                 goto out;
2045
2046         list_for_each_entry(sl, &table->security_levels, list) {
2047                 if (nl802154_send_seclevel(skb, NL802154_CMD_NEW_SEC_LEVEL,
2048                                            NETLINK_CB(cb->skb).portid,
2049                                            cb->nlh->nlmsg_seq, NLM_F_MULTI,
2050                                            rdev, wpan_dev->netdev, sl) < 0) {
2051                         /* TODO */
2052                         err = -EIO;
2053                         rdev_unlock_llsec_table(rdev, wpan_dev);
2054                         goto out_err;
2055                 }
2056         }
2057
2058         cb->args[2] = 1;
2059
2060 out:
2061         rdev_unlock_llsec_table(rdev, wpan_dev);
2062         err = skb->len;
2063 out_err:
2064         nl802154_finish_wpan_dev_dump(rdev);
2065
2066         return err;
2067 }
2068
2069 static const struct nla_policy nl802154_seclevel_policy[NL802154_SECLEVEL_ATTR_MAX + 1] = {
2070         [NL802154_SECLEVEL_ATTR_LEVELS] = { .type = NLA_U8 },
2071         [NL802154_SECLEVEL_ATTR_FRAME] = { .type = NLA_U32 },
2072         [NL802154_SECLEVEL_ATTR_CMD_FRAME] = { .type = NLA_U32 },
2073         [NL802154_SECLEVEL_ATTR_DEV_OVERRIDE] = { .type = NLA_U8 },
2074 };
2075
2076 static int
2077 llsec_parse_seclevel(struct nlattr *nla, struct ieee802154_llsec_seclevel *sl)
2078 {
2079         struct nlattr *attrs[NL802154_SECLEVEL_ATTR_MAX + 1];
2080
2081         if (!nla || nla_parse_nested_deprecated(attrs, NL802154_SECLEVEL_ATTR_MAX, nla, nl802154_seclevel_policy, NULL))
2082                 return -EINVAL;
2083
2084         memset(sl, 0, sizeof(*sl));
2085
2086         if (!attrs[NL802154_SECLEVEL_ATTR_LEVELS] ||
2087             !attrs[NL802154_SECLEVEL_ATTR_FRAME] ||
2088             !attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE])
2089                 return -EINVAL;
2090
2091         sl->sec_levels = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_LEVELS]);
2092         sl->frame_type = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_FRAME]);
2093         sl->device_override = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE]);
2094         if (sl->frame_type > NL802154_FRAME_MAX ||
2095             (sl->device_override != 0 && sl->device_override != 1))
2096                 return -EINVAL;
2097
2098         if (sl->frame_type == NL802154_FRAME_CMD) {
2099                 if (!attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME])
2100                         return -EINVAL;
2101
2102                 sl->cmd_frame_id = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME]);
2103                 if (sl->cmd_frame_id > NL802154_CMD_FRAME_MAX)
2104                         return -EINVAL;
2105         }
2106
2107         return 0;
2108 }
2109
2110 static int nl802154_add_llsec_seclevel(struct sk_buff *skb,
2111                                        struct genl_info *info)
2112 {
2113         struct cfg802154_registered_device *rdev = info->user_ptr[0];
2114         struct net_device *dev = info->user_ptr[1];
2115         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2116         struct ieee802154_llsec_seclevel sl;
2117
2118         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
2119                 return -EOPNOTSUPP;
2120
2121         if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
2122                                  &sl) < 0)
2123                 return -EINVAL;
2124
2125         return rdev_add_seclevel(rdev, wpan_dev, &sl);
2126 }
2127
2128 static int nl802154_del_llsec_seclevel(struct sk_buff *skb,
2129                                        struct genl_info *info)
2130 {
2131         struct cfg802154_registered_device *rdev = info->user_ptr[0];
2132         struct net_device *dev = info->user_ptr[1];
2133         struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
2134         struct ieee802154_llsec_seclevel sl;
2135
2136         if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
2137                 return -EOPNOTSUPP;
2138
2139         if (!info->attrs[NL802154_ATTR_SEC_LEVEL] ||
2140             llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
2141                                  &sl) < 0)
2142                 return -EINVAL;
2143
2144         return rdev_del_seclevel(rdev, wpan_dev, &sl);
2145 }
2146 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2147
2148 #define NL802154_FLAG_NEED_WPAN_PHY     0x01
2149 #define NL802154_FLAG_NEED_NETDEV       0x02
2150 #define NL802154_FLAG_NEED_RTNL         0x04
2151 #define NL802154_FLAG_CHECK_NETDEV_UP   0x08
2152 #define NL802154_FLAG_NEED_WPAN_DEV     0x10
2153
2154 static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
2155                              struct genl_info *info)
2156 {
2157         struct cfg802154_registered_device *rdev;
2158         struct wpan_dev *wpan_dev;
2159         struct net_device *dev;
2160         bool rtnl = ops->internal_flags & NL802154_FLAG_NEED_RTNL;
2161
2162         if (rtnl)
2163                 rtnl_lock();
2164
2165         if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_PHY) {
2166                 rdev = cfg802154_get_dev_from_info(genl_info_net(info), info);
2167                 if (IS_ERR(rdev)) {
2168                         if (rtnl)
2169                                 rtnl_unlock();
2170                         return PTR_ERR(rdev);
2171                 }
2172                 info->user_ptr[0] = rdev;
2173         } else if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV ||
2174                    ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
2175                 ASSERT_RTNL();
2176                 wpan_dev = __cfg802154_wpan_dev_from_attrs(genl_info_net(info),
2177                                                            info->attrs);
2178                 if (IS_ERR(wpan_dev)) {
2179                         if (rtnl)
2180                                 rtnl_unlock();
2181                         return PTR_ERR(wpan_dev);
2182                 }
2183
2184                 dev = wpan_dev->netdev;
2185                 rdev = wpan_phy_to_rdev(wpan_dev->wpan_phy);
2186
2187                 if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV) {
2188                         if (!dev) {
2189                                 if (rtnl)
2190                                         rtnl_unlock();
2191                                 return -EINVAL;
2192                         }
2193
2194                         info->user_ptr[1] = dev;
2195                 } else {
2196                         info->user_ptr[1] = wpan_dev;
2197                 }
2198
2199                 if (dev) {
2200                         if (ops->internal_flags & NL802154_FLAG_CHECK_NETDEV_UP &&
2201                             !netif_running(dev)) {
2202                                 if (rtnl)
2203                                         rtnl_unlock();
2204                                 return -ENETDOWN;
2205                         }
2206
2207                         dev_hold(dev);
2208                 }
2209
2210                 info->user_ptr[0] = rdev;
2211         }
2212
2213         return 0;
2214 }
2215
2216 static void nl802154_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
2217                                struct genl_info *info)
2218 {
2219         if (info->user_ptr[1]) {
2220                 if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) {
2221                         struct wpan_dev *wpan_dev = info->user_ptr[1];
2222
2223                         if (wpan_dev->netdev)
2224                                 dev_put(wpan_dev->netdev);
2225                 } else {
2226                         dev_put(info->user_ptr[1]);
2227                 }
2228         }
2229
2230         if (ops->internal_flags & NL802154_FLAG_NEED_RTNL)
2231                 rtnl_unlock();
2232 }
2233
2234 static const struct genl_ops nl802154_ops[] = {
2235         {
2236                 .cmd = NL802154_CMD_GET_WPAN_PHY,
2237                 .validate = GENL_DONT_VALIDATE_STRICT |
2238                             GENL_DONT_VALIDATE_DUMP_STRICT,
2239                 .doit = nl802154_get_wpan_phy,
2240                 .dumpit = nl802154_dump_wpan_phy,
2241                 .done = nl802154_dump_wpan_phy_done,
2242                 /* can be retrieved by unprivileged users */
2243                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2244                                   NL802154_FLAG_NEED_RTNL,
2245         },
2246         {
2247                 .cmd = NL802154_CMD_GET_INTERFACE,
2248                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2249                 .doit = nl802154_get_interface,
2250                 .dumpit = nl802154_dump_interface,
2251                 /* can be retrieved by unprivileged users */
2252                 .internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
2253                                   NL802154_FLAG_NEED_RTNL,
2254         },
2255         {
2256                 .cmd = NL802154_CMD_NEW_INTERFACE,
2257                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2258                 .doit = nl802154_new_interface,
2259                 .flags = GENL_ADMIN_PERM,
2260                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2261                                   NL802154_FLAG_NEED_RTNL,
2262         },
2263         {
2264                 .cmd = NL802154_CMD_DEL_INTERFACE,
2265                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2266                 .doit = nl802154_del_interface,
2267                 .flags = GENL_ADMIN_PERM,
2268                 .internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
2269                                   NL802154_FLAG_NEED_RTNL,
2270         },
2271         {
2272                 .cmd = NL802154_CMD_SET_CHANNEL,
2273                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2274                 .doit = nl802154_set_channel,
2275                 .flags = GENL_ADMIN_PERM,
2276                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2277                                   NL802154_FLAG_NEED_RTNL,
2278         },
2279         {
2280                 .cmd = NL802154_CMD_SET_CCA_MODE,
2281                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2282                 .doit = nl802154_set_cca_mode,
2283                 .flags = GENL_ADMIN_PERM,
2284                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2285                                   NL802154_FLAG_NEED_RTNL,
2286         },
2287         {
2288                 .cmd = NL802154_CMD_SET_CCA_ED_LEVEL,
2289                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2290                 .doit = nl802154_set_cca_ed_level,
2291                 .flags = GENL_ADMIN_PERM,
2292                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2293                                   NL802154_FLAG_NEED_RTNL,
2294         },
2295         {
2296                 .cmd = NL802154_CMD_SET_TX_POWER,
2297                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2298                 .doit = nl802154_set_tx_power,
2299                 .flags = GENL_ADMIN_PERM,
2300                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2301                                   NL802154_FLAG_NEED_RTNL,
2302         },
2303         {
2304                 .cmd = NL802154_CMD_SET_WPAN_PHY_NETNS,
2305                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2306                 .doit = nl802154_wpan_phy_netns,
2307                 .flags = GENL_ADMIN_PERM,
2308                 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
2309                                   NL802154_FLAG_NEED_RTNL,
2310         },
2311         {
2312                 .cmd = NL802154_CMD_SET_PAN_ID,
2313                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2314                 .doit = nl802154_set_pan_id,
2315                 .flags = GENL_ADMIN_PERM,
2316                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2317                                   NL802154_FLAG_NEED_RTNL,
2318         },
2319         {
2320                 .cmd = NL802154_CMD_SET_SHORT_ADDR,
2321                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2322                 .doit = nl802154_set_short_addr,
2323                 .flags = GENL_ADMIN_PERM,
2324                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2325                                   NL802154_FLAG_NEED_RTNL,
2326         },
2327         {
2328                 .cmd = NL802154_CMD_SET_BACKOFF_EXPONENT,
2329                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2330                 .doit = nl802154_set_backoff_exponent,
2331                 .flags = GENL_ADMIN_PERM,
2332                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2333                                   NL802154_FLAG_NEED_RTNL,
2334         },
2335         {
2336                 .cmd = NL802154_CMD_SET_MAX_CSMA_BACKOFFS,
2337                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2338                 .doit = nl802154_set_max_csma_backoffs,
2339                 .flags = GENL_ADMIN_PERM,
2340                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2341                                   NL802154_FLAG_NEED_RTNL,
2342         },
2343         {
2344                 .cmd = NL802154_CMD_SET_MAX_FRAME_RETRIES,
2345                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2346                 .doit = nl802154_set_max_frame_retries,
2347                 .flags = GENL_ADMIN_PERM,
2348                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2349                                   NL802154_FLAG_NEED_RTNL,
2350         },
2351         {
2352                 .cmd = NL802154_CMD_SET_LBT_MODE,
2353                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2354                 .doit = nl802154_set_lbt_mode,
2355                 .flags = GENL_ADMIN_PERM,
2356                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2357                                   NL802154_FLAG_NEED_RTNL,
2358         },
2359         {
2360                 .cmd = NL802154_CMD_SET_ACKREQ_DEFAULT,
2361                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2362                 .doit = nl802154_set_ackreq_default,
2363                 .flags = GENL_ADMIN_PERM,
2364                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2365                                   NL802154_FLAG_NEED_RTNL,
2366         },
2367 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
2368         {
2369                 .cmd = NL802154_CMD_SET_SEC_PARAMS,
2370                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2371                 .doit = nl802154_set_llsec_params,
2372                 .flags = GENL_ADMIN_PERM,
2373                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2374                                   NL802154_FLAG_NEED_RTNL,
2375         },
2376         {
2377                 .cmd = NL802154_CMD_GET_SEC_KEY,
2378                 .validate = GENL_DONT_VALIDATE_STRICT |
2379                             GENL_DONT_VALIDATE_DUMP_STRICT,
2380                 /* TODO .doit by matching key id? */
2381                 .dumpit = nl802154_dump_llsec_key,
2382                 .flags = GENL_ADMIN_PERM,
2383                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2384                                   NL802154_FLAG_NEED_RTNL,
2385         },
2386         {
2387                 .cmd = NL802154_CMD_NEW_SEC_KEY,
2388                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2389                 .doit = nl802154_add_llsec_key,
2390                 .flags = GENL_ADMIN_PERM,
2391                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2392                                   NL802154_FLAG_NEED_RTNL,
2393         },
2394         {
2395                 .cmd = NL802154_CMD_DEL_SEC_KEY,
2396                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2397                 .doit = nl802154_del_llsec_key,
2398                 .flags = GENL_ADMIN_PERM,
2399                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2400                                   NL802154_FLAG_NEED_RTNL,
2401         },
2402         /* TODO unique identifier must short+pan OR extended_addr */
2403         {
2404                 .cmd = NL802154_CMD_GET_SEC_DEV,
2405                 .validate = GENL_DONT_VALIDATE_STRICT |
2406                             GENL_DONT_VALIDATE_DUMP_STRICT,
2407                 /* TODO .doit by matching extended_addr? */
2408                 .dumpit = nl802154_dump_llsec_dev,
2409                 .flags = GENL_ADMIN_PERM,
2410                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2411                                   NL802154_FLAG_NEED_RTNL,
2412         },
2413         {
2414                 .cmd = NL802154_CMD_NEW_SEC_DEV,
2415                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2416                 .doit = nl802154_add_llsec_dev,
2417                 .flags = GENL_ADMIN_PERM,
2418                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2419                                   NL802154_FLAG_NEED_RTNL,
2420         },
2421         {
2422                 .cmd = NL802154_CMD_DEL_SEC_DEV,
2423                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2424                 .doit = nl802154_del_llsec_dev,
2425                 .flags = GENL_ADMIN_PERM,
2426                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2427                                   NL802154_FLAG_NEED_RTNL,
2428         },
2429         /* TODO remove complete devkey, put it as nested? */
2430         {
2431                 .cmd = NL802154_CMD_GET_SEC_DEVKEY,
2432                 .validate = GENL_DONT_VALIDATE_STRICT |
2433                             GENL_DONT_VALIDATE_DUMP_STRICT,
2434                 /* TODO doit by matching ??? */
2435                 .dumpit = nl802154_dump_llsec_devkey,
2436                 .flags = GENL_ADMIN_PERM,
2437                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2438                                   NL802154_FLAG_NEED_RTNL,
2439         },
2440         {
2441                 .cmd = NL802154_CMD_NEW_SEC_DEVKEY,
2442                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2443                 .doit = nl802154_add_llsec_devkey,
2444                 .flags = GENL_ADMIN_PERM,
2445                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2446                                   NL802154_FLAG_NEED_RTNL,
2447         },
2448         {
2449                 .cmd = NL802154_CMD_DEL_SEC_DEVKEY,
2450                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2451                 .doit = nl802154_del_llsec_devkey,
2452                 .flags = GENL_ADMIN_PERM,
2453                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2454                                   NL802154_FLAG_NEED_RTNL,
2455         },
2456         {
2457                 .cmd = NL802154_CMD_GET_SEC_LEVEL,
2458                 .validate = GENL_DONT_VALIDATE_STRICT |
2459                             GENL_DONT_VALIDATE_DUMP_STRICT,
2460                 /* TODO .doit by matching frame_type? */
2461                 .dumpit = nl802154_dump_llsec_seclevel,
2462                 .flags = GENL_ADMIN_PERM,
2463                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2464                                   NL802154_FLAG_NEED_RTNL,
2465         },
2466         {
2467                 .cmd = NL802154_CMD_NEW_SEC_LEVEL,
2468                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2469                 .doit = nl802154_add_llsec_seclevel,
2470                 .flags = GENL_ADMIN_PERM,
2471                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2472                                   NL802154_FLAG_NEED_RTNL,
2473         },
2474         {
2475                 .cmd = NL802154_CMD_DEL_SEC_LEVEL,
2476                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2477                 /* TODO match frame_type only? */
2478                 .doit = nl802154_del_llsec_seclevel,
2479                 .flags = GENL_ADMIN_PERM,
2480                 .internal_flags = NL802154_FLAG_NEED_NETDEV |
2481                                   NL802154_FLAG_NEED_RTNL,
2482         },
2483 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2484 };
2485
2486 static struct genl_family nl802154_fam __ro_after_init = {
2487         .name = NL802154_GENL_NAME,     /* have users key off the name instead */
2488         .hdrsize = 0,                   /* no private header */
2489         .version = 1,                   /* no particular meaning now */
2490         .maxattr = NL802154_ATTR_MAX,
2491         .policy = nl802154_policy,
2492         .netnsok = true,
2493         .pre_doit = nl802154_pre_doit,
2494         .post_doit = nl802154_post_doit,
2495         .module = THIS_MODULE,
2496         .ops = nl802154_ops,
2497         .n_ops = ARRAY_SIZE(nl802154_ops),
2498         .mcgrps = nl802154_mcgrps,
2499         .n_mcgrps = ARRAY_SIZE(nl802154_mcgrps),
2500 };
2501
2502 /* initialisation/exit functions */
2503 int __init nl802154_init(void)
2504 {
2505         return genl_register_family(&nl802154_fam);
2506 }
2507
2508 void nl802154_exit(void)
2509 {
2510         genl_unregister_family(&nl802154_fam);
2511 }