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