1 // SPDX-License-Identifier: GPL-2.0-only
5 * Alexander Aring <aar@pengutronix.de>
7 * Based on: net/wireless/nl80211.c
10 #include <linux/rtnetlink.h>
12 #include <net/cfg802154.h>
13 #include <net/genetlink.h>
14 #include <net/mac802154.h>
15 #include <net/netlink.h>
16 #include <net/nl802154.h>
23 /* the netlink family */
24 static struct genl_family nl802154_fam
;
26 /* multicast groups */
27 enum nl802154_multicast_groups
{
28 NL802154_MCGRP_CONFIG
,
32 static const struct genl_multicast_group nl802154_mcgrps
[] = {
33 [NL802154_MCGRP_CONFIG
] = { .name
= "config", },
34 [NL802154_MCGRP_SCAN
] = { .name
= "scan", },
37 /* returns ERR_PTR values */
38 static struct wpan_dev
*
39 __cfg802154_wpan_dev_from_attrs(struct net
*netns
, struct nlattr
**attrs
)
41 struct cfg802154_registered_device
*rdev
;
42 struct wpan_dev
*result
= NULL
;
43 bool have_ifidx
= attrs
[NL802154_ATTR_IFINDEX
];
44 bool have_wpan_dev_id
= attrs
[NL802154_ATTR_WPAN_DEV
];
46 int wpan_phy_idx
= -1;
51 if (!have_ifidx
&& !have_wpan_dev_id
)
52 return ERR_PTR(-EINVAL
);
55 ifidx
= nla_get_u32(attrs
[NL802154_ATTR_IFINDEX
]);
56 if (have_wpan_dev_id
) {
57 wpan_dev_id
= nla_get_u64(attrs
[NL802154_ATTR_WPAN_DEV
]);
58 wpan_phy_idx
= wpan_dev_id
>> 32;
61 list_for_each_entry(rdev
, &cfg802154_rdev_list
, list
) {
62 struct wpan_dev
*wpan_dev
;
64 if (wpan_phy_net(&rdev
->wpan_phy
) != netns
)
67 if (have_wpan_dev_id
&& rdev
->wpan_phy_idx
!= wpan_phy_idx
)
70 list_for_each_entry(wpan_dev
, &rdev
->wpan_dev_list
, list
) {
71 if (have_ifidx
&& wpan_dev
->netdev
&&
72 wpan_dev
->netdev
->ifindex
== ifidx
) {
76 if (have_wpan_dev_id
&&
77 wpan_dev
->identifier
== (u32
)wpan_dev_id
) {
90 return ERR_PTR(-ENODEV
);
93 static struct cfg802154_registered_device
*
94 __cfg802154_rdev_from_attrs(struct net
*netns
, struct nlattr
**attrs
)
96 struct cfg802154_registered_device
*rdev
= NULL
, *tmp
;
97 struct net_device
*netdev
;
101 if (!attrs
[NL802154_ATTR_WPAN_PHY
] &&
102 !attrs
[NL802154_ATTR_IFINDEX
] &&
103 !attrs
[NL802154_ATTR_WPAN_DEV
])
104 return ERR_PTR(-EINVAL
);
106 if (attrs
[NL802154_ATTR_WPAN_PHY
])
107 rdev
= cfg802154_rdev_by_wpan_phy_idx(
108 nla_get_u32(attrs
[NL802154_ATTR_WPAN_PHY
]));
110 if (attrs
[NL802154_ATTR_WPAN_DEV
]) {
111 u64 wpan_dev_id
= nla_get_u64(attrs
[NL802154_ATTR_WPAN_DEV
]);
112 struct wpan_dev
*wpan_dev
;
115 tmp
= cfg802154_rdev_by_wpan_phy_idx(wpan_dev_id
>> 32);
117 /* make sure wpan_dev exists */
118 list_for_each_entry(wpan_dev
, &tmp
->wpan_dev_list
, list
) {
119 if (wpan_dev
->identifier
!= (u32
)wpan_dev_id
)
128 if (rdev
&& tmp
!= rdev
)
129 return ERR_PTR(-EINVAL
);
134 if (attrs
[NL802154_ATTR_IFINDEX
]) {
135 int ifindex
= nla_get_u32(attrs
[NL802154_ATTR_IFINDEX
]);
137 netdev
= __dev_get_by_index(netns
, ifindex
);
139 if (netdev
->ieee802154_ptr
)
140 tmp
= wpan_phy_to_rdev(
141 netdev
->ieee802154_ptr
->wpan_phy
);
145 /* not wireless device -- return error */
147 return ERR_PTR(-EINVAL
);
149 /* mismatch -- return error */
150 if (rdev
&& tmp
!= rdev
)
151 return ERR_PTR(-EINVAL
);
158 return ERR_PTR(-ENODEV
);
160 if (netns
!= wpan_phy_net(&rdev
->wpan_phy
))
161 return ERR_PTR(-ENODEV
);
166 /* This function returns a pointer to the driver
167 * that the genl_info item that is passed refers to.
169 * The result of this can be a PTR_ERR and hence must
170 * be checked with IS_ERR() for errors.
172 static struct cfg802154_registered_device
*
173 cfg802154_get_dev_from_info(struct net
*netns
, struct genl_info
*info
)
175 return __cfg802154_rdev_from_attrs(netns
, info
->attrs
);
178 /* policy for the attributes */
179 static const struct nla_policy nl802154_policy
[NL802154_ATTR_MAX
+1] = {
180 [NL802154_ATTR_WPAN_PHY
] = { .type
= NLA_U32
},
181 [NL802154_ATTR_WPAN_PHY_NAME
] = { .type
= NLA_NUL_STRING
,
184 [NL802154_ATTR_IFINDEX
] = { .type
= NLA_U32
},
185 [NL802154_ATTR_IFTYPE
] = { .type
= NLA_U32
},
186 [NL802154_ATTR_IFNAME
] = { .type
= NLA_NUL_STRING
, .len
= IFNAMSIZ
-1 },
188 [NL802154_ATTR_WPAN_DEV
] = { .type
= NLA_U64
},
190 [NL802154_ATTR_PAGE
] = NLA_POLICY_MAX(NLA_U8
, IEEE802154_MAX_PAGE
),
191 [NL802154_ATTR_CHANNEL
] = NLA_POLICY_MAX(NLA_U8
, IEEE802154_MAX_CHANNEL
),
193 [NL802154_ATTR_TX_POWER
] = { .type
= NLA_S32
, },
195 [NL802154_ATTR_CCA_MODE
] = { .type
= NLA_U32
, },
196 [NL802154_ATTR_CCA_OPT
] = { .type
= NLA_U32
, },
197 [NL802154_ATTR_CCA_ED_LEVEL
] = { .type
= NLA_S32
, },
199 [NL802154_ATTR_SUPPORTED_CHANNEL
] = { .type
= NLA_U32
, },
201 [NL802154_ATTR_PAN_ID
] = { .type
= NLA_U16
, },
202 [NL802154_ATTR_EXTENDED_ADDR
] = { .type
= NLA_U64
},
203 [NL802154_ATTR_SHORT_ADDR
] = { .type
= NLA_U16
, },
205 [NL802154_ATTR_MIN_BE
] = { .type
= NLA_U8
, },
206 [NL802154_ATTR_MAX_BE
] = { .type
= NLA_U8
, },
207 [NL802154_ATTR_MAX_CSMA_BACKOFFS
] = { .type
= NLA_U8
, },
209 [NL802154_ATTR_MAX_FRAME_RETRIES
] = { .type
= NLA_S8
, },
211 [NL802154_ATTR_LBT_MODE
] = { .type
= NLA_U8
, },
213 [NL802154_ATTR_WPAN_PHY_CAPS
] = { .type
= NLA_NESTED
},
215 [NL802154_ATTR_SUPPORTED_COMMANDS
] = { .type
= NLA_NESTED
},
217 [NL802154_ATTR_ACKREQ_DEFAULT
] = { .type
= NLA_U8
},
219 [NL802154_ATTR_PID
] = { .type
= NLA_U32
},
220 [NL802154_ATTR_NETNS_FD
] = { .type
= NLA_U32
},
222 [NL802154_ATTR_COORDINATOR
] = { .type
= NLA_NESTED
},
224 [NL802154_ATTR_SCAN_TYPE
] =
225 NLA_POLICY_RANGE(NLA_U8
, NL802154_SCAN_ED
, NL802154_SCAN_RIT_PASSIVE
),
226 [NL802154_ATTR_SCAN_CHANNELS
] =
227 NLA_POLICY_MASK(NLA_U32
, GENMASK(IEEE802154_MAX_CHANNEL
, 0)),
228 [NL802154_ATTR_SCAN_PREAMBLE_CODES
] = { .type
= NLA_REJECT
},
229 [NL802154_ATTR_SCAN_MEAN_PRF
] = { .type
= NLA_REJECT
},
230 [NL802154_ATTR_SCAN_DURATION
] =
231 NLA_POLICY_MAX(NLA_U8
, IEEE802154_MAX_SCAN_DURATION
),
232 [NL802154_ATTR_SCAN_DONE_REASON
] =
233 NLA_POLICY_RANGE(NLA_U8
, NL802154_SCAN_DONE_REASON_FINISHED
,
234 NL802154_SCAN_DONE_REASON_ABORTED
),
235 [NL802154_ATTR_BEACON_INTERVAL
] =
236 NLA_POLICY_MAX(NLA_U8
, IEEE802154_ACTIVE_SCAN_DURATION
),
237 [NL802154_ATTR_MAX_ASSOCIATIONS
] = { .type
= NLA_U32
},
238 [NL802154_ATTR_PEER
] = { .type
= NLA_NESTED
},
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
},
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 */
254 nl802154_prepare_wpan_dev_dump(struct sk_buff
*skb
,
255 struct netlink_callback
*cb
,
256 struct cfg802154_registered_device
**rdev
,
257 struct wpan_dev
**wpan_dev
)
259 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
265 *wpan_dev
= __cfg802154_wpan_dev_from_attrs(sock_net(skb
->sk
),
267 if (IS_ERR(*wpan_dev
)) {
268 err
= PTR_ERR(*wpan_dev
);
271 *rdev
= wpan_phy_to_rdev((*wpan_dev
)->wpan_phy
);
272 /* 0 is the first index - add 1 to parse only once */
273 cb
->args
[0] = (*rdev
)->wpan_phy_idx
+ 1;
274 cb
->args
[1] = (*wpan_dev
)->identifier
;
276 /* subtract the 1 again here */
277 struct wpan_phy
*wpan_phy
= wpan_phy_idx_to_wpan_phy(cb
->args
[0] - 1);
278 struct wpan_dev
*tmp
;
284 *rdev
= wpan_phy_to_rdev(wpan_phy
);
287 list_for_each_entry(tmp
, &(*rdev
)->wpan_dev_list
, list
) {
288 if (tmp
->identifier
== cb
->args
[1]) {
307 nl802154_finish_wpan_dev_dump(struct cfg802154_registered_device
*rdev
)
312 /* message building helper */
313 static inline void *nl802154hdr_put(struct sk_buff
*skb
, u32 portid
, u32 seq
,
316 /* since there is no private header just add the generic one */
317 return genlmsg_put(skb
, portid
, seq
, &nl802154_fam
, flags
, cmd
);
321 nl802154_put_flags(struct sk_buff
*msg
, int attr
, u32 mask
)
323 struct nlattr
*nl_flags
= nla_nest_start_noflag(msg
, attr
);
331 if ((mask
& 1) && nla_put_flag(msg
, i
))
338 nla_nest_end(msg
, nl_flags
);
343 nl802154_send_wpan_phy_channels(struct cfg802154_registered_device
*rdev
,
346 struct nlattr
*nl_page
;
349 nl_page
= nla_nest_start_noflag(msg
, NL802154_ATTR_CHANNELS_SUPPORTED
);
353 for (page
= 0; page
<= IEEE802154_MAX_PAGE
; page
++) {
354 if (nla_put_u32(msg
, NL802154_ATTR_SUPPORTED_CHANNEL
,
355 rdev
->wpan_phy
.supported
.channels
[page
]))
358 nla_nest_end(msg
, nl_page
);
364 nl802154_put_capabilities(struct sk_buff
*msg
,
365 struct cfg802154_registered_device
*rdev
)
367 const struct wpan_phy_supported
*caps
= &rdev
->wpan_phy
.supported
;
368 struct nlattr
*nl_caps
, *nl_channels
;
371 nl_caps
= nla_nest_start_noflag(msg
, NL802154_ATTR_WPAN_PHY_CAPS
);
375 nl_channels
= nla_nest_start_noflag(msg
, NL802154_CAP_ATTR_CHANNELS
);
379 for (i
= 0; i
<= IEEE802154_MAX_PAGE
; i
++) {
380 if (caps
->channels
[i
]) {
381 if (nl802154_put_flags(msg
, i
, caps
->channels
[i
]))
386 nla_nest_end(msg
, nl_channels
);
388 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_ED_LEVEL
) {
389 struct nlattr
*nl_ed_lvls
;
391 nl_ed_lvls
= nla_nest_start_noflag(msg
,
392 NL802154_CAP_ATTR_CCA_ED_LEVELS
);
396 for (i
= 0; i
< caps
->cca_ed_levels_size
; i
++) {
397 if (nla_put_s32(msg
, i
, caps
->cca_ed_levels
[i
]))
401 nla_nest_end(msg
, nl_ed_lvls
);
404 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_TXPOWER
) {
405 struct nlattr
*nl_tx_pwrs
;
407 nl_tx_pwrs
= nla_nest_start_noflag(msg
,
408 NL802154_CAP_ATTR_TX_POWERS
);
412 for (i
= 0; i
< caps
->tx_powers_size
; i
++) {
413 if (nla_put_s32(msg
, i
, caps
->tx_powers
[i
]))
417 nla_nest_end(msg
, nl_tx_pwrs
);
420 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_MODE
) {
421 if (nl802154_put_flags(msg
, NL802154_CAP_ATTR_CCA_MODES
,
423 nl802154_put_flags(msg
, NL802154_CAP_ATTR_CCA_OPTS
,
428 if (nla_put_u8(msg
, NL802154_CAP_ATTR_MIN_MINBE
, caps
->min_minbe
) ||
429 nla_put_u8(msg
, NL802154_CAP_ATTR_MAX_MINBE
, caps
->max_minbe
) ||
430 nla_put_u8(msg
, NL802154_CAP_ATTR_MIN_MAXBE
, caps
->min_maxbe
) ||
431 nla_put_u8(msg
, NL802154_CAP_ATTR_MAX_MAXBE
, caps
->max_maxbe
) ||
432 nla_put_u8(msg
, NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS
,
433 caps
->min_csma_backoffs
) ||
434 nla_put_u8(msg
, NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS
,
435 caps
->max_csma_backoffs
) ||
436 nla_put_s8(msg
, NL802154_CAP_ATTR_MIN_FRAME_RETRIES
,
437 caps
->min_frame_retries
) ||
438 nla_put_s8(msg
, NL802154_CAP_ATTR_MAX_FRAME_RETRIES
,
439 caps
->max_frame_retries
) ||
440 nl802154_put_flags(msg
, NL802154_CAP_ATTR_IFTYPES
,
442 nla_put_u32(msg
, NL802154_CAP_ATTR_LBT
, caps
->lbt
))
445 nla_nest_end(msg
, nl_caps
);
450 static int nl802154_send_wpan_phy(struct cfg802154_registered_device
*rdev
,
451 enum nl802154_commands cmd
,
452 struct sk_buff
*msg
, u32 portid
, u32 seq
,
455 struct nlattr
*nl_cmds
;
459 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
, cmd
);
463 if (nla_put_u32(msg
, NL802154_ATTR_WPAN_PHY
, rdev
->wpan_phy_idx
) ||
464 nla_put_string(msg
, NL802154_ATTR_WPAN_PHY_NAME
,
465 wpan_phy_name(&rdev
->wpan_phy
)) ||
466 nla_put_u32(msg
, NL802154_ATTR_GENERATION
,
467 cfg802154_rdev_list_generation
))
468 goto nla_put_failure
;
470 if (cmd
!= NL802154_CMD_NEW_WPAN_PHY
)
475 /* current channel settings */
476 if (nla_put_u8(msg
, NL802154_ATTR_PAGE
,
477 rdev
->wpan_phy
.current_page
) ||
478 nla_put_u8(msg
, NL802154_ATTR_CHANNEL
,
479 rdev
->wpan_phy
.current_channel
))
480 goto nla_put_failure
;
482 /* TODO remove this behaviour, we still keep support it for a while
483 * so users can change the behaviour to the new one.
485 if (nl802154_send_wpan_phy_channels(rdev
, msg
))
486 goto nla_put_failure
;
489 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_MODE
) {
490 if (nla_put_u32(msg
, NL802154_ATTR_CCA_MODE
,
491 rdev
->wpan_phy
.cca
.mode
))
492 goto nla_put_failure
;
494 if (rdev
->wpan_phy
.cca
.mode
== NL802154_CCA_ENERGY_CARRIER
) {
495 if (nla_put_u32(msg
, NL802154_ATTR_CCA_OPT
,
496 rdev
->wpan_phy
.cca
.opt
))
497 goto nla_put_failure
;
501 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_TXPOWER
) {
502 if (nla_put_s32(msg
, NL802154_ATTR_TX_POWER
,
503 rdev
->wpan_phy
.transmit_power
))
504 goto nla_put_failure
;
507 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_ED_LEVEL
) {
508 if (nla_put_s32(msg
, NL802154_ATTR_CCA_ED_LEVEL
,
509 rdev
->wpan_phy
.cca_ed_level
))
510 goto nla_put_failure
;
513 if (nl802154_put_capabilities(msg
, rdev
))
514 goto nla_put_failure
;
516 nl_cmds
= nla_nest_start_noflag(msg
, NL802154_ATTR_SUPPORTED_COMMANDS
);
518 goto nla_put_failure
;
523 if (rdev->ops->op) { \
525 if (nla_put_u32(msg, i, NL802154_CMD_ ## n)) \
526 goto nla_put_failure; \
530 CMD(add_virtual_intf
, NEW_INTERFACE
);
531 CMD(del_virtual_intf
, DEL_INTERFACE
);
532 CMD(set_channel
, SET_CHANNEL
);
533 CMD(set_pan_id
, SET_PAN_ID
);
534 CMD(set_short_addr
, SET_SHORT_ADDR
);
535 CMD(set_backoff_exponent
, SET_BACKOFF_EXPONENT
);
536 CMD(set_max_csma_backoffs
, SET_MAX_CSMA_BACKOFFS
);
537 CMD(set_max_frame_retries
, SET_MAX_FRAME_RETRIES
);
538 CMD(set_lbt_mode
, SET_LBT_MODE
);
539 CMD(set_ackreq_default
, SET_ACKREQ_DEFAULT
);
541 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_TXPOWER
)
542 CMD(set_tx_power
, SET_TX_POWER
);
544 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_ED_LEVEL
)
545 CMD(set_cca_ed_level
, SET_CCA_ED_LEVEL
);
547 if (rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_MODE
)
548 CMD(set_cca_mode
, SET_CCA_MODE
);
551 nla_nest_end(msg
, nl_cmds
);
554 genlmsg_end(msg
, hdr
);
558 genlmsg_cancel(msg
, hdr
);
562 struct nl802154_dump_wpan_phy_state
{
568 static int nl802154_dump_wpan_phy_parse(struct sk_buff
*skb
,
569 struct netlink_callback
*cb
,
570 struct nl802154_dump_wpan_phy_state
*state
)
572 const struct genl_dumpit_info
*info
= genl_dumpit_info(cb
);
573 struct nlattr
**tb
= info
->info
.attrs
;
575 if (tb
[NL802154_ATTR_WPAN_PHY
])
576 state
->filter_wpan_phy
= nla_get_u32(tb
[NL802154_ATTR_WPAN_PHY
]);
577 if (tb
[NL802154_ATTR_WPAN_DEV
])
578 state
->filter_wpan_phy
= nla_get_u64(tb
[NL802154_ATTR_WPAN_DEV
]) >> 32;
579 if (tb
[NL802154_ATTR_IFINDEX
]) {
580 struct net_device
*netdev
;
581 struct cfg802154_registered_device
*rdev
;
582 int ifidx
= nla_get_u32(tb
[NL802154_ATTR_IFINDEX
]);
584 netdev
= __dev_get_by_index(&init_net
, ifidx
);
587 if (netdev
->ieee802154_ptr
) {
588 rdev
= wpan_phy_to_rdev(
589 netdev
->ieee802154_ptr
->wpan_phy
);
590 state
->filter_wpan_phy
= rdev
->wpan_phy_idx
;
598 nl802154_dump_wpan_phy(struct sk_buff
*skb
, struct netlink_callback
*cb
)
601 struct nl802154_dump_wpan_phy_state
*state
= (void *)cb
->args
[0];
602 struct cfg802154_registered_device
*rdev
;
606 state
= kzalloc(sizeof(*state
), GFP_KERNEL
);
611 state
->filter_wpan_phy
= -1;
612 ret
= nl802154_dump_wpan_phy_parse(skb
, cb
, state
);
618 cb
->args
[0] = (long)state
;
621 list_for_each_entry(rdev
, &cfg802154_rdev_list
, list
) {
622 if (!net_eq(wpan_phy_net(&rdev
->wpan_phy
), sock_net(skb
->sk
)))
624 if (++idx
<= state
->start
)
626 if (state
->filter_wpan_phy
!= -1 &&
627 state
->filter_wpan_phy
!= rdev
->wpan_phy_idx
)
629 /* attempt to fit multiple wpan_phy data chunks into the skb */
630 ret
= nl802154_send_wpan_phy(rdev
,
631 NL802154_CMD_NEW_WPAN_PHY
,
633 NETLINK_CB(cb
->skb
).portid
,
634 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
);
636 if ((ret
== -ENOBUFS
|| ret
== -EMSGSIZE
) &&
637 !skb
->len
&& cb
->min_dump_alloc
< 4096) {
638 cb
->min_dump_alloc
= 4096;
654 static int nl802154_dump_wpan_phy_done(struct netlink_callback
*cb
)
656 kfree((void *)cb
->args
[0]);
660 static int nl802154_get_wpan_phy(struct sk_buff
*skb
, struct genl_info
*info
)
663 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
665 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
669 if (nl802154_send_wpan_phy(rdev
, NL802154_CMD_NEW_WPAN_PHY
, msg
,
670 info
->snd_portid
, info
->snd_seq
, 0) < 0) {
675 return genlmsg_reply(msg
, info
);
678 static inline u64
wpan_dev_id(struct wpan_dev
*wpan_dev
)
680 return (u64
)wpan_dev
->identifier
|
681 ((u64
)wpan_phy_to_rdev(wpan_dev
->wpan_phy
)->wpan_phy_idx
<< 32);
684 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
685 #include <net/ieee802154_netdev.h>
688 ieee802154_llsec_send_key_id(struct sk_buff
*msg
,
689 const struct ieee802154_llsec_key_id
*desc
)
691 struct nlattr
*nl_dev_addr
;
693 if (nla_put_u32(msg
, NL802154_KEY_ID_ATTR_MODE
, desc
->mode
))
696 switch (desc
->mode
) {
697 case NL802154_KEY_ID_MODE_IMPLICIT
:
698 nl_dev_addr
= nla_nest_start_noflag(msg
,
699 NL802154_KEY_ID_ATTR_IMPLICIT
);
703 if (nla_put_le16(msg
, NL802154_DEV_ADDR_ATTR_PAN_ID
,
704 desc
->device_addr
.pan_id
) ||
705 nla_put_u32(msg
, NL802154_DEV_ADDR_ATTR_MODE
,
706 desc
->device_addr
.mode
))
709 switch (desc
->device_addr
.mode
) {
710 case NL802154_DEV_ADDR_SHORT
:
711 if (nla_put_le16(msg
, NL802154_DEV_ADDR_ATTR_SHORT
,
712 desc
->device_addr
.short_addr
))
715 case NL802154_DEV_ADDR_EXTENDED
:
716 if (nla_put_le64(msg
, NL802154_DEV_ADDR_ATTR_EXTENDED
,
717 desc
->device_addr
.extended_addr
,
718 NL802154_DEV_ADDR_ATTR_PAD
))
722 /* userspace should handle unknown */
726 nla_nest_end(msg
, nl_dev_addr
);
728 case NL802154_KEY_ID_MODE_INDEX
:
730 case NL802154_KEY_ID_MODE_INDEX_SHORT
:
731 /* TODO renmae short_source? */
732 if (nla_put_le32(msg
, NL802154_KEY_ID_ATTR_SOURCE_SHORT
,
736 case NL802154_KEY_ID_MODE_INDEX_EXTENDED
:
737 if (nla_put_le64(msg
, NL802154_KEY_ID_ATTR_SOURCE_EXTENDED
,
738 desc
->extended_source
,
739 NL802154_KEY_ID_ATTR_PAD
))
743 /* userspace should handle unknown */
747 /* TODO key_id to key_idx ? Check naming */
748 if (desc
->mode
!= NL802154_KEY_ID_MODE_IMPLICIT
) {
749 if (nla_put_u8(msg
, NL802154_KEY_ID_ATTR_INDEX
, desc
->id
))
756 static int nl802154_get_llsec_params(struct sk_buff
*msg
,
757 struct cfg802154_registered_device
*rdev
,
758 struct wpan_dev
*wpan_dev
)
760 struct nlattr
*nl_key_id
;
761 struct ieee802154_llsec_params params
;
764 ret
= rdev_get_llsec_params(rdev
, wpan_dev
, ¶ms
);
768 if (nla_put_u8(msg
, NL802154_ATTR_SEC_ENABLED
, params
.enabled
) ||
769 nla_put_u32(msg
, NL802154_ATTR_SEC_OUT_LEVEL
, params
.out_level
) ||
770 nla_put_be32(msg
, NL802154_ATTR_SEC_FRAME_COUNTER
,
771 params
.frame_counter
))
774 nl_key_id
= nla_nest_start_noflag(msg
, NL802154_ATTR_SEC_OUT_KEY_ID
);
778 ret
= ieee802154_llsec_send_key_id(msg
, ¶ms
.out_key
);
782 nla_nest_end(msg
, nl_key_id
);
786 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
789 nl802154_send_iface(struct sk_buff
*msg
, u32 portid
, u32 seq
, int flags
,
790 struct cfg802154_registered_device
*rdev
,
791 struct wpan_dev
*wpan_dev
)
793 struct net_device
*dev
= wpan_dev
->netdev
;
796 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
,
797 NL802154_CMD_NEW_INTERFACE
);
802 (nla_put_u32(msg
, NL802154_ATTR_IFINDEX
, dev
->ifindex
) ||
803 nla_put_string(msg
, NL802154_ATTR_IFNAME
, dev
->name
)))
804 goto nla_put_failure
;
806 if (nla_put_u32(msg
, NL802154_ATTR_WPAN_PHY
, rdev
->wpan_phy_idx
) ||
807 nla_put_u32(msg
, NL802154_ATTR_IFTYPE
, wpan_dev
->iftype
) ||
808 nla_put_u64_64bit(msg
, NL802154_ATTR_WPAN_DEV
,
809 wpan_dev_id(wpan_dev
), NL802154_ATTR_PAD
) ||
810 nla_put_u32(msg
, NL802154_ATTR_GENERATION
,
811 rdev
->devlist_generation
^
812 (cfg802154_rdev_list_generation
<< 2)))
813 goto nla_put_failure
;
815 /* address settings */
816 if (nla_put_le64(msg
, NL802154_ATTR_EXTENDED_ADDR
,
817 wpan_dev
->extended_addr
,
818 NL802154_ATTR_PAD
) ||
819 nla_put_le16(msg
, NL802154_ATTR_SHORT_ADDR
,
820 wpan_dev
->short_addr
) ||
821 nla_put_le16(msg
, NL802154_ATTR_PAN_ID
, wpan_dev
->pan_id
))
822 goto nla_put_failure
;
825 if (nla_put_s8(msg
, NL802154_ATTR_MAX_FRAME_RETRIES
,
826 wpan_dev
->frame_retries
) ||
827 nla_put_u8(msg
, NL802154_ATTR_MAX_BE
, wpan_dev
->max_be
) ||
828 nla_put_u8(msg
, NL802154_ATTR_MAX_CSMA_BACKOFFS
,
829 wpan_dev
->csma_retries
) ||
830 nla_put_u8(msg
, NL802154_ATTR_MIN_BE
, wpan_dev
->min_be
))
831 goto nla_put_failure
;
833 /* listen before transmit */
834 if (nla_put_u8(msg
, NL802154_ATTR_LBT_MODE
, wpan_dev
->lbt
))
835 goto nla_put_failure
;
837 /* ackreq default behaviour */
838 if (nla_put_u8(msg
, NL802154_ATTR_ACKREQ_DEFAULT
, wpan_dev
->ackreq
))
839 goto nla_put_failure
;
841 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
842 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
845 if (nl802154_get_llsec_params(msg
, rdev
, wpan_dev
) < 0)
846 goto nla_put_failure
;
849 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
851 genlmsg_end(msg
, hdr
);
855 genlmsg_cancel(msg
, hdr
);
860 nl802154_dump_interface(struct sk_buff
*skb
, struct netlink_callback
*cb
)
864 int wp_start
= cb
->args
[0];
865 int if_start
= cb
->args
[1];
866 struct cfg802154_registered_device
*rdev
;
867 struct wpan_dev
*wpan_dev
;
870 list_for_each_entry(rdev
, &cfg802154_rdev_list
, list
) {
871 if (!net_eq(wpan_phy_net(&rdev
->wpan_phy
), sock_net(skb
->sk
)))
873 if (wp_idx
< wp_start
) {
879 list_for_each_entry(wpan_dev
, &rdev
->wpan_dev_list
, list
) {
880 if (if_idx
< if_start
) {
884 if (nl802154_send_iface(skb
, NETLINK_CB(cb
->skb
).portid
,
885 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
886 rdev
, wpan_dev
) < 0) {
897 cb
->args
[0] = wp_idx
;
898 cb
->args
[1] = if_idx
;
903 static int nl802154_get_interface(struct sk_buff
*skb
, struct genl_info
*info
)
906 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
907 struct wpan_dev
*wdev
= info
->user_ptr
[1];
909 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
913 if (nl802154_send_iface(msg
, info
->snd_portid
, info
->snd_seq
, 0,
919 return genlmsg_reply(msg
, info
);
922 static int nl802154_new_interface(struct sk_buff
*skb
, struct genl_info
*info
)
924 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
925 enum nl802154_iftype type
= NL802154_IFTYPE_UNSPEC
;
926 __le64 extended_addr
= cpu_to_le64(0x0000000000000000ULL
);
928 /* TODO avoid failing a new interface
929 * creation due to pending removal?
932 if (!info
->attrs
[NL802154_ATTR_IFNAME
])
935 if (info
->attrs
[NL802154_ATTR_IFTYPE
]) {
936 type
= nla_get_u32(info
->attrs
[NL802154_ATTR_IFTYPE
]);
937 if (type
> NL802154_IFTYPE_MAX
||
938 !(rdev
->wpan_phy
.supported
.iftypes
& BIT(type
)))
942 if (info
->attrs
[NL802154_ATTR_EXTENDED_ADDR
])
943 extended_addr
= nla_get_le64(info
->attrs
[NL802154_ATTR_EXTENDED_ADDR
]);
945 if (!rdev
->ops
->add_virtual_intf
)
948 return rdev_add_virtual_intf(rdev
,
949 nla_data(info
->attrs
[NL802154_ATTR_IFNAME
]),
950 NET_NAME_USER
, type
, extended_addr
);
953 static int nl802154_del_interface(struct sk_buff
*skb
, struct genl_info
*info
)
955 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
956 struct wpan_dev
*wpan_dev
= info
->user_ptr
[1];
958 if (!rdev
->ops
->del_virtual_intf
)
961 /* If we remove a wpan device without a netdev then clear
962 * user_ptr[1] so that nl802154_post_doit won't dereference it
963 * to check if it needs to do dev_put(). Otherwise it crashes
964 * since the wpan_dev has been freed, unlike with a netdev where
965 * we need the dev_put() for the netdev to really be freed.
967 if (!wpan_dev
->netdev
)
968 info
->user_ptr
[1] = NULL
;
970 return rdev_del_virtual_intf(rdev
, wpan_dev
);
973 static int nl802154_set_channel(struct sk_buff
*skb
, struct genl_info
*info
)
975 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
978 if (!info
->attrs
[NL802154_ATTR_PAGE
] ||
979 !info
->attrs
[NL802154_ATTR_CHANNEL
])
982 page
= nla_get_u8(info
->attrs
[NL802154_ATTR_PAGE
]);
983 channel
= nla_get_u8(info
->attrs
[NL802154_ATTR_CHANNEL
]);
985 /* check 802.15.4 constraints */
986 if (!ieee802154_chan_is_valid(&rdev
->wpan_phy
, page
, channel
))
989 return rdev_set_channel(rdev
, page
, channel
);
992 static int nl802154_set_cca_mode(struct sk_buff
*skb
, struct genl_info
*info
)
994 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
995 struct wpan_phy_cca cca
;
997 if (!(rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_MODE
))
1000 if (!info
->attrs
[NL802154_ATTR_CCA_MODE
])
1003 cca
.mode
= nla_get_u32(info
->attrs
[NL802154_ATTR_CCA_MODE
]);
1004 /* checking 802.15.4 constraints */
1005 if (cca
.mode
< NL802154_CCA_ENERGY
||
1006 cca
.mode
> NL802154_CCA_ATTR_MAX
||
1007 !(rdev
->wpan_phy
.supported
.cca_modes
& BIT(cca
.mode
)))
1010 if (cca
.mode
== NL802154_CCA_ENERGY_CARRIER
) {
1011 if (!info
->attrs
[NL802154_ATTR_CCA_OPT
])
1014 cca
.opt
= nla_get_u32(info
->attrs
[NL802154_ATTR_CCA_OPT
]);
1015 if (cca
.opt
> NL802154_CCA_OPT_ATTR_MAX
||
1016 !(rdev
->wpan_phy
.supported
.cca_opts
& BIT(cca
.opt
)))
1020 return rdev_set_cca_mode(rdev
, &cca
);
1023 static int nl802154_set_cca_ed_level(struct sk_buff
*skb
, struct genl_info
*info
)
1025 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1029 if (!(rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_CCA_ED_LEVEL
))
1032 if (!info
->attrs
[NL802154_ATTR_CCA_ED_LEVEL
])
1035 ed_level
= nla_get_s32(info
->attrs
[NL802154_ATTR_CCA_ED_LEVEL
]);
1037 for (i
= 0; i
< rdev
->wpan_phy
.supported
.cca_ed_levels_size
; i
++) {
1038 if (ed_level
== rdev
->wpan_phy
.supported
.cca_ed_levels
[i
])
1039 return rdev_set_cca_ed_level(rdev
, ed_level
);
1045 static int nl802154_set_tx_power(struct sk_buff
*skb
, struct genl_info
*info
)
1047 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1051 if (!(rdev
->wpan_phy
.flags
& WPAN_PHY_FLAG_TXPOWER
))
1054 if (!info
->attrs
[NL802154_ATTR_TX_POWER
])
1057 power
= nla_get_s32(info
->attrs
[NL802154_ATTR_TX_POWER
]);
1059 for (i
= 0; i
< rdev
->wpan_phy
.supported
.tx_powers_size
; i
++) {
1060 if (power
== rdev
->wpan_phy
.supported
.tx_powers
[i
])
1061 return rdev_set_tx_power(rdev
, power
);
1067 static int nl802154_set_pan_id(struct sk_buff
*skb
, struct genl_info
*info
)
1069 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1070 struct net_device
*dev
= info
->user_ptr
[1];
1071 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1074 /* conflict here while tx/rx calls */
1075 if (netif_running(dev
))
1078 if (wpan_dev
->lowpan_dev
) {
1079 if (netif_running(wpan_dev
->lowpan_dev
))
1083 /* don't change address fields on monitor */
1084 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
||
1085 !info
->attrs
[NL802154_ATTR_PAN_ID
])
1088 pan_id
= nla_get_le16(info
->attrs
[NL802154_ATTR_PAN_ID
]);
1090 /* Only allow changing the PAN ID when the device has no more
1091 * associations ongoing to avoid confusing peers.
1093 if (cfg802154_device_is_associated(wpan_dev
)) {
1094 NL_SET_ERR_MSG(info
->extack
,
1095 "Existing associations, changing PAN ID forbidden");
1099 return rdev_set_pan_id(rdev
, wpan_dev
, pan_id
);
1102 static int nl802154_set_short_addr(struct sk_buff
*skb
, struct genl_info
*info
)
1104 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1105 struct net_device
*dev
= info
->user_ptr
[1];
1106 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1109 /* conflict here while tx/rx calls */
1110 if (netif_running(dev
))
1113 if (wpan_dev
->lowpan_dev
) {
1114 if (netif_running(wpan_dev
->lowpan_dev
))
1118 /* don't change address fields on monitor */
1119 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
||
1120 !info
->attrs
[NL802154_ATTR_SHORT_ADDR
])
1123 short_addr
= nla_get_le16(info
->attrs
[NL802154_ATTR_SHORT_ADDR
]);
1125 /* The short address only has a meaning when part of a PAN, after a
1126 * proper association procedure. However, we want to still offer the
1127 * possibility to create static networks so changing the short address
1128 * is only allowed when not already associated to other devices with
1129 * the official handshake.
1131 if (cfg802154_device_is_associated(wpan_dev
)) {
1132 NL_SET_ERR_MSG(info
->extack
,
1133 "Existing associations, changing short address forbidden");
1137 return rdev_set_short_addr(rdev
, wpan_dev
, short_addr
);
1141 nl802154_set_backoff_exponent(struct sk_buff
*skb
, struct genl_info
*info
)
1143 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1144 struct net_device
*dev
= info
->user_ptr
[1];
1145 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1148 /* should be set on netif open inside phy settings */
1149 if (netif_running(dev
))
1152 if (!info
->attrs
[NL802154_ATTR_MIN_BE
] ||
1153 !info
->attrs
[NL802154_ATTR_MAX_BE
])
1156 min_be
= nla_get_u8(info
->attrs
[NL802154_ATTR_MIN_BE
]);
1157 max_be
= nla_get_u8(info
->attrs
[NL802154_ATTR_MAX_BE
]);
1159 /* check 802.15.4 constraints */
1160 if (min_be
< rdev
->wpan_phy
.supported
.min_minbe
||
1161 min_be
> rdev
->wpan_phy
.supported
.max_minbe
||
1162 max_be
< rdev
->wpan_phy
.supported
.min_maxbe
||
1163 max_be
> rdev
->wpan_phy
.supported
.max_maxbe
||
1167 return rdev_set_backoff_exponent(rdev
, wpan_dev
, min_be
, max_be
);
1171 nl802154_set_max_csma_backoffs(struct sk_buff
*skb
, struct genl_info
*info
)
1173 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1174 struct net_device
*dev
= info
->user_ptr
[1];
1175 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1176 u8 max_csma_backoffs
;
1178 /* conflict here while other running iface settings */
1179 if (netif_running(dev
))
1182 if (!info
->attrs
[NL802154_ATTR_MAX_CSMA_BACKOFFS
])
1185 max_csma_backoffs
= nla_get_u8(
1186 info
->attrs
[NL802154_ATTR_MAX_CSMA_BACKOFFS
]);
1188 /* check 802.15.4 constraints */
1189 if (max_csma_backoffs
< rdev
->wpan_phy
.supported
.min_csma_backoffs
||
1190 max_csma_backoffs
> rdev
->wpan_phy
.supported
.max_csma_backoffs
)
1193 return rdev_set_max_csma_backoffs(rdev
, wpan_dev
, max_csma_backoffs
);
1197 nl802154_set_max_frame_retries(struct sk_buff
*skb
, struct genl_info
*info
)
1199 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1200 struct net_device
*dev
= info
->user_ptr
[1];
1201 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1202 s8 max_frame_retries
;
1204 if (netif_running(dev
))
1207 if (!info
->attrs
[NL802154_ATTR_MAX_FRAME_RETRIES
])
1210 max_frame_retries
= nla_get_s8(
1211 info
->attrs
[NL802154_ATTR_MAX_FRAME_RETRIES
]);
1213 /* check 802.15.4 constraints */
1214 if (max_frame_retries
< rdev
->wpan_phy
.supported
.min_frame_retries
||
1215 max_frame_retries
> rdev
->wpan_phy
.supported
.max_frame_retries
)
1218 return rdev_set_max_frame_retries(rdev
, wpan_dev
, max_frame_retries
);
1221 static int nl802154_set_lbt_mode(struct sk_buff
*skb
, struct genl_info
*info
)
1223 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1224 struct net_device
*dev
= info
->user_ptr
[1];
1225 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1228 if (netif_running(dev
))
1231 if (!info
->attrs
[NL802154_ATTR_LBT_MODE
])
1234 mode
= nla_get_u8(info
->attrs
[NL802154_ATTR_LBT_MODE
]);
1236 if (mode
!= 0 && mode
!= 1)
1239 if (!wpan_phy_supported_bool(mode
, rdev
->wpan_phy
.supported
.lbt
))
1242 return rdev_set_lbt_mode(rdev
, wpan_dev
, mode
);
1246 nl802154_set_ackreq_default(struct sk_buff
*skb
, struct genl_info
*info
)
1248 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1249 struct net_device
*dev
= info
->user_ptr
[1];
1250 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1253 if (netif_running(dev
))
1256 if (!info
->attrs
[NL802154_ATTR_ACKREQ_DEFAULT
])
1259 ackreq
= nla_get_u8(info
->attrs
[NL802154_ATTR_ACKREQ_DEFAULT
]);
1261 if (ackreq
!= 0 && ackreq
!= 1)
1264 return rdev_set_ackreq_default(rdev
, wpan_dev
, ackreq
);
1267 static int nl802154_wpan_phy_netns(struct sk_buff
*skb
, struct genl_info
*info
)
1269 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1273 if (info
->attrs
[NL802154_ATTR_PID
]) {
1274 u32 pid
= nla_get_u32(info
->attrs
[NL802154_ATTR_PID
]);
1276 net
= get_net_ns_by_pid(pid
);
1277 } else if (info
->attrs
[NL802154_ATTR_NETNS_FD
]) {
1278 u32 fd
= nla_get_u32(info
->attrs
[NL802154_ATTR_NETNS_FD
]);
1280 net
= get_net_ns_by_fd(fd
);
1286 return PTR_ERR(net
);
1290 /* check if anything to do */
1291 if (!net_eq(wpan_phy_net(&rdev
->wpan_phy
), net
))
1292 err
= cfg802154_switch_netns(rdev
, net
);
1298 static int nl802154_prep_scan_event_msg(struct sk_buff
*msg
,
1299 struct cfg802154_registered_device
*rdev
,
1300 struct wpan_dev
*wpan_dev
,
1301 u32 portid
, u32 seq
, int flags
, u8 cmd
,
1302 struct ieee802154_coord_desc
*desc
)
1307 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
, cmd
);
1311 if (nla_put_u32(msg
, NL802154_ATTR_WPAN_PHY
, rdev
->wpan_phy_idx
))
1312 goto nla_put_failure
;
1314 if (wpan_dev
->netdev
&&
1315 nla_put_u32(msg
, NL802154_ATTR_IFINDEX
, wpan_dev
->netdev
->ifindex
))
1316 goto nla_put_failure
;
1318 if (nla_put_u64_64bit(msg
, NL802154_ATTR_WPAN_DEV
,
1319 wpan_dev_id(wpan_dev
), NL802154_ATTR_PAD
))
1320 goto nla_put_failure
;
1322 nla
= nla_nest_start_noflag(msg
, NL802154_ATTR_COORDINATOR
);
1324 goto nla_put_failure
;
1326 if (nla_put(msg
, NL802154_COORD_PANID
, IEEE802154_PAN_ID_LEN
,
1327 &desc
->addr
.pan_id
))
1328 goto nla_put_failure
;
1330 if (desc
->addr
.mode
== IEEE802154_ADDR_SHORT
) {
1331 if (nla_put(msg
, NL802154_COORD_ADDR
,
1332 IEEE802154_SHORT_ADDR_LEN
,
1333 &desc
->addr
.short_addr
))
1334 goto nla_put_failure
;
1336 if (nla_put(msg
, NL802154_COORD_ADDR
,
1337 IEEE802154_EXTENDED_ADDR_LEN
,
1338 &desc
->addr
.extended_addr
))
1339 goto nla_put_failure
;
1342 if (nla_put_u8(msg
, NL802154_COORD_CHANNEL
, desc
->channel
))
1343 goto nla_put_failure
;
1345 if (nla_put_u8(msg
, NL802154_COORD_PAGE
, desc
->page
))
1346 goto nla_put_failure
;
1348 if (nla_put_u16(msg
, NL802154_COORD_SUPERFRAME_SPEC
,
1349 desc
->superframe_spec
))
1350 goto nla_put_failure
;
1352 if (nla_put_u8(msg
, NL802154_COORD_LINK_QUALITY
, desc
->link_quality
))
1353 goto nla_put_failure
;
1355 if (desc
->gts_permit
&& nla_put_flag(msg
, NL802154_COORD_GTS_PERMIT
))
1356 goto nla_put_failure
;
1358 /* TODO: NL802154_COORD_PAYLOAD_DATA if any */
1360 nla_nest_end(msg
, nla
);
1362 genlmsg_end(msg
, hdr
);
1367 genlmsg_cancel(msg
, hdr
);
1372 int nl802154_scan_event(struct wpan_phy
*wpan_phy
, struct wpan_dev
*wpan_dev
,
1373 struct ieee802154_coord_desc
*desc
)
1375 struct cfg802154_registered_device
*rdev
= wpan_phy_to_rdev(wpan_phy
);
1376 struct sk_buff
*msg
;
1379 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_ATOMIC
);
1383 ret
= nl802154_prep_scan_event_msg(msg
, rdev
, wpan_dev
, 0, 0, 0,
1384 NL802154_CMD_SCAN_EVENT
,
1391 return genlmsg_multicast_netns(&nl802154_fam
, wpan_phy_net(wpan_phy
),
1392 msg
, 0, NL802154_MCGRP_SCAN
, GFP_ATOMIC
);
1394 EXPORT_SYMBOL_GPL(nl802154_scan_event
);
1396 static int nl802154_trigger_scan(struct sk_buff
*skb
, struct genl_info
*info
)
1398 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1399 struct net_device
*dev
= info
->user_ptr
[1];
1400 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1401 struct wpan_phy
*wpan_phy
= &rdev
->wpan_phy
;
1402 struct cfg802154_scan_request
*request
;
1406 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
) {
1407 NL_SET_ERR_MSG(info
->extack
, "Monitors are not allowed to perform scans");
1411 if (!info
->attrs
[NL802154_ATTR_SCAN_TYPE
]) {
1412 NL_SET_ERR_MSG(info
->extack
, "Malformed request, missing scan type");
1416 if (wpan_phy
->flags
& WPAN_PHY_FLAG_DATAGRAMS_ONLY
) {
1417 NL_SET_ERR_MSG(info
->extack
, "PHY only supports datagrams");
1421 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
1425 request
->wpan_dev
= wpan_dev
;
1426 request
->wpan_phy
= wpan_phy
;
1428 type
= nla_get_u8(info
->attrs
[NL802154_ATTR_SCAN_TYPE
]);
1430 case NL802154_SCAN_ACTIVE
:
1431 case NL802154_SCAN_PASSIVE
:
1432 request
->type
= type
;
1435 NL_SET_ERR_MSG_FMT(info
->extack
, "Unsupported scan type: %d", type
);
1440 /* Use current page by default */
1441 if (info
->attrs
[NL802154_ATTR_PAGE
])
1442 request
->page
= nla_get_u8(info
->attrs
[NL802154_ATTR_PAGE
]);
1444 request
->page
= wpan_phy
->current_page
;
1446 /* Scan all supported channels by default */
1447 if (info
->attrs
[NL802154_ATTR_SCAN_CHANNELS
])
1448 request
->channels
= nla_get_u32(info
->attrs
[NL802154_ATTR_SCAN_CHANNELS
]);
1450 request
->channels
= wpan_phy
->supported
.channels
[request
->page
];
1452 /* Use maximum duration order by default */
1453 if (info
->attrs
[NL802154_ATTR_SCAN_DURATION
])
1454 request
->duration
= nla_get_u8(info
->attrs
[NL802154_ATTR_SCAN_DURATION
]);
1456 request
->duration
= IEEE802154_MAX_SCAN_DURATION
;
1458 err
= rdev_trigger_scan(rdev
, request
);
1460 pr_err("Failure starting scanning (%d)\n", err
);
1472 static int nl802154_prep_scan_msg(struct sk_buff
*msg
,
1473 struct cfg802154_registered_device
*rdev
,
1474 struct wpan_dev
*wpan_dev
, u32 portid
,
1475 u32 seq
, int flags
, u8 cmd
, u8 arg
)
1479 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
, cmd
);
1483 if (nla_put_u32(msg
, NL802154_ATTR_WPAN_PHY
, rdev
->wpan_phy_idx
))
1484 goto nla_put_failure
;
1486 if (wpan_dev
->netdev
&&
1487 nla_put_u32(msg
, NL802154_ATTR_IFINDEX
, wpan_dev
->netdev
->ifindex
))
1488 goto nla_put_failure
;
1490 if (nla_put_u64_64bit(msg
, NL802154_ATTR_WPAN_DEV
,
1491 wpan_dev_id(wpan_dev
), NL802154_ATTR_PAD
))
1492 goto nla_put_failure
;
1494 if (cmd
== NL802154_CMD_SCAN_DONE
&&
1495 nla_put_u8(msg
, NL802154_ATTR_SCAN_DONE_REASON
, arg
))
1496 goto nla_put_failure
;
1498 genlmsg_end(msg
, hdr
);
1503 genlmsg_cancel(msg
, hdr
);
1508 static int nl802154_send_scan_msg(struct cfg802154_registered_device
*rdev
,
1509 struct wpan_dev
*wpan_dev
, u8 cmd
, u8 arg
)
1511 struct sk_buff
*msg
;
1514 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
1518 ret
= nl802154_prep_scan_msg(msg
, rdev
, wpan_dev
, 0, 0, 0, cmd
, arg
);
1524 return genlmsg_multicast_netns(&nl802154_fam
,
1525 wpan_phy_net(&rdev
->wpan_phy
), msg
, 0,
1526 NL802154_MCGRP_SCAN
, GFP_KERNEL
);
1529 int nl802154_scan_started(struct wpan_phy
*wpan_phy
, struct wpan_dev
*wpan_dev
)
1531 struct cfg802154_registered_device
*rdev
= wpan_phy_to_rdev(wpan_phy
);
1534 /* Ignore errors when there are no listeners */
1535 err
= nl802154_send_scan_msg(rdev
, wpan_dev
, NL802154_CMD_TRIGGER_SCAN
, 0);
1541 EXPORT_SYMBOL_GPL(nl802154_scan_started
);
1543 int nl802154_scan_done(struct wpan_phy
*wpan_phy
, struct wpan_dev
*wpan_dev
,
1544 enum nl802154_scan_done_reasons reason
)
1546 struct cfg802154_registered_device
*rdev
= wpan_phy_to_rdev(wpan_phy
);
1549 /* Ignore errors when there are no listeners */
1550 err
= nl802154_send_scan_msg(rdev
, wpan_dev
, NL802154_CMD_SCAN_DONE
, reason
);
1556 EXPORT_SYMBOL_GPL(nl802154_scan_done
);
1558 static int nl802154_abort_scan(struct sk_buff
*skb
, struct genl_info
*info
)
1560 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1561 struct net_device
*dev
= info
->user_ptr
[1];
1562 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1564 /* Resources are released in the notification helper above */
1565 return rdev_abort_scan(rdev
, wpan_dev
);
1569 nl802154_send_beacons(struct sk_buff
*skb
, struct genl_info
*info
)
1571 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1572 struct net_device
*dev
= info
->user_ptr
[1];
1573 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1574 struct wpan_phy
*wpan_phy
= &rdev
->wpan_phy
;
1575 struct cfg802154_beacon_request
*request
;
1578 if (wpan_dev
->iftype
!= NL802154_IFTYPE_COORD
) {
1579 NL_SET_ERR_MSG(info
->extack
, "Only coordinators can send beacons");
1583 if (wpan_dev
->pan_id
== cpu_to_le16(IEEE802154_PANID_BROADCAST
)) {
1584 NL_SET_ERR_MSG(info
->extack
, "Device is not part of any PAN");
1588 if (wpan_phy
->flags
& WPAN_PHY_FLAG_DATAGRAMS_ONLY
) {
1589 NL_SET_ERR_MSG(info
->extack
, "PHY only supports datagrams");
1593 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
1597 request
->wpan_dev
= wpan_dev
;
1598 request
->wpan_phy
= wpan_phy
;
1600 /* Use maximum duration order by default */
1601 if (info
->attrs
[NL802154_ATTR_BEACON_INTERVAL
])
1602 request
->interval
= nla_get_u8(info
->attrs
[NL802154_ATTR_BEACON_INTERVAL
]);
1604 request
->interval
= IEEE802154_MAX_SCAN_DURATION
;
1606 err
= rdev_send_beacons(rdev
, request
);
1608 pr_err("Failure starting sending beacons (%d)\n", err
);
1620 void nl802154_beaconing_done(struct wpan_dev
*wpan_dev
)
1624 EXPORT_SYMBOL_GPL(nl802154_beaconing_done
);
1627 nl802154_stop_beacons(struct sk_buff
*skb
, struct genl_info
*info
)
1629 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1630 struct net_device
*dev
= info
->user_ptr
[1];
1631 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1633 /* Resources are released in the notification helper above */
1634 return rdev_stop_beacons(rdev
, wpan_dev
);
1637 static int nl802154_associate(struct sk_buff
*skb
, struct genl_info
*info
)
1639 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1640 struct net_device
*dev
= info
->user_ptr
[1];
1641 struct wpan_dev
*wpan_dev
;
1642 struct wpan_phy
*wpan_phy
;
1643 struct ieee802154_addr coord
;
1646 wpan_dev
= dev
->ieee802154_ptr
;
1647 wpan_phy
= &rdev
->wpan_phy
;
1649 if (wpan_phy
->flags
& WPAN_PHY_FLAG_DATAGRAMS_ONLY
) {
1650 NL_SET_ERR_MSG(info
->extack
, "PHY only supports datagrams");
1654 if (!info
->attrs
[NL802154_ATTR_PAN_ID
] ||
1655 !info
->attrs
[NL802154_ATTR_EXTENDED_ADDR
])
1658 coord
.pan_id
= nla_get_le16(info
->attrs
[NL802154_ATTR_PAN_ID
]);
1659 coord
.mode
= IEEE802154_ADDR_LONG
;
1660 coord
.extended_addr
= nla_get_le64(info
->attrs
[NL802154_ATTR_EXTENDED_ADDR
]);
1662 mutex_lock(&wpan_dev
->association_lock
);
1663 err
= rdev_associate(rdev
, wpan_dev
, &coord
);
1664 mutex_unlock(&wpan_dev
->association_lock
);
1666 pr_err("Association with PAN ID 0x%x failed (%d)\n",
1667 le16_to_cpu(coord
.pan_id
), err
);
1672 static int nl802154_disassociate(struct sk_buff
*skb
, struct genl_info
*info
)
1674 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1675 struct net_device
*dev
= info
->user_ptr
[1];
1676 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1677 struct wpan_phy
*wpan_phy
= &rdev
->wpan_phy
;
1678 struct ieee802154_addr target
;
1680 if (wpan_phy
->flags
& WPAN_PHY_FLAG_DATAGRAMS_ONLY
) {
1681 NL_SET_ERR_MSG(info
->extack
, "PHY only supports datagrams");
1685 target
.pan_id
= wpan_dev
->pan_id
;
1687 if (info
->attrs
[NL802154_ATTR_EXTENDED_ADDR
]) {
1688 target
.mode
= IEEE802154_ADDR_LONG
;
1689 target
.extended_addr
= nla_get_le64(info
->attrs
[NL802154_ATTR_EXTENDED_ADDR
]);
1690 } else if (info
->attrs
[NL802154_ATTR_SHORT_ADDR
]) {
1691 target
.mode
= IEEE802154_ADDR_SHORT
;
1692 target
.short_addr
= nla_get_le16(info
->attrs
[NL802154_ATTR_SHORT_ADDR
]);
1694 NL_SET_ERR_MSG(info
->extack
, "Device address is missing");
1698 mutex_lock(&wpan_dev
->association_lock
);
1699 rdev_disassociate(rdev
, wpan_dev
, &target
);
1700 mutex_unlock(&wpan_dev
->association_lock
);
1705 static int nl802154_set_max_associations(struct sk_buff
*skb
, struct genl_info
*info
)
1707 struct net_device
*dev
= info
->user_ptr
[1];
1708 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1709 unsigned int max_assoc
;
1711 if (!info
->attrs
[NL802154_ATTR_MAX_ASSOCIATIONS
]) {
1712 NL_SET_ERR_MSG(info
->extack
, "No maximum number of association given");
1716 max_assoc
= nla_get_u32(info
->attrs
[NL802154_ATTR_MAX_ASSOCIATIONS
]);
1718 mutex_lock(&wpan_dev
->association_lock
);
1719 cfg802154_set_max_associations(wpan_dev
, max_assoc
);
1720 mutex_unlock(&wpan_dev
->association_lock
);
1725 static int nl802154_send_peer_info(struct sk_buff
*msg
,
1726 struct netlink_callback
*cb
,
1728 struct cfg802154_registered_device
*rdev
,
1729 struct wpan_dev
*wpan_dev
,
1730 struct ieee802154_pan_device
*peer
,
1731 enum nl802154_peer_type type
)
1738 hdr
= nl802154hdr_put(msg
, NETLINK_CB(cb
->skb
).portid
, seq
, flags
,
1739 NL802154_CMD_LIST_ASSOCIATIONS
);
1743 genl_dump_check_consistent(cb
, hdr
);
1745 nla
= nla_nest_start_noflag(msg
, NL802154_ATTR_PEER
);
1747 goto nla_put_failure
;
1749 if (nla_put_u8(msg
, NL802154_DEV_ADDR_ATTR_PEER_TYPE
, type
))
1750 goto nla_put_failure
;
1752 if (nla_put_u8(msg
, NL802154_DEV_ADDR_ATTR_MODE
, peer
->mode
))
1753 goto nla_put_failure
;
1755 if (nla_put(msg
, NL802154_DEV_ADDR_ATTR_SHORT
,
1756 IEEE802154_SHORT_ADDR_LEN
, &peer
->short_addr
))
1757 goto nla_put_failure
;
1759 if (nla_put(msg
, NL802154_DEV_ADDR_ATTR_EXTENDED
,
1760 IEEE802154_EXTENDED_ADDR_LEN
, &peer
->extended_addr
))
1761 goto nla_put_failure
;
1763 nla_nest_end(msg
, nla
);
1765 genlmsg_end(msg
, hdr
);
1770 genlmsg_cancel(msg
, hdr
);
1774 static int nl802154_list_associations(struct sk_buff
*skb
,
1775 struct netlink_callback
*cb
)
1777 struct cfg802154_registered_device
*rdev
;
1778 struct ieee802154_pan_device
*child
;
1779 struct wpan_dev
*wpan_dev
;
1782 err
= nl802154_prepare_wpan_dev_dump(skb
, cb
, &rdev
, &wpan_dev
);
1786 mutex_lock(&wpan_dev
->association_lock
);
1791 if (wpan_dev
->parent
) {
1792 err
= nl802154_send_peer_info(skb
, cb
, cb
->nlh
->nlmsg_seq
,
1793 NLM_F_MULTI
, rdev
, wpan_dev
,
1795 NL802154_PEER_TYPE_PARENT
);
1800 list_for_each_entry(child
, &wpan_dev
->children
, node
) {
1801 err
= nl802154_send_peer_info(skb
, cb
, cb
->nlh
->nlmsg_seq
,
1802 NLM_F_MULTI
, rdev
, wpan_dev
,
1804 NL802154_PEER_TYPE_CHILD
);
1813 mutex_unlock(&wpan_dev
->association_lock
);
1815 nl802154_finish_wpan_dev_dump(rdev
);
1820 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
1821 static const struct nla_policy nl802154_dev_addr_policy
[NL802154_DEV_ADDR_ATTR_MAX
+ 1] = {
1822 [NL802154_DEV_ADDR_ATTR_PAN_ID
] = { .type
= NLA_U16
},
1823 [NL802154_DEV_ADDR_ATTR_MODE
] = { .type
= NLA_U32
},
1824 [NL802154_DEV_ADDR_ATTR_SHORT
] = { .type
= NLA_U16
},
1825 [NL802154_DEV_ADDR_ATTR_EXTENDED
] = { .type
= NLA_U64
},
1829 ieee802154_llsec_parse_dev_addr(struct nlattr
*nla
,
1830 struct ieee802154_addr
*addr
)
1832 struct nlattr
*attrs
[NL802154_DEV_ADDR_ATTR_MAX
+ 1];
1834 if (!nla
|| nla_parse_nested_deprecated(attrs
, NL802154_DEV_ADDR_ATTR_MAX
, nla
, nl802154_dev_addr_policy
, NULL
))
1837 if (!attrs
[NL802154_DEV_ADDR_ATTR_PAN_ID
] || !attrs
[NL802154_DEV_ADDR_ATTR_MODE
])
1840 addr
->pan_id
= nla_get_le16(attrs
[NL802154_DEV_ADDR_ATTR_PAN_ID
]);
1841 addr
->mode
= nla_get_u32(attrs
[NL802154_DEV_ADDR_ATTR_MODE
]);
1842 switch (addr
->mode
) {
1843 case NL802154_DEV_ADDR_SHORT
:
1844 if (!attrs
[NL802154_DEV_ADDR_ATTR_SHORT
])
1846 addr
->short_addr
= nla_get_le16(attrs
[NL802154_DEV_ADDR_ATTR_SHORT
]);
1848 case NL802154_DEV_ADDR_EXTENDED
:
1849 if (!attrs
[NL802154_DEV_ADDR_ATTR_EXTENDED
])
1851 addr
->extended_addr
= nla_get_le64(attrs
[NL802154_DEV_ADDR_ATTR_EXTENDED
]);
1860 static const struct nla_policy nl802154_key_id_policy
[NL802154_KEY_ID_ATTR_MAX
+ 1] = {
1861 [NL802154_KEY_ID_ATTR_MODE
] = { .type
= NLA_U32
},
1862 [NL802154_KEY_ID_ATTR_INDEX
] = { .type
= NLA_U8
},
1863 [NL802154_KEY_ID_ATTR_IMPLICIT
] = { .type
= NLA_NESTED
},
1864 [NL802154_KEY_ID_ATTR_SOURCE_SHORT
] = { .type
= NLA_U32
},
1865 [NL802154_KEY_ID_ATTR_SOURCE_EXTENDED
] = { .type
= NLA_U64
},
1869 ieee802154_llsec_parse_key_id(struct nlattr
*nla
,
1870 struct ieee802154_llsec_key_id
*desc
)
1872 struct nlattr
*attrs
[NL802154_KEY_ID_ATTR_MAX
+ 1];
1874 if (!nla
|| nla_parse_nested_deprecated(attrs
, NL802154_KEY_ID_ATTR_MAX
, nla
, nl802154_key_id_policy
, NULL
))
1877 if (!attrs
[NL802154_KEY_ID_ATTR_MODE
])
1880 desc
->mode
= nla_get_u32(attrs
[NL802154_KEY_ID_ATTR_MODE
]);
1881 switch (desc
->mode
) {
1882 case NL802154_KEY_ID_MODE_IMPLICIT
:
1883 if (!attrs
[NL802154_KEY_ID_ATTR_IMPLICIT
])
1886 if (ieee802154_llsec_parse_dev_addr(attrs
[NL802154_KEY_ID_ATTR_IMPLICIT
],
1887 &desc
->device_addr
) < 0)
1890 case NL802154_KEY_ID_MODE_INDEX
:
1892 case NL802154_KEY_ID_MODE_INDEX_SHORT
:
1893 if (!attrs
[NL802154_KEY_ID_ATTR_SOURCE_SHORT
])
1896 desc
->short_source
= nla_get_le32(attrs
[NL802154_KEY_ID_ATTR_SOURCE_SHORT
]);
1898 case NL802154_KEY_ID_MODE_INDEX_EXTENDED
:
1899 if (!attrs
[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED
])
1902 desc
->extended_source
= nla_get_le64(attrs
[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED
]);
1908 if (desc
->mode
!= NL802154_KEY_ID_MODE_IMPLICIT
) {
1909 if (!attrs
[NL802154_KEY_ID_ATTR_INDEX
])
1912 /* TODO change id to idx */
1913 desc
->id
= nla_get_u8(attrs
[NL802154_KEY_ID_ATTR_INDEX
]);
1919 static int nl802154_set_llsec_params(struct sk_buff
*skb
,
1920 struct genl_info
*info
)
1922 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
1923 struct net_device
*dev
= info
->user_ptr
[1];
1924 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
1925 struct ieee802154_llsec_params params
;
1929 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
1932 if (info
->attrs
[NL802154_ATTR_SEC_ENABLED
]) {
1935 enabled
= nla_get_u8(info
->attrs
[NL802154_ATTR_SEC_ENABLED
]);
1936 if (enabled
!= 0 && enabled
!= 1)
1939 params
.enabled
= nla_get_u8(info
->attrs
[NL802154_ATTR_SEC_ENABLED
]);
1940 changed
|= IEEE802154_LLSEC_PARAM_ENABLED
;
1943 if (info
->attrs
[NL802154_ATTR_SEC_OUT_KEY_ID
]) {
1944 ret
= ieee802154_llsec_parse_key_id(info
->attrs
[NL802154_ATTR_SEC_OUT_KEY_ID
],
1949 changed
|= IEEE802154_LLSEC_PARAM_OUT_KEY
;
1952 if (info
->attrs
[NL802154_ATTR_SEC_OUT_LEVEL
]) {
1953 params
.out_level
= nla_get_u32(info
->attrs
[NL802154_ATTR_SEC_OUT_LEVEL
]);
1954 if (params
.out_level
> NL802154_SECLEVEL_MAX
)
1957 changed
|= IEEE802154_LLSEC_PARAM_OUT_LEVEL
;
1960 if (info
->attrs
[NL802154_ATTR_SEC_FRAME_COUNTER
]) {
1961 params
.frame_counter
= nla_get_be32(info
->attrs
[NL802154_ATTR_SEC_FRAME_COUNTER
]);
1962 changed
|= IEEE802154_LLSEC_PARAM_FRAME_COUNTER
;
1965 return rdev_set_llsec_params(rdev
, wpan_dev
, ¶ms
, changed
);
1968 static int nl802154_send_key(struct sk_buff
*msg
, u32 cmd
, u32 portid
,
1970 struct cfg802154_registered_device
*rdev
,
1971 struct net_device
*dev
,
1972 const struct ieee802154_llsec_key_entry
*key
)
1975 u32 commands
[NL802154_CMD_FRAME_NR_IDS
/ 32];
1976 struct nlattr
*nl_key
, *nl_key_id
;
1978 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
, cmd
);
1982 if (nla_put_u32(msg
, NL802154_ATTR_IFINDEX
, dev
->ifindex
))
1983 goto nla_put_failure
;
1985 nl_key
= nla_nest_start_noflag(msg
, NL802154_ATTR_SEC_KEY
);
1987 goto nla_put_failure
;
1989 nl_key_id
= nla_nest_start_noflag(msg
, NL802154_KEY_ATTR_ID
);
1991 goto nla_put_failure
;
1993 if (ieee802154_llsec_send_key_id(msg
, &key
->id
) < 0)
1994 goto nla_put_failure
;
1996 nla_nest_end(msg
, nl_key_id
);
1998 if (nla_put_u8(msg
, NL802154_KEY_ATTR_USAGE_FRAMES
,
1999 key
->key
->frame_types
))
2000 goto nla_put_failure
;
2002 if (key
->key
->frame_types
& BIT(NL802154_FRAME_CMD
)) {
2003 /* TODO for each nested */
2004 memset(commands
, 0, sizeof(commands
));
2005 commands
[7] = key
->key
->cmd_frame_ids
;
2006 if (nla_put(msg
, NL802154_KEY_ATTR_USAGE_CMDS
,
2007 sizeof(commands
), commands
))
2008 goto nla_put_failure
;
2011 if (nla_put(msg
, NL802154_KEY_ATTR_BYTES
, NL802154_KEY_SIZE
,
2013 goto nla_put_failure
;
2015 nla_nest_end(msg
, nl_key
);
2016 genlmsg_end(msg
, hdr
);
2021 genlmsg_cancel(msg
, hdr
);
2026 nl802154_dump_llsec_key(struct sk_buff
*skb
, struct netlink_callback
*cb
)
2028 struct cfg802154_registered_device
*rdev
= NULL
;
2029 struct ieee802154_llsec_key_entry
*key
;
2030 struct ieee802154_llsec_table
*table
;
2031 struct wpan_dev
*wpan_dev
;
2034 err
= nl802154_prepare_wpan_dev_dump(skb
, cb
, &rdev
, &wpan_dev
);
2038 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
) {
2043 if (!wpan_dev
->netdev
) {
2048 rdev_lock_llsec_table(rdev
, wpan_dev
);
2049 rdev_get_llsec_table(rdev
, wpan_dev
, &table
);
2051 /* TODO make it like station dump */
2055 list_for_each_entry(key
, &table
->keys
, list
) {
2056 if (nl802154_send_key(skb
, NL802154_CMD_NEW_SEC_KEY
,
2057 NETLINK_CB(cb
->skb
).portid
,
2058 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
2059 rdev
, wpan_dev
->netdev
, key
) < 0) {
2062 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2070 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2073 nl802154_finish_wpan_dev_dump(rdev
);
2078 static const struct nla_policy nl802154_key_policy
[NL802154_KEY_ATTR_MAX
+ 1] = {
2079 [NL802154_KEY_ATTR_ID
] = { NLA_NESTED
},
2080 /* TODO handle it as for_each_nested and NLA_FLAG? */
2081 [NL802154_KEY_ATTR_USAGE_FRAMES
] = { NLA_U8
},
2082 /* TODO handle it as for_each_nested, not static array? */
2083 [NL802154_KEY_ATTR_USAGE_CMDS
] = { .len
= NL802154_CMD_FRAME_NR_IDS
/ 8 },
2084 [NL802154_KEY_ATTR_BYTES
] = { .len
= NL802154_KEY_SIZE
},
2087 static int nl802154_add_llsec_key(struct sk_buff
*skb
, struct genl_info
*info
)
2089 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2090 struct net_device
*dev
= info
->user_ptr
[1];
2091 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2092 struct nlattr
*attrs
[NL802154_KEY_ATTR_MAX
+ 1];
2093 struct ieee802154_llsec_key key
= { };
2094 struct ieee802154_llsec_key_id id
= { };
2095 u32 commands
[NL802154_CMD_FRAME_NR_IDS
/ 32] = { };
2097 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2100 if (!info
->attrs
[NL802154_ATTR_SEC_KEY
] ||
2101 nla_parse_nested_deprecated(attrs
, NL802154_KEY_ATTR_MAX
, info
->attrs
[NL802154_ATTR_SEC_KEY
], nl802154_key_policy
, info
->extack
))
2104 if (!attrs
[NL802154_KEY_ATTR_USAGE_FRAMES
] ||
2105 !attrs
[NL802154_KEY_ATTR_BYTES
])
2108 if (ieee802154_llsec_parse_key_id(attrs
[NL802154_KEY_ATTR_ID
], &id
) < 0)
2111 key
.frame_types
= nla_get_u8(attrs
[NL802154_KEY_ATTR_USAGE_FRAMES
]);
2112 if (key
.frame_types
> BIT(NL802154_FRAME_MAX
) ||
2113 ((key
.frame_types
& BIT(NL802154_FRAME_CMD
)) &&
2114 !attrs
[NL802154_KEY_ATTR_USAGE_CMDS
]))
2117 if (attrs
[NL802154_KEY_ATTR_USAGE_CMDS
]) {
2118 /* TODO for each nested */
2119 nla_memcpy(commands
, attrs
[NL802154_KEY_ATTR_USAGE_CMDS
],
2120 NL802154_CMD_FRAME_NR_IDS
/ 8);
2122 /* TODO understand the -EINVAL logic here? last condition */
2123 if (commands
[0] || commands
[1] || commands
[2] || commands
[3] ||
2124 commands
[4] || commands
[5] || commands
[6] ||
2125 commands
[7] > BIT(NL802154_CMD_FRAME_MAX
))
2128 key
.cmd_frame_ids
= commands
[7];
2130 key
.cmd_frame_ids
= 0;
2133 nla_memcpy(key
.key
, attrs
[NL802154_KEY_ATTR_BYTES
], NL802154_KEY_SIZE
);
2135 if (ieee802154_llsec_parse_key_id(attrs
[NL802154_KEY_ATTR_ID
], &id
) < 0)
2138 return rdev_add_llsec_key(rdev
, wpan_dev
, &id
, &key
);
2141 static int nl802154_del_llsec_key(struct sk_buff
*skb
, struct genl_info
*info
)
2143 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2144 struct net_device
*dev
= info
->user_ptr
[1];
2145 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2146 struct nlattr
*attrs
[NL802154_KEY_ATTR_MAX
+ 1];
2147 struct ieee802154_llsec_key_id id
;
2149 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2152 if (!info
->attrs
[NL802154_ATTR_SEC_KEY
] ||
2153 nla_parse_nested_deprecated(attrs
, NL802154_KEY_ATTR_MAX
, info
->attrs
[NL802154_ATTR_SEC_KEY
], nl802154_key_policy
, info
->extack
))
2156 if (ieee802154_llsec_parse_key_id(attrs
[NL802154_KEY_ATTR_ID
], &id
) < 0)
2159 return rdev_del_llsec_key(rdev
, wpan_dev
, &id
);
2162 static int nl802154_send_device(struct sk_buff
*msg
, u32 cmd
, u32 portid
,
2164 struct cfg802154_registered_device
*rdev
,
2165 struct net_device
*dev
,
2166 const struct ieee802154_llsec_device
*dev_desc
)
2169 struct nlattr
*nl_device
;
2171 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
, cmd
);
2175 if (nla_put_u32(msg
, NL802154_ATTR_IFINDEX
, dev
->ifindex
))
2176 goto nla_put_failure
;
2178 nl_device
= nla_nest_start_noflag(msg
, NL802154_ATTR_SEC_DEVICE
);
2180 goto nla_put_failure
;
2182 if (nla_put_u32(msg
, NL802154_DEV_ATTR_FRAME_COUNTER
,
2183 dev_desc
->frame_counter
) ||
2184 nla_put_le16(msg
, NL802154_DEV_ATTR_PAN_ID
, dev_desc
->pan_id
) ||
2185 nla_put_le16(msg
, NL802154_DEV_ATTR_SHORT_ADDR
,
2186 dev_desc
->short_addr
) ||
2187 nla_put_le64(msg
, NL802154_DEV_ATTR_EXTENDED_ADDR
,
2188 dev_desc
->hwaddr
, NL802154_DEV_ATTR_PAD
) ||
2189 nla_put_u8(msg
, NL802154_DEV_ATTR_SECLEVEL_EXEMPT
,
2190 dev_desc
->seclevel_exempt
) ||
2191 nla_put_u32(msg
, NL802154_DEV_ATTR_KEY_MODE
, dev_desc
->key_mode
))
2192 goto nla_put_failure
;
2194 nla_nest_end(msg
, nl_device
);
2195 genlmsg_end(msg
, hdr
);
2200 genlmsg_cancel(msg
, hdr
);
2205 nl802154_dump_llsec_dev(struct sk_buff
*skb
, struct netlink_callback
*cb
)
2207 struct cfg802154_registered_device
*rdev
= NULL
;
2208 struct ieee802154_llsec_device
*dev
;
2209 struct ieee802154_llsec_table
*table
;
2210 struct wpan_dev
*wpan_dev
;
2213 err
= nl802154_prepare_wpan_dev_dump(skb
, cb
, &rdev
, &wpan_dev
);
2217 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
) {
2222 if (!wpan_dev
->netdev
) {
2227 rdev_lock_llsec_table(rdev
, wpan_dev
);
2228 rdev_get_llsec_table(rdev
, wpan_dev
, &table
);
2230 /* TODO make it like station dump */
2234 list_for_each_entry(dev
, &table
->devices
, list
) {
2235 if (nl802154_send_device(skb
, NL802154_CMD_NEW_SEC_LEVEL
,
2236 NETLINK_CB(cb
->skb
).portid
,
2237 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
2238 rdev
, wpan_dev
->netdev
, dev
) < 0) {
2241 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2249 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2252 nl802154_finish_wpan_dev_dump(rdev
);
2257 static const struct nla_policy nl802154_dev_policy
[NL802154_DEV_ATTR_MAX
+ 1] = {
2258 [NL802154_DEV_ATTR_FRAME_COUNTER
] = { NLA_U32
},
2259 [NL802154_DEV_ATTR_PAN_ID
] = { .type
= NLA_U16
},
2260 [NL802154_DEV_ATTR_SHORT_ADDR
] = { .type
= NLA_U16
},
2261 [NL802154_DEV_ATTR_EXTENDED_ADDR
] = { .type
= NLA_U64
},
2262 [NL802154_DEV_ATTR_SECLEVEL_EXEMPT
] = { NLA_U8
},
2263 [NL802154_DEV_ATTR_KEY_MODE
] = { NLA_U32
},
2267 ieee802154_llsec_parse_device(struct nlattr
*nla
,
2268 struct ieee802154_llsec_device
*dev
)
2270 struct nlattr
*attrs
[NL802154_DEV_ATTR_MAX
+ 1];
2272 if (!nla
|| nla_parse_nested_deprecated(attrs
, NL802154_DEV_ATTR_MAX
, nla
, nl802154_dev_policy
, NULL
))
2275 memset(dev
, 0, sizeof(*dev
));
2277 if (!attrs
[NL802154_DEV_ATTR_FRAME_COUNTER
] ||
2278 !attrs
[NL802154_DEV_ATTR_PAN_ID
] ||
2279 !attrs
[NL802154_DEV_ATTR_SHORT_ADDR
] ||
2280 !attrs
[NL802154_DEV_ATTR_EXTENDED_ADDR
] ||
2281 !attrs
[NL802154_DEV_ATTR_SECLEVEL_EXEMPT
] ||
2282 !attrs
[NL802154_DEV_ATTR_KEY_MODE
])
2286 dev
->frame_counter
= nla_get_u32(attrs
[NL802154_DEV_ATTR_FRAME_COUNTER
]);
2287 dev
->pan_id
= nla_get_le16(attrs
[NL802154_DEV_ATTR_PAN_ID
]);
2288 dev
->short_addr
= nla_get_le16(attrs
[NL802154_DEV_ATTR_SHORT_ADDR
]);
2289 /* TODO rename hwaddr to extended_addr */
2290 dev
->hwaddr
= nla_get_le64(attrs
[NL802154_DEV_ATTR_EXTENDED_ADDR
]);
2291 dev
->seclevel_exempt
= nla_get_u8(attrs
[NL802154_DEV_ATTR_SECLEVEL_EXEMPT
]);
2292 dev
->key_mode
= nla_get_u32(attrs
[NL802154_DEV_ATTR_KEY_MODE
]);
2294 if (dev
->key_mode
> NL802154_DEVKEY_MAX
||
2295 (dev
->seclevel_exempt
!= 0 && dev
->seclevel_exempt
!= 1))
2301 static int nl802154_add_llsec_dev(struct sk_buff
*skb
, struct genl_info
*info
)
2303 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2304 struct net_device
*dev
= info
->user_ptr
[1];
2305 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2306 struct ieee802154_llsec_device dev_desc
;
2308 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2311 if (ieee802154_llsec_parse_device(info
->attrs
[NL802154_ATTR_SEC_DEVICE
],
2315 return rdev_add_device(rdev
, wpan_dev
, &dev_desc
);
2318 static int nl802154_del_llsec_dev(struct sk_buff
*skb
, struct genl_info
*info
)
2320 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2321 struct net_device
*dev
= info
->user_ptr
[1];
2322 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2323 struct nlattr
*attrs
[NL802154_DEV_ATTR_MAX
+ 1];
2324 __le64 extended_addr
;
2326 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2329 if (!info
->attrs
[NL802154_ATTR_SEC_DEVICE
] ||
2330 nla_parse_nested_deprecated(attrs
, NL802154_DEV_ATTR_MAX
, info
->attrs
[NL802154_ATTR_SEC_DEVICE
], nl802154_dev_policy
, info
->extack
))
2333 if (!attrs
[NL802154_DEV_ATTR_EXTENDED_ADDR
])
2336 extended_addr
= nla_get_le64(attrs
[NL802154_DEV_ATTR_EXTENDED_ADDR
]);
2337 return rdev_del_device(rdev
, wpan_dev
, extended_addr
);
2340 static int nl802154_send_devkey(struct sk_buff
*msg
, u32 cmd
, u32 portid
,
2342 struct cfg802154_registered_device
*rdev
,
2343 struct net_device
*dev
, __le64 extended_addr
,
2344 const struct ieee802154_llsec_device_key
*devkey
)
2347 struct nlattr
*nl_devkey
, *nl_key_id
;
2349 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
, cmd
);
2353 if (nla_put_u32(msg
, NL802154_ATTR_IFINDEX
, dev
->ifindex
))
2354 goto nla_put_failure
;
2356 nl_devkey
= nla_nest_start_noflag(msg
, NL802154_ATTR_SEC_DEVKEY
);
2358 goto nla_put_failure
;
2360 if (nla_put_le64(msg
, NL802154_DEVKEY_ATTR_EXTENDED_ADDR
,
2361 extended_addr
, NL802154_DEVKEY_ATTR_PAD
) ||
2362 nla_put_u32(msg
, NL802154_DEVKEY_ATTR_FRAME_COUNTER
,
2363 devkey
->frame_counter
))
2364 goto nla_put_failure
;
2366 nl_key_id
= nla_nest_start_noflag(msg
, NL802154_DEVKEY_ATTR_ID
);
2368 goto nla_put_failure
;
2370 if (ieee802154_llsec_send_key_id(msg
, &devkey
->key_id
) < 0)
2371 goto nla_put_failure
;
2373 nla_nest_end(msg
, nl_key_id
);
2374 nla_nest_end(msg
, nl_devkey
);
2375 genlmsg_end(msg
, hdr
);
2380 genlmsg_cancel(msg
, hdr
);
2385 nl802154_dump_llsec_devkey(struct sk_buff
*skb
, struct netlink_callback
*cb
)
2387 struct cfg802154_registered_device
*rdev
= NULL
;
2388 struct ieee802154_llsec_device_key
*kpos
;
2389 struct ieee802154_llsec_device
*dpos
;
2390 struct ieee802154_llsec_table
*table
;
2391 struct wpan_dev
*wpan_dev
;
2394 err
= nl802154_prepare_wpan_dev_dump(skb
, cb
, &rdev
, &wpan_dev
);
2398 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
) {
2403 if (!wpan_dev
->netdev
) {
2408 rdev_lock_llsec_table(rdev
, wpan_dev
);
2409 rdev_get_llsec_table(rdev
, wpan_dev
, &table
);
2411 /* TODO make it like station dump */
2415 /* TODO look if remove devkey and do some nested attribute */
2416 list_for_each_entry(dpos
, &table
->devices
, list
) {
2417 list_for_each_entry(kpos
, &dpos
->keys
, list
) {
2418 if (nl802154_send_devkey(skb
,
2419 NL802154_CMD_NEW_SEC_LEVEL
,
2420 NETLINK_CB(cb
->skb
).portid
,
2428 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2437 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2440 nl802154_finish_wpan_dev_dump(rdev
);
2445 static const struct nla_policy nl802154_devkey_policy
[NL802154_DEVKEY_ATTR_MAX
+ 1] = {
2446 [NL802154_DEVKEY_ATTR_FRAME_COUNTER
] = { NLA_U32
},
2447 [NL802154_DEVKEY_ATTR_EXTENDED_ADDR
] = { NLA_U64
},
2448 [NL802154_DEVKEY_ATTR_ID
] = { NLA_NESTED
},
2451 static int nl802154_add_llsec_devkey(struct sk_buff
*skb
, struct genl_info
*info
)
2453 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2454 struct net_device
*dev
= info
->user_ptr
[1];
2455 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2456 struct nlattr
*attrs
[NL802154_DEVKEY_ATTR_MAX
+ 1];
2457 struct ieee802154_llsec_device_key key
;
2458 __le64 extended_addr
;
2460 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2463 if (!info
->attrs
[NL802154_ATTR_SEC_DEVKEY
] ||
2464 nla_parse_nested_deprecated(attrs
, NL802154_DEVKEY_ATTR_MAX
, info
->attrs
[NL802154_ATTR_SEC_DEVKEY
], nl802154_devkey_policy
, info
->extack
) < 0)
2467 if (!attrs
[NL802154_DEVKEY_ATTR_FRAME_COUNTER
] ||
2468 !attrs
[NL802154_DEVKEY_ATTR_EXTENDED_ADDR
])
2471 /* TODO change key.id ? */
2472 if (ieee802154_llsec_parse_key_id(attrs
[NL802154_DEVKEY_ATTR_ID
],
2477 key
.frame_counter
= nla_get_u32(attrs
[NL802154_DEVKEY_ATTR_FRAME_COUNTER
]);
2478 /* TODO change naming hwaddr -> extended_addr
2479 * check unique identifier short+pan OR extended_addr
2481 extended_addr
= nla_get_le64(attrs
[NL802154_DEVKEY_ATTR_EXTENDED_ADDR
]);
2482 return rdev_add_devkey(rdev
, wpan_dev
, extended_addr
, &key
);
2485 static int nl802154_del_llsec_devkey(struct sk_buff
*skb
, struct genl_info
*info
)
2487 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2488 struct net_device
*dev
= info
->user_ptr
[1];
2489 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2490 struct nlattr
*attrs
[NL802154_DEVKEY_ATTR_MAX
+ 1];
2491 struct ieee802154_llsec_device_key key
;
2492 __le64 extended_addr
;
2494 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2497 if (!info
->attrs
[NL802154_ATTR_SEC_DEVKEY
] ||
2498 nla_parse_nested_deprecated(attrs
, NL802154_DEVKEY_ATTR_MAX
, info
->attrs
[NL802154_ATTR_SEC_DEVKEY
], nl802154_devkey_policy
, info
->extack
))
2501 if (!attrs
[NL802154_DEVKEY_ATTR_EXTENDED_ADDR
])
2504 /* TODO change key.id ? */
2505 if (ieee802154_llsec_parse_key_id(attrs
[NL802154_DEVKEY_ATTR_ID
],
2509 /* TODO change naming hwaddr -> extended_addr
2510 * check unique identifier short+pan OR extended_addr
2512 extended_addr
= nla_get_le64(attrs
[NL802154_DEVKEY_ATTR_EXTENDED_ADDR
]);
2513 return rdev_del_devkey(rdev
, wpan_dev
, extended_addr
, &key
);
2516 static int nl802154_send_seclevel(struct sk_buff
*msg
, u32 cmd
, u32 portid
,
2518 struct cfg802154_registered_device
*rdev
,
2519 struct net_device
*dev
,
2520 const struct ieee802154_llsec_seclevel
*sl
)
2523 struct nlattr
*nl_seclevel
;
2525 hdr
= nl802154hdr_put(msg
, portid
, seq
, flags
, cmd
);
2529 if (nla_put_u32(msg
, NL802154_ATTR_IFINDEX
, dev
->ifindex
))
2530 goto nla_put_failure
;
2532 nl_seclevel
= nla_nest_start_noflag(msg
, NL802154_ATTR_SEC_LEVEL
);
2534 goto nla_put_failure
;
2536 if (nla_put_u32(msg
, NL802154_SECLEVEL_ATTR_FRAME
, sl
->frame_type
) ||
2537 nla_put_u32(msg
, NL802154_SECLEVEL_ATTR_LEVELS
, sl
->sec_levels
) ||
2538 nla_put_u8(msg
, NL802154_SECLEVEL_ATTR_DEV_OVERRIDE
,
2539 sl
->device_override
))
2540 goto nla_put_failure
;
2542 if (sl
->frame_type
== NL802154_FRAME_CMD
) {
2543 if (nla_put_u32(msg
, NL802154_SECLEVEL_ATTR_CMD_FRAME
,
2545 goto nla_put_failure
;
2548 nla_nest_end(msg
, nl_seclevel
);
2549 genlmsg_end(msg
, hdr
);
2554 genlmsg_cancel(msg
, hdr
);
2559 nl802154_dump_llsec_seclevel(struct sk_buff
*skb
, struct netlink_callback
*cb
)
2561 struct cfg802154_registered_device
*rdev
= NULL
;
2562 struct ieee802154_llsec_seclevel
*sl
;
2563 struct ieee802154_llsec_table
*table
;
2564 struct wpan_dev
*wpan_dev
;
2567 err
= nl802154_prepare_wpan_dev_dump(skb
, cb
, &rdev
, &wpan_dev
);
2571 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
) {
2576 if (!wpan_dev
->netdev
) {
2581 rdev_lock_llsec_table(rdev
, wpan_dev
);
2582 rdev_get_llsec_table(rdev
, wpan_dev
, &table
);
2584 /* TODO make it like station dump */
2588 list_for_each_entry(sl
, &table
->security_levels
, list
) {
2589 if (nl802154_send_seclevel(skb
, NL802154_CMD_NEW_SEC_LEVEL
,
2590 NETLINK_CB(cb
->skb
).portid
,
2591 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
2592 rdev
, wpan_dev
->netdev
, sl
) < 0) {
2595 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2603 rdev_unlock_llsec_table(rdev
, wpan_dev
);
2606 nl802154_finish_wpan_dev_dump(rdev
);
2611 static const struct nla_policy nl802154_seclevel_policy
[NL802154_SECLEVEL_ATTR_MAX
+ 1] = {
2612 [NL802154_SECLEVEL_ATTR_LEVELS
] = { .type
= NLA_U8
},
2613 [NL802154_SECLEVEL_ATTR_FRAME
] = { .type
= NLA_U32
},
2614 [NL802154_SECLEVEL_ATTR_CMD_FRAME
] = { .type
= NLA_U32
},
2615 [NL802154_SECLEVEL_ATTR_DEV_OVERRIDE
] = { .type
= NLA_U8
},
2619 llsec_parse_seclevel(struct nlattr
*nla
, struct ieee802154_llsec_seclevel
*sl
)
2621 struct nlattr
*attrs
[NL802154_SECLEVEL_ATTR_MAX
+ 1];
2623 if (!nla
|| nla_parse_nested_deprecated(attrs
, NL802154_SECLEVEL_ATTR_MAX
, nla
, nl802154_seclevel_policy
, NULL
))
2626 memset(sl
, 0, sizeof(*sl
));
2628 if (!attrs
[NL802154_SECLEVEL_ATTR_LEVELS
] ||
2629 !attrs
[NL802154_SECLEVEL_ATTR_FRAME
] ||
2630 !attrs
[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE
])
2633 sl
->sec_levels
= nla_get_u8(attrs
[NL802154_SECLEVEL_ATTR_LEVELS
]);
2634 sl
->frame_type
= nla_get_u32(attrs
[NL802154_SECLEVEL_ATTR_FRAME
]);
2635 sl
->device_override
= nla_get_u8(attrs
[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE
]);
2636 if (sl
->frame_type
> NL802154_FRAME_MAX
||
2637 (sl
->device_override
!= 0 && sl
->device_override
!= 1))
2640 if (sl
->frame_type
== NL802154_FRAME_CMD
) {
2641 if (!attrs
[NL802154_SECLEVEL_ATTR_CMD_FRAME
])
2644 sl
->cmd_frame_id
= nla_get_u32(attrs
[NL802154_SECLEVEL_ATTR_CMD_FRAME
]);
2645 if (sl
->cmd_frame_id
> NL802154_CMD_FRAME_MAX
)
2652 static int nl802154_add_llsec_seclevel(struct sk_buff
*skb
,
2653 struct genl_info
*info
)
2655 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2656 struct net_device
*dev
= info
->user_ptr
[1];
2657 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2658 struct ieee802154_llsec_seclevel sl
;
2660 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2663 if (llsec_parse_seclevel(info
->attrs
[NL802154_ATTR_SEC_LEVEL
],
2667 return rdev_add_seclevel(rdev
, wpan_dev
, &sl
);
2670 static int nl802154_del_llsec_seclevel(struct sk_buff
*skb
,
2671 struct genl_info
*info
)
2673 struct cfg802154_registered_device
*rdev
= info
->user_ptr
[0];
2674 struct net_device
*dev
= info
->user_ptr
[1];
2675 struct wpan_dev
*wpan_dev
= dev
->ieee802154_ptr
;
2676 struct ieee802154_llsec_seclevel sl
;
2678 if (wpan_dev
->iftype
== NL802154_IFTYPE_MONITOR
)
2681 if (llsec_parse_seclevel(info
->attrs
[NL802154_ATTR_SEC_LEVEL
],
2685 return rdev_del_seclevel(rdev
, wpan_dev
, &sl
);
2687 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
2689 #define NL802154_FLAG_NEED_WPAN_PHY 0x01
2690 #define NL802154_FLAG_NEED_NETDEV 0x02
2691 #define NL802154_FLAG_NEED_RTNL 0x04
2692 #define NL802154_FLAG_CHECK_NETDEV_UP 0x08
2693 #define NL802154_FLAG_NEED_WPAN_DEV 0x10
2695 static int nl802154_pre_doit(const struct genl_split_ops
*ops
,
2696 struct sk_buff
*skb
,
2697 struct genl_info
*info
)
2699 struct cfg802154_registered_device
*rdev
;
2700 struct wpan_dev
*wpan_dev
;
2701 struct net_device
*dev
;
2702 bool rtnl
= ops
->internal_flags
& NL802154_FLAG_NEED_RTNL
;
2707 if (ops
->internal_flags
& NL802154_FLAG_NEED_WPAN_PHY
) {
2708 rdev
= cfg802154_get_dev_from_info(genl_info_net(info
), info
);
2712 return PTR_ERR(rdev
);
2714 info
->user_ptr
[0] = rdev
;
2715 } else if (ops
->internal_flags
& NL802154_FLAG_NEED_NETDEV
||
2716 ops
->internal_flags
& NL802154_FLAG_NEED_WPAN_DEV
) {
2718 wpan_dev
= __cfg802154_wpan_dev_from_attrs(genl_info_net(info
),
2720 if (IS_ERR(wpan_dev
)) {
2723 return PTR_ERR(wpan_dev
);
2726 dev
= wpan_dev
->netdev
;
2727 rdev
= wpan_phy_to_rdev(wpan_dev
->wpan_phy
);
2729 if (ops
->internal_flags
& NL802154_FLAG_NEED_NETDEV
) {
2736 info
->user_ptr
[1] = dev
;
2738 info
->user_ptr
[1] = wpan_dev
;
2742 if (ops
->internal_flags
& NL802154_FLAG_CHECK_NETDEV_UP
&&
2743 !netif_running(dev
)) {
2752 info
->user_ptr
[0] = rdev
;
2758 static void nl802154_post_doit(const struct genl_split_ops
*ops
,
2759 struct sk_buff
*skb
,
2760 struct genl_info
*info
)
2762 if (info
->user_ptr
[1]) {
2763 if (ops
->internal_flags
& NL802154_FLAG_NEED_WPAN_DEV
) {
2764 struct wpan_dev
*wpan_dev
= info
->user_ptr
[1];
2766 dev_put(wpan_dev
->netdev
);
2768 dev_put(info
->user_ptr
[1]);
2772 if (ops
->internal_flags
& NL802154_FLAG_NEED_RTNL
)
2776 static const struct genl_ops nl802154_ops
[] = {
2778 .cmd
= NL802154_CMD_GET_WPAN_PHY
,
2779 .validate
= GENL_DONT_VALIDATE_STRICT
|
2780 GENL_DONT_VALIDATE_DUMP_STRICT
,
2781 .doit
= nl802154_get_wpan_phy
,
2782 .dumpit
= nl802154_dump_wpan_phy
,
2783 .done
= nl802154_dump_wpan_phy_done
,
2784 /* can be retrieved by unprivileged users */
2785 .internal_flags
= NL802154_FLAG_NEED_WPAN_PHY
|
2786 NL802154_FLAG_NEED_RTNL
,
2789 .cmd
= NL802154_CMD_GET_INTERFACE
,
2790 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2791 .doit
= nl802154_get_interface
,
2792 .dumpit
= nl802154_dump_interface
,
2793 /* can be retrieved by unprivileged users */
2794 .internal_flags
= NL802154_FLAG_NEED_WPAN_DEV
|
2795 NL802154_FLAG_NEED_RTNL
,
2798 .cmd
= NL802154_CMD_NEW_INTERFACE
,
2799 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2800 .doit
= nl802154_new_interface
,
2801 .flags
= GENL_ADMIN_PERM
,
2802 .internal_flags
= NL802154_FLAG_NEED_WPAN_PHY
|
2803 NL802154_FLAG_NEED_RTNL
,
2806 .cmd
= NL802154_CMD_DEL_INTERFACE
,
2807 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2808 .doit
= nl802154_del_interface
,
2809 .flags
= GENL_ADMIN_PERM
,
2810 .internal_flags
= NL802154_FLAG_NEED_WPAN_DEV
|
2811 NL802154_FLAG_NEED_RTNL
,
2814 .cmd
= NL802154_CMD_SET_CHANNEL
,
2815 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2816 .doit
= nl802154_set_channel
,
2817 .flags
= GENL_ADMIN_PERM
,
2818 .internal_flags
= NL802154_FLAG_NEED_WPAN_PHY
|
2819 NL802154_FLAG_NEED_RTNL
,
2822 .cmd
= NL802154_CMD_SET_CCA_MODE
,
2823 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2824 .doit
= nl802154_set_cca_mode
,
2825 .flags
= GENL_ADMIN_PERM
,
2826 .internal_flags
= NL802154_FLAG_NEED_WPAN_PHY
|
2827 NL802154_FLAG_NEED_RTNL
,
2830 .cmd
= NL802154_CMD_SET_CCA_ED_LEVEL
,
2831 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2832 .doit
= nl802154_set_cca_ed_level
,
2833 .flags
= GENL_ADMIN_PERM
,
2834 .internal_flags
= NL802154_FLAG_NEED_WPAN_PHY
|
2835 NL802154_FLAG_NEED_RTNL
,
2838 .cmd
= NL802154_CMD_SET_TX_POWER
,
2839 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2840 .doit
= nl802154_set_tx_power
,
2841 .flags
= GENL_ADMIN_PERM
,
2842 .internal_flags
= NL802154_FLAG_NEED_WPAN_PHY
|
2843 NL802154_FLAG_NEED_RTNL
,
2846 .cmd
= NL802154_CMD_SET_WPAN_PHY_NETNS
,
2847 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2848 .doit
= nl802154_wpan_phy_netns
,
2849 .flags
= GENL_ADMIN_PERM
,
2850 .internal_flags
= NL802154_FLAG_NEED_WPAN_PHY
|
2851 NL802154_FLAG_NEED_RTNL
,
2854 .cmd
= NL802154_CMD_SET_PAN_ID
,
2855 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2856 .doit
= nl802154_set_pan_id
,
2857 .flags
= GENL_ADMIN_PERM
,
2858 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2859 NL802154_FLAG_NEED_RTNL
,
2862 .cmd
= NL802154_CMD_SET_SHORT_ADDR
,
2863 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2864 .doit
= nl802154_set_short_addr
,
2865 .flags
= GENL_ADMIN_PERM
,
2866 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2867 NL802154_FLAG_NEED_RTNL
,
2870 .cmd
= NL802154_CMD_SET_BACKOFF_EXPONENT
,
2871 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2872 .doit
= nl802154_set_backoff_exponent
,
2873 .flags
= GENL_ADMIN_PERM
,
2874 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2875 NL802154_FLAG_NEED_RTNL
,
2878 .cmd
= NL802154_CMD_SET_MAX_CSMA_BACKOFFS
,
2879 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2880 .doit
= nl802154_set_max_csma_backoffs
,
2881 .flags
= GENL_ADMIN_PERM
,
2882 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2883 NL802154_FLAG_NEED_RTNL
,
2886 .cmd
= NL802154_CMD_SET_MAX_FRAME_RETRIES
,
2887 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2888 .doit
= nl802154_set_max_frame_retries
,
2889 .flags
= GENL_ADMIN_PERM
,
2890 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2891 NL802154_FLAG_NEED_RTNL
,
2894 .cmd
= NL802154_CMD_SET_LBT_MODE
,
2895 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2896 .doit
= nl802154_set_lbt_mode
,
2897 .flags
= GENL_ADMIN_PERM
,
2898 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2899 NL802154_FLAG_NEED_RTNL
,
2902 .cmd
= NL802154_CMD_SET_ACKREQ_DEFAULT
,
2903 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2904 .doit
= nl802154_set_ackreq_default
,
2905 .flags
= GENL_ADMIN_PERM
,
2906 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2907 NL802154_FLAG_NEED_RTNL
,
2910 .cmd
= NL802154_CMD_TRIGGER_SCAN
,
2911 .doit
= nl802154_trigger_scan
,
2912 .flags
= GENL_ADMIN_PERM
,
2913 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2914 NL802154_FLAG_CHECK_NETDEV_UP
|
2915 NL802154_FLAG_NEED_RTNL
,
2918 .cmd
= NL802154_CMD_ABORT_SCAN
,
2919 .doit
= nl802154_abort_scan
,
2920 .flags
= GENL_ADMIN_PERM
,
2921 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2922 NL802154_FLAG_CHECK_NETDEV_UP
|
2923 NL802154_FLAG_NEED_RTNL
,
2926 .cmd
= NL802154_CMD_SEND_BEACONS
,
2927 .doit
= nl802154_send_beacons
,
2928 .flags
= GENL_ADMIN_PERM
,
2929 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2930 NL802154_FLAG_CHECK_NETDEV_UP
|
2931 NL802154_FLAG_NEED_RTNL
,
2934 .cmd
= NL802154_CMD_STOP_BEACONS
,
2935 .doit
= nl802154_stop_beacons
,
2936 .flags
= GENL_ADMIN_PERM
,
2937 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2938 NL802154_FLAG_CHECK_NETDEV_UP
|
2939 NL802154_FLAG_NEED_RTNL
,
2942 .cmd
= NL802154_CMD_ASSOCIATE
,
2943 .doit
= nl802154_associate
,
2944 .flags
= GENL_ADMIN_PERM
,
2945 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2946 NL802154_FLAG_CHECK_NETDEV_UP
|
2947 NL802154_FLAG_NEED_RTNL
,
2950 .cmd
= NL802154_CMD_DISASSOCIATE
,
2951 .doit
= nl802154_disassociate
,
2952 .flags
= GENL_ADMIN_PERM
,
2953 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2954 NL802154_FLAG_CHECK_NETDEV_UP
|
2955 NL802154_FLAG_NEED_RTNL
,
2958 .cmd
= NL802154_CMD_SET_MAX_ASSOCIATIONS
,
2959 .doit
= nl802154_set_max_associations
,
2960 .flags
= GENL_ADMIN_PERM
,
2961 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2962 NL802154_FLAG_NEED_RTNL
,
2965 .cmd
= NL802154_CMD_LIST_ASSOCIATIONS
,
2966 .dumpit
= nl802154_list_associations
,
2967 /* can be retrieved by unprivileged users */
2969 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
2971 .cmd
= NL802154_CMD_SET_SEC_PARAMS
,
2972 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2973 .doit
= nl802154_set_llsec_params
,
2974 .flags
= GENL_ADMIN_PERM
,
2975 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2976 NL802154_FLAG_NEED_RTNL
,
2979 .cmd
= NL802154_CMD_GET_SEC_KEY
,
2980 .validate
= GENL_DONT_VALIDATE_STRICT
|
2981 GENL_DONT_VALIDATE_DUMP_STRICT
,
2982 /* TODO .doit by matching key id? */
2983 .dumpit
= nl802154_dump_llsec_key
,
2984 .flags
= GENL_ADMIN_PERM
,
2985 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2986 NL802154_FLAG_NEED_RTNL
,
2989 .cmd
= NL802154_CMD_NEW_SEC_KEY
,
2990 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2991 .doit
= nl802154_add_llsec_key
,
2992 .flags
= GENL_ADMIN_PERM
,
2993 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
2994 NL802154_FLAG_NEED_RTNL
,
2997 .cmd
= NL802154_CMD_DEL_SEC_KEY
,
2998 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
2999 .doit
= nl802154_del_llsec_key
,
3000 .flags
= GENL_ADMIN_PERM
,
3001 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3002 NL802154_FLAG_NEED_RTNL
,
3004 /* TODO unique identifier must short+pan OR extended_addr */
3006 .cmd
= NL802154_CMD_GET_SEC_DEV
,
3007 .validate
= GENL_DONT_VALIDATE_STRICT
|
3008 GENL_DONT_VALIDATE_DUMP_STRICT
,
3009 /* TODO .doit by matching extended_addr? */
3010 .dumpit
= nl802154_dump_llsec_dev
,
3011 .flags
= GENL_ADMIN_PERM
,
3012 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3013 NL802154_FLAG_NEED_RTNL
,
3016 .cmd
= NL802154_CMD_NEW_SEC_DEV
,
3017 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
3018 .doit
= nl802154_add_llsec_dev
,
3019 .flags
= GENL_ADMIN_PERM
,
3020 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3021 NL802154_FLAG_NEED_RTNL
,
3024 .cmd
= NL802154_CMD_DEL_SEC_DEV
,
3025 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
3026 .doit
= nl802154_del_llsec_dev
,
3027 .flags
= GENL_ADMIN_PERM
,
3028 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3029 NL802154_FLAG_NEED_RTNL
,
3031 /* TODO remove complete devkey, put it as nested? */
3033 .cmd
= NL802154_CMD_GET_SEC_DEVKEY
,
3034 .validate
= GENL_DONT_VALIDATE_STRICT
|
3035 GENL_DONT_VALIDATE_DUMP_STRICT
,
3036 /* TODO doit by matching ??? */
3037 .dumpit
= nl802154_dump_llsec_devkey
,
3038 .flags
= GENL_ADMIN_PERM
,
3039 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3040 NL802154_FLAG_NEED_RTNL
,
3043 .cmd
= NL802154_CMD_NEW_SEC_DEVKEY
,
3044 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
3045 .doit
= nl802154_add_llsec_devkey
,
3046 .flags
= GENL_ADMIN_PERM
,
3047 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3048 NL802154_FLAG_NEED_RTNL
,
3051 .cmd
= NL802154_CMD_DEL_SEC_DEVKEY
,
3052 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
3053 .doit
= nl802154_del_llsec_devkey
,
3054 .flags
= GENL_ADMIN_PERM
,
3055 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3056 NL802154_FLAG_NEED_RTNL
,
3059 .cmd
= NL802154_CMD_GET_SEC_LEVEL
,
3060 .validate
= GENL_DONT_VALIDATE_STRICT
|
3061 GENL_DONT_VALIDATE_DUMP_STRICT
,
3062 /* TODO .doit by matching frame_type? */
3063 .dumpit
= nl802154_dump_llsec_seclevel
,
3064 .flags
= GENL_ADMIN_PERM
,
3065 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3066 NL802154_FLAG_NEED_RTNL
,
3069 .cmd
= NL802154_CMD_NEW_SEC_LEVEL
,
3070 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
3071 .doit
= nl802154_add_llsec_seclevel
,
3072 .flags
= GENL_ADMIN_PERM
,
3073 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3074 NL802154_FLAG_NEED_RTNL
,
3077 .cmd
= NL802154_CMD_DEL_SEC_LEVEL
,
3078 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
3079 /* TODO match frame_type only? */
3080 .doit
= nl802154_del_llsec_seclevel
,
3081 .flags
= GENL_ADMIN_PERM
,
3082 .internal_flags
= NL802154_FLAG_NEED_NETDEV
|
3083 NL802154_FLAG_NEED_RTNL
,
3085 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
3088 static struct genl_family nl802154_fam __ro_after_init
= {
3089 .name
= NL802154_GENL_NAME
, /* have users key off the name instead */
3090 .hdrsize
= 0, /* no private header */
3091 .version
= 1, /* no particular meaning now */
3092 .maxattr
= NL802154_ATTR_MAX
,
3093 .policy
= nl802154_policy
,
3095 .pre_doit
= nl802154_pre_doit
,
3096 .post_doit
= nl802154_post_doit
,
3097 .module
= THIS_MODULE
,
3098 .ops
= nl802154_ops
,
3099 .n_ops
= ARRAY_SIZE(nl802154_ops
),
3100 .resv_start_op
= NL802154_CMD_DEL_SEC_LEVEL
+ 1,
3101 .mcgrps
= nl802154_mcgrps
,
3102 .n_mcgrps
= ARRAY_SIZE(nl802154_mcgrps
),
3105 /* initialisation/exit functions */
3106 int __init
nl802154_init(void)
3108 return genl_register_family(&nl802154_fam
);
3111 void nl802154_exit(void)
3113 genl_unregister_family(&nl802154_fam
);