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