1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * 4 * Authors: 5 * Alexander Aring <aar@pengutronix.de> 6 * 7 * Based on: net/wireless/nl80211.c 8 */ 9 10 #include <linux/rtnetlink.h> 11 12 #include <net/cfg802154.h> 13 #include <net/genetlink.h> 14 #include <net/mac802154.h> 15 #include <net/netlink.h> 16 #include <net/nl802154.h> 17 #include <net/sock.h> 18 19 #include "nl802154.h" 20 #include "rdev-ops.h" 21 #include "core.h" 22 23 /* the netlink family */ 24 static struct genl_family nl802154_fam; 25 26 /* multicast groups */ 27 enum nl802154_multicast_groups { 28 NL802154_MCGRP_CONFIG, 29 NL802154_MCGRP_SCAN, 30 }; 31 32 static const struct genl_multicast_group nl802154_mcgrps[] = { 33 [NL802154_MCGRP_CONFIG] = { .name = "config", }, 34 [NL802154_MCGRP_SCAN] = { .name = "scan", }, 35 }; 36 37 /* returns ERR_PTR values */ 38 static struct wpan_dev * 39 __cfg802154_wpan_dev_from_attrs(struct net *netns, struct nlattr **attrs) 40 { 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]; 45 u64 wpan_dev_id; 46 int wpan_phy_idx = -1; 47 int ifidx = -1; 48 49 ASSERT_RTNL(); 50 51 if (!have_ifidx && !have_wpan_dev_id) 52 return ERR_PTR(-EINVAL); 53 54 if (have_ifidx) 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; 59 } 60 61 list_for_each_entry(rdev, &cfg802154_rdev_list, list) { 62 struct wpan_dev *wpan_dev; 63 64 if (wpan_phy_net(&rdev->wpan_phy) != netns) 65 continue; 66 67 if (have_wpan_dev_id && rdev->wpan_phy_idx != wpan_phy_idx) 68 continue; 69 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) { 73 result = wpan_dev; 74 break; 75 } 76 if (have_wpan_dev_id && 77 wpan_dev->identifier == (u32)wpan_dev_id) { 78 result = wpan_dev; 79 break; 80 } 81 } 82 83 if (result) 84 break; 85 } 86 87 if (result) 88 return result; 89 90 return ERR_PTR(-ENODEV); 91 } 92 93 static struct cfg802154_registered_device * 94 __cfg802154_rdev_from_attrs(struct net *netns, struct nlattr **attrs) 95 { 96 struct cfg802154_registered_device *rdev = NULL, *tmp; 97 struct net_device *netdev; 98 99 ASSERT_RTNL(); 100 101 if (!attrs[NL802154_ATTR_WPAN_PHY] && 102 !attrs[NL802154_ATTR_IFINDEX] && 103 !attrs[NL802154_ATTR_WPAN_DEV]) 104 return ERR_PTR(-EINVAL); 105 106 if (attrs[NL802154_ATTR_WPAN_PHY]) 107 rdev = cfg802154_rdev_by_wpan_phy_idx( 108 nla_get_u32(attrs[NL802154_ATTR_WPAN_PHY])); 109 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; 113 bool found = false; 114 115 tmp = cfg802154_rdev_by_wpan_phy_idx(wpan_dev_id >> 32); 116 if (tmp) { 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) 120 continue; 121 found = true; 122 break; 123 } 124 125 if (!found) 126 tmp = NULL; 127 128 if (rdev && tmp != rdev) 129 return ERR_PTR(-EINVAL); 130 rdev = tmp; 131 } 132 } 133 134 if (attrs[NL802154_ATTR_IFINDEX]) { 135 int ifindex = nla_get_u32(attrs[NL802154_ATTR_IFINDEX]); 136 137 netdev = __dev_get_by_index(netns, ifindex); 138 if (netdev) { 139 if (netdev->ieee802154_ptr) 140 tmp = wpan_phy_to_rdev( 141 netdev->ieee802154_ptr->wpan_phy); 142 else 143 tmp = NULL; 144 145 /* not wireless device -- return error */ 146 if (!tmp) 147 return ERR_PTR(-EINVAL); 148 149 /* mismatch -- return error */ 150 if (rdev && tmp != rdev) 151 return ERR_PTR(-EINVAL); 152 153 rdev = tmp; 154 } 155 } 156 157 if (!rdev) 158 return ERR_PTR(-ENODEV); 159 160 if (netns != wpan_phy_net(&rdev->wpan_phy)) 161 return ERR_PTR(-ENODEV); 162 163 return rdev; 164 } 165 166 /* This function returns a pointer to the driver 167 * that the genl_info item that is passed refers to. 168 * 169 * The result of this can be a PTR_ERR and hence must 170 * be checked with IS_ERR() for errors. 171 */ 172 static struct cfg802154_registered_device * 173 cfg802154_get_dev_from_info(struct net *netns, struct genl_info *info) 174 { 175 return __cfg802154_rdev_from_attrs(netns, info->attrs); 176 } 177 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, 182 .len = 20-1 }, 183 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 }, 187 188 [NL802154_ATTR_WPAN_DEV] = { .type = NLA_U64 }, 189 190 [NL802154_ATTR_PAGE] = NLA_POLICY_MAX(NLA_U8, IEEE802154_MAX_PAGE), 191 [NL802154_ATTR_CHANNEL] = NLA_POLICY_MAX(NLA_U8, IEEE802154_MAX_CHANNEL), 192 193 [NL802154_ATTR_TX_POWER] = { .type = NLA_S32, }, 194 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, }, 198 199 [NL802154_ATTR_SUPPORTED_CHANNEL] = { .type = NLA_U32, }, 200 201 [NL802154_ATTR_PAN_ID] = { .type = NLA_U16, }, 202 [NL802154_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 }, 203 [NL802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, }, 204 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, }, 208 209 [NL802154_ATTR_MAX_FRAME_RETRIES] = { .type = NLA_S8, }, 210 211 [NL802154_ATTR_LBT_MODE] = { .type = NLA_U8, }, 212 213 [NL802154_ATTR_WPAN_PHY_CAPS] = { .type = NLA_NESTED }, 214 215 [NL802154_ATTR_SUPPORTED_COMMANDS] = { .type = NLA_NESTED }, 216 217 [NL802154_ATTR_ACKREQ_DEFAULT] = { .type = NLA_U8 }, 218 219 [NL802154_ATTR_PID] = { .type = NLA_U32 }, 220 [NL802154_ATTR_NETNS_FD] = { .type = NLA_U32 }, 221 222 [NL802154_ATTR_COORDINATOR] = { .type = NLA_NESTED }, 223 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 239 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL 240 [NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, }, 241 [NL802154_ATTR_SEC_OUT_LEVEL] = { .type = NLA_U32, }, 242 [NL802154_ATTR_SEC_OUT_KEY_ID] = { .type = NLA_NESTED, }, 243 [NL802154_ATTR_SEC_FRAME_COUNTER] = { .type = NLA_U32 }, 244 245 [NL802154_ATTR_SEC_LEVEL] = { .type = NLA_NESTED }, 246 [NL802154_ATTR_SEC_DEVICE] = { .type = NLA_NESTED }, 247 [NL802154_ATTR_SEC_DEVKEY] = { .type = NLA_NESTED }, 248 [NL802154_ATTR_SEC_KEY] = { .type = NLA_NESTED }, 249 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ 250 }; 251 252 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL 253 static int 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) 258 { 259 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 260 int err; 261 262 rtnl_lock(); 263 264 if (!cb->args[0]) { 265 *wpan_dev = __cfg802154_wpan_dev_from_attrs(sock_net(skb->sk), 266 info->info.attrs); 267 if (IS_ERR(*wpan_dev)) { 268 err = PTR_ERR(*wpan_dev); 269 goto out_unlock; 270 } 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; 275 } else { 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; 279 280 if (!wpan_phy) { 281 err = -ENODEV; 282 goto out_unlock; 283 } 284 *rdev = wpan_phy_to_rdev(wpan_phy); 285 *wpan_dev = NULL; 286 287 list_for_each_entry(tmp, &(*rdev)->wpan_dev_list, list) { 288 if (tmp->identifier == cb->args[1]) { 289 *wpan_dev = tmp; 290 break; 291 } 292 } 293 294 if (!*wpan_dev) { 295 err = -ENODEV; 296 goto out_unlock; 297 } 298 } 299 300 return 0; 301 out_unlock: 302 rtnl_unlock(); 303 return err; 304 } 305 306 static void 307 nl802154_finish_wpan_dev_dump(struct cfg802154_registered_device *rdev) 308 { 309 rtnl_unlock(); 310 } 311 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ 312 313 /* message building helper */ 314 static inline void *nl802154hdr_put(struct sk_buff *skb, u32 portid, u32 seq, 315 int flags, u8 cmd) 316 { 317 /* since there is no private header just add the generic one */ 318 return genlmsg_put(skb, portid, seq, &nl802154_fam, flags, cmd); 319 } 320 321 static int 322 nl802154_put_flags(struct sk_buff *msg, int attr, u32 mask) 323 { 324 struct nlattr *nl_flags = nla_nest_start_noflag(msg, attr); 325 int i; 326 327 if (!nl_flags) 328 return -ENOBUFS; 329 330 i = 0; 331 while (mask) { 332 if ((mask & 1) && nla_put_flag(msg, i)) 333 return -ENOBUFS; 334 335 mask >>= 1; 336 i++; 337 } 338 339 nla_nest_end(msg, nl_flags); 340 return 0; 341 } 342 343 static int 344 nl802154_send_wpan_phy_channels(struct cfg802154_registered_device *rdev, 345 struct sk_buff *msg) 346 { 347 struct nlattr *nl_page; 348 unsigned long page; 349 350 nl_page = nla_nest_start_noflag(msg, NL802154_ATTR_CHANNELS_SUPPORTED); 351 if (!nl_page) 352 return -ENOBUFS; 353 354 for (page = 0; page <= IEEE802154_MAX_PAGE; page++) { 355 if (nla_put_u32(msg, NL802154_ATTR_SUPPORTED_CHANNEL, 356 rdev->wpan_phy.supported.channels[page])) 357 return -ENOBUFS; 358 } 359 nla_nest_end(msg, nl_page); 360 361 return 0; 362 } 363 364 static int 365 nl802154_put_capabilities(struct sk_buff *msg, 366 struct cfg802154_registered_device *rdev) 367 { 368 const struct wpan_phy_supported *caps = &rdev->wpan_phy.supported; 369 struct nlattr *nl_caps, *nl_channels; 370 int i; 371 372 nl_caps = nla_nest_start_noflag(msg, NL802154_ATTR_WPAN_PHY_CAPS); 373 if (!nl_caps) 374 return -ENOBUFS; 375 376 nl_channels = nla_nest_start_noflag(msg, NL802154_CAP_ATTR_CHANNELS); 377 if (!nl_channels) 378 return -ENOBUFS; 379 380 for (i = 0; i <= IEEE802154_MAX_PAGE; i++) { 381 if (caps->channels[i]) { 382 if (nl802154_put_flags(msg, i, caps->channels[i])) 383 return -ENOBUFS; 384 } 385 } 386 387 nla_nest_end(msg, nl_channels); 388 389 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) { 390 struct nlattr *nl_ed_lvls; 391 392 nl_ed_lvls = nla_nest_start_noflag(msg, 393 NL802154_CAP_ATTR_CCA_ED_LEVELS); 394 if (!nl_ed_lvls) 395 return -ENOBUFS; 396 397 for (i = 0; i < caps->cca_ed_levels_size; i++) { 398 if (nla_put_s32(msg, i, caps->cca_ed_levels[i])) 399 return -ENOBUFS; 400 } 401 402 nla_nest_end(msg, nl_ed_lvls); 403 } 404 405 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) { 406 struct nlattr *nl_tx_pwrs; 407 408 nl_tx_pwrs = nla_nest_start_noflag(msg, 409 NL802154_CAP_ATTR_TX_POWERS); 410 if (!nl_tx_pwrs) 411 return -ENOBUFS; 412 413 for (i = 0; i < caps->tx_powers_size; i++) { 414 if (nla_put_s32(msg, i, caps->tx_powers[i])) 415 return -ENOBUFS; 416 } 417 418 nla_nest_end(msg, nl_tx_pwrs); 419 } 420 421 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) { 422 if (nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_MODES, 423 caps->cca_modes) || 424 nl802154_put_flags(msg, NL802154_CAP_ATTR_CCA_OPTS, 425 caps->cca_opts)) 426 return -ENOBUFS; 427 } 428 429 if (nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MINBE, caps->min_minbe) || 430 nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MINBE, caps->max_minbe) || 431 nla_put_u8(msg, NL802154_CAP_ATTR_MIN_MAXBE, caps->min_maxbe) || 432 nla_put_u8(msg, NL802154_CAP_ATTR_MAX_MAXBE, caps->max_maxbe) || 433 nla_put_u8(msg, NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS, 434 caps->min_csma_backoffs) || 435 nla_put_u8(msg, NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS, 436 caps->max_csma_backoffs) || 437 nla_put_s8(msg, NL802154_CAP_ATTR_MIN_FRAME_RETRIES, 438 caps->min_frame_retries) || 439 nla_put_s8(msg, NL802154_CAP_ATTR_MAX_FRAME_RETRIES, 440 caps->max_frame_retries) || 441 nl802154_put_flags(msg, NL802154_CAP_ATTR_IFTYPES, 442 caps->iftypes) || 443 nla_put_u32(msg, NL802154_CAP_ATTR_LBT, caps->lbt)) 444 return -ENOBUFS; 445 446 nla_nest_end(msg, nl_caps); 447 448 return 0; 449 } 450 451 static int nl802154_send_wpan_phy(struct cfg802154_registered_device *rdev, 452 enum nl802154_commands cmd, 453 struct sk_buff *msg, u32 portid, u32 seq, 454 int flags) 455 { 456 struct nlattr *nl_cmds; 457 void *hdr; 458 int i; 459 460 hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); 461 if (!hdr) 462 return -ENOBUFS; 463 464 if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) || 465 nla_put_string(msg, NL802154_ATTR_WPAN_PHY_NAME, 466 wpan_phy_name(&rdev->wpan_phy)) || 467 nla_put_u32(msg, NL802154_ATTR_GENERATION, 468 cfg802154_rdev_list_generation)) 469 goto nla_put_failure; 470 471 if (cmd != NL802154_CMD_NEW_WPAN_PHY) 472 goto finish; 473 474 /* DUMP PHY PIB */ 475 476 /* current channel settings */ 477 if (nla_put_u8(msg, NL802154_ATTR_PAGE, 478 rdev->wpan_phy.current_page) || 479 nla_put_u8(msg, NL802154_ATTR_CHANNEL, 480 rdev->wpan_phy.current_channel)) 481 goto nla_put_failure; 482 483 /* TODO remove this behaviour, we still keep support it for a while 484 * so users can change the behaviour to the new one. 485 */ 486 if (nl802154_send_wpan_phy_channels(rdev, msg)) 487 goto nla_put_failure; 488 489 /* cca mode */ 490 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) { 491 if (nla_put_u32(msg, NL802154_ATTR_CCA_MODE, 492 rdev->wpan_phy.cca.mode)) 493 goto nla_put_failure; 494 495 if (rdev->wpan_phy.cca.mode == NL802154_CCA_ENERGY_CARRIER) { 496 if (nla_put_u32(msg, NL802154_ATTR_CCA_OPT, 497 rdev->wpan_phy.cca.opt)) 498 goto nla_put_failure; 499 } 500 } 501 502 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) { 503 if (nla_put_s32(msg, NL802154_ATTR_TX_POWER, 504 rdev->wpan_phy.transmit_power)) 505 goto nla_put_failure; 506 } 507 508 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) { 509 if (nla_put_s32(msg, NL802154_ATTR_CCA_ED_LEVEL, 510 rdev->wpan_phy.cca_ed_level)) 511 goto nla_put_failure; 512 } 513 514 if (nl802154_put_capabilities(msg, rdev)) 515 goto nla_put_failure; 516 517 nl_cmds = nla_nest_start_noflag(msg, NL802154_ATTR_SUPPORTED_COMMANDS); 518 if (!nl_cmds) 519 goto nla_put_failure; 520 521 i = 0; 522 #define CMD(op, n) \ 523 do { \ 524 if (rdev->ops->op) { \ 525 i++; \ 526 if (nla_put_u32(msg, i, NL802154_CMD_ ## n)) \ 527 goto nla_put_failure; \ 528 } \ 529 } while (0) 530 531 CMD(add_virtual_intf, NEW_INTERFACE); 532 CMD(del_virtual_intf, DEL_INTERFACE); 533 CMD(set_channel, SET_CHANNEL); 534 CMD(set_pan_id, SET_PAN_ID); 535 CMD(set_short_addr, SET_SHORT_ADDR); 536 CMD(set_backoff_exponent, SET_BACKOFF_EXPONENT); 537 CMD(set_max_csma_backoffs, SET_MAX_CSMA_BACKOFFS); 538 CMD(set_max_frame_retries, SET_MAX_FRAME_RETRIES); 539 CMD(set_lbt_mode, SET_LBT_MODE); 540 CMD(set_ackreq_default, SET_ACKREQ_DEFAULT); 541 542 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER) 543 CMD(set_tx_power, SET_TX_POWER); 544 545 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) 546 CMD(set_cca_ed_level, SET_CCA_ED_LEVEL); 547 548 if (rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE) 549 CMD(set_cca_mode, SET_CCA_MODE); 550 551 #undef CMD 552 nla_nest_end(msg, nl_cmds); 553 554 finish: 555 genlmsg_end(msg, hdr); 556 return 0; 557 558 nla_put_failure: 559 genlmsg_cancel(msg, hdr); 560 return -EMSGSIZE; 561 } 562 563 struct nl802154_dump_wpan_phy_state { 564 s64 filter_wpan_phy; 565 long start; 566 567 }; 568 569 static int nl802154_dump_wpan_phy_parse(struct sk_buff *skb, 570 struct netlink_callback *cb, 571 struct nl802154_dump_wpan_phy_state *state) 572 { 573 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 574 struct nlattr **tb = info->info.attrs; 575 576 if (tb[NL802154_ATTR_WPAN_PHY]) 577 state->filter_wpan_phy = nla_get_u32(tb[NL802154_ATTR_WPAN_PHY]); 578 if (tb[NL802154_ATTR_WPAN_DEV]) 579 state->filter_wpan_phy = nla_get_u64(tb[NL802154_ATTR_WPAN_DEV]) >> 32; 580 if (tb[NL802154_ATTR_IFINDEX]) { 581 struct net_device *netdev; 582 struct cfg802154_registered_device *rdev; 583 int ifidx = nla_get_u32(tb[NL802154_ATTR_IFINDEX]); 584 585 netdev = __dev_get_by_index(&init_net, ifidx); 586 if (!netdev) 587 return -ENODEV; 588 if (netdev->ieee802154_ptr) { 589 rdev = wpan_phy_to_rdev( 590 netdev->ieee802154_ptr->wpan_phy); 591 state->filter_wpan_phy = rdev->wpan_phy_idx; 592 } 593 } 594 595 return 0; 596 } 597 598 static int 599 nl802154_dump_wpan_phy(struct sk_buff *skb, struct netlink_callback *cb) 600 { 601 int idx = 0, ret; 602 struct nl802154_dump_wpan_phy_state *state = (void *)cb->args[0]; 603 struct cfg802154_registered_device *rdev; 604 605 rtnl_lock(); 606 if (!state) { 607 state = kzalloc(sizeof(*state), GFP_KERNEL); 608 if (!state) { 609 rtnl_unlock(); 610 return -ENOMEM; 611 } 612 state->filter_wpan_phy = -1; 613 ret = nl802154_dump_wpan_phy_parse(skb, cb, state); 614 if (ret) { 615 kfree(state); 616 rtnl_unlock(); 617 return ret; 618 } 619 cb->args[0] = (long)state; 620 } 621 622 list_for_each_entry(rdev, &cfg802154_rdev_list, list) { 623 if (!net_eq(wpan_phy_net(&rdev->wpan_phy), sock_net(skb->sk))) 624 continue; 625 if (++idx <= state->start) 626 continue; 627 if (state->filter_wpan_phy != -1 && 628 state->filter_wpan_phy != rdev->wpan_phy_idx) 629 continue; 630 /* attempt to fit multiple wpan_phy data chunks into the skb */ 631 ret = nl802154_send_wpan_phy(rdev, 632 NL802154_CMD_NEW_WPAN_PHY, 633 skb, 634 NETLINK_CB(cb->skb).portid, 635 cb->nlh->nlmsg_seq, NLM_F_MULTI); 636 if (ret < 0) { 637 if ((ret == -ENOBUFS || ret == -EMSGSIZE) && 638 !skb->len && cb->min_dump_alloc < 4096) { 639 cb->min_dump_alloc = 4096; 640 rtnl_unlock(); 641 return 1; 642 } 643 idx--; 644 break; 645 } 646 break; 647 } 648 rtnl_unlock(); 649 650 state->start = idx; 651 652 return skb->len; 653 } 654 655 static int nl802154_dump_wpan_phy_done(struct netlink_callback *cb) 656 { 657 kfree((void *)cb->args[0]); 658 return 0; 659 } 660 661 static int nl802154_get_wpan_phy(struct sk_buff *skb, struct genl_info *info) 662 { 663 struct sk_buff *msg; 664 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 665 666 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 667 if (!msg) 668 return -ENOMEM; 669 670 if (nl802154_send_wpan_phy(rdev, NL802154_CMD_NEW_WPAN_PHY, msg, 671 info->snd_portid, info->snd_seq, 0) < 0) { 672 nlmsg_free(msg); 673 return -ENOBUFS; 674 } 675 676 return genlmsg_reply(msg, info); 677 } 678 679 static inline u64 wpan_dev_id(struct wpan_dev *wpan_dev) 680 { 681 return (u64)wpan_dev->identifier | 682 ((u64)wpan_phy_to_rdev(wpan_dev->wpan_phy)->wpan_phy_idx << 32); 683 } 684 685 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL 686 #include <net/ieee802154_netdev.h> 687 688 static int 689 ieee802154_llsec_send_key_id(struct sk_buff *msg, 690 const struct ieee802154_llsec_key_id *desc) 691 { 692 struct nlattr *nl_dev_addr; 693 694 if (nla_put_u32(msg, NL802154_KEY_ID_ATTR_MODE, desc->mode)) 695 return -ENOBUFS; 696 697 switch (desc->mode) { 698 case NL802154_KEY_ID_MODE_IMPLICIT: 699 nl_dev_addr = nla_nest_start_noflag(msg, 700 NL802154_KEY_ID_ATTR_IMPLICIT); 701 if (!nl_dev_addr) 702 return -ENOBUFS; 703 704 if (nla_put_le16(msg, NL802154_DEV_ADDR_ATTR_PAN_ID, 705 desc->device_addr.pan_id) || 706 nla_put_u32(msg, NL802154_DEV_ADDR_ATTR_MODE, 707 desc->device_addr.mode)) 708 return -ENOBUFS; 709 710 switch (desc->device_addr.mode) { 711 case NL802154_DEV_ADDR_SHORT: 712 if (nla_put_le16(msg, NL802154_DEV_ADDR_ATTR_SHORT, 713 desc->device_addr.short_addr)) 714 return -ENOBUFS; 715 break; 716 case NL802154_DEV_ADDR_EXTENDED: 717 if (nla_put_le64(msg, NL802154_DEV_ADDR_ATTR_EXTENDED, 718 desc->device_addr.extended_addr, 719 NL802154_DEV_ADDR_ATTR_PAD)) 720 return -ENOBUFS; 721 break; 722 default: 723 /* userspace should handle unknown */ 724 break; 725 } 726 727 nla_nest_end(msg, nl_dev_addr); 728 break; 729 case NL802154_KEY_ID_MODE_INDEX: 730 break; 731 case NL802154_KEY_ID_MODE_INDEX_SHORT: 732 /* TODO renmae short_source? */ 733 if (nla_put_le32(msg, NL802154_KEY_ID_ATTR_SOURCE_SHORT, 734 desc->short_source)) 735 return -ENOBUFS; 736 break; 737 case NL802154_KEY_ID_MODE_INDEX_EXTENDED: 738 if (nla_put_le64(msg, NL802154_KEY_ID_ATTR_SOURCE_EXTENDED, 739 desc->extended_source, 740 NL802154_KEY_ID_ATTR_PAD)) 741 return -ENOBUFS; 742 break; 743 default: 744 /* userspace should handle unknown */ 745 break; 746 } 747 748 /* TODO key_id to key_idx ? Check naming */ 749 if (desc->mode != NL802154_KEY_ID_MODE_IMPLICIT) { 750 if (nla_put_u8(msg, NL802154_KEY_ID_ATTR_INDEX, desc->id)) 751 return -ENOBUFS; 752 } 753 754 return 0; 755 } 756 757 static int nl802154_get_llsec_params(struct sk_buff *msg, 758 struct cfg802154_registered_device *rdev, 759 struct wpan_dev *wpan_dev) 760 { 761 struct nlattr *nl_key_id; 762 struct ieee802154_llsec_params params; 763 int ret; 764 765 ret = rdev_get_llsec_params(rdev, wpan_dev, ¶ms); 766 if (ret < 0) 767 return ret; 768 769 if (nla_put_u8(msg, NL802154_ATTR_SEC_ENABLED, params.enabled) || 770 nla_put_u32(msg, NL802154_ATTR_SEC_OUT_LEVEL, params.out_level) || 771 nla_put_be32(msg, NL802154_ATTR_SEC_FRAME_COUNTER, 772 params.frame_counter)) 773 return -ENOBUFS; 774 775 nl_key_id = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_OUT_KEY_ID); 776 if (!nl_key_id) 777 return -ENOBUFS; 778 779 ret = ieee802154_llsec_send_key_id(msg, ¶ms.out_key); 780 if (ret < 0) 781 return ret; 782 783 nla_nest_end(msg, nl_key_id); 784 785 return 0; 786 } 787 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ 788 789 static int 790 nl802154_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, 791 struct cfg802154_registered_device *rdev, 792 struct wpan_dev *wpan_dev) 793 { 794 struct net_device *dev = wpan_dev->netdev; 795 void *hdr; 796 797 hdr = nl802154hdr_put(msg, portid, seq, flags, 798 NL802154_CMD_NEW_INTERFACE); 799 if (!hdr) 800 return -1; 801 802 if (dev && 803 (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex) || 804 nla_put_string(msg, NL802154_ATTR_IFNAME, dev->name))) 805 goto nla_put_failure; 806 807 if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx) || 808 nla_put_u32(msg, NL802154_ATTR_IFTYPE, wpan_dev->iftype) || 809 nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV, 810 wpan_dev_id(wpan_dev), NL802154_ATTR_PAD) || 811 nla_put_u32(msg, NL802154_ATTR_GENERATION, 812 rdev->devlist_generation ^ 813 (cfg802154_rdev_list_generation << 2))) 814 goto nla_put_failure; 815 816 /* address settings */ 817 if (nla_put_le64(msg, NL802154_ATTR_EXTENDED_ADDR, 818 wpan_dev->extended_addr, 819 NL802154_ATTR_PAD) || 820 nla_put_le16(msg, NL802154_ATTR_SHORT_ADDR, 821 wpan_dev->short_addr) || 822 nla_put_le16(msg, NL802154_ATTR_PAN_ID, wpan_dev->pan_id)) 823 goto nla_put_failure; 824 825 /* ARET handling */ 826 if (nla_put_s8(msg, NL802154_ATTR_MAX_FRAME_RETRIES, 827 wpan_dev->frame_retries) || 828 nla_put_u8(msg, NL802154_ATTR_MAX_BE, wpan_dev->max_be) || 829 nla_put_u8(msg, NL802154_ATTR_MAX_CSMA_BACKOFFS, 830 wpan_dev->csma_retries) || 831 nla_put_u8(msg, NL802154_ATTR_MIN_BE, wpan_dev->min_be)) 832 goto nla_put_failure; 833 834 /* listen before transmit */ 835 if (nla_put_u8(msg, NL802154_ATTR_LBT_MODE, wpan_dev->lbt)) 836 goto nla_put_failure; 837 838 /* ackreq default behaviour */ 839 if (nla_put_u8(msg, NL802154_ATTR_ACKREQ_DEFAULT, wpan_dev->ackreq)) 840 goto nla_put_failure; 841 842 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL 843 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 844 goto out; 845 846 if (nl802154_get_llsec_params(msg, rdev, wpan_dev) < 0) 847 goto nla_put_failure; 848 849 out: 850 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ 851 852 genlmsg_end(msg, hdr); 853 return 0; 854 855 nla_put_failure: 856 genlmsg_cancel(msg, hdr); 857 return -EMSGSIZE; 858 } 859 860 static int 861 nl802154_dump_interface(struct sk_buff *skb, struct netlink_callback *cb) 862 { 863 int wp_idx = 0; 864 int if_idx = 0; 865 int wp_start = cb->args[0]; 866 int if_start = cb->args[1]; 867 struct cfg802154_registered_device *rdev; 868 struct wpan_dev *wpan_dev; 869 870 rtnl_lock(); 871 list_for_each_entry(rdev, &cfg802154_rdev_list, list) { 872 if (!net_eq(wpan_phy_net(&rdev->wpan_phy), sock_net(skb->sk))) 873 continue; 874 if (wp_idx < wp_start) { 875 wp_idx++; 876 continue; 877 } 878 if_idx = 0; 879 880 list_for_each_entry(wpan_dev, &rdev->wpan_dev_list, list) { 881 if (if_idx < if_start) { 882 if_idx++; 883 continue; 884 } 885 if (nl802154_send_iface(skb, NETLINK_CB(cb->skb).portid, 886 cb->nlh->nlmsg_seq, NLM_F_MULTI, 887 rdev, wpan_dev) < 0) { 888 goto out; 889 } 890 if_idx++; 891 } 892 893 wp_idx++; 894 } 895 out: 896 rtnl_unlock(); 897 898 cb->args[0] = wp_idx; 899 cb->args[1] = if_idx; 900 901 return skb->len; 902 } 903 904 static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info) 905 { 906 struct sk_buff *msg; 907 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 908 struct wpan_dev *wdev = info->user_ptr[1]; 909 910 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 911 if (!msg) 912 return -ENOMEM; 913 914 if (nl802154_send_iface(msg, info->snd_portid, info->snd_seq, 0, 915 rdev, wdev) < 0) { 916 nlmsg_free(msg); 917 return -ENOBUFS; 918 } 919 920 return genlmsg_reply(msg, info); 921 } 922 923 static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info) 924 { 925 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 926 enum nl802154_iftype type = NL802154_IFTYPE_UNSPEC; 927 __le64 extended_addr = cpu_to_le64(0x0000000000000000ULL); 928 929 /* TODO avoid failing a new interface 930 * creation due to pending removal? 931 */ 932 933 if (!info->attrs[NL802154_ATTR_IFNAME]) 934 return -EINVAL; 935 936 if (info->attrs[NL802154_ATTR_IFTYPE]) { 937 type = nla_get_u32(info->attrs[NL802154_ATTR_IFTYPE]); 938 if (type > NL802154_IFTYPE_MAX || 939 !(rdev->wpan_phy.supported.iftypes & BIT(type))) 940 return -EINVAL; 941 } 942 943 if (info->attrs[NL802154_ATTR_EXTENDED_ADDR]) 944 extended_addr = nla_get_le64(info->attrs[NL802154_ATTR_EXTENDED_ADDR]); 945 946 if (!rdev->ops->add_virtual_intf) 947 return -EOPNOTSUPP; 948 949 return rdev_add_virtual_intf(rdev, 950 nla_data(info->attrs[NL802154_ATTR_IFNAME]), 951 NET_NAME_USER, type, extended_addr); 952 } 953 954 static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info) 955 { 956 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 957 struct wpan_dev *wpan_dev = info->user_ptr[1]; 958 959 if (!rdev->ops->del_virtual_intf) 960 return -EOPNOTSUPP; 961 962 /* If we remove a wpan device without a netdev then clear 963 * user_ptr[1] so that nl802154_post_doit won't dereference it 964 * to check if it needs to do dev_put(). Otherwise it crashes 965 * since the wpan_dev has been freed, unlike with a netdev where 966 * we need the dev_put() for the netdev to really be freed. 967 */ 968 if (!wpan_dev->netdev) 969 info->user_ptr[1] = NULL; 970 971 return rdev_del_virtual_intf(rdev, wpan_dev); 972 } 973 974 static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info) 975 { 976 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 977 u8 channel, page; 978 979 if (!info->attrs[NL802154_ATTR_PAGE] || 980 !info->attrs[NL802154_ATTR_CHANNEL]) 981 return -EINVAL; 982 983 page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]); 984 channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]); 985 986 /* check 802.15.4 constraints */ 987 if (!ieee802154_chan_is_valid(&rdev->wpan_phy, page, channel)) 988 return -EINVAL; 989 990 return rdev_set_channel(rdev, page, channel); 991 } 992 993 static int nl802154_set_cca_mode(struct sk_buff *skb, struct genl_info *info) 994 { 995 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 996 struct wpan_phy_cca cca; 997 998 if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_MODE)) 999 return -EOPNOTSUPP; 1000 1001 if (!info->attrs[NL802154_ATTR_CCA_MODE]) 1002 return -EINVAL; 1003 1004 cca.mode = nla_get_u32(info->attrs[NL802154_ATTR_CCA_MODE]); 1005 /* checking 802.15.4 constraints */ 1006 if (cca.mode < NL802154_CCA_ENERGY || 1007 cca.mode > NL802154_CCA_ATTR_MAX || 1008 !(rdev->wpan_phy.supported.cca_modes & BIT(cca.mode))) 1009 return -EINVAL; 1010 1011 if (cca.mode == NL802154_CCA_ENERGY_CARRIER) { 1012 if (!info->attrs[NL802154_ATTR_CCA_OPT]) 1013 return -EINVAL; 1014 1015 cca.opt = nla_get_u32(info->attrs[NL802154_ATTR_CCA_OPT]); 1016 if (cca.opt > NL802154_CCA_OPT_ATTR_MAX || 1017 !(rdev->wpan_phy.supported.cca_opts & BIT(cca.opt))) 1018 return -EINVAL; 1019 } 1020 1021 return rdev_set_cca_mode(rdev, &cca); 1022 } 1023 1024 static int nl802154_set_cca_ed_level(struct sk_buff *skb, struct genl_info *info) 1025 { 1026 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1027 s32 ed_level; 1028 int i; 1029 1030 if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_CCA_ED_LEVEL)) 1031 return -EOPNOTSUPP; 1032 1033 if (!info->attrs[NL802154_ATTR_CCA_ED_LEVEL]) 1034 return -EINVAL; 1035 1036 ed_level = nla_get_s32(info->attrs[NL802154_ATTR_CCA_ED_LEVEL]); 1037 1038 for (i = 0; i < rdev->wpan_phy.supported.cca_ed_levels_size; i++) { 1039 if (ed_level == rdev->wpan_phy.supported.cca_ed_levels[i]) 1040 return rdev_set_cca_ed_level(rdev, ed_level); 1041 } 1042 1043 return -EINVAL; 1044 } 1045 1046 static int nl802154_set_tx_power(struct sk_buff *skb, struct genl_info *info) 1047 { 1048 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1049 s32 power; 1050 int i; 1051 1052 if (!(rdev->wpan_phy.flags & WPAN_PHY_FLAG_TXPOWER)) 1053 return -EOPNOTSUPP; 1054 1055 if (!info->attrs[NL802154_ATTR_TX_POWER]) 1056 return -EINVAL; 1057 1058 power = nla_get_s32(info->attrs[NL802154_ATTR_TX_POWER]); 1059 1060 for (i = 0; i < rdev->wpan_phy.supported.tx_powers_size; i++) { 1061 if (power == rdev->wpan_phy.supported.tx_powers[i]) 1062 return rdev_set_tx_power(rdev, power); 1063 } 1064 1065 return -EINVAL; 1066 } 1067 1068 static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info) 1069 { 1070 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1071 struct net_device *dev = info->user_ptr[1]; 1072 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1073 __le16 pan_id; 1074 1075 /* conflict here while tx/rx calls */ 1076 if (netif_running(dev)) 1077 return -EBUSY; 1078 1079 if (wpan_dev->lowpan_dev) { 1080 if (netif_running(wpan_dev->lowpan_dev)) 1081 return -EBUSY; 1082 } 1083 1084 /* don't change address fields on monitor */ 1085 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR || 1086 !info->attrs[NL802154_ATTR_PAN_ID]) 1087 return -EINVAL; 1088 1089 pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]); 1090 1091 return rdev_set_pan_id(rdev, wpan_dev, pan_id); 1092 } 1093 1094 static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info) 1095 { 1096 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1097 struct net_device *dev = info->user_ptr[1]; 1098 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1099 __le16 short_addr; 1100 1101 /* conflict here while tx/rx calls */ 1102 if (netif_running(dev)) 1103 return -EBUSY; 1104 1105 if (wpan_dev->lowpan_dev) { 1106 if (netif_running(wpan_dev->lowpan_dev)) 1107 return -EBUSY; 1108 } 1109 1110 /* don't change address fields on monitor */ 1111 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR || 1112 !info->attrs[NL802154_ATTR_SHORT_ADDR]) 1113 return -EINVAL; 1114 1115 short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]); 1116 1117 /* TODO 1118 * I am not sure about to check here on broadcast short_addr. 1119 * Broadcast is a valid setting, comment from 802.15.4: 1120 * A value of 0xfffe indicates that the device has 1121 * associated but has not been allocated an address. A 1122 * value of 0xffff indicates that the device does not 1123 * have a short address. 1124 * 1125 * I think we should allow to set these settings but 1126 * don't allow to allow socket communication with it. 1127 */ 1128 if (short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC) || 1129 short_addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST)) 1130 return -EINVAL; 1131 1132 return rdev_set_short_addr(rdev, wpan_dev, short_addr); 1133 } 1134 1135 static int 1136 nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info) 1137 { 1138 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1139 struct net_device *dev = info->user_ptr[1]; 1140 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1141 u8 min_be, max_be; 1142 1143 /* should be set on netif open inside phy settings */ 1144 if (netif_running(dev)) 1145 return -EBUSY; 1146 1147 if (!info->attrs[NL802154_ATTR_MIN_BE] || 1148 !info->attrs[NL802154_ATTR_MAX_BE]) 1149 return -EINVAL; 1150 1151 min_be = nla_get_u8(info->attrs[NL802154_ATTR_MIN_BE]); 1152 max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]); 1153 1154 /* check 802.15.4 constraints */ 1155 if (min_be < rdev->wpan_phy.supported.min_minbe || 1156 min_be > rdev->wpan_phy.supported.max_minbe || 1157 max_be < rdev->wpan_phy.supported.min_maxbe || 1158 max_be > rdev->wpan_phy.supported.max_maxbe || 1159 min_be > max_be) 1160 return -EINVAL; 1161 1162 return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be); 1163 } 1164 1165 static int 1166 nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info) 1167 { 1168 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1169 struct net_device *dev = info->user_ptr[1]; 1170 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1171 u8 max_csma_backoffs; 1172 1173 /* conflict here while other running iface settings */ 1174 if (netif_running(dev)) 1175 return -EBUSY; 1176 1177 if (!info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]) 1178 return -EINVAL; 1179 1180 max_csma_backoffs = nla_get_u8( 1181 info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]); 1182 1183 /* check 802.15.4 constraints */ 1184 if (max_csma_backoffs < rdev->wpan_phy.supported.min_csma_backoffs || 1185 max_csma_backoffs > rdev->wpan_phy.supported.max_csma_backoffs) 1186 return -EINVAL; 1187 1188 return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs); 1189 } 1190 1191 static int 1192 nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info) 1193 { 1194 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1195 struct net_device *dev = info->user_ptr[1]; 1196 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1197 s8 max_frame_retries; 1198 1199 if (netif_running(dev)) 1200 return -EBUSY; 1201 1202 if (!info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]) 1203 return -EINVAL; 1204 1205 max_frame_retries = nla_get_s8( 1206 info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]); 1207 1208 /* check 802.15.4 constraints */ 1209 if (max_frame_retries < rdev->wpan_phy.supported.min_frame_retries || 1210 max_frame_retries > rdev->wpan_phy.supported.max_frame_retries) 1211 return -EINVAL; 1212 1213 return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries); 1214 } 1215 1216 static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info) 1217 { 1218 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1219 struct net_device *dev = info->user_ptr[1]; 1220 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1221 int mode; 1222 1223 if (netif_running(dev)) 1224 return -EBUSY; 1225 1226 if (!info->attrs[NL802154_ATTR_LBT_MODE]) 1227 return -EINVAL; 1228 1229 mode = nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]); 1230 1231 if (mode != 0 && mode != 1) 1232 return -EINVAL; 1233 1234 if (!wpan_phy_supported_bool(mode, rdev->wpan_phy.supported.lbt)) 1235 return -EINVAL; 1236 1237 return rdev_set_lbt_mode(rdev, wpan_dev, mode); 1238 } 1239 1240 static int 1241 nl802154_set_ackreq_default(struct sk_buff *skb, struct genl_info *info) 1242 { 1243 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1244 struct net_device *dev = info->user_ptr[1]; 1245 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1246 int ackreq; 1247 1248 if (netif_running(dev)) 1249 return -EBUSY; 1250 1251 if (!info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]) 1252 return -EINVAL; 1253 1254 ackreq = nla_get_u8(info->attrs[NL802154_ATTR_ACKREQ_DEFAULT]); 1255 1256 if (ackreq != 0 && ackreq != 1) 1257 return -EINVAL; 1258 1259 return rdev_set_ackreq_default(rdev, wpan_dev, ackreq); 1260 } 1261 1262 static int nl802154_wpan_phy_netns(struct sk_buff *skb, struct genl_info *info) 1263 { 1264 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1265 struct net *net; 1266 int err; 1267 1268 if (info->attrs[NL802154_ATTR_PID]) { 1269 u32 pid = nla_get_u32(info->attrs[NL802154_ATTR_PID]); 1270 1271 net = get_net_ns_by_pid(pid); 1272 } else if (info->attrs[NL802154_ATTR_NETNS_FD]) { 1273 u32 fd = nla_get_u32(info->attrs[NL802154_ATTR_NETNS_FD]); 1274 1275 net = get_net_ns_by_fd(fd); 1276 } else { 1277 return -EINVAL; 1278 } 1279 1280 if (IS_ERR(net)) 1281 return PTR_ERR(net); 1282 1283 err = 0; 1284 1285 /* check if anything to do */ 1286 if (!net_eq(wpan_phy_net(&rdev->wpan_phy), net)) 1287 err = cfg802154_switch_netns(rdev, net); 1288 1289 put_net(net); 1290 return err; 1291 } 1292 1293 static int nl802154_prep_scan_event_msg(struct sk_buff *msg, 1294 struct cfg802154_registered_device *rdev, 1295 struct wpan_dev *wpan_dev, 1296 u32 portid, u32 seq, int flags, u8 cmd, 1297 struct ieee802154_coord_desc *desc) 1298 { 1299 struct nlattr *nla; 1300 void *hdr; 1301 1302 hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); 1303 if (!hdr) 1304 return -ENOBUFS; 1305 1306 if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx)) 1307 goto nla_put_failure; 1308 1309 if (wpan_dev->netdev && 1310 nla_put_u32(msg, NL802154_ATTR_IFINDEX, wpan_dev->netdev->ifindex)) 1311 goto nla_put_failure; 1312 1313 if (nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV, 1314 wpan_dev_id(wpan_dev), NL802154_ATTR_PAD)) 1315 goto nla_put_failure; 1316 1317 nla = nla_nest_start_noflag(msg, NL802154_ATTR_COORDINATOR); 1318 if (!nla) 1319 goto nla_put_failure; 1320 1321 if (nla_put(msg, NL802154_COORD_PANID, IEEE802154_PAN_ID_LEN, 1322 &desc->addr.pan_id)) 1323 goto nla_put_failure; 1324 1325 if (desc->addr.mode == IEEE802154_ADDR_SHORT) { 1326 if (nla_put(msg, NL802154_COORD_ADDR, 1327 IEEE802154_SHORT_ADDR_LEN, 1328 &desc->addr.short_addr)) 1329 goto nla_put_failure; 1330 } else { 1331 if (nla_put(msg, NL802154_COORD_ADDR, 1332 IEEE802154_EXTENDED_ADDR_LEN, 1333 &desc->addr.extended_addr)) 1334 goto nla_put_failure; 1335 } 1336 1337 if (nla_put_u8(msg, NL802154_COORD_CHANNEL, desc->channel)) 1338 goto nla_put_failure; 1339 1340 if (nla_put_u8(msg, NL802154_COORD_PAGE, desc->page)) 1341 goto nla_put_failure; 1342 1343 if (nla_put_u16(msg, NL802154_COORD_SUPERFRAME_SPEC, 1344 desc->superframe_spec)) 1345 goto nla_put_failure; 1346 1347 if (nla_put_u8(msg, NL802154_COORD_LINK_QUALITY, desc->link_quality)) 1348 goto nla_put_failure; 1349 1350 if (desc->gts_permit && nla_put_flag(msg, NL802154_COORD_GTS_PERMIT)) 1351 goto nla_put_failure; 1352 1353 /* TODO: NL802154_COORD_PAYLOAD_DATA if any */ 1354 1355 nla_nest_end(msg, nla); 1356 1357 genlmsg_end(msg, hdr); 1358 1359 return 0; 1360 1361 nla_put_failure: 1362 genlmsg_cancel(msg, hdr); 1363 1364 return -EMSGSIZE; 1365 } 1366 1367 int nl802154_scan_event(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, 1368 struct ieee802154_coord_desc *desc) 1369 { 1370 struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(wpan_phy); 1371 struct sk_buff *msg; 1372 int ret; 1373 1374 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 1375 if (!msg) 1376 return -ENOMEM; 1377 1378 ret = nl802154_prep_scan_event_msg(msg, rdev, wpan_dev, 0, 0, 0, 1379 NL802154_CMD_SCAN_EVENT, 1380 desc); 1381 if (ret < 0) { 1382 nlmsg_free(msg); 1383 return ret; 1384 } 1385 1386 return genlmsg_multicast_netns(&nl802154_fam, wpan_phy_net(wpan_phy), 1387 msg, 0, NL802154_MCGRP_SCAN, GFP_ATOMIC); 1388 } 1389 EXPORT_SYMBOL_GPL(nl802154_scan_event); 1390 1391 static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info) 1392 { 1393 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1394 struct net_device *dev = info->user_ptr[1]; 1395 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1396 struct wpan_phy *wpan_phy = &rdev->wpan_phy; 1397 struct cfg802154_scan_request *request; 1398 u8 type; 1399 int err; 1400 1401 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) { 1402 NL_SET_ERR_MSG(info->extack, "Monitors are not allowed to perform scans"); 1403 return -EOPNOTSUPP; 1404 } 1405 1406 if (!info->attrs[NL802154_ATTR_SCAN_TYPE]) { 1407 NL_SET_ERR_MSG(info->extack, "Malformed request, missing scan type"); 1408 return -EINVAL; 1409 } 1410 1411 if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) { 1412 NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams"); 1413 return -EOPNOTSUPP; 1414 } 1415 1416 request = kzalloc(sizeof(*request), GFP_KERNEL); 1417 if (!request) 1418 return -ENOMEM; 1419 1420 request->wpan_dev = wpan_dev; 1421 request->wpan_phy = wpan_phy; 1422 1423 type = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_TYPE]); 1424 switch (type) { 1425 case NL802154_SCAN_ACTIVE: 1426 case NL802154_SCAN_PASSIVE: 1427 request->type = type; 1428 break; 1429 default: 1430 NL_SET_ERR_MSG_FMT(info->extack, "Unsupported scan type: %d", type); 1431 err = -EINVAL; 1432 goto free_request; 1433 } 1434 1435 /* Use current page by default */ 1436 if (info->attrs[NL802154_ATTR_PAGE]) 1437 request->page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]); 1438 else 1439 request->page = wpan_phy->current_page; 1440 1441 /* Scan all supported channels by default */ 1442 if (info->attrs[NL802154_ATTR_SCAN_CHANNELS]) 1443 request->channels = nla_get_u32(info->attrs[NL802154_ATTR_SCAN_CHANNELS]); 1444 else 1445 request->channels = wpan_phy->supported.channels[request->page]; 1446 1447 /* Use maximum duration order by default */ 1448 if (info->attrs[NL802154_ATTR_SCAN_DURATION]) 1449 request->duration = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_DURATION]); 1450 else 1451 request->duration = IEEE802154_MAX_SCAN_DURATION; 1452 1453 err = rdev_trigger_scan(rdev, request); 1454 if (err) { 1455 pr_err("Failure starting scanning (%d)\n", err); 1456 goto free_request; 1457 } 1458 1459 return 0; 1460 1461 free_request: 1462 kfree(request); 1463 1464 return err; 1465 } 1466 1467 static int nl802154_prep_scan_msg(struct sk_buff *msg, 1468 struct cfg802154_registered_device *rdev, 1469 struct wpan_dev *wpan_dev, u32 portid, 1470 u32 seq, int flags, u8 cmd, u8 arg) 1471 { 1472 void *hdr; 1473 1474 hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); 1475 if (!hdr) 1476 return -ENOBUFS; 1477 1478 if (nla_put_u32(msg, NL802154_ATTR_WPAN_PHY, rdev->wpan_phy_idx)) 1479 goto nla_put_failure; 1480 1481 if (wpan_dev->netdev && 1482 nla_put_u32(msg, NL802154_ATTR_IFINDEX, wpan_dev->netdev->ifindex)) 1483 goto nla_put_failure; 1484 1485 if (nla_put_u64_64bit(msg, NL802154_ATTR_WPAN_DEV, 1486 wpan_dev_id(wpan_dev), NL802154_ATTR_PAD)) 1487 goto nla_put_failure; 1488 1489 if (cmd == NL802154_CMD_SCAN_DONE && 1490 nla_put_u8(msg, NL802154_ATTR_SCAN_DONE_REASON, arg)) 1491 goto nla_put_failure; 1492 1493 genlmsg_end(msg, hdr); 1494 1495 return 0; 1496 1497 nla_put_failure: 1498 genlmsg_cancel(msg, hdr); 1499 1500 return -EMSGSIZE; 1501 } 1502 1503 static int nl802154_send_scan_msg(struct cfg802154_registered_device *rdev, 1504 struct wpan_dev *wpan_dev, u8 cmd, u8 arg) 1505 { 1506 struct sk_buff *msg; 1507 int ret; 1508 1509 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1510 if (!msg) 1511 return -ENOMEM; 1512 1513 ret = nl802154_prep_scan_msg(msg, rdev, wpan_dev, 0, 0, 0, cmd, arg); 1514 if (ret < 0) { 1515 nlmsg_free(msg); 1516 return ret; 1517 } 1518 1519 return genlmsg_multicast_netns(&nl802154_fam, 1520 wpan_phy_net(&rdev->wpan_phy), msg, 0, 1521 NL802154_MCGRP_SCAN, GFP_KERNEL); 1522 } 1523 1524 int nl802154_scan_started(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev) 1525 { 1526 struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(wpan_phy); 1527 int err; 1528 1529 /* Ignore errors when there are no listeners */ 1530 err = nl802154_send_scan_msg(rdev, wpan_dev, NL802154_CMD_TRIGGER_SCAN, 0); 1531 if (err == -ESRCH) 1532 err = 0; 1533 1534 return err; 1535 } 1536 EXPORT_SYMBOL_GPL(nl802154_scan_started); 1537 1538 int nl802154_scan_done(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, 1539 enum nl802154_scan_done_reasons reason) 1540 { 1541 struct cfg802154_registered_device *rdev = wpan_phy_to_rdev(wpan_phy); 1542 int err; 1543 1544 /* Ignore errors when there are no listeners */ 1545 err = nl802154_send_scan_msg(rdev, wpan_dev, NL802154_CMD_SCAN_DONE, reason); 1546 if (err == -ESRCH) 1547 err = 0; 1548 1549 return err; 1550 } 1551 EXPORT_SYMBOL_GPL(nl802154_scan_done); 1552 1553 static int nl802154_abort_scan(struct sk_buff *skb, struct genl_info *info) 1554 { 1555 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1556 struct net_device *dev = info->user_ptr[1]; 1557 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1558 1559 /* Resources are released in the notification helper above */ 1560 return rdev_abort_scan(rdev, wpan_dev); 1561 } 1562 1563 static int 1564 nl802154_send_beacons(struct sk_buff *skb, struct genl_info *info) 1565 { 1566 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1567 struct net_device *dev = info->user_ptr[1]; 1568 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1569 struct wpan_phy *wpan_phy = &rdev->wpan_phy; 1570 struct cfg802154_beacon_request *request; 1571 int err; 1572 1573 if (wpan_dev->iftype != NL802154_IFTYPE_COORD) { 1574 NL_SET_ERR_MSG(info->extack, "Only coordinators can send beacons"); 1575 return -EOPNOTSUPP; 1576 } 1577 1578 if (wpan_dev->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { 1579 NL_SET_ERR_MSG(info->extack, "Device is not part of any PAN"); 1580 return -EPERM; 1581 } 1582 1583 if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) { 1584 NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams"); 1585 return -EOPNOTSUPP; 1586 } 1587 1588 request = kzalloc(sizeof(*request), GFP_KERNEL); 1589 if (!request) 1590 return -ENOMEM; 1591 1592 request->wpan_dev = wpan_dev; 1593 request->wpan_phy = wpan_phy; 1594 1595 /* Use maximum duration order by default */ 1596 if (info->attrs[NL802154_ATTR_BEACON_INTERVAL]) 1597 request->interval = nla_get_u8(info->attrs[NL802154_ATTR_BEACON_INTERVAL]); 1598 else 1599 request->interval = IEEE802154_MAX_SCAN_DURATION; 1600 1601 err = rdev_send_beacons(rdev, request); 1602 if (err) { 1603 pr_err("Failure starting sending beacons (%d)\n", err); 1604 goto free_request; 1605 } 1606 1607 return 0; 1608 1609 free_request: 1610 kfree(request); 1611 1612 return err; 1613 } 1614 1615 void nl802154_beaconing_done(struct wpan_dev *wpan_dev) 1616 { 1617 /* NOP */ 1618 } 1619 EXPORT_SYMBOL_GPL(nl802154_beaconing_done); 1620 1621 static int 1622 nl802154_stop_beacons(struct sk_buff *skb, struct genl_info *info) 1623 { 1624 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1625 struct net_device *dev = info->user_ptr[1]; 1626 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1627 1628 /* Resources are released in the notification helper above */ 1629 return rdev_stop_beacons(rdev, wpan_dev); 1630 } 1631 1632 static int nl802154_associate(struct sk_buff *skb, struct genl_info *info) 1633 { 1634 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1635 struct net_device *dev = info->user_ptr[1]; 1636 struct wpan_dev *wpan_dev; 1637 struct wpan_phy *wpan_phy; 1638 struct ieee802154_addr coord; 1639 int err; 1640 1641 wpan_dev = dev->ieee802154_ptr; 1642 wpan_phy = &rdev->wpan_phy; 1643 1644 if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) { 1645 NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams"); 1646 return -EOPNOTSUPP; 1647 } 1648 1649 if (!info->attrs[NL802154_ATTR_PAN_ID] || 1650 !info->attrs[NL802154_ATTR_EXTENDED_ADDR]) 1651 return -EINVAL; 1652 1653 coord.pan_id = nla_get_le16(info->attrs[NL802154_ATTR_PAN_ID]); 1654 coord.mode = IEEE802154_ADDR_LONG; 1655 coord.extended_addr = nla_get_le64(info->attrs[NL802154_ATTR_EXTENDED_ADDR]); 1656 1657 mutex_lock(&wpan_dev->association_lock); 1658 err = rdev_associate(rdev, wpan_dev, &coord); 1659 mutex_unlock(&wpan_dev->association_lock); 1660 if (err) 1661 pr_err("Association with PAN ID 0x%x failed (%d)\n", 1662 le16_to_cpu(coord.pan_id), err); 1663 1664 return err; 1665 } 1666 1667 static int nl802154_disassociate(struct sk_buff *skb, struct genl_info *info) 1668 { 1669 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1670 struct net_device *dev = info->user_ptr[1]; 1671 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1672 struct wpan_phy *wpan_phy = &rdev->wpan_phy; 1673 struct ieee802154_addr target; 1674 1675 if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) { 1676 NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams"); 1677 return -EOPNOTSUPP; 1678 } 1679 1680 target.pan_id = wpan_dev->pan_id; 1681 1682 if (info->attrs[NL802154_ATTR_EXTENDED_ADDR]) { 1683 target.mode = IEEE802154_ADDR_LONG; 1684 target.extended_addr = nla_get_le64(info->attrs[NL802154_ATTR_EXTENDED_ADDR]); 1685 } else if (info->attrs[NL802154_ATTR_SHORT_ADDR]) { 1686 target.mode = IEEE802154_ADDR_SHORT; 1687 target.short_addr = nla_get_le16(info->attrs[NL802154_ATTR_SHORT_ADDR]); 1688 } else { 1689 NL_SET_ERR_MSG(info->extack, "Device address is missing"); 1690 return -EINVAL; 1691 } 1692 1693 mutex_lock(&wpan_dev->association_lock); 1694 rdev_disassociate(rdev, wpan_dev, &target); 1695 mutex_unlock(&wpan_dev->association_lock); 1696 1697 return 0; 1698 } 1699 1700 static int nl802154_set_max_associations(struct sk_buff *skb, struct genl_info *info) 1701 { 1702 struct net_device *dev = info->user_ptr[1]; 1703 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1704 unsigned int max_assoc; 1705 1706 if (!info->attrs[NL802154_ATTR_MAX_ASSOCIATIONS]) { 1707 NL_SET_ERR_MSG(info->extack, "No maximum number of association given"); 1708 return -EINVAL; 1709 } 1710 1711 max_assoc = nla_get_u32(info->attrs[NL802154_ATTR_MAX_ASSOCIATIONS]); 1712 1713 mutex_lock(&wpan_dev->association_lock); 1714 cfg802154_set_max_associations(wpan_dev, max_assoc); 1715 mutex_unlock(&wpan_dev->association_lock); 1716 1717 return 0; 1718 } 1719 1720 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL 1721 static const struct nla_policy nl802154_dev_addr_policy[NL802154_DEV_ADDR_ATTR_MAX + 1] = { 1722 [NL802154_DEV_ADDR_ATTR_PAN_ID] = { .type = NLA_U16 }, 1723 [NL802154_DEV_ADDR_ATTR_MODE] = { .type = NLA_U32 }, 1724 [NL802154_DEV_ADDR_ATTR_SHORT] = { .type = NLA_U16 }, 1725 [NL802154_DEV_ADDR_ATTR_EXTENDED] = { .type = NLA_U64 }, 1726 }; 1727 1728 static int 1729 ieee802154_llsec_parse_dev_addr(struct nlattr *nla, 1730 struct ieee802154_addr *addr) 1731 { 1732 struct nlattr *attrs[NL802154_DEV_ADDR_ATTR_MAX + 1]; 1733 1734 if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ADDR_ATTR_MAX, nla, nl802154_dev_addr_policy, NULL)) 1735 return -EINVAL; 1736 1737 if (!attrs[NL802154_DEV_ADDR_ATTR_PAN_ID] || !attrs[NL802154_DEV_ADDR_ATTR_MODE]) 1738 return -EINVAL; 1739 1740 addr->pan_id = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_PAN_ID]); 1741 addr->mode = nla_get_u32(attrs[NL802154_DEV_ADDR_ATTR_MODE]); 1742 switch (addr->mode) { 1743 case NL802154_DEV_ADDR_SHORT: 1744 if (!attrs[NL802154_DEV_ADDR_ATTR_SHORT]) 1745 return -EINVAL; 1746 addr->short_addr = nla_get_le16(attrs[NL802154_DEV_ADDR_ATTR_SHORT]); 1747 break; 1748 case NL802154_DEV_ADDR_EXTENDED: 1749 if (!attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]) 1750 return -EINVAL; 1751 addr->extended_addr = nla_get_le64(attrs[NL802154_DEV_ADDR_ATTR_EXTENDED]); 1752 break; 1753 default: 1754 return -EINVAL; 1755 } 1756 1757 return 0; 1758 } 1759 1760 static const struct nla_policy nl802154_key_id_policy[NL802154_KEY_ID_ATTR_MAX + 1] = { 1761 [NL802154_KEY_ID_ATTR_MODE] = { .type = NLA_U32 }, 1762 [NL802154_KEY_ID_ATTR_INDEX] = { .type = NLA_U8 }, 1763 [NL802154_KEY_ID_ATTR_IMPLICIT] = { .type = NLA_NESTED }, 1764 [NL802154_KEY_ID_ATTR_SOURCE_SHORT] = { .type = NLA_U32 }, 1765 [NL802154_KEY_ID_ATTR_SOURCE_EXTENDED] = { .type = NLA_U64 }, 1766 }; 1767 1768 static int 1769 ieee802154_llsec_parse_key_id(struct nlattr *nla, 1770 struct ieee802154_llsec_key_id *desc) 1771 { 1772 struct nlattr *attrs[NL802154_KEY_ID_ATTR_MAX + 1]; 1773 1774 if (!nla || nla_parse_nested_deprecated(attrs, NL802154_KEY_ID_ATTR_MAX, nla, nl802154_key_id_policy, NULL)) 1775 return -EINVAL; 1776 1777 if (!attrs[NL802154_KEY_ID_ATTR_MODE]) 1778 return -EINVAL; 1779 1780 desc->mode = nla_get_u32(attrs[NL802154_KEY_ID_ATTR_MODE]); 1781 switch (desc->mode) { 1782 case NL802154_KEY_ID_MODE_IMPLICIT: 1783 if (!attrs[NL802154_KEY_ID_ATTR_IMPLICIT]) 1784 return -EINVAL; 1785 1786 if (ieee802154_llsec_parse_dev_addr(attrs[NL802154_KEY_ID_ATTR_IMPLICIT], 1787 &desc->device_addr) < 0) 1788 return -EINVAL; 1789 break; 1790 case NL802154_KEY_ID_MODE_INDEX: 1791 break; 1792 case NL802154_KEY_ID_MODE_INDEX_SHORT: 1793 if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT]) 1794 return -EINVAL; 1795 1796 desc->short_source = nla_get_le32(attrs[NL802154_KEY_ID_ATTR_SOURCE_SHORT]); 1797 break; 1798 case NL802154_KEY_ID_MODE_INDEX_EXTENDED: 1799 if (!attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED]) 1800 return -EINVAL; 1801 1802 desc->extended_source = nla_get_le64(attrs[NL802154_KEY_ID_ATTR_SOURCE_EXTENDED]); 1803 break; 1804 default: 1805 return -EINVAL; 1806 } 1807 1808 if (desc->mode != NL802154_KEY_ID_MODE_IMPLICIT) { 1809 if (!attrs[NL802154_KEY_ID_ATTR_INDEX]) 1810 return -EINVAL; 1811 1812 /* TODO change id to idx */ 1813 desc->id = nla_get_u8(attrs[NL802154_KEY_ID_ATTR_INDEX]); 1814 } 1815 1816 return 0; 1817 } 1818 1819 static int nl802154_set_llsec_params(struct sk_buff *skb, 1820 struct genl_info *info) 1821 { 1822 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1823 struct net_device *dev = info->user_ptr[1]; 1824 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1825 struct ieee802154_llsec_params params; 1826 u32 changed = 0; 1827 int ret; 1828 1829 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 1830 return -EOPNOTSUPP; 1831 1832 if (info->attrs[NL802154_ATTR_SEC_ENABLED]) { 1833 u8 enabled; 1834 1835 enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]); 1836 if (enabled != 0 && enabled != 1) 1837 return -EINVAL; 1838 1839 params.enabled = nla_get_u8(info->attrs[NL802154_ATTR_SEC_ENABLED]); 1840 changed |= IEEE802154_LLSEC_PARAM_ENABLED; 1841 } 1842 1843 if (info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID]) { 1844 ret = ieee802154_llsec_parse_key_id(info->attrs[NL802154_ATTR_SEC_OUT_KEY_ID], 1845 ¶ms.out_key); 1846 if (ret < 0) 1847 return ret; 1848 1849 changed |= IEEE802154_LLSEC_PARAM_OUT_KEY; 1850 } 1851 1852 if (info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]) { 1853 params.out_level = nla_get_u32(info->attrs[NL802154_ATTR_SEC_OUT_LEVEL]); 1854 if (params.out_level > NL802154_SECLEVEL_MAX) 1855 return -EINVAL; 1856 1857 changed |= IEEE802154_LLSEC_PARAM_OUT_LEVEL; 1858 } 1859 1860 if (info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]) { 1861 params.frame_counter = nla_get_be32(info->attrs[NL802154_ATTR_SEC_FRAME_COUNTER]); 1862 changed |= IEEE802154_LLSEC_PARAM_FRAME_COUNTER; 1863 } 1864 1865 return rdev_set_llsec_params(rdev, wpan_dev, ¶ms, changed); 1866 } 1867 1868 static int nl802154_send_key(struct sk_buff *msg, u32 cmd, u32 portid, 1869 u32 seq, int flags, 1870 struct cfg802154_registered_device *rdev, 1871 struct net_device *dev, 1872 const struct ieee802154_llsec_key_entry *key) 1873 { 1874 void *hdr; 1875 u32 commands[NL802154_CMD_FRAME_NR_IDS / 32]; 1876 struct nlattr *nl_key, *nl_key_id; 1877 1878 hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); 1879 if (!hdr) 1880 return -ENOBUFS; 1881 1882 if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) 1883 goto nla_put_failure; 1884 1885 nl_key = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_KEY); 1886 if (!nl_key) 1887 goto nla_put_failure; 1888 1889 nl_key_id = nla_nest_start_noflag(msg, NL802154_KEY_ATTR_ID); 1890 if (!nl_key_id) 1891 goto nla_put_failure; 1892 1893 if (ieee802154_llsec_send_key_id(msg, &key->id) < 0) 1894 goto nla_put_failure; 1895 1896 nla_nest_end(msg, nl_key_id); 1897 1898 if (nla_put_u8(msg, NL802154_KEY_ATTR_USAGE_FRAMES, 1899 key->key->frame_types)) 1900 goto nla_put_failure; 1901 1902 if (key->key->frame_types & BIT(NL802154_FRAME_CMD)) { 1903 /* TODO for each nested */ 1904 memset(commands, 0, sizeof(commands)); 1905 commands[7] = key->key->cmd_frame_ids; 1906 if (nla_put(msg, NL802154_KEY_ATTR_USAGE_CMDS, 1907 sizeof(commands), commands)) 1908 goto nla_put_failure; 1909 } 1910 1911 if (nla_put(msg, NL802154_KEY_ATTR_BYTES, NL802154_KEY_SIZE, 1912 key->key->key)) 1913 goto nla_put_failure; 1914 1915 nla_nest_end(msg, nl_key); 1916 genlmsg_end(msg, hdr); 1917 1918 return 0; 1919 1920 nla_put_failure: 1921 genlmsg_cancel(msg, hdr); 1922 return -EMSGSIZE; 1923 } 1924 1925 static int 1926 nl802154_dump_llsec_key(struct sk_buff *skb, struct netlink_callback *cb) 1927 { 1928 struct cfg802154_registered_device *rdev = NULL; 1929 struct ieee802154_llsec_key_entry *key; 1930 struct ieee802154_llsec_table *table; 1931 struct wpan_dev *wpan_dev; 1932 int err; 1933 1934 err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev); 1935 if (err) 1936 return err; 1937 1938 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) { 1939 err = skb->len; 1940 goto out_err; 1941 } 1942 1943 if (!wpan_dev->netdev) { 1944 err = -EINVAL; 1945 goto out_err; 1946 } 1947 1948 rdev_lock_llsec_table(rdev, wpan_dev); 1949 rdev_get_llsec_table(rdev, wpan_dev, &table); 1950 1951 /* TODO make it like station dump */ 1952 if (cb->args[2]) 1953 goto out; 1954 1955 list_for_each_entry(key, &table->keys, list) { 1956 if (nl802154_send_key(skb, NL802154_CMD_NEW_SEC_KEY, 1957 NETLINK_CB(cb->skb).portid, 1958 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1959 rdev, wpan_dev->netdev, key) < 0) { 1960 /* TODO */ 1961 err = -EIO; 1962 rdev_unlock_llsec_table(rdev, wpan_dev); 1963 goto out_err; 1964 } 1965 } 1966 1967 cb->args[2] = 1; 1968 1969 out: 1970 rdev_unlock_llsec_table(rdev, wpan_dev); 1971 err = skb->len; 1972 out_err: 1973 nl802154_finish_wpan_dev_dump(rdev); 1974 1975 return err; 1976 } 1977 1978 static const struct nla_policy nl802154_key_policy[NL802154_KEY_ATTR_MAX + 1] = { 1979 [NL802154_KEY_ATTR_ID] = { NLA_NESTED }, 1980 /* TODO handle it as for_each_nested and NLA_FLAG? */ 1981 [NL802154_KEY_ATTR_USAGE_FRAMES] = { NLA_U8 }, 1982 /* TODO handle it as for_each_nested, not static array? */ 1983 [NL802154_KEY_ATTR_USAGE_CMDS] = { .len = NL802154_CMD_FRAME_NR_IDS / 8 }, 1984 [NL802154_KEY_ATTR_BYTES] = { .len = NL802154_KEY_SIZE }, 1985 }; 1986 1987 static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info) 1988 { 1989 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 1990 struct net_device *dev = info->user_ptr[1]; 1991 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 1992 struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1]; 1993 struct ieee802154_llsec_key key = { }; 1994 struct ieee802154_llsec_key_id id = { }; 1995 u32 commands[NL802154_CMD_FRAME_NR_IDS / 32] = { }; 1996 1997 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 1998 return -EOPNOTSUPP; 1999 2000 if (!info->attrs[NL802154_ATTR_SEC_KEY] || 2001 nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack)) 2002 return -EINVAL; 2003 2004 if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] || 2005 !attrs[NL802154_KEY_ATTR_BYTES]) 2006 return -EINVAL; 2007 2008 if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0) 2009 return -ENOBUFS; 2010 2011 key.frame_types = nla_get_u8(attrs[NL802154_KEY_ATTR_USAGE_FRAMES]); 2012 if (key.frame_types > BIT(NL802154_FRAME_MAX) || 2013 ((key.frame_types & BIT(NL802154_FRAME_CMD)) && 2014 !attrs[NL802154_KEY_ATTR_USAGE_CMDS])) 2015 return -EINVAL; 2016 2017 if (attrs[NL802154_KEY_ATTR_USAGE_CMDS]) { 2018 /* TODO for each nested */ 2019 nla_memcpy(commands, attrs[NL802154_KEY_ATTR_USAGE_CMDS], 2020 NL802154_CMD_FRAME_NR_IDS / 8); 2021 2022 /* TODO understand the -EINVAL logic here? last condition */ 2023 if (commands[0] || commands[1] || commands[2] || commands[3] || 2024 commands[4] || commands[5] || commands[6] || 2025 commands[7] > BIT(NL802154_CMD_FRAME_MAX)) 2026 return -EINVAL; 2027 2028 key.cmd_frame_ids = commands[7]; 2029 } else { 2030 key.cmd_frame_ids = 0; 2031 } 2032 2033 nla_memcpy(key.key, attrs[NL802154_KEY_ATTR_BYTES], NL802154_KEY_SIZE); 2034 2035 if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0) 2036 return -ENOBUFS; 2037 2038 return rdev_add_llsec_key(rdev, wpan_dev, &id, &key); 2039 } 2040 2041 static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info) 2042 { 2043 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 2044 struct net_device *dev = info->user_ptr[1]; 2045 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 2046 struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1]; 2047 struct ieee802154_llsec_key_id id; 2048 2049 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 2050 return -EOPNOTSUPP; 2051 2052 if (!info->attrs[NL802154_ATTR_SEC_KEY] || 2053 nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack)) 2054 return -EINVAL; 2055 2056 if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0) 2057 return -ENOBUFS; 2058 2059 return rdev_del_llsec_key(rdev, wpan_dev, &id); 2060 } 2061 2062 static int nl802154_send_device(struct sk_buff *msg, u32 cmd, u32 portid, 2063 u32 seq, int flags, 2064 struct cfg802154_registered_device *rdev, 2065 struct net_device *dev, 2066 const struct ieee802154_llsec_device *dev_desc) 2067 { 2068 void *hdr; 2069 struct nlattr *nl_device; 2070 2071 hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); 2072 if (!hdr) 2073 return -ENOBUFS; 2074 2075 if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) 2076 goto nla_put_failure; 2077 2078 nl_device = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVICE); 2079 if (!nl_device) 2080 goto nla_put_failure; 2081 2082 if (nla_put_u32(msg, NL802154_DEV_ATTR_FRAME_COUNTER, 2083 dev_desc->frame_counter) || 2084 nla_put_le16(msg, NL802154_DEV_ATTR_PAN_ID, dev_desc->pan_id) || 2085 nla_put_le16(msg, NL802154_DEV_ATTR_SHORT_ADDR, 2086 dev_desc->short_addr) || 2087 nla_put_le64(msg, NL802154_DEV_ATTR_EXTENDED_ADDR, 2088 dev_desc->hwaddr, NL802154_DEV_ATTR_PAD) || 2089 nla_put_u8(msg, NL802154_DEV_ATTR_SECLEVEL_EXEMPT, 2090 dev_desc->seclevel_exempt) || 2091 nla_put_u32(msg, NL802154_DEV_ATTR_KEY_MODE, dev_desc->key_mode)) 2092 goto nla_put_failure; 2093 2094 nla_nest_end(msg, nl_device); 2095 genlmsg_end(msg, hdr); 2096 2097 return 0; 2098 2099 nla_put_failure: 2100 genlmsg_cancel(msg, hdr); 2101 return -EMSGSIZE; 2102 } 2103 2104 static int 2105 nl802154_dump_llsec_dev(struct sk_buff *skb, struct netlink_callback *cb) 2106 { 2107 struct cfg802154_registered_device *rdev = NULL; 2108 struct ieee802154_llsec_device *dev; 2109 struct ieee802154_llsec_table *table; 2110 struct wpan_dev *wpan_dev; 2111 int err; 2112 2113 err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev); 2114 if (err) 2115 return err; 2116 2117 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) { 2118 err = skb->len; 2119 goto out_err; 2120 } 2121 2122 if (!wpan_dev->netdev) { 2123 err = -EINVAL; 2124 goto out_err; 2125 } 2126 2127 rdev_lock_llsec_table(rdev, wpan_dev); 2128 rdev_get_llsec_table(rdev, wpan_dev, &table); 2129 2130 /* TODO make it like station dump */ 2131 if (cb->args[2]) 2132 goto out; 2133 2134 list_for_each_entry(dev, &table->devices, list) { 2135 if (nl802154_send_device(skb, NL802154_CMD_NEW_SEC_LEVEL, 2136 NETLINK_CB(cb->skb).portid, 2137 cb->nlh->nlmsg_seq, NLM_F_MULTI, 2138 rdev, wpan_dev->netdev, dev) < 0) { 2139 /* TODO */ 2140 err = -EIO; 2141 rdev_unlock_llsec_table(rdev, wpan_dev); 2142 goto out_err; 2143 } 2144 } 2145 2146 cb->args[2] = 1; 2147 2148 out: 2149 rdev_unlock_llsec_table(rdev, wpan_dev); 2150 err = skb->len; 2151 out_err: 2152 nl802154_finish_wpan_dev_dump(rdev); 2153 2154 return err; 2155 } 2156 2157 static const struct nla_policy nl802154_dev_policy[NL802154_DEV_ATTR_MAX + 1] = { 2158 [NL802154_DEV_ATTR_FRAME_COUNTER] = { NLA_U32 }, 2159 [NL802154_DEV_ATTR_PAN_ID] = { .type = NLA_U16 }, 2160 [NL802154_DEV_ATTR_SHORT_ADDR] = { .type = NLA_U16 }, 2161 [NL802154_DEV_ATTR_EXTENDED_ADDR] = { .type = NLA_U64 }, 2162 [NL802154_DEV_ATTR_SECLEVEL_EXEMPT] = { NLA_U8 }, 2163 [NL802154_DEV_ATTR_KEY_MODE] = { NLA_U32 }, 2164 }; 2165 2166 static int 2167 ieee802154_llsec_parse_device(struct nlattr *nla, 2168 struct ieee802154_llsec_device *dev) 2169 { 2170 struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1]; 2171 2172 if (!nla || nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, nla, nl802154_dev_policy, NULL)) 2173 return -EINVAL; 2174 2175 memset(dev, 0, sizeof(*dev)); 2176 2177 if (!attrs[NL802154_DEV_ATTR_FRAME_COUNTER] || 2178 !attrs[NL802154_DEV_ATTR_PAN_ID] || 2179 !attrs[NL802154_DEV_ATTR_SHORT_ADDR] || 2180 !attrs[NL802154_DEV_ATTR_EXTENDED_ADDR] || 2181 !attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT] || 2182 !attrs[NL802154_DEV_ATTR_KEY_MODE]) 2183 return -EINVAL; 2184 2185 /* TODO be32 */ 2186 dev->frame_counter = nla_get_u32(attrs[NL802154_DEV_ATTR_FRAME_COUNTER]); 2187 dev->pan_id = nla_get_le16(attrs[NL802154_DEV_ATTR_PAN_ID]); 2188 dev->short_addr = nla_get_le16(attrs[NL802154_DEV_ATTR_SHORT_ADDR]); 2189 /* TODO rename hwaddr to extended_addr */ 2190 dev->hwaddr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]); 2191 dev->seclevel_exempt = nla_get_u8(attrs[NL802154_DEV_ATTR_SECLEVEL_EXEMPT]); 2192 dev->key_mode = nla_get_u32(attrs[NL802154_DEV_ATTR_KEY_MODE]); 2193 2194 if (dev->key_mode > NL802154_DEVKEY_MAX || 2195 (dev->seclevel_exempt != 0 && dev->seclevel_exempt != 1)) 2196 return -EINVAL; 2197 2198 return 0; 2199 } 2200 2201 static int nl802154_add_llsec_dev(struct sk_buff *skb, struct genl_info *info) 2202 { 2203 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 2204 struct net_device *dev = info->user_ptr[1]; 2205 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 2206 struct ieee802154_llsec_device dev_desc; 2207 2208 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 2209 return -EOPNOTSUPP; 2210 2211 if (ieee802154_llsec_parse_device(info->attrs[NL802154_ATTR_SEC_DEVICE], 2212 &dev_desc) < 0) 2213 return -EINVAL; 2214 2215 return rdev_add_device(rdev, wpan_dev, &dev_desc); 2216 } 2217 2218 static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info) 2219 { 2220 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 2221 struct net_device *dev = info->user_ptr[1]; 2222 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 2223 struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1]; 2224 __le64 extended_addr; 2225 2226 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 2227 return -EOPNOTSUPP; 2228 2229 if (!info->attrs[NL802154_ATTR_SEC_DEVICE] || 2230 nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVICE], nl802154_dev_policy, info->extack)) 2231 return -EINVAL; 2232 2233 if (!attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]) 2234 return -EINVAL; 2235 2236 extended_addr = nla_get_le64(attrs[NL802154_DEV_ATTR_EXTENDED_ADDR]); 2237 return rdev_del_device(rdev, wpan_dev, extended_addr); 2238 } 2239 2240 static int nl802154_send_devkey(struct sk_buff *msg, u32 cmd, u32 portid, 2241 u32 seq, int flags, 2242 struct cfg802154_registered_device *rdev, 2243 struct net_device *dev, __le64 extended_addr, 2244 const struct ieee802154_llsec_device_key *devkey) 2245 { 2246 void *hdr; 2247 struct nlattr *nl_devkey, *nl_key_id; 2248 2249 hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); 2250 if (!hdr) 2251 return -ENOBUFS; 2252 2253 if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) 2254 goto nla_put_failure; 2255 2256 nl_devkey = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_DEVKEY); 2257 if (!nl_devkey) 2258 goto nla_put_failure; 2259 2260 if (nla_put_le64(msg, NL802154_DEVKEY_ATTR_EXTENDED_ADDR, 2261 extended_addr, NL802154_DEVKEY_ATTR_PAD) || 2262 nla_put_u32(msg, NL802154_DEVKEY_ATTR_FRAME_COUNTER, 2263 devkey->frame_counter)) 2264 goto nla_put_failure; 2265 2266 nl_key_id = nla_nest_start_noflag(msg, NL802154_DEVKEY_ATTR_ID); 2267 if (!nl_key_id) 2268 goto nla_put_failure; 2269 2270 if (ieee802154_llsec_send_key_id(msg, &devkey->key_id) < 0) 2271 goto nla_put_failure; 2272 2273 nla_nest_end(msg, nl_key_id); 2274 nla_nest_end(msg, nl_devkey); 2275 genlmsg_end(msg, hdr); 2276 2277 return 0; 2278 2279 nla_put_failure: 2280 genlmsg_cancel(msg, hdr); 2281 return -EMSGSIZE; 2282 } 2283 2284 static int 2285 nl802154_dump_llsec_devkey(struct sk_buff *skb, struct netlink_callback *cb) 2286 { 2287 struct cfg802154_registered_device *rdev = NULL; 2288 struct ieee802154_llsec_device_key *kpos; 2289 struct ieee802154_llsec_device *dpos; 2290 struct ieee802154_llsec_table *table; 2291 struct wpan_dev *wpan_dev; 2292 int err; 2293 2294 err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev); 2295 if (err) 2296 return err; 2297 2298 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) { 2299 err = skb->len; 2300 goto out_err; 2301 } 2302 2303 if (!wpan_dev->netdev) { 2304 err = -EINVAL; 2305 goto out_err; 2306 } 2307 2308 rdev_lock_llsec_table(rdev, wpan_dev); 2309 rdev_get_llsec_table(rdev, wpan_dev, &table); 2310 2311 /* TODO make it like station dump */ 2312 if (cb->args[2]) 2313 goto out; 2314 2315 /* TODO look if remove devkey and do some nested attribute */ 2316 list_for_each_entry(dpos, &table->devices, list) { 2317 list_for_each_entry(kpos, &dpos->keys, list) { 2318 if (nl802154_send_devkey(skb, 2319 NL802154_CMD_NEW_SEC_LEVEL, 2320 NETLINK_CB(cb->skb).portid, 2321 cb->nlh->nlmsg_seq, 2322 NLM_F_MULTI, rdev, 2323 wpan_dev->netdev, 2324 dpos->hwaddr, 2325 kpos) < 0) { 2326 /* TODO */ 2327 err = -EIO; 2328 rdev_unlock_llsec_table(rdev, wpan_dev); 2329 goto out_err; 2330 } 2331 } 2332 } 2333 2334 cb->args[2] = 1; 2335 2336 out: 2337 rdev_unlock_llsec_table(rdev, wpan_dev); 2338 err = skb->len; 2339 out_err: 2340 nl802154_finish_wpan_dev_dump(rdev); 2341 2342 return err; 2343 } 2344 2345 static const struct nla_policy nl802154_devkey_policy[NL802154_DEVKEY_ATTR_MAX + 1] = { 2346 [NL802154_DEVKEY_ATTR_FRAME_COUNTER] = { NLA_U32 }, 2347 [NL802154_DEVKEY_ATTR_EXTENDED_ADDR] = { NLA_U64 }, 2348 [NL802154_DEVKEY_ATTR_ID] = { NLA_NESTED }, 2349 }; 2350 2351 static int nl802154_add_llsec_devkey(struct sk_buff *skb, struct genl_info *info) 2352 { 2353 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 2354 struct net_device *dev = info->user_ptr[1]; 2355 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 2356 struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1]; 2357 struct ieee802154_llsec_device_key key; 2358 __le64 extended_addr; 2359 2360 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 2361 return -EOPNOTSUPP; 2362 2363 if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] || 2364 nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack) < 0) 2365 return -EINVAL; 2366 2367 if (!attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER] || 2368 !attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]) 2369 return -EINVAL; 2370 2371 /* TODO change key.id ? */ 2372 if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID], 2373 &key.key_id) < 0) 2374 return -ENOBUFS; 2375 2376 /* TODO be32 */ 2377 key.frame_counter = nla_get_u32(attrs[NL802154_DEVKEY_ATTR_FRAME_COUNTER]); 2378 /* TODO change naming hwaddr -> extended_addr 2379 * check unique identifier short+pan OR extended_addr 2380 */ 2381 extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]); 2382 return rdev_add_devkey(rdev, wpan_dev, extended_addr, &key); 2383 } 2384 2385 static int nl802154_del_llsec_devkey(struct sk_buff *skb, struct genl_info *info) 2386 { 2387 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 2388 struct net_device *dev = info->user_ptr[1]; 2389 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 2390 struct nlattr *attrs[NL802154_DEVKEY_ATTR_MAX + 1]; 2391 struct ieee802154_llsec_device_key key; 2392 __le64 extended_addr; 2393 2394 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 2395 return -EOPNOTSUPP; 2396 2397 if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] || 2398 nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack)) 2399 return -EINVAL; 2400 2401 if (!attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]) 2402 return -EINVAL; 2403 2404 /* TODO change key.id ? */ 2405 if (ieee802154_llsec_parse_key_id(attrs[NL802154_DEVKEY_ATTR_ID], 2406 &key.key_id) < 0) 2407 return -ENOBUFS; 2408 2409 /* TODO change naming hwaddr -> extended_addr 2410 * check unique identifier short+pan OR extended_addr 2411 */ 2412 extended_addr = nla_get_le64(attrs[NL802154_DEVKEY_ATTR_EXTENDED_ADDR]); 2413 return rdev_del_devkey(rdev, wpan_dev, extended_addr, &key); 2414 } 2415 2416 static int nl802154_send_seclevel(struct sk_buff *msg, u32 cmd, u32 portid, 2417 u32 seq, int flags, 2418 struct cfg802154_registered_device *rdev, 2419 struct net_device *dev, 2420 const struct ieee802154_llsec_seclevel *sl) 2421 { 2422 void *hdr; 2423 struct nlattr *nl_seclevel; 2424 2425 hdr = nl802154hdr_put(msg, portid, seq, flags, cmd); 2426 if (!hdr) 2427 return -ENOBUFS; 2428 2429 if (nla_put_u32(msg, NL802154_ATTR_IFINDEX, dev->ifindex)) 2430 goto nla_put_failure; 2431 2432 nl_seclevel = nla_nest_start_noflag(msg, NL802154_ATTR_SEC_LEVEL); 2433 if (!nl_seclevel) 2434 goto nla_put_failure; 2435 2436 if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_FRAME, sl->frame_type) || 2437 nla_put_u32(msg, NL802154_SECLEVEL_ATTR_LEVELS, sl->sec_levels) || 2438 nla_put_u8(msg, NL802154_SECLEVEL_ATTR_DEV_OVERRIDE, 2439 sl->device_override)) 2440 goto nla_put_failure; 2441 2442 if (sl->frame_type == NL802154_FRAME_CMD) { 2443 if (nla_put_u32(msg, NL802154_SECLEVEL_ATTR_CMD_FRAME, 2444 sl->cmd_frame_id)) 2445 goto nla_put_failure; 2446 } 2447 2448 nla_nest_end(msg, nl_seclevel); 2449 genlmsg_end(msg, hdr); 2450 2451 return 0; 2452 2453 nla_put_failure: 2454 genlmsg_cancel(msg, hdr); 2455 return -EMSGSIZE; 2456 } 2457 2458 static int 2459 nl802154_dump_llsec_seclevel(struct sk_buff *skb, struct netlink_callback *cb) 2460 { 2461 struct cfg802154_registered_device *rdev = NULL; 2462 struct ieee802154_llsec_seclevel *sl; 2463 struct ieee802154_llsec_table *table; 2464 struct wpan_dev *wpan_dev; 2465 int err; 2466 2467 err = nl802154_prepare_wpan_dev_dump(skb, cb, &rdev, &wpan_dev); 2468 if (err) 2469 return err; 2470 2471 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) { 2472 err = skb->len; 2473 goto out_err; 2474 } 2475 2476 if (!wpan_dev->netdev) { 2477 err = -EINVAL; 2478 goto out_err; 2479 } 2480 2481 rdev_lock_llsec_table(rdev, wpan_dev); 2482 rdev_get_llsec_table(rdev, wpan_dev, &table); 2483 2484 /* TODO make it like station dump */ 2485 if (cb->args[2]) 2486 goto out; 2487 2488 list_for_each_entry(sl, &table->security_levels, list) { 2489 if (nl802154_send_seclevel(skb, NL802154_CMD_NEW_SEC_LEVEL, 2490 NETLINK_CB(cb->skb).portid, 2491 cb->nlh->nlmsg_seq, NLM_F_MULTI, 2492 rdev, wpan_dev->netdev, sl) < 0) { 2493 /* TODO */ 2494 err = -EIO; 2495 rdev_unlock_llsec_table(rdev, wpan_dev); 2496 goto out_err; 2497 } 2498 } 2499 2500 cb->args[2] = 1; 2501 2502 out: 2503 rdev_unlock_llsec_table(rdev, wpan_dev); 2504 err = skb->len; 2505 out_err: 2506 nl802154_finish_wpan_dev_dump(rdev); 2507 2508 return err; 2509 } 2510 2511 static const struct nla_policy nl802154_seclevel_policy[NL802154_SECLEVEL_ATTR_MAX + 1] = { 2512 [NL802154_SECLEVEL_ATTR_LEVELS] = { .type = NLA_U8 }, 2513 [NL802154_SECLEVEL_ATTR_FRAME] = { .type = NLA_U32 }, 2514 [NL802154_SECLEVEL_ATTR_CMD_FRAME] = { .type = NLA_U32 }, 2515 [NL802154_SECLEVEL_ATTR_DEV_OVERRIDE] = { .type = NLA_U8 }, 2516 }; 2517 2518 static int 2519 llsec_parse_seclevel(struct nlattr *nla, struct ieee802154_llsec_seclevel *sl) 2520 { 2521 struct nlattr *attrs[NL802154_SECLEVEL_ATTR_MAX + 1]; 2522 2523 if (!nla || nla_parse_nested_deprecated(attrs, NL802154_SECLEVEL_ATTR_MAX, nla, nl802154_seclevel_policy, NULL)) 2524 return -EINVAL; 2525 2526 memset(sl, 0, sizeof(*sl)); 2527 2528 if (!attrs[NL802154_SECLEVEL_ATTR_LEVELS] || 2529 !attrs[NL802154_SECLEVEL_ATTR_FRAME] || 2530 !attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE]) 2531 return -EINVAL; 2532 2533 sl->sec_levels = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_LEVELS]); 2534 sl->frame_type = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_FRAME]); 2535 sl->device_override = nla_get_u8(attrs[NL802154_SECLEVEL_ATTR_DEV_OVERRIDE]); 2536 if (sl->frame_type > NL802154_FRAME_MAX || 2537 (sl->device_override != 0 && sl->device_override != 1)) 2538 return -EINVAL; 2539 2540 if (sl->frame_type == NL802154_FRAME_CMD) { 2541 if (!attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME]) 2542 return -EINVAL; 2543 2544 sl->cmd_frame_id = nla_get_u32(attrs[NL802154_SECLEVEL_ATTR_CMD_FRAME]); 2545 if (sl->cmd_frame_id > NL802154_CMD_FRAME_MAX) 2546 return -EINVAL; 2547 } 2548 2549 return 0; 2550 } 2551 2552 static int nl802154_add_llsec_seclevel(struct sk_buff *skb, 2553 struct genl_info *info) 2554 { 2555 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 2556 struct net_device *dev = info->user_ptr[1]; 2557 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 2558 struct ieee802154_llsec_seclevel sl; 2559 2560 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 2561 return -EOPNOTSUPP; 2562 2563 if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL], 2564 &sl) < 0) 2565 return -EINVAL; 2566 2567 return rdev_add_seclevel(rdev, wpan_dev, &sl); 2568 } 2569 2570 static int nl802154_del_llsec_seclevel(struct sk_buff *skb, 2571 struct genl_info *info) 2572 { 2573 struct cfg802154_registered_device *rdev = info->user_ptr[0]; 2574 struct net_device *dev = info->user_ptr[1]; 2575 struct wpan_dev *wpan_dev = dev->ieee802154_ptr; 2576 struct ieee802154_llsec_seclevel sl; 2577 2578 if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) 2579 return -EOPNOTSUPP; 2580 2581 if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL], 2582 &sl) < 0) 2583 return -EINVAL; 2584 2585 return rdev_del_seclevel(rdev, wpan_dev, &sl); 2586 } 2587 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ 2588 2589 #define NL802154_FLAG_NEED_WPAN_PHY 0x01 2590 #define NL802154_FLAG_NEED_NETDEV 0x02 2591 #define NL802154_FLAG_NEED_RTNL 0x04 2592 #define NL802154_FLAG_CHECK_NETDEV_UP 0x08 2593 #define NL802154_FLAG_NEED_WPAN_DEV 0x10 2594 2595 static int nl802154_pre_doit(const struct genl_split_ops *ops, 2596 struct sk_buff *skb, 2597 struct genl_info *info) 2598 { 2599 struct cfg802154_registered_device *rdev; 2600 struct wpan_dev *wpan_dev; 2601 struct net_device *dev; 2602 bool rtnl = ops->internal_flags & NL802154_FLAG_NEED_RTNL; 2603 2604 if (rtnl) 2605 rtnl_lock(); 2606 2607 if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_PHY) { 2608 rdev = cfg802154_get_dev_from_info(genl_info_net(info), info); 2609 if (IS_ERR(rdev)) { 2610 if (rtnl) 2611 rtnl_unlock(); 2612 return PTR_ERR(rdev); 2613 } 2614 info->user_ptr[0] = rdev; 2615 } else if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV || 2616 ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) { 2617 ASSERT_RTNL(); 2618 wpan_dev = __cfg802154_wpan_dev_from_attrs(genl_info_net(info), 2619 info->attrs); 2620 if (IS_ERR(wpan_dev)) { 2621 if (rtnl) 2622 rtnl_unlock(); 2623 return PTR_ERR(wpan_dev); 2624 } 2625 2626 dev = wpan_dev->netdev; 2627 rdev = wpan_phy_to_rdev(wpan_dev->wpan_phy); 2628 2629 if (ops->internal_flags & NL802154_FLAG_NEED_NETDEV) { 2630 if (!dev) { 2631 if (rtnl) 2632 rtnl_unlock(); 2633 return -EINVAL; 2634 } 2635 2636 info->user_ptr[1] = dev; 2637 } else { 2638 info->user_ptr[1] = wpan_dev; 2639 } 2640 2641 if (dev) { 2642 if (ops->internal_flags & NL802154_FLAG_CHECK_NETDEV_UP && 2643 !netif_running(dev)) { 2644 if (rtnl) 2645 rtnl_unlock(); 2646 return -ENETDOWN; 2647 } 2648 2649 dev_hold(dev); 2650 } 2651 2652 info->user_ptr[0] = rdev; 2653 } 2654 2655 return 0; 2656 } 2657 2658 static void nl802154_post_doit(const struct genl_split_ops *ops, 2659 struct sk_buff *skb, 2660 struct genl_info *info) 2661 { 2662 if (info->user_ptr[1]) { 2663 if (ops->internal_flags & NL802154_FLAG_NEED_WPAN_DEV) { 2664 struct wpan_dev *wpan_dev = info->user_ptr[1]; 2665 2666 dev_put(wpan_dev->netdev); 2667 } else { 2668 dev_put(info->user_ptr[1]); 2669 } 2670 } 2671 2672 if (ops->internal_flags & NL802154_FLAG_NEED_RTNL) 2673 rtnl_unlock(); 2674 } 2675 2676 static const struct genl_ops nl802154_ops[] = { 2677 { 2678 .cmd = NL802154_CMD_GET_WPAN_PHY, 2679 .validate = GENL_DONT_VALIDATE_STRICT | 2680 GENL_DONT_VALIDATE_DUMP_STRICT, 2681 .doit = nl802154_get_wpan_phy, 2682 .dumpit = nl802154_dump_wpan_phy, 2683 .done = nl802154_dump_wpan_phy_done, 2684 /* can be retrieved by unprivileged users */ 2685 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 2686 NL802154_FLAG_NEED_RTNL, 2687 }, 2688 { 2689 .cmd = NL802154_CMD_GET_INTERFACE, 2690 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2691 .doit = nl802154_get_interface, 2692 .dumpit = nl802154_dump_interface, 2693 /* can be retrieved by unprivileged users */ 2694 .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | 2695 NL802154_FLAG_NEED_RTNL, 2696 }, 2697 { 2698 .cmd = NL802154_CMD_NEW_INTERFACE, 2699 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2700 .doit = nl802154_new_interface, 2701 .flags = GENL_ADMIN_PERM, 2702 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 2703 NL802154_FLAG_NEED_RTNL, 2704 }, 2705 { 2706 .cmd = NL802154_CMD_DEL_INTERFACE, 2707 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2708 .doit = nl802154_del_interface, 2709 .flags = GENL_ADMIN_PERM, 2710 .internal_flags = NL802154_FLAG_NEED_WPAN_DEV | 2711 NL802154_FLAG_NEED_RTNL, 2712 }, 2713 { 2714 .cmd = NL802154_CMD_SET_CHANNEL, 2715 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2716 .doit = nl802154_set_channel, 2717 .flags = GENL_ADMIN_PERM, 2718 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 2719 NL802154_FLAG_NEED_RTNL, 2720 }, 2721 { 2722 .cmd = NL802154_CMD_SET_CCA_MODE, 2723 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2724 .doit = nl802154_set_cca_mode, 2725 .flags = GENL_ADMIN_PERM, 2726 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 2727 NL802154_FLAG_NEED_RTNL, 2728 }, 2729 { 2730 .cmd = NL802154_CMD_SET_CCA_ED_LEVEL, 2731 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2732 .doit = nl802154_set_cca_ed_level, 2733 .flags = GENL_ADMIN_PERM, 2734 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 2735 NL802154_FLAG_NEED_RTNL, 2736 }, 2737 { 2738 .cmd = NL802154_CMD_SET_TX_POWER, 2739 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2740 .doit = nl802154_set_tx_power, 2741 .flags = GENL_ADMIN_PERM, 2742 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 2743 NL802154_FLAG_NEED_RTNL, 2744 }, 2745 { 2746 .cmd = NL802154_CMD_SET_WPAN_PHY_NETNS, 2747 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2748 .doit = nl802154_wpan_phy_netns, 2749 .flags = GENL_ADMIN_PERM, 2750 .internal_flags = NL802154_FLAG_NEED_WPAN_PHY | 2751 NL802154_FLAG_NEED_RTNL, 2752 }, 2753 { 2754 .cmd = NL802154_CMD_SET_PAN_ID, 2755 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2756 .doit = nl802154_set_pan_id, 2757 .flags = GENL_ADMIN_PERM, 2758 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2759 NL802154_FLAG_NEED_RTNL, 2760 }, 2761 { 2762 .cmd = NL802154_CMD_SET_SHORT_ADDR, 2763 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2764 .doit = nl802154_set_short_addr, 2765 .flags = GENL_ADMIN_PERM, 2766 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2767 NL802154_FLAG_NEED_RTNL, 2768 }, 2769 { 2770 .cmd = NL802154_CMD_SET_BACKOFF_EXPONENT, 2771 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2772 .doit = nl802154_set_backoff_exponent, 2773 .flags = GENL_ADMIN_PERM, 2774 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2775 NL802154_FLAG_NEED_RTNL, 2776 }, 2777 { 2778 .cmd = NL802154_CMD_SET_MAX_CSMA_BACKOFFS, 2779 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2780 .doit = nl802154_set_max_csma_backoffs, 2781 .flags = GENL_ADMIN_PERM, 2782 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2783 NL802154_FLAG_NEED_RTNL, 2784 }, 2785 { 2786 .cmd = NL802154_CMD_SET_MAX_FRAME_RETRIES, 2787 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2788 .doit = nl802154_set_max_frame_retries, 2789 .flags = GENL_ADMIN_PERM, 2790 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2791 NL802154_FLAG_NEED_RTNL, 2792 }, 2793 { 2794 .cmd = NL802154_CMD_SET_LBT_MODE, 2795 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2796 .doit = nl802154_set_lbt_mode, 2797 .flags = GENL_ADMIN_PERM, 2798 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2799 NL802154_FLAG_NEED_RTNL, 2800 }, 2801 { 2802 .cmd = NL802154_CMD_SET_ACKREQ_DEFAULT, 2803 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2804 .doit = nl802154_set_ackreq_default, 2805 .flags = GENL_ADMIN_PERM, 2806 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2807 NL802154_FLAG_NEED_RTNL, 2808 }, 2809 { 2810 .cmd = NL802154_CMD_TRIGGER_SCAN, 2811 .doit = nl802154_trigger_scan, 2812 .flags = GENL_ADMIN_PERM, 2813 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2814 NL802154_FLAG_CHECK_NETDEV_UP | 2815 NL802154_FLAG_NEED_RTNL, 2816 }, 2817 { 2818 .cmd = NL802154_CMD_ABORT_SCAN, 2819 .doit = nl802154_abort_scan, 2820 .flags = GENL_ADMIN_PERM, 2821 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2822 NL802154_FLAG_CHECK_NETDEV_UP | 2823 NL802154_FLAG_NEED_RTNL, 2824 }, 2825 { 2826 .cmd = NL802154_CMD_SEND_BEACONS, 2827 .doit = nl802154_send_beacons, 2828 .flags = GENL_ADMIN_PERM, 2829 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2830 NL802154_FLAG_CHECK_NETDEV_UP | 2831 NL802154_FLAG_NEED_RTNL, 2832 }, 2833 { 2834 .cmd = NL802154_CMD_STOP_BEACONS, 2835 .doit = nl802154_stop_beacons, 2836 .flags = GENL_ADMIN_PERM, 2837 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2838 NL802154_FLAG_CHECK_NETDEV_UP | 2839 NL802154_FLAG_NEED_RTNL, 2840 }, 2841 { 2842 .cmd = NL802154_CMD_ASSOCIATE, 2843 .doit = nl802154_associate, 2844 .flags = GENL_ADMIN_PERM, 2845 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2846 NL802154_FLAG_CHECK_NETDEV_UP | 2847 NL802154_FLAG_NEED_RTNL, 2848 }, 2849 { 2850 .cmd = NL802154_CMD_DISASSOCIATE, 2851 .doit = nl802154_disassociate, 2852 .flags = GENL_ADMIN_PERM, 2853 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2854 NL802154_FLAG_CHECK_NETDEV_UP | 2855 NL802154_FLAG_NEED_RTNL, 2856 }, 2857 { 2858 .cmd = NL802154_CMD_SET_MAX_ASSOCIATIONS, 2859 .doit = nl802154_set_max_associations, 2860 .flags = GENL_ADMIN_PERM, 2861 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2862 NL802154_FLAG_NEED_RTNL, 2863 }, 2864 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL 2865 { 2866 .cmd = NL802154_CMD_SET_SEC_PARAMS, 2867 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2868 .doit = nl802154_set_llsec_params, 2869 .flags = GENL_ADMIN_PERM, 2870 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2871 NL802154_FLAG_NEED_RTNL, 2872 }, 2873 { 2874 .cmd = NL802154_CMD_GET_SEC_KEY, 2875 .validate = GENL_DONT_VALIDATE_STRICT | 2876 GENL_DONT_VALIDATE_DUMP_STRICT, 2877 /* TODO .doit by matching key id? */ 2878 .dumpit = nl802154_dump_llsec_key, 2879 .flags = GENL_ADMIN_PERM, 2880 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2881 NL802154_FLAG_NEED_RTNL, 2882 }, 2883 { 2884 .cmd = NL802154_CMD_NEW_SEC_KEY, 2885 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2886 .doit = nl802154_add_llsec_key, 2887 .flags = GENL_ADMIN_PERM, 2888 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2889 NL802154_FLAG_NEED_RTNL, 2890 }, 2891 { 2892 .cmd = NL802154_CMD_DEL_SEC_KEY, 2893 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2894 .doit = nl802154_del_llsec_key, 2895 .flags = GENL_ADMIN_PERM, 2896 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2897 NL802154_FLAG_NEED_RTNL, 2898 }, 2899 /* TODO unique identifier must short+pan OR extended_addr */ 2900 { 2901 .cmd = NL802154_CMD_GET_SEC_DEV, 2902 .validate = GENL_DONT_VALIDATE_STRICT | 2903 GENL_DONT_VALIDATE_DUMP_STRICT, 2904 /* TODO .doit by matching extended_addr? */ 2905 .dumpit = nl802154_dump_llsec_dev, 2906 .flags = GENL_ADMIN_PERM, 2907 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2908 NL802154_FLAG_NEED_RTNL, 2909 }, 2910 { 2911 .cmd = NL802154_CMD_NEW_SEC_DEV, 2912 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2913 .doit = nl802154_add_llsec_dev, 2914 .flags = GENL_ADMIN_PERM, 2915 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2916 NL802154_FLAG_NEED_RTNL, 2917 }, 2918 { 2919 .cmd = NL802154_CMD_DEL_SEC_DEV, 2920 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2921 .doit = nl802154_del_llsec_dev, 2922 .flags = GENL_ADMIN_PERM, 2923 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2924 NL802154_FLAG_NEED_RTNL, 2925 }, 2926 /* TODO remove complete devkey, put it as nested? */ 2927 { 2928 .cmd = NL802154_CMD_GET_SEC_DEVKEY, 2929 .validate = GENL_DONT_VALIDATE_STRICT | 2930 GENL_DONT_VALIDATE_DUMP_STRICT, 2931 /* TODO doit by matching ??? */ 2932 .dumpit = nl802154_dump_llsec_devkey, 2933 .flags = GENL_ADMIN_PERM, 2934 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2935 NL802154_FLAG_NEED_RTNL, 2936 }, 2937 { 2938 .cmd = NL802154_CMD_NEW_SEC_DEVKEY, 2939 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2940 .doit = nl802154_add_llsec_devkey, 2941 .flags = GENL_ADMIN_PERM, 2942 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2943 NL802154_FLAG_NEED_RTNL, 2944 }, 2945 { 2946 .cmd = NL802154_CMD_DEL_SEC_DEVKEY, 2947 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2948 .doit = nl802154_del_llsec_devkey, 2949 .flags = GENL_ADMIN_PERM, 2950 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2951 NL802154_FLAG_NEED_RTNL, 2952 }, 2953 { 2954 .cmd = NL802154_CMD_GET_SEC_LEVEL, 2955 .validate = GENL_DONT_VALIDATE_STRICT | 2956 GENL_DONT_VALIDATE_DUMP_STRICT, 2957 /* TODO .doit by matching frame_type? */ 2958 .dumpit = nl802154_dump_llsec_seclevel, 2959 .flags = GENL_ADMIN_PERM, 2960 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2961 NL802154_FLAG_NEED_RTNL, 2962 }, 2963 { 2964 .cmd = NL802154_CMD_NEW_SEC_LEVEL, 2965 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2966 .doit = nl802154_add_llsec_seclevel, 2967 .flags = GENL_ADMIN_PERM, 2968 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2969 NL802154_FLAG_NEED_RTNL, 2970 }, 2971 { 2972 .cmd = NL802154_CMD_DEL_SEC_LEVEL, 2973 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 2974 /* TODO match frame_type only? */ 2975 .doit = nl802154_del_llsec_seclevel, 2976 .flags = GENL_ADMIN_PERM, 2977 .internal_flags = NL802154_FLAG_NEED_NETDEV | 2978 NL802154_FLAG_NEED_RTNL, 2979 }, 2980 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ 2981 }; 2982 2983 static struct genl_family nl802154_fam __ro_after_init = { 2984 .name = NL802154_GENL_NAME, /* have users key off the name instead */ 2985 .hdrsize = 0, /* no private header */ 2986 .version = 1, /* no particular meaning now */ 2987 .maxattr = NL802154_ATTR_MAX, 2988 .policy = nl802154_policy, 2989 .netnsok = true, 2990 .pre_doit = nl802154_pre_doit, 2991 .post_doit = nl802154_post_doit, 2992 .module = THIS_MODULE, 2993 .ops = nl802154_ops, 2994 .n_ops = ARRAY_SIZE(nl802154_ops), 2995 .resv_start_op = NL802154_CMD_DEL_SEC_LEVEL + 1, 2996 .mcgrps = nl802154_mcgrps, 2997 .n_mcgrps = ARRAY_SIZE(nl802154_mcgrps), 2998 }; 2999 3000 /* initialisation/exit functions */ 3001 int __init nl802154_init(void) 3002 { 3003 return genl_register_family(&nl802154_fam); 3004 } 3005 3006 void nl802154_exit(void) 3007 { 3008 genl_unregister_family(&nl802154_fam); 3009 } 3010