cfg.c revision db4d1169d0b893bfb7923b6526748fe2c5a7373f
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 "ieee80211_rate.h" 18 19static enum ieee80211_if_types 20nl80211_type_to_mac80211_type(enum nl80211_iftype type) 21{ 22 switch (type) { 23 case NL80211_IFTYPE_UNSPECIFIED: 24 return IEEE80211_IF_TYPE_STA; 25 case NL80211_IFTYPE_ADHOC: 26 return IEEE80211_IF_TYPE_IBSS; 27 case NL80211_IFTYPE_STATION: 28 return IEEE80211_IF_TYPE_STA; 29 case NL80211_IFTYPE_MONITOR: 30 return IEEE80211_IF_TYPE_MNTR; 31 default: 32 return IEEE80211_IF_TYPE_INVALID; 33 } 34} 35 36static int ieee80211_add_iface(struct wiphy *wiphy, char *name, 37 enum nl80211_iftype type, u32 *flags) 38{ 39 struct ieee80211_local *local = wiphy_priv(wiphy); 40 enum ieee80211_if_types itype; 41 struct net_device *dev; 42 struct ieee80211_sub_if_data *sdata; 43 int err; 44 45 if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) 46 return -ENODEV; 47 48 itype = nl80211_type_to_mac80211_type(type); 49 if (itype == IEEE80211_IF_TYPE_INVALID) 50 return -EINVAL; 51 52 err = ieee80211_if_add(local->mdev, name, &dev, itype); 53 if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) 54 return err; 55 56 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 57 sdata->u.mntr_flags = *flags; 58 return 0; 59} 60 61static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) 62{ 63 struct ieee80211_local *local = wiphy_priv(wiphy); 64 struct net_device *dev; 65 char *name; 66 67 if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) 68 return -ENODEV; 69 70 /* we're under RTNL */ 71 dev = __dev_get_by_index(&init_net, ifindex); 72 if (!dev) 73 return 0; 74 75 name = dev->name; 76 77 return ieee80211_if_remove(local->mdev, name, -1); 78} 79 80static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, 81 enum nl80211_iftype type, u32 *flags) 82{ 83 struct ieee80211_local *local = wiphy_priv(wiphy); 84 struct net_device *dev; 85 enum ieee80211_if_types itype; 86 struct ieee80211_sub_if_data *sdata; 87 88 if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) 89 return -ENODEV; 90 91 /* we're under RTNL */ 92 dev = __dev_get_by_index(&init_net, ifindex); 93 if (!dev) 94 return -ENODEV; 95 96 if (netif_running(dev)) 97 return -EBUSY; 98 99 itype = nl80211_type_to_mac80211_type(type); 100 if (itype == IEEE80211_IF_TYPE_INVALID) 101 return -EINVAL; 102 103 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 104 105 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 106 return -EOPNOTSUPP; 107 108 ieee80211_if_reinit(dev); 109 ieee80211_if_set_type(dev, itype); 110 111 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags) 112 return 0; 113 114 sdata->u.mntr_flags = *flags; 115 return 0; 116} 117 118static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 119 u8 key_idx, u8 *mac_addr, 120 struct key_params *params) 121{ 122 struct ieee80211_sub_if_data *sdata; 123 struct sta_info *sta = NULL; 124 enum ieee80211_key_alg alg; 125 int ret; 126 struct ieee80211_key *key; 127 128 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 129 130 switch (params->cipher) { 131 case WLAN_CIPHER_SUITE_WEP40: 132 case WLAN_CIPHER_SUITE_WEP104: 133 alg = ALG_WEP; 134 break; 135 case WLAN_CIPHER_SUITE_TKIP: 136 alg = ALG_TKIP; 137 break; 138 case WLAN_CIPHER_SUITE_CCMP: 139 alg = ALG_CCMP; 140 break; 141 default: 142 return -EINVAL; 143 } 144 145 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key); 146 if (!key) 147 return -ENOMEM; 148 149 if (mac_addr) { 150 sta = sta_info_get(sdata->local, mac_addr); 151 if (!sta) { 152 ieee80211_key_free(key); 153 return -ENOENT; 154 } 155 } 156 157 ieee80211_key_link(key, sdata, sta); 158 159 ret = 0; 160 161 if (sta) 162 sta_info_put(sta); 163 164 return ret; 165} 166 167static 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 struct ieee80211_key *key; 174 175 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 176 177 if (mac_addr) { 178 sta = sta_info_get(sdata->local, mac_addr); 179 if (!sta) 180 return -ENOENT; 181 182 ret = 0; 183 if (sta->key) { 184 key = sta->key; 185 ieee80211_key_free(key); 186 WARN_ON(sta->key); 187 } else 188 ret = -ENOENT; 189 190 sta_info_put(sta); 191 return ret; 192 } 193 194 if (!sdata->keys[key_idx]) 195 return -ENOENT; 196 197 key = sdata->keys[key_idx]; 198 ieee80211_key_free(key); 199 WARN_ON(sdata->keys[key_idx]); 200 201 return 0; 202} 203 204static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 205 u8 key_idx, u8 *mac_addr, void *cookie, 206 void (*callback)(void *cookie, 207 struct key_params *params)) 208{ 209 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 210 struct sta_info *sta = NULL; 211 u8 seq[6] = {0}; 212 struct key_params params; 213 struct ieee80211_key *key; 214 u32 iv32; 215 u16 iv16; 216 int err = -ENOENT; 217 218 if (mac_addr) { 219 sta = sta_info_get(sdata->local, mac_addr); 220 if (!sta) 221 goto out; 222 223 key = sta->key; 224 } else 225 key = sdata->keys[key_idx]; 226 227 if (!key) 228 goto out; 229 230 memset(¶ms, 0, sizeof(params)); 231 232 switch (key->conf.alg) { 233 case ALG_TKIP: 234 params.cipher = WLAN_CIPHER_SUITE_TKIP; 235 236 iv32 = key->u.tkip.iv32; 237 iv16 = key->u.tkip.iv16; 238 239 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && 240 sdata->local->ops->get_tkip_seq) 241 sdata->local->ops->get_tkip_seq( 242 local_to_hw(sdata->local), 243 key->conf.hw_key_idx, 244 &iv32, &iv16); 245 246 seq[0] = iv16 & 0xff; 247 seq[1] = (iv16 >> 8) & 0xff; 248 seq[2] = iv32 & 0xff; 249 seq[3] = (iv32 >> 8) & 0xff; 250 seq[4] = (iv32 >> 16) & 0xff; 251 seq[5] = (iv32 >> 24) & 0xff; 252 params.seq = seq; 253 params.seq_len = 6; 254 break; 255 case ALG_CCMP: 256 params.cipher = WLAN_CIPHER_SUITE_CCMP; 257 seq[0] = key->u.ccmp.tx_pn[5]; 258 seq[1] = key->u.ccmp.tx_pn[4]; 259 seq[2] = key->u.ccmp.tx_pn[3]; 260 seq[3] = key->u.ccmp.tx_pn[2]; 261 seq[4] = key->u.ccmp.tx_pn[1]; 262 seq[5] = key->u.ccmp.tx_pn[0]; 263 params.seq = seq; 264 params.seq_len = 6; 265 break; 266 case ALG_WEP: 267 if (key->conf.keylen == 5) 268 params.cipher = WLAN_CIPHER_SUITE_WEP40; 269 else 270 params.cipher = WLAN_CIPHER_SUITE_WEP104; 271 break; 272 } 273 274 params.key = key->conf.key; 275 params.key_len = key->conf.keylen; 276 277 callback(cookie, ¶ms); 278 err = 0; 279 280 out: 281 if (sta) 282 sta_info_put(sta); 283 return err; 284} 285 286static int ieee80211_config_default_key(struct wiphy *wiphy, 287 struct net_device *dev, 288 u8 key_idx) 289{ 290 struct ieee80211_sub_if_data *sdata; 291 292 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 293 ieee80211_set_default_key(sdata, key_idx); 294 295 return 0; 296} 297 298static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 299 u8 *mac, struct station_stats *stats) 300{ 301 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 302 struct sta_info *sta; 303 304 sta = sta_info_get(local, mac); 305 if (!sta) 306 return -ENOENT; 307 308 /* XXX: verify sta->dev == dev */ 309 310 stats->filled = STATION_STAT_INACTIVE_TIME | 311 STATION_STAT_RX_BYTES | 312 STATION_STAT_TX_BYTES; 313 314 stats->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 315 stats->rx_bytes = sta->rx_bytes; 316 stats->tx_bytes = sta->tx_bytes; 317 318 sta_info_put(sta); 319 320 return 0; 321} 322 323/* 324 * This handles both adding a beacon and setting new beacon info 325 */ 326static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, 327 struct beacon_parameters *params) 328{ 329 struct beacon_data *new, *old; 330 int new_head_len, new_tail_len; 331 int size; 332 int err = -EINVAL; 333 334 old = sdata->u.ap.beacon; 335 336 /* head must not be zero-length */ 337 if (params->head && !params->head_len) 338 return -EINVAL; 339 340 /* 341 * This is a kludge. beacon interval should really be part 342 * of the beacon information. 343 */ 344 if (params->interval) { 345 sdata->local->hw.conf.beacon_int = params->interval; 346 if (ieee80211_hw_config(sdata->local)) 347 return -EINVAL; 348 /* 349 * We updated some parameter so if below bails out 350 * it's not an error. 351 */ 352 err = 0; 353 } 354 355 /* Need to have a beacon head if we don't have one yet */ 356 if (!params->head && !old) 357 return err; 358 359 /* sorry, no way to start beaconing without dtim period */ 360 if (!params->dtim_period && !old) 361 return err; 362 363 /* new or old head? */ 364 if (params->head) 365 new_head_len = params->head_len; 366 else 367 new_head_len = old->head_len; 368 369 /* new or old tail? */ 370 if (params->tail || !old) 371 /* params->tail_len will be zero for !params->tail */ 372 new_tail_len = params->tail_len; 373 else 374 new_tail_len = old->tail_len; 375 376 size = sizeof(*new) + new_head_len + new_tail_len; 377 378 new = kzalloc(size, GFP_KERNEL); 379 if (!new) 380 return -ENOMEM; 381 382 /* start filling the new info now */ 383 384 /* new or old dtim period? */ 385 if (params->dtim_period) 386 new->dtim_period = params->dtim_period; 387 else 388 new->dtim_period = old->dtim_period; 389 390 /* 391 * pointers go into the block we allocated, 392 * memory is | beacon_data | head | tail | 393 */ 394 new->head = ((u8 *) new) + sizeof(*new); 395 new->tail = new->head + new_head_len; 396 new->head_len = new_head_len; 397 new->tail_len = new_tail_len; 398 399 /* copy in head */ 400 if (params->head) 401 memcpy(new->head, params->head, new_head_len); 402 else 403 memcpy(new->head, old->head, new_head_len); 404 405 /* copy in optional tail */ 406 if (params->tail) 407 memcpy(new->tail, params->tail, new_tail_len); 408 else 409 if (old) 410 memcpy(new->tail, old->tail, new_tail_len); 411 412 rcu_assign_pointer(sdata->u.ap.beacon, new); 413 414 synchronize_rcu(); 415 416 kfree(old); 417 418 return ieee80211_if_config_beacon(sdata->dev); 419} 420 421static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 422 struct beacon_parameters *params) 423{ 424 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 425 struct beacon_data *old; 426 427 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 428 return -EINVAL; 429 430 old = sdata->u.ap.beacon; 431 432 if (old) 433 return -EALREADY; 434 435 return ieee80211_config_beacon(sdata, params); 436} 437 438static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, 439 struct beacon_parameters *params) 440{ 441 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 442 struct beacon_data *old; 443 444 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 445 return -EINVAL; 446 447 old = sdata->u.ap.beacon; 448 449 if (!old) 450 return -ENOENT; 451 452 return ieee80211_config_beacon(sdata, params); 453} 454 455static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) 456{ 457 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 458 struct beacon_data *old; 459 460 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 461 return -EINVAL; 462 463 old = sdata->u.ap.beacon; 464 465 if (!old) 466 return -ENOENT; 467 468 rcu_assign_pointer(sdata->u.ap.beacon, NULL); 469 synchronize_rcu(); 470 kfree(old); 471 472 return ieee80211_if_config_beacon(dev); 473} 474 475/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 476struct iapp_layer2_update { 477 u8 da[ETH_ALEN]; /* broadcast */ 478 u8 sa[ETH_ALEN]; /* STA addr */ 479 __be16 len; /* 6 */ 480 u8 dsap; /* 0 */ 481 u8 ssap; /* 0 */ 482 u8 control; 483 u8 xid_info[3]; 484} __attribute__ ((packed)); 485 486static void ieee80211_send_layer2_update(struct sta_info *sta) 487{ 488 struct iapp_layer2_update *msg; 489 struct sk_buff *skb; 490 491 /* Send Level 2 Update Frame to update forwarding tables in layer 2 492 * bridge devices */ 493 494 skb = dev_alloc_skb(sizeof(*msg)); 495 if (!skb) 496 return; 497 msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg)); 498 499 /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) 500 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ 501 502 memset(msg->da, 0xff, ETH_ALEN); 503 memcpy(msg->sa, sta->addr, ETH_ALEN); 504 msg->len = htons(6); 505 msg->dsap = 0; 506 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ 507 msg->control = 0xaf; /* XID response lsb.1111F101. 508 * F=0 (no poll command; unsolicited frame) */ 509 msg->xid_info[0] = 0x81; /* XID format identifier */ 510 msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ 511 msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */ 512 513 skb->dev = sta->dev; 514 skb->protocol = eth_type_trans(skb, sta->dev); 515 memset(skb->cb, 0, sizeof(skb->cb)); 516 netif_rx(skb); 517} 518 519static void sta_apply_parameters(struct ieee80211_local *local, 520 struct sta_info *sta, 521 struct station_parameters *params) 522{ 523 u32 rates; 524 int i, j; 525 struct ieee80211_supported_band *sband; 526 527 if (params->station_flags & STATION_FLAG_CHANGED) { 528 sta->flags &= ~WLAN_STA_AUTHORIZED; 529 if (params->station_flags & STATION_FLAG_AUTHORIZED) 530 sta->flags |= WLAN_STA_AUTHORIZED; 531 532 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 533 if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE) 534 sta->flags |= WLAN_STA_SHORT_PREAMBLE; 535 536 sta->flags &= ~WLAN_STA_WME; 537 if (params->station_flags & STATION_FLAG_WME) 538 sta->flags |= WLAN_STA_WME; 539 } 540 541 if (params->aid) { 542 sta->aid = params->aid; 543 if (sta->aid > IEEE80211_MAX_AID) 544 sta->aid = 0; /* XXX: should this be an error? */ 545 } 546 547 if (params->listen_interval >= 0) 548 sta->listen_interval = params->listen_interval; 549 550 if (params->supported_rates) { 551 rates = 0; 552 sband = local->hw.wiphy->bands[local->oper_channel->band]; 553 554 for (i = 0; i < params->supported_rates_len; i++) { 555 int rate = (params->supported_rates[i] & 0x7f) * 5; 556 for (j = 0; j < sband->n_bitrates; j++) { 557 if (sband->bitrates[j].bitrate == rate) 558 rates |= BIT(j); 559 } 560 } 561 sta->supp_rates[local->oper_channel->band] = rates; 562 } 563} 564 565static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, 566 u8 *mac, struct station_parameters *params) 567{ 568 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 569 struct sta_info *sta; 570 struct ieee80211_sub_if_data *sdata; 571 572 /* Prevent a race with changing the rate control algorithm */ 573 if (!netif_running(dev)) 574 return -ENETDOWN; 575 576 if (params->vlan) { 577 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 578 579 if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN || 580 sdata->vif.type != IEEE80211_IF_TYPE_AP) 581 return -EINVAL; 582 } else 583 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 584 585 sta = sta_info_add(local, dev, mac, GFP_KERNEL); 586 if (IS_ERR(sta)) 587 return PTR_ERR(sta); 588 589 sta->dev = sdata->dev; 590 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN || 591 sdata->vif.type == IEEE80211_IF_TYPE_AP) 592 ieee80211_send_layer2_update(sta); 593 594 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; 595 596 sta_apply_parameters(local, sta, params); 597 598 rate_control_rate_init(sta, local); 599 600 sta_info_put(sta); 601 602 return 0; 603} 604 605static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, 606 u8 *mac) 607{ 608 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 609 struct sta_info *sta; 610 611 if (mac) { 612 /* XXX: get sta belonging to dev */ 613 sta = sta_info_get(local, mac); 614 if (!sta) 615 return -ENOENT; 616 617 sta_info_free(sta); 618 sta_info_put(sta); 619 } else 620 sta_info_flush(local, dev); 621 622 return 0; 623} 624 625static int ieee80211_change_station(struct wiphy *wiphy, 626 struct net_device *dev, 627 u8 *mac, 628 struct station_parameters *params) 629{ 630 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 631 struct sta_info *sta; 632 struct ieee80211_sub_if_data *vlansdata; 633 634 /* XXX: get sta belonging to dev */ 635 sta = sta_info_get(local, mac); 636 if (!sta) 637 return -ENOENT; 638 639 if (params->vlan && params->vlan != sta->dev) { 640 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 641 642 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN || 643 vlansdata->vif.type != IEEE80211_IF_TYPE_AP) 644 return -EINVAL; 645 646 sta->dev = params->vlan; 647 ieee80211_send_layer2_update(sta); 648 } 649 650 sta_apply_parameters(local, sta, params); 651 652 sta_info_put(sta); 653 654 return 0; 655} 656 657struct cfg80211_ops mac80211_config_ops = { 658 .add_virtual_intf = ieee80211_add_iface, 659 .del_virtual_intf = ieee80211_del_iface, 660 .change_virtual_intf = ieee80211_change_iface, 661 .add_key = ieee80211_add_key, 662 .del_key = ieee80211_del_key, 663 .get_key = ieee80211_get_key, 664 .set_default_key = ieee80211_config_default_key, 665 .add_beacon = ieee80211_add_beacon, 666 .set_beacon = ieee80211_set_beacon, 667 .del_beacon = ieee80211_del_beacon, 668 .add_station = ieee80211_add_station, 669 .del_station = ieee80211_del_station, 670 .change_station = ieee80211_change_station, 671 .get_station = ieee80211_get_station, 672}; 673