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