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