2 * Netlink interface for IEEE 802.15.4 stack
4 * Copyright 2007, 2008 Siemens AG
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 * Sergey Lapin <slapin@ossfans.org>
17 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
18 * Maxim Osipov <maxim.osipov@siemens.com>
21 #include <linux/gfp.h>
22 #include <linux/kernel.h>
23 #include <linux/if_arp.h>
24 #include <linux/netdevice.h>
25 #include <linux/ieee802154.h>
26 #include <net/netlink.h>
27 #include <net/genetlink.h>
29 #include <linux/nl802154.h>
30 #include <linux/export.h>
31 #include <net/af_ieee802154.h>
32 #include <net/ieee802154_netdev.h>
33 #include <net/cfg802154.h>
35 #include "ieee802154.h"
37 static int nla_put_hwaddr(struct sk_buff
*msg
, int type
, __le64 hwaddr
)
39 return nla_put_u64(msg
, type
, swab64((__force u64
)hwaddr
));
42 static __le64
nla_get_hwaddr(const struct nlattr
*nla
)
44 return ieee802154_devaddr_from_raw(nla_data(nla
));
47 static int nla_put_shortaddr(struct sk_buff
*msg
, int type
, __le16 addr
)
49 return nla_put_u16(msg
, type
, le16_to_cpu(addr
));
52 static __le16
nla_get_shortaddr(const struct nlattr
*nla
)
54 return cpu_to_le16(nla_get_u16(nla
));
57 static int ieee802154_nl_start_confirm(struct net_device
*dev
, u8 status
)
61 pr_debug("%s\n", __func__
);
63 msg
= ieee802154_nl_create(0, IEEE802154_START_CONF
);
67 if (nla_put_string(msg
, IEEE802154_ATTR_DEV_NAME
, dev
->name
) ||
68 nla_put_u32(msg
, IEEE802154_ATTR_DEV_INDEX
, dev
->ifindex
) ||
69 nla_put(msg
, IEEE802154_ATTR_HW_ADDR
, IEEE802154_ADDR_LEN
,
71 nla_put_u8(msg
, IEEE802154_ATTR_STATUS
, status
))
73 return ieee802154_nl_mcast(msg
, IEEE802154_COORD_MCGRP
);
79 EXPORT_SYMBOL(ieee802154_nl_start_confirm
);
81 static int ieee802154_nl_fill_iface(struct sk_buff
*msg
, u32 portid
,
82 u32 seq
, int flags
, struct net_device
*dev
)
86 struct ieee802154_mlme_ops
*ops
;
87 __le16 short_addr
, pan_id
;
89 pr_debug("%s\n", __func__
);
91 hdr
= genlmsg_put(msg
, 0, seq
, &nl802154_family
, flags
,
92 IEEE802154_LIST_IFACE
);
96 ops
= ieee802154_mlme_ops(dev
);
97 phy
= dev
->ieee802154_ptr
->wpan_phy
;
99 get_device(&phy
->dev
);
101 short_addr
= ops
->get_short_addr(dev
);
102 pan_id
= ops
->get_pan_id(dev
);
104 if (nla_put_string(msg
, IEEE802154_ATTR_DEV_NAME
, dev
->name
) ||
105 nla_put_string(msg
, IEEE802154_ATTR_PHY_NAME
, wpan_phy_name(phy
)) ||
106 nla_put_u32(msg
, IEEE802154_ATTR_DEV_INDEX
, dev
->ifindex
) ||
107 nla_put(msg
, IEEE802154_ATTR_HW_ADDR
, IEEE802154_ADDR_LEN
,
109 nla_put_shortaddr(msg
, IEEE802154_ATTR_SHORT_ADDR
, short_addr
) ||
110 nla_put_shortaddr(msg
, IEEE802154_ATTR_PAN_ID
, pan_id
))
111 goto nla_put_failure
;
113 if (ops
->get_mac_params
) {
114 struct ieee802154_mac_params params
;
117 ops
->get_mac_params(dev
, ¶ms
);
120 if (nla_put_s8(msg
, IEEE802154_ATTR_TXPOWER
,
121 params
.transmit_power
) ||
122 nla_put_u8(msg
, IEEE802154_ATTR_LBT_ENABLED
, params
.lbt
) ||
123 nla_put_u8(msg
, IEEE802154_ATTR_CCA_MODE
,
125 nla_put_s32(msg
, IEEE802154_ATTR_CCA_ED_LEVEL
,
126 params
.cca_ed_level
) ||
127 nla_put_u8(msg
, IEEE802154_ATTR_CSMA_RETRIES
,
128 params
.csma_retries
) ||
129 nla_put_u8(msg
, IEEE802154_ATTR_CSMA_MIN_BE
,
131 nla_put_u8(msg
, IEEE802154_ATTR_CSMA_MAX_BE
,
133 nla_put_s8(msg
, IEEE802154_ATTR_FRAME_RETRIES
,
134 params
.frame_retries
))
135 goto nla_put_failure
;
139 genlmsg_end(msg
, hdr
);
144 genlmsg_cancel(msg
, hdr
);
149 /* Requests from userspace */
150 static struct net_device
*ieee802154_nl_get_dev(struct genl_info
*info
)
152 struct net_device
*dev
;
154 if (info
->attrs
[IEEE802154_ATTR_DEV_NAME
]) {
155 char name
[IFNAMSIZ
+ 1];
157 nla_strlcpy(name
, info
->attrs
[IEEE802154_ATTR_DEV_NAME
],
159 dev
= dev_get_by_name(&init_net
, name
);
160 } else if (info
->attrs
[IEEE802154_ATTR_DEV_INDEX
]) {
161 dev
= dev_get_by_index(&init_net
,
162 nla_get_u32(info
->attrs
[IEEE802154_ATTR_DEV_INDEX
]));
170 /* Check on mtu is currently a hacked solution because lowpan
171 * and wpan have the same ARPHRD type.
173 if (dev
->type
!= ARPHRD_IEEE802154
|| dev
->mtu
!= IEEE802154_MTU
) {
181 int ieee802154_associate_req(struct sk_buff
*skb
, struct genl_info
*info
)
183 struct net_device
*dev
;
184 struct ieee802154_addr addr
;
186 int ret
= -EOPNOTSUPP
;
188 if (!info
->attrs
[IEEE802154_ATTR_CHANNEL
] ||
189 !info
->attrs
[IEEE802154_ATTR_COORD_PAN_ID
] ||
190 (!info
->attrs
[IEEE802154_ATTR_COORD_HW_ADDR
] &&
191 !info
->attrs
[IEEE802154_ATTR_COORD_SHORT_ADDR
]) ||
192 !info
->attrs
[IEEE802154_ATTR_CAPABILITY
])
195 dev
= ieee802154_nl_get_dev(info
);
198 if (!ieee802154_mlme_ops(dev
)->assoc_req
)
201 if (info
->attrs
[IEEE802154_ATTR_COORD_HW_ADDR
]) {
202 addr
.mode
= IEEE802154_ADDR_LONG
;
203 addr
.extended_addr
= nla_get_hwaddr(
204 info
->attrs
[IEEE802154_ATTR_COORD_HW_ADDR
]);
206 addr
.mode
= IEEE802154_ADDR_SHORT
;
207 addr
.short_addr
= nla_get_shortaddr(
208 info
->attrs
[IEEE802154_ATTR_COORD_SHORT_ADDR
]);
210 addr
.pan_id
= nla_get_shortaddr(
211 info
->attrs
[IEEE802154_ATTR_COORD_PAN_ID
]);
213 if (info
->attrs
[IEEE802154_ATTR_PAGE
])
214 page
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_PAGE
]);
218 ret
= ieee802154_mlme_ops(dev
)->assoc_req(dev
, &addr
,
219 nla_get_u8(info
->attrs
[IEEE802154_ATTR_CHANNEL
]),
221 nla_get_u8(info
->attrs
[IEEE802154_ATTR_CAPABILITY
]));
228 int ieee802154_associate_resp(struct sk_buff
*skb
, struct genl_info
*info
)
230 struct net_device
*dev
;
231 struct ieee802154_addr addr
;
232 int ret
= -EOPNOTSUPP
;
234 if (!info
->attrs
[IEEE802154_ATTR_STATUS
] ||
235 !info
->attrs
[IEEE802154_ATTR_DEST_HW_ADDR
] ||
236 !info
->attrs
[IEEE802154_ATTR_DEST_SHORT_ADDR
])
239 dev
= ieee802154_nl_get_dev(info
);
242 if (!ieee802154_mlme_ops(dev
)->assoc_resp
)
245 addr
.mode
= IEEE802154_ADDR_LONG
;
246 addr
.extended_addr
= nla_get_hwaddr(
247 info
->attrs
[IEEE802154_ATTR_DEST_HW_ADDR
]);
248 addr
.pan_id
= ieee802154_mlme_ops(dev
)->get_pan_id(dev
);
250 ret
= ieee802154_mlme_ops(dev
)->assoc_resp(dev
, &addr
,
251 nla_get_shortaddr(info
->attrs
[IEEE802154_ATTR_DEST_SHORT_ADDR
]),
252 nla_get_u8(info
->attrs
[IEEE802154_ATTR_STATUS
]));
259 int ieee802154_disassociate_req(struct sk_buff
*skb
, struct genl_info
*info
)
261 struct net_device
*dev
;
262 struct ieee802154_addr addr
;
263 int ret
= -EOPNOTSUPP
;
265 if ((!info
->attrs
[IEEE802154_ATTR_DEST_HW_ADDR
] &&
266 !info
->attrs
[IEEE802154_ATTR_DEST_SHORT_ADDR
]) ||
267 !info
->attrs
[IEEE802154_ATTR_REASON
])
270 dev
= ieee802154_nl_get_dev(info
);
273 if (!ieee802154_mlme_ops(dev
)->disassoc_req
)
276 if (info
->attrs
[IEEE802154_ATTR_DEST_HW_ADDR
]) {
277 addr
.mode
= IEEE802154_ADDR_LONG
;
278 addr
.extended_addr
= nla_get_hwaddr(
279 info
->attrs
[IEEE802154_ATTR_DEST_HW_ADDR
]);
281 addr
.mode
= IEEE802154_ADDR_SHORT
;
282 addr
.short_addr
= nla_get_shortaddr(
283 info
->attrs
[IEEE802154_ATTR_DEST_SHORT_ADDR
]);
285 addr
.pan_id
= ieee802154_mlme_ops(dev
)->get_pan_id(dev
);
287 ret
= ieee802154_mlme_ops(dev
)->disassoc_req(dev
, &addr
,
288 nla_get_u8(info
->attrs
[IEEE802154_ATTR_REASON
]));
295 /* PANid, channel, beacon_order = 15, superframe_order = 15,
296 * PAN_coordinator, battery_life_extension = 0,
297 * coord_realignment = 0, security_enable = 0
299 int ieee802154_start_req(struct sk_buff
*skb
, struct genl_info
*info
)
301 struct net_device
*dev
;
302 struct ieee802154_addr addr
;
304 u8 channel
, bcn_ord
, sf_ord
;
306 int pan_coord
, blx
, coord_realign
;
309 if (!info
->attrs
[IEEE802154_ATTR_COORD_PAN_ID
] ||
310 !info
->attrs
[IEEE802154_ATTR_COORD_SHORT_ADDR
] ||
311 !info
->attrs
[IEEE802154_ATTR_CHANNEL
] ||
312 !info
->attrs
[IEEE802154_ATTR_BCN_ORD
] ||
313 !info
->attrs
[IEEE802154_ATTR_SF_ORD
] ||
314 !info
->attrs
[IEEE802154_ATTR_PAN_COORD
] ||
315 !info
->attrs
[IEEE802154_ATTR_BAT_EXT
] ||
316 !info
->attrs
[IEEE802154_ATTR_COORD_REALIGN
]
320 dev
= ieee802154_nl_get_dev(info
);
324 if (netif_running(dev
))
327 if (!ieee802154_mlme_ops(dev
)->start_req
) {
332 addr
.mode
= IEEE802154_ADDR_SHORT
;
333 addr
.short_addr
= nla_get_shortaddr(
334 info
->attrs
[IEEE802154_ATTR_COORD_SHORT_ADDR
]);
335 addr
.pan_id
= nla_get_shortaddr(
336 info
->attrs
[IEEE802154_ATTR_COORD_PAN_ID
]);
338 channel
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_CHANNEL
]);
339 bcn_ord
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_BCN_ORD
]);
340 sf_ord
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_SF_ORD
]);
341 pan_coord
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_PAN_COORD
]);
342 blx
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_BAT_EXT
]);
343 coord_realign
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_COORD_REALIGN
]);
345 if (info
->attrs
[IEEE802154_ATTR_PAGE
])
346 page
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_PAGE
]);
350 if (addr
.short_addr
== cpu_to_le16(IEEE802154_ADDR_BROADCAST
)) {
351 ieee802154_nl_start_confirm(dev
, IEEE802154_NO_SHORT_ADDRESS
);
357 ret
= ieee802154_mlme_ops(dev
)->start_req(dev
, &addr
, channel
, page
,
358 bcn_ord
, sf_ord
, pan_coord
, blx
, coord_realign
);
361 /* FIXME: add validation for unused parameters to be sane
364 ieee802154_nl_start_confirm(dev
, IEEE802154_SUCCESS
);
371 int ieee802154_scan_req(struct sk_buff
*skb
, struct genl_info
*info
)
373 struct net_device
*dev
;
374 int ret
= -EOPNOTSUPP
;
380 if (!info
->attrs
[IEEE802154_ATTR_SCAN_TYPE
] ||
381 !info
->attrs
[IEEE802154_ATTR_CHANNELS
] ||
382 !info
->attrs
[IEEE802154_ATTR_DURATION
])
385 dev
= ieee802154_nl_get_dev(info
);
388 if (!ieee802154_mlme_ops(dev
)->scan_req
)
391 type
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_SCAN_TYPE
]);
392 channels
= nla_get_u32(info
->attrs
[IEEE802154_ATTR_CHANNELS
]);
393 duration
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_DURATION
]);
395 if (info
->attrs
[IEEE802154_ATTR_PAGE
])
396 page
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_PAGE
]);
400 ret
= ieee802154_mlme_ops(dev
)->scan_req(dev
, type
, channels
,
408 int ieee802154_list_iface(struct sk_buff
*skb
, struct genl_info
*info
)
410 /* Request for interface name, index, type, IEEE address,
411 * PAN Id, short address
414 struct net_device
*dev
= NULL
;
417 pr_debug("%s\n", __func__
);
419 dev
= ieee802154_nl_get_dev(info
);
423 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
427 rc
= ieee802154_nl_fill_iface(msg
, info
->snd_portid
, info
->snd_seq
,
434 return genlmsg_reply(msg
, info
);
442 int ieee802154_dump_iface(struct sk_buff
*skb
, struct netlink_callback
*cb
)
444 struct net
*net
= sock_net(skb
->sk
);
445 struct net_device
*dev
;
447 int s_idx
= cb
->args
[0];
449 pr_debug("%s\n", __func__
);
452 for_each_netdev(net
, dev
) {
453 /* Check on mtu is currently a hacked solution because lowpan
454 * and wpan have the same ARPHRD type.
456 if (idx
< s_idx
|| dev
->type
!= ARPHRD_IEEE802154
||
457 dev
->mtu
!= IEEE802154_MTU
)
460 if (ieee802154_nl_fill_iface(skb
, NETLINK_CB(cb
->skb
).portid
,
462 NLM_F_MULTI
, dev
) < 0)
472 int ieee802154_set_macparams(struct sk_buff
*skb
, struct genl_info
*info
)
474 struct net_device
*dev
= NULL
;
475 struct ieee802154_mlme_ops
*ops
;
476 struct ieee802154_mac_params params
;
477 struct wpan_phy
*phy
;
480 pr_debug("%s\n", __func__
);
482 dev
= ieee802154_nl_get_dev(info
);
486 ops
= ieee802154_mlme_ops(dev
);
488 if (!ops
->get_mac_params
|| !ops
->set_mac_params
) {
493 if (netif_running(dev
)) {
498 if (!info
->attrs
[IEEE802154_ATTR_LBT_ENABLED
] &&
499 !info
->attrs
[IEEE802154_ATTR_CCA_MODE
] &&
500 !info
->attrs
[IEEE802154_ATTR_CCA_ED_LEVEL
] &&
501 !info
->attrs
[IEEE802154_ATTR_CSMA_RETRIES
] &&
502 !info
->attrs
[IEEE802154_ATTR_CSMA_MIN_BE
] &&
503 !info
->attrs
[IEEE802154_ATTR_CSMA_MAX_BE
] &&
504 !info
->attrs
[IEEE802154_ATTR_FRAME_RETRIES
])
507 phy
= dev
->ieee802154_ptr
->wpan_phy
;
508 get_device(&phy
->dev
);
511 ops
->get_mac_params(dev
, ¶ms
);
513 if (info
->attrs
[IEEE802154_ATTR_TXPOWER
])
514 params
.transmit_power
= nla_get_s8(info
->attrs
[IEEE802154_ATTR_TXPOWER
]);
516 if (info
->attrs
[IEEE802154_ATTR_LBT_ENABLED
])
517 params
.lbt
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LBT_ENABLED
]);
519 if (info
->attrs
[IEEE802154_ATTR_CCA_MODE
])
520 params
.cca
.mode
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_CCA_MODE
]);
522 if (info
->attrs
[IEEE802154_ATTR_CCA_ED_LEVEL
])
523 params
.cca_ed_level
= nla_get_s32(info
->attrs
[IEEE802154_ATTR_CCA_ED_LEVEL
]);
525 if (info
->attrs
[IEEE802154_ATTR_CSMA_RETRIES
])
526 params
.csma_retries
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_CSMA_RETRIES
]);
528 if (info
->attrs
[IEEE802154_ATTR_CSMA_MIN_BE
])
529 params
.min_be
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_CSMA_MIN_BE
]);
531 if (info
->attrs
[IEEE802154_ATTR_CSMA_MAX_BE
])
532 params
.max_be
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_CSMA_MAX_BE
]);
534 if (info
->attrs
[IEEE802154_ATTR_FRAME_RETRIES
])
535 params
.frame_retries
= nla_get_s8(info
->attrs
[IEEE802154_ATTR_FRAME_RETRIES
]);
537 rc
= ops
->set_mac_params(dev
, ¶ms
);
551 ieee802154_llsec_parse_key_id(struct genl_info
*info
,
552 struct ieee802154_llsec_key_id
*desc
)
554 memset(desc
, 0, sizeof(*desc
));
556 if (!info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_MODE
])
559 desc
->mode
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_MODE
]);
561 if (desc
->mode
== IEEE802154_SCF_KEY_IMPLICIT
) {
562 if (!info
->attrs
[IEEE802154_ATTR_PAN_ID
] &&
563 !(info
->attrs
[IEEE802154_ATTR_SHORT_ADDR
] ||
564 info
->attrs
[IEEE802154_ATTR_HW_ADDR
]))
567 desc
->device_addr
.pan_id
= nla_get_shortaddr(info
->attrs
[IEEE802154_ATTR_PAN_ID
]);
569 if (info
->attrs
[IEEE802154_ATTR_SHORT_ADDR
]) {
570 desc
->device_addr
.mode
= IEEE802154_ADDR_SHORT
;
571 desc
->device_addr
.short_addr
= nla_get_shortaddr(info
->attrs
[IEEE802154_ATTR_SHORT_ADDR
]);
573 desc
->device_addr
.mode
= IEEE802154_ADDR_LONG
;
574 desc
->device_addr
.extended_addr
= nla_get_hwaddr(info
->attrs
[IEEE802154_ATTR_HW_ADDR
]);
578 if (desc
->mode
!= IEEE802154_SCF_KEY_IMPLICIT
&&
579 !info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_ID
])
582 if (desc
->mode
== IEEE802154_SCF_KEY_SHORT_INDEX
&&
583 !info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_SOURCE_SHORT
])
586 if (desc
->mode
== IEEE802154_SCF_KEY_HW_INDEX
&&
587 !info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_SOURCE_EXTENDED
])
590 if (desc
->mode
!= IEEE802154_SCF_KEY_IMPLICIT
)
591 desc
->id
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_ID
]);
593 switch (desc
->mode
) {
594 case IEEE802154_SCF_KEY_SHORT_INDEX
:
596 u32 source
= nla_get_u32(info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_SOURCE_SHORT
]);
598 desc
->short_source
= cpu_to_le32(source
);
601 case IEEE802154_SCF_KEY_HW_INDEX
:
602 desc
->extended_source
= nla_get_hwaddr(info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_SOURCE_EXTENDED
]);
610 ieee802154_llsec_fill_key_id(struct sk_buff
*msg
,
611 const struct ieee802154_llsec_key_id
*desc
)
613 if (nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_KEY_MODE
, desc
->mode
))
616 if (desc
->mode
== IEEE802154_SCF_KEY_IMPLICIT
) {
617 if (nla_put_shortaddr(msg
, IEEE802154_ATTR_PAN_ID
,
618 desc
->device_addr
.pan_id
))
621 if (desc
->device_addr
.mode
== IEEE802154_ADDR_SHORT
&&
622 nla_put_shortaddr(msg
, IEEE802154_ATTR_SHORT_ADDR
,
623 desc
->device_addr
.short_addr
))
626 if (desc
->device_addr
.mode
== IEEE802154_ADDR_LONG
&&
627 nla_put_hwaddr(msg
, IEEE802154_ATTR_HW_ADDR
,
628 desc
->device_addr
.extended_addr
))
632 if (desc
->mode
!= IEEE802154_SCF_KEY_IMPLICIT
&&
633 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_KEY_ID
, desc
->id
))
636 if (desc
->mode
== IEEE802154_SCF_KEY_SHORT_INDEX
&&
637 nla_put_u32(msg
, IEEE802154_ATTR_LLSEC_KEY_SOURCE_SHORT
,
638 le32_to_cpu(desc
->short_source
)))
641 if (desc
->mode
== IEEE802154_SCF_KEY_HW_INDEX
&&
642 nla_put_hwaddr(msg
, IEEE802154_ATTR_LLSEC_KEY_SOURCE_EXTENDED
,
643 desc
->extended_source
))
649 int ieee802154_llsec_getparams(struct sk_buff
*skb
, struct genl_info
*info
)
652 struct net_device
*dev
= NULL
;
654 struct ieee802154_mlme_ops
*ops
;
656 struct ieee802154_llsec_params params
;
658 pr_debug("%s\n", __func__
);
660 dev
= ieee802154_nl_get_dev(info
);
664 ops
= ieee802154_mlme_ops(dev
);
670 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
674 hdr
= genlmsg_put(msg
, 0, info
->snd_seq
, &nl802154_family
, 0,
675 IEEE802154_LLSEC_GETPARAMS
);
679 rc
= ops
->llsec
->get_params(dev
, ¶ms
);
683 if (nla_put_string(msg
, IEEE802154_ATTR_DEV_NAME
, dev
->name
) ||
684 nla_put_u32(msg
, IEEE802154_ATTR_DEV_INDEX
, dev
->ifindex
) ||
685 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_ENABLED
, params
.enabled
) ||
686 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_SECLEVEL
, params
.out_level
) ||
687 nla_put_u32(msg
, IEEE802154_ATTR_LLSEC_FRAME_COUNTER
,
688 be32_to_cpu(params
.frame_counter
)) ||
689 ieee802154_llsec_fill_key_id(msg
, ¶ms
.out_key
))
694 return ieee802154_nl_reply(msg
, info
);
702 int ieee802154_llsec_setparams(struct sk_buff
*skb
, struct genl_info
*info
)
704 struct net_device
*dev
= NULL
;
706 struct ieee802154_mlme_ops
*ops
;
707 struct ieee802154_llsec_params params
;
710 pr_debug("%s\n", __func__
);
712 dev
= ieee802154_nl_get_dev(info
);
716 if (!info
->attrs
[IEEE802154_ATTR_LLSEC_ENABLED
] &&
717 !info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_MODE
] &&
718 !info
->attrs
[IEEE802154_ATTR_LLSEC_SECLEVEL
])
721 ops
= ieee802154_mlme_ops(dev
);
727 if (info
->attrs
[IEEE802154_ATTR_LLSEC_SECLEVEL
] &&
728 nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_SECLEVEL
]) > 7)
731 if (info
->attrs
[IEEE802154_ATTR_LLSEC_ENABLED
]) {
732 params
.enabled
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_ENABLED
]);
733 changed
|= IEEE802154_LLSEC_PARAM_ENABLED
;
736 if (info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_MODE
]) {
737 if (ieee802154_llsec_parse_key_id(info
, ¶ms
.out_key
))
740 changed
|= IEEE802154_LLSEC_PARAM_OUT_KEY
;
743 if (info
->attrs
[IEEE802154_ATTR_LLSEC_SECLEVEL
]) {
744 params
.out_level
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_SECLEVEL
]);
745 changed
|= IEEE802154_LLSEC_PARAM_OUT_LEVEL
;
748 if (info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_COUNTER
]) {
749 u32 fc
= nla_get_u32(info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_COUNTER
]);
751 params
.frame_counter
= cpu_to_be32(fc
);
752 changed
|= IEEE802154_LLSEC_PARAM_FRAME_COUNTER
;
755 rc
= ops
->llsec
->set_params(dev
, ¶ms
, changed
);
765 struct llsec_dump_data
{
770 struct net_device
*dev
;
771 struct ieee802154_mlme_ops
*ops
;
772 struct ieee802154_llsec_table
*table
;
776 ieee802154_llsec_dump_table(struct sk_buff
*skb
, struct netlink_callback
*cb
,
777 int (*step
)(struct llsec_dump_data
*))
779 struct net
*net
= sock_net(skb
->sk
);
780 struct net_device
*dev
;
781 struct llsec_dump_data data
;
783 int first_dev
= cb
->args
[0];
786 for_each_netdev(net
, dev
) {
787 /* Check on mtu is currently a hacked solution because lowpan
788 * and wpan have the same ARPHRD type.
790 if (idx
< first_dev
|| dev
->type
!= ARPHRD_IEEE802154
||
791 dev
->mtu
!= IEEE802154_MTU
)
794 data
.ops
= ieee802154_mlme_ops(dev
);
795 if (!data
.ops
->llsec
)
799 data
.s_idx
= cb
->args
[1];
800 data
.s_idx2
= cb
->args
[2];
802 data
.portid
= NETLINK_CB(cb
->skb
).portid
;
803 data
.nlmsg_seq
= cb
->nlh
->nlmsg_seq
;
805 data
.ops
->llsec
->lock_table(dev
);
806 data
.ops
->llsec
->get_table(data
.dev
, &data
.table
);
808 data
.ops
->llsec
->unlock_table(dev
);
822 ieee802154_nl_llsec_change(struct sk_buff
*skb
, struct genl_info
*info
,
823 int (*fn
)(struct net_device
*, struct genl_info
*))
825 struct net_device
*dev
= NULL
;
828 dev
= ieee802154_nl_get_dev(info
);
832 if (!ieee802154_mlme_ops(dev
)->llsec
)
842 ieee802154_llsec_parse_key(struct genl_info
*info
,
843 struct ieee802154_llsec_key
*key
)
846 u32 commands
[256 / 32];
848 memset(key
, 0, sizeof(*key
));
850 if (!info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_USAGE_FRAME_TYPES
] ||
851 !info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_BYTES
])
854 frames
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_USAGE_FRAME_TYPES
]);
855 if ((frames
& BIT(IEEE802154_FC_TYPE_MAC_CMD
)) &&
856 !info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_USAGE_COMMANDS
])
859 if (info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_USAGE_COMMANDS
]) {
861 info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_USAGE_COMMANDS
],
864 if (commands
[0] || commands
[1] || commands
[2] || commands
[3] ||
865 commands
[4] || commands
[5] || commands
[6] ||
866 commands
[7] >= BIT(IEEE802154_CMD_GTS_REQ
+ 1))
869 key
->cmd_frame_ids
= commands
[7];
872 key
->frame_types
= frames
;
874 nla_memcpy(key
->key
, info
->attrs
[IEEE802154_ATTR_LLSEC_KEY_BYTES
],
875 IEEE802154_LLSEC_KEY_SIZE
);
880 static int llsec_add_key(struct net_device
*dev
, struct genl_info
*info
)
882 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
883 struct ieee802154_llsec_key key
;
884 struct ieee802154_llsec_key_id id
;
886 if (ieee802154_llsec_parse_key(info
, &key
) ||
887 ieee802154_llsec_parse_key_id(info
, &id
))
890 return ops
->llsec
->add_key(dev
, &id
, &key
);
893 int ieee802154_llsec_add_key(struct sk_buff
*skb
, struct genl_info
*info
)
895 if ((info
->nlhdr
->nlmsg_flags
& (NLM_F_CREATE
| NLM_F_EXCL
)) !=
896 (NLM_F_CREATE
| NLM_F_EXCL
))
899 return ieee802154_nl_llsec_change(skb
, info
, llsec_add_key
);
902 static int llsec_remove_key(struct net_device
*dev
, struct genl_info
*info
)
904 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
905 struct ieee802154_llsec_key_id id
;
907 if (ieee802154_llsec_parse_key_id(info
, &id
))
910 return ops
->llsec
->del_key(dev
, &id
);
913 int ieee802154_llsec_del_key(struct sk_buff
*skb
, struct genl_info
*info
)
915 return ieee802154_nl_llsec_change(skb
, info
, llsec_remove_key
);
919 ieee802154_nl_fill_key(struct sk_buff
*msg
, u32 portid
, u32 seq
,
920 const struct ieee802154_llsec_key_entry
*key
,
921 const struct net_device
*dev
)
924 u32 commands
[256 / 32];
926 hdr
= genlmsg_put(msg
, 0, seq
, &nl802154_family
, NLM_F_MULTI
,
927 IEEE802154_LLSEC_LIST_KEY
);
931 if (nla_put_string(msg
, IEEE802154_ATTR_DEV_NAME
, dev
->name
) ||
932 nla_put_u32(msg
, IEEE802154_ATTR_DEV_INDEX
, dev
->ifindex
) ||
933 ieee802154_llsec_fill_key_id(msg
, &key
->id
) ||
934 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_KEY_USAGE_FRAME_TYPES
,
935 key
->key
->frame_types
))
936 goto nla_put_failure
;
938 if (key
->key
->frame_types
& BIT(IEEE802154_FC_TYPE_MAC_CMD
)) {
939 memset(commands
, 0, sizeof(commands
));
940 commands
[7] = key
->key
->cmd_frame_ids
;
941 if (nla_put(msg
, IEEE802154_ATTR_LLSEC_KEY_USAGE_COMMANDS
,
942 sizeof(commands
), commands
))
943 goto nla_put_failure
;
946 if (nla_put(msg
, IEEE802154_ATTR_LLSEC_KEY_BYTES
,
947 IEEE802154_LLSEC_KEY_SIZE
, key
->key
->key
))
948 goto nla_put_failure
;
950 genlmsg_end(msg
, hdr
);
954 genlmsg_cancel(msg
, hdr
);
959 static int llsec_iter_keys(struct llsec_dump_data
*data
)
961 struct ieee802154_llsec_key_entry
*pos
;
964 list_for_each_entry(pos
, &data
->table
->keys
, list
) {
965 if (idx
++ < data
->s_idx
)
968 if (ieee802154_nl_fill_key(data
->skb
, data
->portid
,
969 data
->nlmsg_seq
, pos
, data
->dev
)) {
980 int ieee802154_llsec_dump_keys(struct sk_buff
*skb
, struct netlink_callback
*cb
)
982 return ieee802154_llsec_dump_table(skb
, cb
, llsec_iter_keys
);
986 llsec_parse_dev(struct genl_info
*info
,
987 struct ieee802154_llsec_device
*dev
)
989 memset(dev
, 0, sizeof(*dev
));
991 if (!info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_COUNTER
] ||
992 !info
->attrs
[IEEE802154_ATTR_HW_ADDR
] ||
993 !info
->attrs
[IEEE802154_ATTR_LLSEC_DEV_OVERRIDE
] ||
994 !info
->attrs
[IEEE802154_ATTR_LLSEC_DEV_KEY_MODE
] ||
995 (!!info
->attrs
[IEEE802154_ATTR_PAN_ID
] !=
996 !!info
->attrs
[IEEE802154_ATTR_SHORT_ADDR
]))
999 if (info
->attrs
[IEEE802154_ATTR_PAN_ID
]) {
1000 dev
->pan_id
= nla_get_shortaddr(info
->attrs
[IEEE802154_ATTR_PAN_ID
]);
1001 dev
->short_addr
= nla_get_shortaddr(info
->attrs
[IEEE802154_ATTR_SHORT_ADDR
]);
1003 dev
->short_addr
= cpu_to_le16(IEEE802154_ADDR_UNDEF
);
1006 dev
->hwaddr
= nla_get_hwaddr(info
->attrs
[IEEE802154_ATTR_HW_ADDR
]);
1007 dev
->frame_counter
= nla_get_u32(info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_COUNTER
]);
1008 dev
->seclevel_exempt
= !!nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_DEV_OVERRIDE
]);
1009 dev
->key_mode
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_DEV_KEY_MODE
]);
1011 if (dev
->key_mode
>= __IEEE802154_LLSEC_DEVKEY_MAX
)
1017 static int llsec_add_dev(struct net_device
*dev
, struct genl_info
*info
)
1019 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
1020 struct ieee802154_llsec_device desc
;
1022 if (llsec_parse_dev(info
, &desc
))
1025 return ops
->llsec
->add_dev(dev
, &desc
);
1028 int ieee802154_llsec_add_dev(struct sk_buff
*skb
, struct genl_info
*info
)
1030 if ((info
->nlhdr
->nlmsg_flags
& (NLM_F_CREATE
| NLM_F_EXCL
)) !=
1031 (NLM_F_CREATE
| NLM_F_EXCL
))
1034 return ieee802154_nl_llsec_change(skb
, info
, llsec_add_dev
);
1037 static int llsec_del_dev(struct net_device
*dev
, struct genl_info
*info
)
1039 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
1042 if (!info
->attrs
[IEEE802154_ATTR_HW_ADDR
])
1045 devaddr
= nla_get_hwaddr(info
->attrs
[IEEE802154_ATTR_HW_ADDR
]);
1047 return ops
->llsec
->del_dev(dev
, devaddr
);
1050 int ieee802154_llsec_del_dev(struct sk_buff
*skb
, struct genl_info
*info
)
1052 return ieee802154_nl_llsec_change(skb
, info
, llsec_del_dev
);
1056 ieee802154_nl_fill_dev(struct sk_buff
*msg
, u32 portid
, u32 seq
,
1057 const struct ieee802154_llsec_device
*desc
,
1058 const struct net_device
*dev
)
1062 hdr
= genlmsg_put(msg
, 0, seq
, &nl802154_family
, NLM_F_MULTI
,
1063 IEEE802154_LLSEC_LIST_DEV
);
1067 if (nla_put_string(msg
, IEEE802154_ATTR_DEV_NAME
, dev
->name
) ||
1068 nla_put_u32(msg
, IEEE802154_ATTR_DEV_INDEX
, dev
->ifindex
) ||
1069 nla_put_shortaddr(msg
, IEEE802154_ATTR_PAN_ID
, desc
->pan_id
) ||
1070 nla_put_shortaddr(msg
, IEEE802154_ATTR_SHORT_ADDR
,
1071 desc
->short_addr
) ||
1072 nla_put_hwaddr(msg
, IEEE802154_ATTR_HW_ADDR
, desc
->hwaddr
) ||
1073 nla_put_u32(msg
, IEEE802154_ATTR_LLSEC_FRAME_COUNTER
,
1074 desc
->frame_counter
) ||
1075 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_DEV_OVERRIDE
,
1076 desc
->seclevel_exempt
) ||
1077 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_DEV_KEY_MODE
, desc
->key_mode
))
1078 goto nla_put_failure
;
1080 genlmsg_end(msg
, hdr
);
1084 genlmsg_cancel(msg
, hdr
);
1089 static int llsec_iter_devs(struct llsec_dump_data
*data
)
1091 struct ieee802154_llsec_device
*pos
;
1092 int rc
= 0, idx
= 0;
1094 list_for_each_entry(pos
, &data
->table
->devices
, list
) {
1095 if (idx
++ < data
->s_idx
)
1098 if (ieee802154_nl_fill_dev(data
->skb
, data
->portid
,
1099 data
->nlmsg_seq
, pos
, data
->dev
)) {
1110 int ieee802154_llsec_dump_devs(struct sk_buff
*skb
, struct netlink_callback
*cb
)
1112 return ieee802154_llsec_dump_table(skb
, cb
, llsec_iter_devs
);
1115 static int llsec_add_devkey(struct net_device
*dev
, struct genl_info
*info
)
1117 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
1118 struct ieee802154_llsec_device_key key
;
1121 if (!info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_COUNTER
] ||
1122 !info
->attrs
[IEEE802154_ATTR_HW_ADDR
] ||
1123 ieee802154_llsec_parse_key_id(info
, &key
.key_id
))
1126 devaddr
= nla_get_hwaddr(info
->attrs
[IEEE802154_ATTR_HW_ADDR
]);
1127 key
.frame_counter
= nla_get_u32(info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_COUNTER
]);
1129 return ops
->llsec
->add_devkey(dev
, devaddr
, &key
);
1132 int ieee802154_llsec_add_devkey(struct sk_buff
*skb
, struct genl_info
*info
)
1134 if ((info
->nlhdr
->nlmsg_flags
& (NLM_F_CREATE
| NLM_F_EXCL
)) !=
1135 (NLM_F_CREATE
| NLM_F_EXCL
))
1138 return ieee802154_nl_llsec_change(skb
, info
, llsec_add_devkey
);
1141 static int llsec_del_devkey(struct net_device
*dev
, struct genl_info
*info
)
1143 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
1144 struct ieee802154_llsec_device_key key
;
1147 if (!info
->attrs
[IEEE802154_ATTR_HW_ADDR
] ||
1148 ieee802154_llsec_parse_key_id(info
, &key
.key_id
))
1151 devaddr
= nla_get_hwaddr(info
->attrs
[IEEE802154_ATTR_HW_ADDR
]);
1153 return ops
->llsec
->del_devkey(dev
, devaddr
, &key
);
1156 int ieee802154_llsec_del_devkey(struct sk_buff
*skb
, struct genl_info
*info
)
1158 return ieee802154_nl_llsec_change(skb
, info
, llsec_del_devkey
);
1162 ieee802154_nl_fill_devkey(struct sk_buff
*msg
, u32 portid
, u32 seq
,
1164 const struct ieee802154_llsec_device_key
*devkey
,
1165 const struct net_device
*dev
)
1169 hdr
= genlmsg_put(msg
, 0, seq
, &nl802154_family
, NLM_F_MULTI
,
1170 IEEE802154_LLSEC_LIST_DEVKEY
);
1174 if (nla_put_string(msg
, IEEE802154_ATTR_DEV_NAME
, dev
->name
) ||
1175 nla_put_u32(msg
, IEEE802154_ATTR_DEV_INDEX
, dev
->ifindex
) ||
1176 nla_put_hwaddr(msg
, IEEE802154_ATTR_HW_ADDR
, devaddr
) ||
1177 nla_put_u32(msg
, IEEE802154_ATTR_LLSEC_FRAME_COUNTER
,
1178 devkey
->frame_counter
) ||
1179 ieee802154_llsec_fill_key_id(msg
, &devkey
->key_id
))
1180 goto nla_put_failure
;
1182 genlmsg_end(msg
, hdr
);
1186 genlmsg_cancel(msg
, hdr
);
1191 static int llsec_iter_devkeys(struct llsec_dump_data
*data
)
1193 struct ieee802154_llsec_device
*dpos
;
1194 struct ieee802154_llsec_device_key
*kpos
;
1195 int rc
= 0, idx
= 0, idx2
;
1197 list_for_each_entry(dpos
, &data
->table
->devices
, list
) {
1198 if (idx
++ < data
->s_idx
)
1203 list_for_each_entry(kpos
, &dpos
->keys
, list
) {
1204 if (idx2
++ < data
->s_idx2
)
1207 if (ieee802154_nl_fill_devkey(data
->skb
, data
->portid
,
1211 return rc
= -EMSGSIZE
;
1223 int ieee802154_llsec_dump_devkeys(struct sk_buff
*skb
,
1224 struct netlink_callback
*cb
)
1226 return ieee802154_llsec_dump_table(skb
, cb
, llsec_iter_devkeys
);
1230 llsec_parse_seclevel(struct genl_info
*info
,
1231 struct ieee802154_llsec_seclevel
*sl
)
1233 memset(sl
, 0, sizeof(*sl
));
1235 if (!info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_TYPE
] ||
1236 !info
->attrs
[IEEE802154_ATTR_LLSEC_SECLEVELS
] ||
1237 !info
->attrs
[IEEE802154_ATTR_LLSEC_DEV_OVERRIDE
])
1240 sl
->frame_type
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_FRAME_TYPE
]);
1241 if (sl
->frame_type
== IEEE802154_FC_TYPE_MAC_CMD
) {
1242 if (!info
->attrs
[IEEE802154_ATTR_LLSEC_CMD_FRAME_ID
])
1245 sl
->cmd_frame_id
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_CMD_FRAME_ID
]);
1248 sl
->sec_levels
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_SECLEVELS
]);
1249 sl
->device_override
= nla_get_u8(info
->attrs
[IEEE802154_ATTR_LLSEC_DEV_OVERRIDE
]);
1254 static int llsec_add_seclevel(struct net_device
*dev
, struct genl_info
*info
)
1256 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
1257 struct ieee802154_llsec_seclevel sl
;
1259 if (llsec_parse_seclevel(info
, &sl
))
1262 return ops
->llsec
->add_seclevel(dev
, &sl
);
1265 int ieee802154_llsec_add_seclevel(struct sk_buff
*skb
, struct genl_info
*info
)
1267 if ((info
->nlhdr
->nlmsg_flags
& (NLM_F_CREATE
| NLM_F_EXCL
)) !=
1268 (NLM_F_CREATE
| NLM_F_EXCL
))
1271 return ieee802154_nl_llsec_change(skb
, info
, llsec_add_seclevel
);
1274 static int llsec_del_seclevel(struct net_device
*dev
, struct genl_info
*info
)
1276 struct ieee802154_mlme_ops
*ops
= ieee802154_mlme_ops(dev
);
1277 struct ieee802154_llsec_seclevel sl
;
1279 if (llsec_parse_seclevel(info
, &sl
))
1282 return ops
->llsec
->del_seclevel(dev
, &sl
);
1285 int ieee802154_llsec_del_seclevel(struct sk_buff
*skb
, struct genl_info
*info
)
1287 return ieee802154_nl_llsec_change(skb
, info
, llsec_del_seclevel
);
1291 ieee802154_nl_fill_seclevel(struct sk_buff
*msg
, u32 portid
, u32 seq
,
1292 const struct ieee802154_llsec_seclevel
*sl
,
1293 const struct net_device
*dev
)
1297 hdr
= genlmsg_put(msg
, 0, seq
, &nl802154_family
, NLM_F_MULTI
,
1298 IEEE802154_LLSEC_LIST_SECLEVEL
);
1302 if (nla_put_string(msg
, IEEE802154_ATTR_DEV_NAME
, dev
->name
) ||
1303 nla_put_u32(msg
, IEEE802154_ATTR_DEV_INDEX
, dev
->ifindex
) ||
1304 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_FRAME_TYPE
, sl
->frame_type
) ||
1305 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_SECLEVELS
, sl
->sec_levels
) ||
1306 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_DEV_OVERRIDE
,
1307 sl
->device_override
))
1308 goto nla_put_failure
;
1310 if (sl
->frame_type
== IEEE802154_FC_TYPE_MAC_CMD
&&
1311 nla_put_u8(msg
, IEEE802154_ATTR_LLSEC_CMD_FRAME_ID
,
1313 goto nla_put_failure
;
1315 genlmsg_end(msg
, hdr
);
1319 genlmsg_cancel(msg
, hdr
);
1324 static int llsec_iter_seclevels(struct llsec_dump_data
*data
)
1326 struct ieee802154_llsec_seclevel
*pos
;
1327 int rc
= 0, idx
= 0;
1329 list_for_each_entry(pos
, &data
->table
->security_levels
, list
) {
1330 if (idx
++ < data
->s_idx
)
1333 if (ieee802154_nl_fill_seclevel(data
->skb
, data
->portid
,
1334 data
->nlmsg_seq
, pos
,
1346 int ieee802154_llsec_dump_seclevels(struct sk_buff
*skb
,
1347 struct netlink_callback
*cb
)
1349 return ieee802154_llsec_dump_table(skb
, cb
, llsec_iter_seclevels
);