1 /* 2 * mac80211 configuration hooks for cfg80211 3 * 4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 5 * 6 * This file is GPLv2 as found in COPYING. 7 */ 8 9 #include <linux/ieee80211.h> 10 #include <linux/nl80211.h> 11 #include <linux/rtnetlink.h> 12 #include <net/net_namespace.h> 13 #include <linux/rcupdate.h> 14 #include <net/cfg80211.h> 15 #include "ieee80211_i.h" 16 #include "cfg.h" 17 #include "rate.h" 18 #include "mesh.h" 19 20 static enum ieee80211_if_types 21 nl80211_type_to_mac80211_type(enum nl80211_iftype type) 22 { 23 switch (type) { 24 case NL80211_IFTYPE_UNSPECIFIED: 25 return IEEE80211_IF_TYPE_STA; 26 case NL80211_IFTYPE_ADHOC: 27 return IEEE80211_IF_TYPE_IBSS; 28 case NL80211_IFTYPE_STATION: 29 return IEEE80211_IF_TYPE_STA; 30 case NL80211_IFTYPE_MONITOR: 31 return IEEE80211_IF_TYPE_MNTR; 32 #ifdef CONFIG_MAC80211_MESH 33 case NL80211_IFTYPE_MESH_POINT: 34 return IEEE80211_IF_TYPE_MESH_POINT; 35 #endif 36 case NL80211_IFTYPE_WDS: 37 return IEEE80211_IF_TYPE_WDS; 38 default: 39 return IEEE80211_IF_TYPE_INVALID; 40 } 41 } 42 43 static int ieee80211_add_iface(struct wiphy *wiphy, char *name, 44 enum nl80211_iftype type, u32 *flags, 45 struct vif_params *params) 46 { 47 struct ieee80211_local *local = wiphy_priv(wiphy); 48 enum ieee80211_if_types itype; 49 struct net_device *dev; 50 struct ieee80211_sub_if_data *sdata; 51 int err; 52 53 itype = nl80211_type_to_mac80211_type(type); 54 if (itype == IEEE80211_IF_TYPE_INVALID) 55 return -EINVAL; 56 57 err = ieee80211_if_add(local, name, &dev, itype, params); 58 if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) 59 return err; 60 61 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 62 sdata->u.mntr_flags = *flags; 63 return 0; 64 } 65 66 static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) 67 { 68 struct net_device *dev; 69 70 /* we're under RTNL */ 71 dev = __dev_get_by_index(&init_net, ifindex); 72 if (!dev) 73 return -ENODEV; 74 75 ieee80211_if_remove(dev); 76 77 return 0; 78 } 79 80 static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, 81 enum nl80211_iftype type, u32 *flags, 82 struct vif_params *params) 83 { 84 struct net_device *dev; 85 enum ieee80211_if_types itype; 86 struct ieee80211_sub_if_data *sdata; 87 int ret; 88 89 /* we're under RTNL */ 90 dev = __dev_get_by_index(&init_net, ifindex); 91 if (!dev) 92 return -ENODEV; 93 94 itype = nl80211_type_to_mac80211_type(type); 95 if (itype == IEEE80211_IF_TYPE_INVALID) 96 return -EINVAL; 97 98 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 99 100 ret = ieee80211_if_change_type(sdata, itype); 101 if (ret) 102 return ret; 103 104 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) 105 ieee80211_if_sta_set_mesh_id(&sdata->u.sta, 106 params->mesh_id_len, 107 params->mesh_id); 108 109 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags) 110 return 0; 111 112 sdata->u.mntr_flags = *flags; 113 return 0; 114 } 115 116 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 117 u8 key_idx, u8 *mac_addr, 118 struct key_params *params) 119 { 120 struct ieee80211_sub_if_data *sdata; 121 struct sta_info *sta = NULL; 122 enum ieee80211_key_alg alg; 123 struct ieee80211_key *key; 124 int err; 125 126 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 127 128 switch (params->cipher) { 129 case WLAN_CIPHER_SUITE_WEP40: 130 case WLAN_CIPHER_SUITE_WEP104: 131 alg = ALG_WEP; 132 break; 133 case WLAN_CIPHER_SUITE_TKIP: 134 alg = ALG_TKIP; 135 break; 136 case WLAN_CIPHER_SUITE_CCMP: 137 alg = ALG_CCMP; 138 break; 139 default: 140 return -EINVAL; 141 } 142 143 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key); 144 if (!key) 145 return -ENOMEM; 146 147 rcu_read_lock(); 148 149 if (mac_addr) { 150 sta = sta_info_get(sdata->local, mac_addr); 151 if (!sta) { 152 ieee80211_key_free(key); 153 err = -ENOENT; 154 goto out_unlock; 155 } 156 } 157 158 ieee80211_key_link(key, sdata, sta); 159 160 err = 0; 161 out_unlock: 162 rcu_read_unlock(); 163 164 return err; 165 } 166 167 static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 168 u8 key_idx, u8 *mac_addr) 169 { 170 struct ieee80211_sub_if_data *sdata; 171 struct sta_info *sta; 172 int ret; 173 174 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 175 176 rcu_read_lock(); 177 178 if (mac_addr) { 179 ret = -ENOENT; 180 181 sta = sta_info_get(sdata->local, mac_addr); 182 if (!sta) 183 goto out_unlock; 184 185 if (sta->key) { 186 ieee80211_key_free(sta->key); 187 WARN_ON(sta->key); 188 ret = 0; 189 } 190 191 goto out_unlock; 192 } 193 194 if (!sdata->keys[key_idx]) { 195 ret = -ENOENT; 196 goto out_unlock; 197 } 198 199 ieee80211_key_free(sdata->keys[key_idx]); 200 WARN_ON(sdata->keys[key_idx]); 201 202 ret = 0; 203 out_unlock: 204 rcu_read_unlock(); 205 206 return ret; 207 } 208 209 static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 210 u8 key_idx, u8 *mac_addr, void *cookie, 211 void (*callback)(void *cookie, 212 struct key_params *params)) 213 { 214 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 215 struct sta_info *sta = NULL; 216 u8 seq[6] = {0}; 217 struct key_params params; 218 struct ieee80211_key *key; 219 u32 iv32; 220 u16 iv16; 221 int err = -ENOENT; 222 223 rcu_read_lock(); 224 225 if (mac_addr) { 226 sta = sta_info_get(sdata->local, mac_addr); 227 if (!sta) 228 goto out; 229 230 key = sta->key; 231 } else 232 key = sdata->keys[key_idx]; 233 234 if (!key) 235 goto out; 236 237 memset(¶ms, 0, sizeof(params)); 238 239 switch (key->conf.alg) { 240 case ALG_TKIP: 241 params.cipher = WLAN_CIPHER_SUITE_TKIP; 242 243 iv32 = key->u.tkip.tx.iv32; 244 iv16 = key->u.tkip.tx.iv16; 245 246 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && 247 sdata->local->ops->get_tkip_seq) 248 sdata->local->ops->get_tkip_seq( 249 local_to_hw(sdata->local), 250 key->conf.hw_key_idx, 251 &iv32, &iv16); 252 253 seq[0] = iv16 & 0xff; 254 seq[1] = (iv16 >> 8) & 0xff; 255 seq[2] = iv32 & 0xff; 256 seq[3] = (iv32 >> 8) & 0xff; 257 seq[4] = (iv32 >> 16) & 0xff; 258 seq[5] = (iv32 >> 24) & 0xff; 259 params.seq = seq; 260 params.seq_len = 6; 261 break; 262 case ALG_CCMP: 263 params.cipher = WLAN_CIPHER_SUITE_CCMP; 264 seq[0] = key->u.ccmp.tx_pn[5]; 265 seq[1] = key->u.ccmp.tx_pn[4]; 266 seq[2] = key->u.ccmp.tx_pn[3]; 267 seq[3] = key->u.ccmp.tx_pn[2]; 268 seq[4] = key->u.ccmp.tx_pn[1]; 269 seq[5] = key->u.ccmp.tx_pn[0]; 270 params.seq = seq; 271 params.seq_len = 6; 272 break; 273 case ALG_WEP: 274 if (key->conf.keylen == 5) 275 params.cipher = WLAN_CIPHER_SUITE_WEP40; 276 else 277 params.cipher = WLAN_CIPHER_SUITE_WEP104; 278 break; 279 } 280 281 params.key = key->conf.key; 282 params.key_len = key->conf.keylen; 283 284 callback(cookie, ¶ms); 285 err = 0; 286 287 out: 288 rcu_read_unlock(); 289 return err; 290 } 291 292 static int ieee80211_config_default_key(struct wiphy *wiphy, 293 struct net_device *dev, 294 u8 key_idx) 295 { 296 struct ieee80211_sub_if_data *sdata; 297 298 rcu_read_lock(); 299 300 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 301 ieee80211_set_default_key(sdata, key_idx); 302 303 rcu_read_unlock(); 304 305 return 0; 306 } 307 308 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 309 { 310 struct ieee80211_sub_if_data *sdata = sta->sdata; 311 312 sinfo->filled = STATION_INFO_INACTIVE_TIME | 313 STATION_INFO_RX_BYTES | 314 STATION_INFO_TX_BYTES; 315 316 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 317 sinfo->rx_bytes = sta->rx_bytes; 318 sinfo->tx_bytes = sta->tx_bytes; 319 320 if (ieee80211_vif_is_mesh(&sdata->vif)) { 321 #ifdef CONFIG_MAC80211_MESH 322 sinfo->filled |= STATION_INFO_LLID | 323 STATION_INFO_PLID | 324 STATION_INFO_PLINK_STATE; 325 326 sinfo->llid = le16_to_cpu(sta->llid); 327 sinfo->plid = le16_to_cpu(sta->plid); 328 sinfo->plink_state = sta->plink_state; 329 #endif 330 } 331 } 332 333 334 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, 335 int idx, u8 *mac, struct station_info *sinfo) 336 { 337 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 338 struct sta_info *sta; 339 int ret = -ENOENT; 340 341 rcu_read_lock(); 342 343 sta = sta_info_get_by_idx(local, idx, dev); 344 if (sta) { 345 ret = 0; 346 memcpy(mac, sta->addr, ETH_ALEN); 347 sta_set_sinfo(sta, sinfo); 348 } 349 350 rcu_read_unlock(); 351 352 return ret; 353 } 354 355 static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 356 u8 *mac, struct station_info *sinfo) 357 { 358 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 359 struct sta_info *sta; 360 int ret = -ENOENT; 361 362 rcu_read_lock(); 363 364 /* XXX: verify sta->dev == dev */ 365 366 sta = sta_info_get(local, mac); 367 if (sta) { 368 ret = 0; 369 sta_set_sinfo(sta, sinfo); 370 } 371 372 rcu_read_unlock(); 373 374 return ret; 375 } 376 377 /* 378 * This handles both adding a beacon and setting new beacon info 379 */ 380 static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, 381 struct beacon_parameters *params) 382 { 383 struct beacon_data *new, *old; 384 int new_head_len, new_tail_len; 385 int size; 386 int err = -EINVAL; 387 388 old = sdata->u.ap.beacon; 389 390 /* head must not be zero-length */ 391 if (params->head && !params->head_len) 392 return -EINVAL; 393 394 /* 395 * This is a kludge. beacon interval should really be part 396 * of the beacon information. 397 */ 398 if (params->interval) { 399 sdata->local->hw.conf.beacon_int = params->interval; 400 if (ieee80211_hw_config(sdata->local)) 401 return -EINVAL; 402 /* 403 * We updated some parameter so if below bails out 404 * it's not an error. 405 */ 406 err = 0; 407 } 408 409 /* Need to have a beacon head if we don't have one yet */ 410 if (!params->head && !old) 411 return err; 412 413 /* sorry, no way to start beaconing without dtim period */ 414 if (!params->dtim_period && !old) 415 return err; 416 417 /* new or old head? */ 418 if (params->head) 419 new_head_len = params->head_len; 420 else 421 new_head_len = old->head_len; 422 423 /* new or old tail? */ 424 if (params->tail || !old) 425 /* params->tail_len will be zero for !params->tail */ 426 new_tail_len = params->tail_len; 427 else 428 new_tail_len = old->tail_len; 429 430 size = sizeof(*new) + new_head_len + new_tail_len; 431 432 new = kzalloc(size, GFP_KERNEL); 433 if (!new) 434 return -ENOMEM; 435 436 /* start filling the new info now */ 437 438 /* new or old dtim period? */ 439 if (params->dtim_period) 440 new->dtim_period = params->dtim_period; 441 else 442 new->dtim_period = old->dtim_period; 443 444 /* 445 * pointers go into the block we allocated, 446 * memory is | beacon_data | head | tail | 447 */ 448 new->head = ((u8 *) new) + sizeof(*new); 449 new->tail = new->head + new_head_len; 450 new->head_len = new_head_len; 451 new->tail_len = new_tail_len; 452 453 /* copy in head */ 454 if (params->head) 455 memcpy(new->head, params->head, new_head_len); 456 else 457 memcpy(new->head, old->head, new_head_len); 458 459 /* copy in optional tail */ 460 if (params->tail) 461 memcpy(new->tail, params->tail, new_tail_len); 462 else 463 if (old) 464 memcpy(new->tail, old->tail, new_tail_len); 465 466 rcu_assign_pointer(sdata->u.ap.beacon, new); 467 468 synchronize_rcu(); 469 470 kfree(old); 471 472 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 473 } 474 475 static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 476 struct beacon_parameters *params) 477 { 478 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 479 struct beacon_data *old; 480 481 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 482 return -EINVAL; 483 484 old = sdata->u.ap.beacon; 485 486 if (old) 487 return -EALREADY; 488 489 return ieee80211_config_beacon(sdata, params); 490 } 491 492 static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, 493 struct beacon_parameters *params) 494 { 495 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 496 struct beacon_data *old; 497 498 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 499 return -EINVAL; 500 501 old = sdata->u.ap.beacon; 502 503 if (!old) 504 return -ENOENT; 505 506 return ieee80211_config_beacon(sdata, params); 507 } 508 509 static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) 510 { 511 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 512 struct beacon_data *old; 513 514 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 515 return -EINVAL; 516 517 old = sdata->u.ap.beacon; 518 519 if (!old) 520 return -ENOENT; 521 522 rcu_assign_pointer(sdata->u.ap.beacon, NULL); 523 synchronize_rcu(); 524 kfree(old); 525 526 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 527 } 528 529 /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 530 struct iapp_layer2_update { 531 u8 da[ETH_ALEN]; /* broadcast */ 532 u8 sa[ETH_ALEN]; /* STA addr */ 533 __be16 len; /* 6 */ 534 u8 dsap; /* 0 */ 535 u8 ssap; /* 0 */ 536 u8 control; 537 u8 xid_info[3]; 538 } __attribute__ ((packed)); 539 540 static void ieee80211_send_layer2_update(struct sta_info *sta) 541 { 542 struct iapp_layer2_update *msg; 543 struct sk_buff *skb; 544 545 /* Send Level 2 Update Frame to update forwarding tables in layer 2 546 * bridge devices */ 547 548 skb = dev_alloc_skb(sizeof(*msg)); 549 if (!skb) 550 return; 551 msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg)); 552 553 /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) 554 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ 555 556 memset(msg->da, 0xff, ETH_ALEN); 557 memcpy(msg->sa, sta->addr, ETH_ALEN); 558 msg->len = htons(6); 559 msg->dsap = 0; 560 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ 561 msg->control = 0xaf; /* XID response lsb.1111F101. 562 * F=0 (no poll command; unsolicited frame) */ 563 msg->xid_info[0] = 0x81; /* XID format identifier */ 564 msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ 565 msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */ 566 567 skb->dev = sta->sdata->dev; 568 skb->protocol = eth_type_trans(skb, sta->sdata->dev); 569 memset(skb->cb, 0, sizeof(skb->cb)); 570 netif_rx(skb); 571 } 572 573 static void sta_apply_parameters(struct ieee80211_local *local, 574 struct sta_info *sta, 575 struct station_parameters *params) 576 { 577 u32 rates; 578 int i, j; 579 struct ieee80211_supported_band *sband; 580 struct ieee80211_sub_if_data *sdata = sta->sdata; 581 582 /* 583 * FIXME: updating the flags is racy when this function is 584 * called from ieee80211_change_station(), this will 585 * be resolved in a future patch. 586 */ 587 588 if (params->station_flags & STATION_FLAG_CHANGED) { 589 spin_lock_bh(&sta->lock); 590 sta->flags &= ~WLAN_STA_AUTHORIZED; 591 if (params->station_flags & STATION_FLAG_AUTHORIZED) 592 sta->flags |= WLAN_STA_AUTHORIZED; 593 594 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 595 if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE) 596 sta->flags |= WLAN_STA_SHORT_PREAMBLE; 597 598 sta->flags &= ~WLAN_STA_WME; 599 if (params->station_flags & STATION_FLAG_WME) 600 sta->flags |= WLAN_STA_WME; 601 spin_unlock_bh(&sta->lock); 602 } 603 604 /* 605 * FIXME: updating the following information is racy when this 606 * function is called from ieee80211_change_station(). 607 * However, all this information should be static so 608 * maybe we should just reject attemps to change it. 609 */ 610 611 if (params->aid) { 612 sta->aid = params->aid; 613 if (sta->aid > IEEE80211_MAX_AID) 614 sta->aid = 0; /* XXX: should this be an error? */ 615 } 616 617 if (params->listen_interval >= 0) 618 sta->listen_interval = params->listen_interval; 619 620 if (params->supported_rates) { 621 rates = 0; 622 sband = local->hw.wiphy->bands[local->oper_channel->band]; 623 624 for (i = 0; i < params->supported_rates_len; i++) { 625 int rate = (params->supported_rates[i] & 0x7f) * 5; 626 for (j = 0; j < sband->n_bitrates; j++) { 627 if (sband->bitrates[j].bitrate == rate) 628 rates |= BIT(j); 629 } 630 } 631 sta->supp_rates[local->oper_channel->band] = rates; 632 } 633 634 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 635 switch (params->plink_action) { 636 case PLINK_ACTION_OPEN: 637 mesh_plink_open(sta); 638 break; 639 case PLINK_ACTION_BLOCK: 640 mesh_plink_block(sta); 641 break; 642 } 643 } 644 } 645 646 static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, 647 u8 *mac, struct station_parameters *params) 648 { 649 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 650 struct sta_info *sta; 651 struct ieee80211_sub_if_data *sdata; 652 int err; 653 654 /* Prevent a race with changing the rate control algorithm */ 655 if (!netif_running(dev)) 656 return -ENETDOWN; 657 658 if (params->vlan) { 659 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 660 661 if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN && 662 sdata->vif.type != IEEE80211_IF_TYPE_AP) 663 return -EINVAL; 664 } else 665 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 666 667 if (compare_ether_addr(mac, dev->dev_addr) == 0) 668 return -EINVAL; 669 670 if (is_multicast_ether_addr(mac)) 671 return -EINVAL; 672 673 sta = sta_info_alloc(sdata, mac, GFP_KERNEL); 674 if (!sta) 675 return -ENOMEM; 676 677 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; 678 679 sta_apply_parameters(local, sta, params); 680 681 rate_control_rate_init(sta, local); 682 683 rcu_read_lock(); 684 685 err = sta_info_insert(sta); 686 if (err) { 687 /* STA has been freed */ 688 rcu_read_unlock(); 689 return err; 690 } 691 692 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN || 693 sdata->vif.type == IEEE80211_IF_TYPE_AP) 694 ieee80211_send_layer2_update(sta); 695 696 rcu_read_unlock(); 697 698 return 0; 699 } 700 701 static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, 702 u8 *mac) 703 { 704 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 705 struct ieee80211_local *local = sdata->local; 706 struct sta_info *sta; 707 708 if (mac) { 709 rcu_read_lock(); 710 711 /* XXX: get sta belonging to dev */ 712 sta = sta_info_get(local, mac); 713 if (!sta) { 714 rcu_read_unlock(); 715 return -ENOENT; 716 } 717 718 sta_info_unlink(&sta); 719 rcu_read_unlock(); 720 721 sta_info_destroy(sta); 722 } else 723 sta_info_flush(local, sdata); 724 725 return 0; 726 } 727 728 static int ieee80211_change_station(struct wiphy *wiphy, 729 struct net_device *dev, 730 u8 *mac, 731 struct station_parameters *params) 732 { 733 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 734 struct sta_info *sta; 735 struct ieee80211_sub_if_data *vlansdata; 736 737 rcu_read_lock(); 738 739 /* XXX: get sta belonging to dev */ 740 sta = sta_info_get(local, mac); 741 if (!sta) { 742 rcu_read_unlock(); 743 return -ENOENT; 744 } 745 746 if (params->vlan && params->vlan != sta->sdata->dev) { 747 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 748 749 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN && 750 vlansdata->vif.type != IEEE80211_IF_TYPE_AP) { 751 rcu_read_unlock(); 752 return -EINVAL; 753 } 754 755 sta->sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 756 ieee80211_send_layer2_update(sta); 757 } 758 759 sta_apply_parameters(local, sta, params); 760 761 rcu_read_unlock(); 762 763 return 0; 764 } 765 766 #ifdef CONFIG_MAC80211_MESH 767 static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, 768 u8 *dst, u8 *next_hop) 769 { 770 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 771 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 772 struct mesh_path *mpath; 773 struct sta_info *sta; 774 int err; 775 776 if (!netif_running(dev)) 777 return -ENETDOWN; 778 779 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 780 return -ENOTSUPP; 781 782 rcu_read_lock(); 783 sta = sta_info_get(local, next_hop); 784 if (!sta) { 785 rcu_read_unlock(); 786 return -ENOENT; 787 } 788 789 err = mesh_path_add(dst, dev); 790 if (err) { 791 rcu_read_unlock(); 792 return err; 793 } 794 795 mpath = mesh_path_lookup(dst, dev); 796 if (!mpath) { 797 rcu_read_unlock(); 798 return -ENXIO; 799 } 800 mesh_path_fix_nexthop(mpath, sta); 801 802 rcu_read_unlock(); 803 return 0; 804 } 805 806 static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, 807 u8 *dst) 808 { 809 if (dst) 810 return mesh_path_del(dst, dev); 811 812 mesh_path_flush(dev); 813 return 0; 814 } 815 816 static int ieee80211_change_mpath(struct wiphy *wiphy, 817 struct net_device *dev, 818 u8 *dst, u8 *next_hop) 819 { 820 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 821 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 822 struct mesh_path *mpath; 823 struct sta_info *sta; 824 825 if (!netif_running(dev)) 826 return -ENETDOWN; 827 828 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 829 return -ENOTSUPP; 830 831 rcu_read_lock(); 832 833 sta = sta_info_get(local, next_hop); 834 if (!sta) { 835 rcu_read_unlock(); 836 return -ENOENT; 837 } 838 839 mpath = mesh_path_lookup(dst, dev); 840 if (!mpath) { 841 rcu_read_unlock(); 842 return -ENOENT; 843 } 844 845 mesh_path_fix_nexthop(mpath, sta); 846 847 rcu_read_unlock(); 848 return 0; 849 } 850 851 static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, 852 struct mpath_info *pinfo) 853 { 854 if (mpath->next_hop) 855 memcpy(next_hop, mpath->next_hop->addr, ETH_ALEN); 856 else 857 memset(next_hop, 0, ETH_ALEN); 858 859 pinfo->filled = MPATH_INFO_FRAME_QLEN | 860 MPATH_INFO_DSN | 861 MPATH_INFO_METRIC | 862 MPATH_INFO_EXPTIME | 863 MPATH_INFO_DISCOVERY_TIMEOUT | 864 MPATH_INFO_DISCOVERY_RETRIES | 865 MPATH_INFO_FLAGS; 866 867 pinfo->frame_qlen = mpath->frame_queue.qlen; 868 pinfo->dsn = mpath->dsn; 869 pinfo->metric = mpath->metric; 870 if (time_before(jiffies, mpath->exp_time)) 871 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); 872 pinfo->discovery_timeout = 873 jiffies_to_msecs(mpath->discovery_timeout); 874 pinfo->discovery_retries = mpath->discovery_retries; 875 pinfo->flags = 0; 876 if (mpath->flags & MESH_PATH_ACTIVE) 877 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; 878 if (mpath->flags & MESH_PATH_RESOLVING) 879 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 880 if (mpath->flags & MESH_PATH_DSN_VALID) 881 pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID; 882 if (mpath->flags & MESH_PATH_FIXED) 883 pinfo->flags |= NL80211_MPATH_FLAG_FIXED; 884 if (mpath->flags & MESH_PATH_RESOLVING) 885 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 886 887 pinfo->flags = mpath->flags; 888 } 889 890 static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, 891 u8 *dst, u8 *next_hop, struct mpath_info *pinfo) 892 893 { 894 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 895 struct mesh_path *mpath; 896 897 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 898 return -ENOTSUPP; 899 900 rcu_read_lock(); 901 mpath = mesh_path_lookup(dst, dev); 902 if (!mpath) { 903 rcu_read_unlock(); 904 return -ENOENT; 905 } 906 memcpy(dst, mpath->dst, ETH_ALEN); 907 mpath_set_pinfo(mpath, next_hop, pinfo); 908 rcu_read_unlock(); 909 return 0; 910 } 911 912 static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, 913 int idx, u8 *dst, u8 *next_hop, 914 struct mpath_info *pinfo) 915 { 916 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 917 struct mesh_path *mpath; 918 919 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 920 return -ENOTSUPP; 921 922 rcu_read_lock(); 923 mpath = mesh_path_lookup_by_idx(idx, dev); 924 if (!mpath) { 925 rcu_read_unlock(); 926 return -ENOENT; 927 } 928 memcpy(dst, mpath->dst, ETH_ALEN); 929 mpath_set_pinfo(mpath, next_hop, pinfo); 930 rcu_read_unlock(); 931 return 0; 932 } 933 #endif 934 935 struct cfg80211_ops mac80211_config_ops = { 936 .add_virtual_intf = ieee80211_add_iface, 937 .del_virtual_intf = ieee80211_del_iface, 938 .change_virtual_intf = ieee80211_change_iface, 939 .add_key = ieee80211_add_key, 940 .del_key = ieee80211_del_key, 941 .get_key = ieee80211_get_key, 942 .set_default_key = ieee80211_config_default_key, 943 .add_beacon = ieee80211_add_beacon, 944 .set_beacon = ieee80211_set_beacon, 945 .del_beacon = ieee80211_del_beacon, 946 .add_station = ieee80211_add_station, 947 .del_station = ieee80211_del_station, 948 .change_station = ieee80211_change_station, 949 .get_station = ieee80211_get_station, 950 .dump_station = ieee80211_dump_station, 951 #ifdef CONFIG_MAC80211_MESH 952 .add_mpath = ieee80211_add_mpath, 953 .del_mpath = ieee80211_del_mpath, 954 .change_mpath = ieee80211_change_mpath, 955 .get_mpath = ieee80211_get_mpath, 956 .dump_mpath = ieee80211_dump_mpath, 957 #endif 958 }; 959