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