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