1 /* 2 * This is the new netlink-based wireless configuration interface. 3 * 4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 5 */ 6 7 #include <linux/if.h> 8 #include <linux/module.h> 9 #include <linux/err.h> 10 #include <linux/mutex.h> 11 #include <linux/list.h> 12 #include <linux/if_ether.h> 13 #include <linux/ieee80211.h> 14 #include <linux/nl80211.h> 15 #include <linux/rtnetlink.h> 16 #include <linux/netlink.h> 17 #include <net/genetlink.h> 18 #include <net/cfg80211.h> 19 #include "core.h" 20 #include "nl80211.h" 21 22 /* the netlink family */ 23 static struct genl_family nl80211_fam = { 24 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ 25 .name = "nl80211", /* have users key off the name instead */ 26 .hdrsize = 0, /* no private header */ 27 .version = 1, /* no particular meaning now */ 28 .maxattr = NL80211_ATTR_MAX, 29 }; 30 31 /* internal helper: get drv and dev */ 32 static int get_drv_dev_by_info_ifindex(struct nlattr **attrs, 33 struct cfg80211_registered_device **drv, 34 struct net_device **dev) 35 { 36 int ifindex; 37 38 if (!attrs[NL80211_ATTR_IFINDEX]) 39 return -EINVAL; 40 41 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); 42 *dev = dev_get_by_index(&init_net, ifindex); 43 if (!*dev) 44 return -ENODEV; 45 46 *drv = cfg80211_get_dev_from_ifindex(ifindex); 47 if (IS_ERR(*drv)) { 48 dev_put(*dev); 49 return PTR_ERR(*drv); 50 } 51 52 return 0; 53 } 54 55 /* policy for the attributes */ 56 static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { 57 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, 58 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, 59 .len = BUS_ID_SIZE-1 }, 60 61 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 62 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 63 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, 64 65 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, 66 67 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, 68 .len = WLAN_MAX_KEY_LEN }, 69 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, 70 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, 71 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, 72 73 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, 74 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, 75 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY, 76 .len = IEEE80211_MAX_DATA_LEN }, 77 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY, 78 .len = IEEE80211_MAX_DATA_LEN }, 79 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 }, 80 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED }, 81 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 }, 82 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY, 83 .len = NL80211_MAX_SUPP_RATES }, 84 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 }, 85 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, 86 [NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED }, 87 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, 88 .len = IEEE80211_MAX_MESH_ID_LEN }, 89 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, 90 }; 91 92 /* message building helper */ 93 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, 94 int flags, u8 cmd) 95 { 96 /* since there is no private header just add the generic one */ 97 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd); 98 } 99 100 /* netlink command implementations */ 101 102 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, 103 struct cfg80211_registered_device *dev) 104 { 105 void *hdr; 106 struct nlattr *nl_bands, *nl_band; 107 struct nlattr *nl_freqs, *nl_freq; 108 struct nlattr *nl_rates, *nl_rate; 109 enum ieee80211_band band; 110 struct ieee80211_channel *chan; 111 struct ieee80211_rate *rate; 112 int i; 113 114 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); 115 if (!hdr) 116 return -1; 117 118 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); 119 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 120 121 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 122 if (!nl_bands) 123 goto nla_put_failure; 124 125 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 126 if (!dev->wiphy.bands[band]) 127 continue; 128 129 nl_band = nla_nest_start(msg, band); 130 if (!nl_band) 131 goto nla_put_failure; 132 133 /* add frequencies */ 134 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); 135 if (!nl_freqs) 136 goto nla_put_failure; 137 138 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) { 139 nl_freq = nla_nest_start(msg, i); 140 if (!nl_freq) 141 goto nla_put_failure; 142 143 chan = &dev->wiphy.bands[band]->channels[i]; 144 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ, 145 chan->center_freq); 146 147 if (chan->flags & IEEE80211_CHAN_DISABLED) 148 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED); 149 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 150 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN); 151 if (chan->flags & IEEE80211_CHAN_NO_IBSS) 152 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS); 153 if (chan->flags & IEEE80211_CHAN_RADAR) 154 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR); 155 156 nla_nest_end(msg, nl_freq); 157 } 158 159 nla_nest_end(msg, nl_freqs); 160 161 /* add bitrates */ 162 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES); 163 if (!nl_rates) 164 goto nla_put_failure; 165 166 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) { 167 nl_rate = nla_nest_start(msg, i); 168 if (!nl_rate) 169 goto nla_put_failure; 170 171 rate = &dev->wiphy.bands[band]->bitrates[i]; 172 NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE, 173 rate->bitrate); 174 if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) 175 NLA_PUT_FLAG(msg, 176 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE); 177 178 nla_nest_end(msg, nl_rate); 179 } 180 181 nla_nest_end(msg, nl_rates); 182 183 nla_nest_end(msg, nl_band); 184 } 185 nla_nest_end(msg, nl_bands); 186 187 return genlmsg_end(msg, hdr); 188 189 nla_put_failure: 190 genlmsg_cancel(msg, hdr); 191 return -EMSGSIZE; 192 } 193 194 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) 195 { 196 int idx = 0; 197 int start = cb->args[0]; 198 struct cfg80211_registered_device *dev; 199 200 mutex_lock(&cfg80211_drv_mutex); 201 list_for_each_entry(dev, &cfg80211_drv_list, list) { 202 if (++idx <= start) 203 continue; 204 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, 205 cb->nlh->nlmsg_seq, NLM_F_MULTI, 206 dev) < 0) { 207 idx--; 208 break; 209 } 210 } 211 mutex_unlock(&cfg80211_drv_mutex); 212 213 cb->args[0] = idx; 214 215 return skb->len; 216 } 217 218 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) 219 { 220 struct sk_buff *msg; 221 struct cfg80211_registered_device *dev; 222 223 dev = cfg80211_get_dev_from_info(info); 224 if (IS_ERR(dev)) 225 return PTR_ERR(dev); 226 227 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 228 if (!msg) 229 goto out_err; 230 231 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) 232 goto out_free; 233 234 cfg80211_put_dev(dev); 235 236 return genlmsg_unicast(msg, info->snd_pid); 237 238 out_free: 239 nlmsg_free(msg); 240 out_err: 241 cfg80211_put_dev(dev); 242 return -ENOBUFS; 243 } 244 245 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) 246 { 247 struct cfg80211_registered_device *rdev; 248 int result; 249 250 if (!info->attrs[NL80211_ATTR_WIPHY_NAME]) 251 return -EINVAL; 252 253 rdev = cfg80211_get_dev_from_info(info); 254 if (IS_ERR(rdev)) 255 return PTR_ERR(rdev); 256 257 result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); 258 259 cfg80211_put_dev(rdev); 260 return result; 261 } 262 263 264 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, 265 struct net_device *dev) 266 { 267 void *hdr; 268 269 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE); 270 if (!hdr) 271 return -1; 272 273 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 274 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); 275 /* TODO: interface type */ 276 return genlmsg_end(msg, hdr); 277 278 nla_put_failure: 279 genlmsg_cancel(msg, hdr); 280 return -EMSGSIZE; 281 } 282 283 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb) 284 { 285 int wp_idx = 0; 286 int if_idx = 0; 287 int wp_start = cb->args[0]; 288 int if_start = cb->args[1]; 289 struct cfg80211_registered_device *dev; 290 struct wireless_dev *wdev; 291 292 mutex_lock(&cfg80211_drv_mutex); 293 list_for_each_entry(dev, &cfg80211_drv_list, list) { 294 if (wp_idx < wp_start) { 295 wp_idx++; 296 continue; 297 } 298 if_idx = 0; 299 300 mutex_lock(&dev->devlist_mtx); 301 list_for_each_entry(wdev, &dev->netdev_list, list) { 302 if (if_idx < if_start) { 303 if_idx++; 304 continue; 305 } 306 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, 307 cb->nlh->nlmsg_seq, NLM_F_MULTI, 308 wdev->netdev) < 0) { 309 mutex_unlock(&dev->devlist_mtx); 310 goto out; 311 } 312 if_idx++; 313 } 314 mutex_unlock(&dev->devlist_mtx); 315 316 wp_idx++; 317 } 318 out: 319 mutex_unlock(&cfg80211_drv_mutex); 320 321 cb->args[0] = wp_idx; 322 cb->args[1] = if_idx; 323 324 return skb->len; 325 } 326 327 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) 328 { 329 struct sk_buff *msg; 330 struct cfg80211_registered_device *dev; 331 struct net_device *netdev; 332 int err; 333 334 err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev); 335 if (err) 336 return err; 337 338 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 339 if (!msg) 340 goto out_err; 341 342 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0) 343 goto out_free; 344 345 dev_put(netdev); 346 cfg80211_put_dev(dev); 347 348 return genlmsg_unicast(msg, info->snd_pid); 349 350 out_free: 351 nlmsg_free(msg); 352 out_err: 353 dev_put(netdev); 354 cfg80211_put_dev(dev); 355 return -ENOBUFS; 356 } 357 358 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { 359 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG }, 360 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG }, 361 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG }, 362 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, 363 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, 364 }; 365 366 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) 367 { 368 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1]; 369 int flag; 370 371 *mntrflags = 0; 372 373 if (!nla) 374 return -EINVAL; 375 376 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX, 377 nla, mntr_flags_policy)) 378 return -EINVAL; 379 380 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++) 381 if (flags[flag]) 382 *mntrflags |= (1<<flag); 383 384 return 0; 385 } 386 387 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) 388 { 389 struct cfg80211_registered_device *drv; 390 struct vif_params params; 391 int err, ifindex; 392 enum nl80211_iftype type; 393 struct net_device *dev; 394 u32 flags; 395 396 memset(¶ms, 0, sizeof(params)); 397 398 if (info->attrs[NL80211_ATTR_IFTYPE]) { 399 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 400 if (type > NL80211_IFTYPE_MAX) 401 return -EINVAL; 402 } else 403 return -EINVAL; 404 405 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 406 if (err) 407 return err; 408 ifindex = dev->ifindex; 409 dev_put(dev); 410 411 if (!drv->ops->change_virtual_intf) { 412 err = -EOPNOTSUPP; 413 goto unlock; 414 } 415 416 if (type == NL80211_IFTYPE_MESH_POINT && 417 info->attrs[NL80211_ATTR_MESH_ID]) { 418 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); 419 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 420 } 421 422 rtnl_lock(); 423 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 424 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, 425 &flags); 426 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, 427 type, err ? NULL : &flags, ¶ms); 428 rtnl_unlock(); 429 430 unlock: 431 cfg80211_put_dev(drv); 432 return err; 433 } 434 435 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) 436 { 437 struct cfg80211_registered_device *drv; 438 struct vif_params params; 439 int err; 440 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; 441 u32 flags; 442 443 memset(¶ms, 0, sizeof(params)); 444 445 if (!info->attrs[NL80211_ATTR_IFNAME]) 446 return -EINVAL; 447 448 if (info->attrs[NL80211_ATTR_IFTYPE]) { 449 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 450 if (type > NL80211_IFTYPE_MAX) 451 return -EINVAL; 452 } 453 454 drv = cfg80211_get_dev_from_info(info); 455 if (IS_ERR(drv)) 456 return PTR_ERR(drv); 457 458 if (!drv->ops->add_virtual_intf) { 459 err = -EOPNOTSUPP; 460 goto unlock; 461 } 462 463 if (type == NL80211_IFTYPE_MESH_POINT && 464 info->attrs[NL80211_ATTR_MESH_ID]) { 465 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); 466 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 467 } 468 469 rtnl_lock(); 470 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 471 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, 472 &flags); 473 err = drv->ops->add_virtual_intf(&drv->wiphy, 474 nla_data(info->attrs[NL80211_ATTR_IFNAME]), 475 type, err ? NULL : &flags, ¶ms); 476 rtnl_unlock(); 477 478 479 unlock: 480 cfg80211_put_dev(drv); 481 return err; 482 } 483 484 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) 485 { 486 struct cfg80211_registered_device *drv; 487 int ifindex, err; 488 struct net_device *dev; 489 490 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 491 if (err) 492 return err; 493 ifindex = dev->ifindex; 494 dev_put(dev); 495 496 if (!drv->ops->del_virtual_intf) { 497 err = -EOPNOTSUPP; 498 goto out; 499 } 500 501 rtnl_lock(); 502 err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex); 503 rtnl_unlock(); 504 505 out: 506 cfg80211_put_dev(drv); 507 return err; 508 } 509 510 struct get_key_cookie { 511 struct sk_buff *msg; 512 int error; 513 }; 514 515 static void get_key_callback(void *c, struct key_params *params) 516 { 517 struct get_key_cookie *cookie = c; 518 519 if (params->key) 520 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA, 521 params->key_len, params->key); 522 523 if (params->seq) 524 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ, 525 params->seq_len, params->seq); 526 527 if (params->cipher) 528 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER, 529 params->cipher); 530 531 return; 532 nla_put_failure: 533 cookie->error = 1; 534 } 535 536 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) 537 { 538 struct cfg80211_registered_device *drv; 539 int err; 540 struct net_device *dev; 541 u8 key_idx = 0; 542 u8 *mac_addr = NULL; 543 struct get_key_cookie cookie = { 544 .error = 0, 545 }; 546 void *hdr; 547 struct sk_buff *msg; 548 549 if (info->attrs[NL80211_ATTR_KEY_IDX]) 550 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 551 552 if (key_idx > 3) 553 return -EINVAL; 554 555 if (info->attrs[NL80211_ATTR_MAC]) 556 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 557 558 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 559 if (err) 560 return err; 561 562 if (!drv->ops->get_key) { 563 err = -EOPNOTSUPP; 564 goto out; 565 } 566 567 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 568 if (!msg) { 569 err = -ENOMEM; 570 goto out; 571 } 572 573 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 574 NL80211_CMD_NEW_KEY); 575 576 if (IS_ERR(hdr)) { 577 err = PTR_ERR(hdr); 578 goto out; 579 } 580 581 cookie.msg = msg; 582 583 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 584 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx); 585 if (mac_addr) 586 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); 587 588 rtnl_lock(); 589 err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr, 590 &cookie, get_key_callback); 591 rtnl_unlock(); 592 593 if (err) 594 goto out; 595 596 if (cookie.error) 597 goto nla_put_failure; 598 599 genlmsg_end(msg, hdr); 600 err = genlmsg_unicast(msg, info->snd_pid); 601 goto out; 602 603 nla_put_failure: 604 err = -ENOBUFS; 605 nlmsg_free(msg); 606 out: 607 cfg80211_put_dev(drv); 608 dev_put(dev); 609 return err; 610 } 611 612 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) 613 { 614 struct cfg80211_registered_device *drv; 615 int err; 616 struct net_device *dev; 617 u8 key_idx; 618 619 if (!info->attrs[NL80211_ATTR_KEY_IDX]) 620 return -EINVAL; 621 622 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 623 624 if (key_idx > 3) 625 return -EINVAL; 626 627 /* currently only support setting default key */ 628 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT]) 629 return -EINVAL; 630 631 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 632 if (err) 633 return err; 634 635 if (!drv->ops->set_default_key) { 636 err = -EOPNOTSUPP; 637 goto out; 638 } 639 640 rtnl_lock(); 641 err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx); 642 rtnl_unlock(); 643 644 out: 645 cfg80211_put_dev(drv); 646 dev_put(dev); 647 return err; 648 } 649 650 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 651 { 652 struct cfg80211_registered_device *drv; 653 int err; 654 struct net_device *dev; 655 struct key_params params; 656 u8 key_idx = 0; 657 u8 *mac_addr = NULL; 658 659 memset(¶ms, 0, sizeof(params)); 660 661 if (!info->attrs[NL80211_ATTR_KEY_CIPHER]) 662 return -EINVAL; 663 664 if (info->attrs[NL80211_ATTR_KEY_DATA]) { 665 params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]); 666 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]); 667 } 668 669 if (info->attrs[NL80211_ATTR_KEY_IDX]) 670 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 671 672 params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]); 673 674 if (info->attrs[NL80211_ATTR_MAC]) 675 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 676 677 if (key_idx > 3) 678 return -EINVAL; 679 680 /* 681 * Disallow pairwise keys with non-zero index unless it's WEP 682 * (because current deployments use pairwise WEP keys with 683 * non-zero indizes but 802.11i clearly specifies to use zero) 684 */ 685 if (mac_addr && key_idx && 686 params.cipher != WLAN_CIPHER_SUITE_WEP40 && 687 params.cipher != WLAN_CIPHER_SUITE_WEP104) 688 return -EINVAL; 689 690 /* TODO: add definitions for the lengths to linux/ieee80211.h */ 691 switch (params.cipher) { 692 case WLAN_CIPHER_SUITE_WEP40: 693 if (params.key_len != 5) 694 return -EINVAL; 695 break; 696 case WLAN_CIPHER_SUITE_TKIP: 697 if (params.key_len != 32) 698 return -EINVAL; 699 break; 700 case WLAN_CIPHER_SUITE_CCMP: 701 if (params.key_len != 16) 702 return -EINVAL; 703 break; 704 case WLAN_CIPHER_SUITE_WEP104: 705 if (params.key_len != 13) 706 return -EINVAL; 707 break; 708 default: 709 return -EINVAL; 710 } 711 712 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 713 if (err) 714 return err; 715 716 if (!drv->ops->add_key) { 717 err = -EOPNOTSUPP; 718 goto out; 719 } 720 721 rtnl_lock(); 722 err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, ¶ms); 723 rtnl_unlock(); 724 725 out: 726 cfg80211_put_dev(drv); 727 dev_put(dev); 728 return err; 729 } 730 731 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) 732 { 733 struct cfg80211_registered_device *drv; 734 int err; 735 struct net_device *dev; 736 u8 key_idx = 0; 737 u8 *mac_addr = NULL; 738 739 if (info->attrs[NL80211_ATTR_KEY_IDX]) 740 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 741 742 if (key_idx > 3) 743 return -EINVAL; 744 745 if (info->attrs[NL80211_ATTR_MAC]) 746 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 747 748 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 749 if (err) 750 return err; 751 752 if (!drv->ops->del_key) { 753 err = -EOPNOTSUPP; 754 goto out; 755 } 756 757 rtnl_lock(); 758 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr); 759 rtnl_unlock(); 760 761 out: 762 cfg80211_put_dev(drv); 763 dev_put(dev); 764 return err; 765 } 766 767 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) 768 { 769 int (*call)(struct wiphy *wiphy, struct net_device *dev, 770 struct beacon_parameters *info); 771 struct cfg80211_registered_device *drv; 772 int err; 773 struct net_device *dev; 774 struct beacon_parameters params; 775 int haveinfo = 0; 776 777 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 778 if (err) 779 return err; 780 781 switch (info->genlhdr->cmd) { 782 case NL80211_CMD_NEW_BEACON: 783 /* these are required for NEW_BEACON */ 784 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || 785 !info->attrs[NL80211_ATTR_DTIM_PERIOD] || 786 !info->attrs[NL80211_ATTR_BEACON_HEAD]) { 787 err = -EINVAL; 788 goto out; 789 } 790 791 call = drv->ops->add_beacon; 792 break; 793 case NL80211_CMD_SET_BEACON: 794 call = drv->ops->set_beacon; 795 break; 796 default: 797 WARN_ON(1); 798 err = -EOPNOTSUPP; 799 goto out; 800 } 801 802 if (!call) { 803 err = -EOPNOTSUPP; 804 goto out; 805 } 806 807 memset(¶ms, 0, sizeof(params)); 808 809 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { 810 params.interval = 811 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); 812 haveinfo = 1; 813 } 814 815 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) { 816 params.dtim_period = 817 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); 818 haveinfo = 1; 819 } 820 821 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { 822 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); 823 params.head_len = 824 nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); 825 haveinfo = 1; 826 } 827 828 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { 829 params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); 830 params.tail_len = 831 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]); 832 haveinfo = 1; 833 } 834 835 if (!haveinfo) { 836 err = -EINVAL; 837 goto out; 838 } 839 840 rtnl_lock(); 841 err = call(&drv->wiphy, dev, ¶ms); 842 rtnl_unlock(); 843 844 out: 845 cfg80211_put_dev(drv); 846 dev_put(dev); 847 return err; 848 } 849 850 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) 851 { 852 struct cfg80211_registered_device *drv; 853 int err; 854 struct net_device *dev; 855 856 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 857 if (err) 858 return err; 859 860 if (!drv->ops->del_beacon) { 861 err = -EOPNOTSUPP; 862 goto out; 863 } 864 865 rtnl_lock(); 866 err = drv->ops->del_beacon(&drv->wiphy, dev); 867 rtnl_unlock(); 868 869 out: 870 cfg80211_put_dev(drv); 871 dev_put(dev); 872 return err; 873 } 874 875 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 876 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG }, 877 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, 878 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, 879 }; 880 881 static int parse_station_flags(struct nlattr *nla, u32 *staflags) 882 { 883 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; 884 int flag; 885 886 *staflags = 0; 887 888 if (!nla) 889 return 0; 890 891 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX, 892 nla, sta_flags_policy)) 893 return -EINVAL; 894 895 *staflags = STATION_FLAG_CHANGED; 896 897 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) 898 if (flags[flag]) 899 *staflags |= (1<<flag); 900 901 return 0; 902 } 903 904 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, 905 int flags, struct net_device *dev, 906 u8 *mac_addr, struct station_info *sinfo) 907 { 908 void *hdr; 909 struct nlattr *sinfoattr; 910 911 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); 912 if (!hdr) 913 return -1; 914 915 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 916 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); 917 918 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); 919 if (!sinfoattr) 920 goto nla_put_failure; 921 if (sinfo->filled & STATION_INFO_INACTIVE_TIME) 922 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, 923 sinfo->inactive_time); 924 if (sinfo->filled & STATION_INFO_RX_BYTES) 925 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES, 926 sinfo->rx_bytes); 927 if (sinfo->filled & STATION_INFO_TX_BYTES) 928 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES, 929 sinfo->tx_bytes); 930 if (sinfo->filled & STATION_INFO_LLID) 931 NLA_PUT_U16(msg, NL80211_STA_INFO_LLID, 932 sinfo->llid); 933 if (sinfo->filled & STATION_INFO_PLID) 934 NLA_PUT_U16(msg, NL80211_STA_INFO_PLID, 935 sinfo->plid); 936 if (sinfo->filled & STATION_INFO_PLINK_STATE) 937 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE, 938 sinfo->plink_state); 939 940 nla_nest_end(msg, sinfoattr); 941 942 return genlmsg_end(msg, hdr); 943 944 nla_put_failure: 945 genlmsg_cancel(msg, hdr); 946 return -EMSGSIZE; 947 } 948 949 static int nl80211_dump_station(struct sk_buff *skb, 950 struct netlink_callback *cb) 951 { 952 struct station_info sinfo; 953 struct cfg80211_registered_device *dev; 954 struct net_device *netdev; 955 u8 mac_addr[ETH_ALEN]; 956 int ifidx = cb->args[0]; 957 int sta_idx = cb->args[1]; 958 int err; 959 960 if (!ifidx) { 961 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 962 nl80211_fam.attrbuf, nl80211_fam.maxattr, 963 nl80211_policy); 964 if (err) 965 return err; 966 967 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]) 968 return -EINVAL; 969 970 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]); 971 if (!ifidx) 972 return -EINVAL; 973 } 974 975 netdev = dev_get_by_index(&init_net, ifidx); 976 if (!netdev) 977 return -ENODEV; 978 979 dev = cfg80211_get_dev_from_ifindex(ifidx); 980 if (IS_ERR(dev)) { 981 err = PTR_ERR(dev); 982 goto out_put_netdev; 983 } 984 985 if (!dev->ops->dump_station) { 986 err = -ENOSYS; 987 goto out_err; 988 } 989 990 rtnl_lock(); 991 992 while (1) { 993 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, 994 mac_addr, &sinfo); 995 if (err == -ENOENT) 996 break; 997 if (err) 998 goto out_err_rtnl; 999 1000 if (nl80211_send_station(skb, 1001 NETLINK_CB(cb->skb).pid, 1002 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1003 netdev, mac_addr, 1004 &sinfo) < 0) 1005 goto out; 1006 1007 sta_idx++; 1008 } 1009 1010 1011 out: 1012 cb->args[1] = sta_idx; 1013 err = skb->len; 1014 out_err_rtnl: 1015 rtnl_unlock(); 1016 out_err: 1017 cfg80211_put_dev(dev); 1018 out_put_netdev: 1019 dev_put(netdev); 1020 1021 return err; 1022 } 1023 1024 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) 1025 { 1026 struct cfg80211_registered_device *drv; 1027 int err; 1028 struct net_device *dev; 1029 struct station_info sinfo; 1030 struct sk_buff *msg; 1031 u8 *mac_addr = NULL; 1032 1033 memset(&sinfo, 0, sizeof(sinfo)); 1034 1035 if (!info->attrs[NL80211_ATTR_MAC]) 1036 return -EINVAL; 1037 1038 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1039 1040 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1041 if (err) 1042 return err; 1043 1044 if (!drv->ops->get_station) { 1045 err = -EOPNOTSUPP; 1046 goto out; 1047 } 1048 1049 rtnl_lock(); 1050 err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo); 1051 rtnl_unlock(); 1052 1053 if (err) 1054 goto out; 1055 1056 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1057 if (!msg) 1058 goto out; 1059 1060 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, 1061 dev, mac_addr, &sinfo) < 0) 1062 goto out_free; 1063 1064 err = genlmsg_unicast(msg, info->snd_pid); 1065 goto out; 1066 1067 out_free: 1068 nlmsg_free(msg); 1069 1070 out: 1071 cfg80211_put_dev(drv); 1072 dev_put(dev); 1073 return err; 1074 } 1075 1076 /* 1077 * Get vlan interface making sure it is on the right wiphy. 1078 */ 1079 static int get_vlan(struct nlattr *vlanattr, 1080 struct cfg80211_registered_device *rdev, 1081 struct net_device **vlan) 1082 { 1083 *vlan = NULL; 1084 1085 if (vlanattr) { 1086 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr)); 1087 if (!*vlan) 1088 return -ENODEV; 1089 if (!(*vlan)->ieee80211_ptr) 1090 return -EINVAL; 1091 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy) 1092 return -EINVAL; 1093 } 1094 return 0; 1095 } 1096 1097 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) 1098 { 1099 struct cfg80211_registered_device *drv; 1100 int err; 1101 struct net_device *dev; 1102 struct station_parameters params; 1103 u8 *mac_addr = NULL; 1104 1105 memset(¶ms, 0, sizeof(params)); 1106 1107 params.listen_interval = -1; 1108 1109 if (info->attrs[NL80211_ATTR_STA_AID]) 1110 return -EINVAL; 1111 1112 if (!info->attrs[NL80211_ATTR_MAC]) 1113 return -EINVAL; 1114 1115 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1116 1117 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) { 1118 params.supported_rates = 1119 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 1120 params.supported_rates_len = 1121 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 1122 } 1123 1124 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) 1125 params.listen_interval = 1126 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1127 1128 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1129 ¶ms.station_flags)) 1130 return -EINVAL; 1131 1132 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) 1133 params.plink_action = 1134 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 1135 1136 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1137 if (err) 1138 return err; 1139 1140 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); 1141 if (err) 1142 goto out; 1143 1144 if (!drv->ops->change_station) { 1145 err = -EOPNOTSUPP; 1146 goto out; 1147 } 1148 1149 rtnl_lock(); 1150 err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, ¶ms); 1151 rtnl_unlock(); 1152 1153 out: 1154 if (params.vlan) 1155 dev_put(params.vlan); 1156 cfg80211_put_dev(drv); 1157 dev_put(dev); 1158 return err; 1159 } 1160 1161 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) 1162 { 1163 struct cfg80211_registered_device *drv; 1164 int err; 1165 struct net_device *dev; 1166 struct station_parameters params; 1167 u8 *mac_addr = NULL; 1168 1169 memset(¶ms, 0, sizeof(params)); 1170 1171 if (!info->attrs[NL80211_ATTR_MAC]) 1172 return -EINVAL; 1173 1174 if (!info->attrs[NL80211_ATTR_STA_AID]) 1175 return -EINVAL; 1176 1177 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) 1178 return -EINVAL; 1179 1180 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) 1181 return -EINVAL; 1182 1183 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1184 params.supported_rates = 1185 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 1186 params.supported_rates_len = 1187 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 1188 params.listen_interval = 1189 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1190 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 1191 1192 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1193 ¶ms.station_flags)) 1194 return -EINVAL; 1195 1196 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1197 if (err) 1198 return err; 1199 1200 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); 1201 if (err) 1202 goto out; 1203 1204 if (!drv->ops->add_station) { 1205 err = -EOPNOTSUPP; 1206 goto out; 1207 } 1208 1209 rtnl_lock(); 1210 err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, ¶ms); 1211 rtnl_unlock(); 1212 1213 out: 1214 if (params.vlan) 1215 dev_put(params.vlan); 1216 cfg80211_put_dev(drv); 1217 dev_put(dev); 1218 return err; 1219 } 1220 1221 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) 1222 { 1223 struct cfg80211_registered_device *drv; 1224 int err; 1225 struct net_device *dev; 1226 u8 *mac_addr = NULL; 1227 1228 if (info->attrs[NL80211_ATTR_MAC]) 1229 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1230 1231 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1232 if (err) 1233 return err; 1234 1235 if (!drv->ops->del_station) { 1236 err = -EOPNOTSUPP; 1237 goto out; 1238 } 1239 1240 rtnl_lock(); 1241 err = drv->ops->del_station(&drv->wiphy, dev, mac_addr); 1242 rtnl_unlock(); 1243 1244 out: 1245 cfg80211_put_dev(drv); 1246 dev_put(dev); 1247 return err; 1248 } 1249 1250 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, 1251 int flags, struct net_device *dev, 1252 u8 *dst, u8 *next_hop, 1253 struct mpath_info *pinfo) 1254 { 1255 void *hdr; 1256 struct nlattr *pinfoattr; 1257 1258 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); 1259 if (!hdr) 1260 return -1; 1261 1262 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 1263 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst); 1264 NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop); 1265 1266 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO); 1267 if (!pinfoattr) 1268 goto nla_put_failure; 1269 if (pinfo->filled & MPATH_INFO_FRAME_QLEN) 1270 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN, 1271 pinfo->frame_qlen); 1272 if (pinfo->filled & MPATH_INFO_DSN) 1273 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN, 1274 pinfo->dsn); 1275 if (pinfo->filled & MPATH_INFO_METRIC) 1276 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC, 1277 pinfo->metric); 1278 if (pinfo->filled & MPATH_INFO_EXPTIME) 1279 NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME, 1280 pinfo->exptime); 1281 if (pinfo->filled & MPATH_INFO_FLAGS) 1282 NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS, 1283 pinfo->flags); 1284 if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) 1285 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, 1286 pinfo->discovery_timeout); 1287 if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) 1288 NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES, 1289 pinfo->discovery_retries); 1290 1291 nla_nest_end(msg, pinfoattr); 1292 1293 return genlmsg_end(msg, hdr); 1294 1295 nla_put_failure: 1296 genlmsg_cancel(msg, hdr); 1297 return -EMSGSIZE; 1298 } 1299 1300 static int nl80211_dump_mpath(struct sk_buff *skb, 1301 struct netlink_callback *cb) 1302 { 1303 struct mpath_info pinfo; 1304 struct cfg80211_registered_device *dev; 1305 struct net_device *netdev; 1306 u8 dst[ETH_ALEN]; 1307 u8 next_hop[ETH_ALEN]; 1308 int ifidx = cb->args[0]; 1309 int path_idx = cb->args[1]; 1310 int err; 1311 1312 if (!ifidx) { 1313 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1314 nl80211_fam.attrbuf, nl80211_fam.maxattr, 1315 nl80211_policy); 1316 if (err) 1317 return err; 1318 1319 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]) 1320 return -EINVAL; 1321 1322 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]); 1323 if (!ifidx) 1324 return -EINVAL; 1325 } 1326 1327 netdev = dev_get_by_index(&init_net, ifidx); 1328 if (!netdev) 1329 return -ENODEV; 1330 1331 dev = cfg80211_get_dev_from_ifindex(ifidx); 1332 if (IS_ERR(dev)) { 1333 err = PTR_ERR(dev); 1334 goto out_put_netdev; 1335 } 1336 1337 if (!dev->ops->dump_mpath) { 1338 err = -ENOSYS; 1339 goto out_err; 1340 } 1341 1342 rtnl_lock(); 1343 1344 while (1) { 1345 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx, 1346 dst, next_hop, &pinfo); 1347 if (err == -ENOENT) 1348 break; 1349 if (err) 1350 goto out_err_rtnl; 1351 1352 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid, 1353 cb->nlh->nlmsg_seq, NLM_F_MULTI, 1354 netdev, dst, next_hop, 1355 &pinfo) < 0) 1356 goto out; 1357 1358 path_idx++; 1359 } 1360 1361 1362 out: 1363 cb->args[1] = path_idx; 1364 err = skb->len; 1365 out_err_rtnl: 1366 rtnl_unlock(); 1367 out_err: 1368 cfg80211_put_dev(dev); 1369 out_put_netdev: 1370 dev_put(netdev); 1371 1372 return err; 1373 } 1374 1375 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) 1376 { 1377 struct cfg80211_registered_device *drv; 1378 int err; 1379 struct net_device *dev; 1380 struct mpath_info pinfo; 1381 struct sk_buff *msg; 1382 u8 *dst = NULL; 1383 u8 next_hop[ETH_ALEN]; 1384 1385 memset(&pinfo, 0, sizeof(pinfo)); 1386 1387 if (!info->attrs[NL80211_ATTR_MAC]) 1388 return -EINVAL; 1389 1390 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1391 1392 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1393 if (err) 1394 return err; 1395 1396 if (!drv->ops->get_mpath) { 1397 err = -EOPNOTSUPP; 1398 goto out; 1399 } 1400 1401 rtnl_lock(); 1402 err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo); 1403 rtnl_unlock(); 1404 1405 if (err) 1406 goto out; 1407 1408 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1409 if (!msg) 1410 goto out; 1411 1412 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0, 1413 dev, dst, next_hop, &pinfo) < 0) 1414 goto out_free; 1415 1416 err = genlmsg_unicast(msg, info->snd_pid); 1417 goto out; 1418 1419 out_free: 1420 nlmsg_free(msg); 1421 1422 out: 1423 cfg80211_put_dev(drv); 1424 dev_put(dev); 1425 return err; 1426 } 1427 1428 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) 1429 { 1430 struct cfg80211_registered_device *drv; 1431 int err; 1432 struct net_device *dev; 1433 u8 *dst = NULL; 1434 u8 *next_hop = NULL; 1435 1436 if (!info->attrs[NL80211_ATTR_MAC]) 1437 return -EINVAL; 1438 1439 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]) 1440 return -EINVAL; 1441 1442 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1443 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 1444 1445 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1446 if (err) 1447 return err; 1448 1449 if (!drv->ops->change_mpath) { 1450 err = -EOPNOTSUPP; 1451 goto out; 1452 } 1453 1454 rtnl_lock(); 1455 err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop); 1456 rtnl_unlock(); 1457 1458 out: 1459 cfg80211_put_dev(drv); 1460 dev_put(dev); 1461 return err; 1462 } 1463 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) 1464 { 1465 struct cfg80211_registered_device *drv; 1466 int err; 1467 struct net_device *dev; 1468 u8 *dst = NULL; 1469 u8 *next_hop = NULL; 1470 1471 if (!info->attrs[NL80211_ATTR_MAC]) 1472 return -EINVAL; 1473 1474 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]) 1475 return -EINVAL; 1476 1477 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1478 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); 1479 1480 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1481 if (err) 1482 return err; 1483 1484 if (!drv->ops->add_mpath) { 1485 err = -EOPNOTSUPP; 1486 goto out; 1487 } 1488 1489 rtnl_lock(); 1490 err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop); 1491 rtnl_unlock(); 1492 1493 out: 1494 cfg80211_put_dev(drv); 1495 dev_put(dev); 1496 return err; 1497 } 1498 1499 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) 1500 { 1501 struct cfg80211_registered_device *drv; 1502 int err; 1503 struct net_device *dev; 1504 u8 *dst = NULL; 1505 1506 if (info->attrs[NL80211_ATTR_MAC]) 1507 dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 1508 1509 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1510 if (err) 1511 return err; 1512 1513 if (!drv->ops->del_mpath) { 1514 err = -EOPNOTSUPP; 1515 goto out; 1516 } 1517 1518 rtnl_lock(); 1519 err = drv->ops->del_mpath(&drv->wiphy, dev, dst); 1520 rtnl_unlock(); 1521 1522 out: 1523 cfg80211_put_dev(drv); 1524 dev_put(dev); 1525 return err; 1526 } 1527 1528 static struct genl_ops nl80211_ops[] = { 1529 { 1530 .cmd = NL80211_CMD_GET_WIPHY, 1531 .doit = nl80211_get_wiphy, 1532 .dumpit = nl80211_dump_wiphy, 1533 .policy = nl80211_policy, 1534 /* can be retrieved by unprivileged users */ 1535 }, 1536 { 1537 .cmd = NL80211_CMD_SET_WIPHY, 1538 .doit = nl80211_set_wiphy, 1539 .policy = nl80211_policy, 1540 .flags = GENL_ADMIN_PERM, 1541 }, 1542 { 1543 .cmd = NL80211_CMD_GET_INTERFACE, 1544 .doit = nl80211_get_interface, 1545 .dumpit = nl80211_dump_interface, 1546 .policy = nl80211_policy, 1547 /* can be retrieved by unprivileged users */ 1548 }, 1549 { 1550 .cmd = NL80211_CMD_SET_INTERFACE, 1551 .doit = nl80211_set_interface, 1552 .policy = nl80211_policy, 1553 .flags = GENL_ADMIN_PERM, 1554 }, 1555 { 1556 .cmd = NL80211_CMD_NEW_INTERFACE, 1557 .doit = nl80211_new_interface, 1558 .policy = nl80211_policy, 1559 .flags = GENL_ADMIN_PERM, 1560 }, 1561 { 1562 .cmd = NL80211_CMD_DEL_INTERFACE, 1563 .doit = nl80211_del_interface, 1564 .policy = nl80211_policy, 1565 .flags = GENL_ADMIN_PERM, 1566 }, 1567 { 1568 .cmd = NL80211_CMD_GET_KEY, 1569 .doit = nl80211_get_key, 1570 .policy = nl80211_policy, 1571 .flags = GENL_ADMIN_PERM, 1572 }, 1573 { 1574 .cmd = NL80211_CMD_SET_KEY, 1575 .doit = nl80211_set_key, 1576 .policy = nl80211_policy, 1577 .flags = GENL_ADMIN_PERM, 1578 }, 1579 { 1580 .cmd = NL80211_CMD_NEW_KEY, 1581 .doit = nl80211_new_key, 1582 .policy = nl80211_policy, 1583 .flags = GENL_ADMIN_PERM, 1584 }, 1585 { 1586 .cmd = NL80211_CMD_DEL_KEY, 1587 .doit = nl80211_del_key, 1588 .policy = nl80211_policy, 1589 .flags = GENL_ADMIN_PERM, 1590 }, 1591 { 1592 .cmd = NL80211_CMD_SET_BEACON, 1593 .policy = nl80211_policy, 1594 .flags = GENL_ADMIN_PERM, 1595 .doit = nl80211_addset_beacon, 1596 }, 1597 { 1598 .cmd = NL80211_CMD_NEW_BEACON, 1599 .policy = nl80211_policy, 1600 .flags = GENL_ADMIN_PERM, 1601 .doit = nl80211_addset_beacon, 1602 }, 1603 { 1604 .cmd = NL80211_CMD_DEL_BEACON, 1605 .policy = nl80211_policy, 1606 .flags = GENL_ADMIN_PERM, 1607 .doit = nl80211_del_beacon, 1608 }, 1609 { 1610 .cmd = NL80211_CMD_GET_STATION, 1611 .doit = nl80211_get_station, 1612 .dumpit = nl80211_dump_station, 1613 .policy = nl80211_policy, 1614 .flags = GENL_ADMIN_PERM, 1615 }, 1616 { 1617 .cmd = NL80211_CMD_SET_STATION, 1618 .doit = nl80211_set_station, 1619 .policy = nl80211_policy, 1620 .flags = GENL_ADMIN_PERM, 1621 }, 1622 { 1623 .cmd = NL80211_CMD_NEW_STATION, 1624 .doit = nl80211_new_station, 1625 .policy = nl80211_policy, 1626 .flags = GENL_ADMIN_PERM, 1627 }, 1628 { 1629 .cmd = NL80211_CMD_DEL_STATION, 1630 .doit = nl80211_del_station, 1631 .policy = nl80211_policy, 1632 .flags = GENL_ADMIN_PERM, 1633 }, 1634 { 1635 .cmd = NL80211_CMD_GET_MPATH, 1636 .doit = nl80211_get_mpath, 1637 .dumpit = nl80211_dump_mpath, 1638 .policy = nl80211_policy, 1639 .flags = GENL_ADMIN_PERM, 1640 }, 1641 { 1642 .cmd = NL80211_CMD_SET_MPATH, 1643 .doit = nl80211_set_mpath, 1644 .policy = nl80211_policy, 1645 .flags = GENL_ADMIN_PERM, 1646 }, 1647 { 1648 .cmd = NL80211_CMD_NEW_MPATH, 1649 .doit = nl80211_new_mpath, 1650 .policy = nl80211_policy, 1651 .flags = GENL_ADMIN_PERM, 1652 }, 1653 { 1654 .cmd = NL80211_CMD_DEL_MPATH, 1655 .doit = nl80211_del_mpath, 1656 .policy = nl80211_policy, 1657 .flags = GENL_ADMIN_PERM, 1658 }, 1659 }; 1660 1661 /* multicast groups */ 1662 static struct genl_multicast_group nl80211_config_mcgrp = { 1663 .name = "config", 1664 }; 1665 1666 /* notification functions */ 1667 1668 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) 1669 { 1670 struct sk_buff *msg; 1671 1672 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1673 if (!msg) 1674 return; 1675 1676 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) { 1677 nlmsg_free(msg); 1678 return; 1679 } 1680 1681 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 1682 } 1683 1684 /* initialisation/exit functions */ 1685 1686 int nl80211_init(void) 1687 { 1688 int err, i; 1689 1690 err = genl_register_family(&nl80211_fam); 1691 if (err) 1692 return err; 1693 1694 for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) { 1695 err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]); 1696 if (err) 1697 goto err_out; 1698 } 1699 1700 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); 1701 if (err) 1702 goto err_out; 1703 1704 return 0; 1705 err_out: 1706 genl_unregister_family(&nl80211_fam); 1707 return err; 1708 } 1709 1710 void nl80211_exit(void) 1711 { 1712 genl_unregister_family(&nl80211_fam); 1713 } 1714