Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.28-rc3 646 lines 16 kB view raw
1/* 2 * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10/* 11 * TODO: 12 * - IBSS mode simulation (Beacon transmission with competition for "air time") 13 * - IEEE 802.11a and 802.11n modes 14 * - RX filtering based on filter configuration (data->rx_filter) 15 */ 16 17#include <linux/list.h> 18#include <linux/spinlock.h> 19#include <net/mac80211.h> 20#include <net/ieee80211_radiotap.h> 21#include <linux/if_arp.h> 22#include <linux/rtnetlink.h> 23#include <linux/etherdevice.h> 24 25MODULE_AUTHOR("Jouni Malinen"); 26MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211"); 27MODULE_LICENSE("GPL"); 28 29static int radios = 2; 30module_param(radios, int, 0444); 31MODULE_PARM_DESC(radios, "Number of simulated radios"); 32 33struct hwsim_vif_priv { 34 u32 magic; 35}; 36 37#define HWSIM_VIF_MAGIC 0x69537748 38 39static inline void hwsim_check_magic(struct ieee80211_vif *vif) 40{ 41 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 42 WARN_ON(vp->magic != HWSIM_VIF_MAGIC); 43} 44 45static inline void hwsim_set_magic(struct ieee80211_vif *vif) 46{ 47 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 48 vp->magic = HWSIM_VIF_MAGIC; 49} 50 51static inline void hwsim_clear_magic(struct ieee80211_vif *vif) 52{ 53 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 54 vp->magic = 0; 55} 56 57struct hwsim_sta_priv { 58 u32 magic; 59}; 60 61#define HWSIM_STA_MAGIC 0x6d537748 62 63static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta) 64{ 65 struct hwsim_sta_priv *sp = (void *)sta->drv_priv; 66 WARN_ON(sp->magic != HWSIM_VIF_MAGIC); 67} 68 69static inline void hwsim_set_sta_magic(struct ieee80211_sta *sta) 70{ 71 struct hwsim_sta_priv *sp = (void *)sta->drv_priv; 72 sp->magic = HWSIM_VIF_MAGIC; 73} 74 75static inline void hwsim_clear_sta_magic(struct ieee80211_sta *sta) 76{ 77 struct hwsim_sta_priv *sp = (void *)sta->drv_priv; 78 sp->magic = 0; 79} 80 81static struct class *hwsim_class; 82 83static struct net_device *hwsim_mon; /* global monitor netdev */ 84 85 86static const struct ieee80211_channel hwsim_channels[] = { 87 { .center_freq = 2412 }, 88 { .center_freq = 2417 }, 89 { .center_freq = 2422 }, 90 { .center_freq = 2427 }, 91 { .center_freq = 2432 }, 92 { .center_freq = 2437 }, 93 { .center_freq = 2442 }, 94 { .center_freq = 2447 }, 95 { .center_freq = 2452 }, 96 { .center_freq = 2457 }, 97 { .center_freq = 2462 }, 98 { .center_freq = 2467 }, 99 { .center_freq = 2472 }, 100 { .center_freq = 2484 }, 101}; 102 103static const struct ieee80211_rate hwsim_rates[] = { 104 { .bitrate = 10 }, 105 { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 106 { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 107 { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, 108 { .bitrate = 60 }, 109 { .bitrate = 90 }, 110 { .bitrate = 120 }, 111 { .bitrate = 180 }, 112 { .bitrate = 240 }, 113 { .bitrate = 360 }, 114 { .bitrate = 480 }, 115 { .bitrate = 540 } 116}; 117 118static spinlock_t hwsim_radio_lock; 119static struct list_head hwsim_radios; 120 121struct mac80211_hwsim_data { 122 struct list_head list; 123 struct ieee80211_hw *hw; 124 struct device *dev; 125 struct ieee80211_supported_band band; 126 struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)]; 127 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 128 129 struct ieee80211_channel *channel; 130 int radio_enabled; 131 unsigned long beacon_int; /* in jiffies unit */ 132 unsigned int rx_filter; 133 int started; 134 struct timer_list beacon_timer; 135}; 136 137 138struct hwsim_radiotap_hdr { 139 struct ieee80211_radiotap_header hdr; 140 u8 rt_flags; 141 u8 rt_rate; 142 __le16 rt_channel; 143 __le16 rt_chbitmask; 144} __attribute__ ((packed)); 145 146 147static int hwsim_mon_xmit(struct sk_buff *skb, struct net_device *dev) 148{ 149 /* TODO: allow packet injection */ 150 dev_kfree_skb(skb); 151 return 0; 152} 153 154 155static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, 156 struct sk_buff *tx_skb) 157{ 158 struct mac80211_hwsim_data *data = hw->priv; 159 struct sk_buff *skb; 160 struct hwsim_radiotap_hdr *hdr; 161 u16 flags; 162 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb); 163 struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); 164 165 if (!netif_running(hwsim_mon)) 166 return; 167 168 skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); 169 if (skb == NULL) 170 return; 171 172 hdr = (struct hwsim_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); 173 hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION; 174 hdr->hdr.it_pad = 0; 175 hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); 176 hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | 177 (1 << IEEE80211_RADIOTAP_RATE) | 178 (1 << IEEE80211_RADIOTAP_CHANNEL)); 179 hdr->rt_flags = 0; 180 hdr->rt_rate = txrate->bitrate / 5; 181 hdr->rt_channel = cpu_to_le16(data->channel->center_freq); 182 flags = IEEE80211_CHAN_2GHZ; 183 if (txrate->flags & IEEE80211_RATE_ERP_G) 184 flags |= IEEE80211_CHAN_OFDM; 185 else 186 flags |= IEEE80211_CHAN_CCK; 187 hdr->rt_chbitmask = cpu_to_le16(flags); 188 189 skb->dev = hwsim_mon; 190 skb_set_mac_header(skb, 0); 191 skb->ip_summed = CHECKSUM_UNNECESSARY; 192 skb->pkt_type = PACKET_OTHERHOST; 193 skb->protocol = htons(ETH_P_802_2); 194 memset(skb->cb, 0, sizeof(skb->cb)); 195 netif_rx(skb); 196} 197 198 199static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, 200 struct sk_buff *skb) 201{ 202 struct mac80211_hwsim_data *data = hw->priv, *data2; 203 bool ack = false; 204 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 205 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 206 struct ieee80211_rx_status rx_status; 207 208 memset(&rx_status, 0, sizeof(rx_status)); 209 /* TODO: set mactime */ 210 rx_status.freq = data->channel->center_freq; 211 rx_status.band = data->channel->band; 212 rx_status.rate_idx = info->tx_rate_idx; 213 /* TODO: simulate signal strength (and optional packet drop) */ 214 215 /* Copy skb to all enabled radios that are on the current frequency */ 216 spin_lock(&hwsim_radio_lock); 217 list_for_each_entry(data2, &hwsim_radios, list) { 218 struct sk_buff *nskb; 219 220 if (data == data2) 221 continue; 222 223 if (!data2->started || !data2->radio_enabled || 224 data->channel->center_freq != data2->channel->center_freq) 225 continue; 226 227 nskb = skb_copy(skb, GFP_ATOMIC); 228 if (nskb == NULL) 229 continue; 230 231 if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr, 232 ETH_ALEN) == 0) 233 ack = true; 234 ieee80211_rx_irqsafe(data2->hw, nskb, &rx_status); 235 } 236 spin_unlock(&hwsim_radio_lock); 237 238 return ack; 239} 240 241 242static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 243{ 244 struct mac80211_hwsim_data *data = hw->priv; 245 bool ack; 246 struct ieee80211_tx_info *txi; 247 248 mac80211_hwsim_monitor_rx(hw, skb); 249 250 if (skb->len < 10) { 251 /* Should not happen; just a sanity check for addr1 use */ 252 dev_kfree_skb(skb); 253 return NETDEV_TX_OK; 254 } 255 256 if (!data->radio_enabled) { 257 printk(KERN_DEBUG "%s: dropped TX frame since radio " 258 "disabled\n", wiphy_name(hw->wiphy)); 259 dev_kfree_skb(skb); 260 return NETDEV_TX_OK; 261 } 262 263 ack = mac80211_hwsim_tx_frame(hw, skb); 264 265 txi = IEEE80211_SKB_CB(skb); 266 267 if (txi->control.vif) 268 hwsim_check_magic(txi->control.vif); 269 if (txi->control.sta) 270 hwsim_check_sta_magic(txi->control.sta); 271 272 memset(&txi->status, 0, sizeof(txi->status)); 273 if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { 274 if (ack) 275 txi->flags |= IEEE80211_TX_STAT_ACK; 276 else 277 txi->status.excessive_retries = 1; 278 } 279 ieee80211_tx_status_irqsafe(hw, skb); 280 return NETDEV_TX_OK; 281} 282 283 284static int mac80211_hwsim_start(struct ieee80211_hw *hw) 285{ 286 struct mac80211_hwsim_data *data = hw->priv; 287 printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); 288 data->started = 1; 289 return 0; 290} 291 292 293static void mac80211_hwsim_stop(struct ieee80211_hw *hw) 294{ 295 struct mac80211_hwsim_data *data = hw->priv; 296 data->started = 0; 297 printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); 298} 299 300 301static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, 302 struct ieee80211_if_init_conf *conf) 303{ 304 DECLARE_MAC_BUF(mac); 305 printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", 306 wiphy_name(hw->wiphy), __func__, conf->type, 307 print_mac(mac, conf->mac_addr)); 308 hwsim_set_magic(conf->vif); 309 return 0; 310} 311 312 313static void mac80211_hwsim_remove_interface( 314 struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) 315{ 316 DECLARE_MAC_BUF(mac); 317 printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", 318 wiphy_name(hw->wiphy), __func__, conf->type, 319 print_mac(mac, conf->mac_addr)); 320 hwsim_check_magic(conf->vif); 321 hwsim_clear_magic(conf->vif); 322} 323 324 325static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, 326 struct ieee80211_vif *vif) 327{ 328 struct ieee80211_hw *hw = arg; 329 struct sk_buff *skb; 330 struct ieee80211_tx_info *info; 331 332 hwsim_check_magic(vif); 333 334 if (vif->type != NL80211_IFTYPE_AP) 335 return; 336 337 skb = ieee80211_beacon_get(hw, vif); 338 if (skb == NULL) 339 return; 340 info = IEEE80211_SKB_CB(skb); 341 342 mac80211_hwsim_monitor_rx(hw, skb); 343 mac80211_hwsim_tx_frame(hw, skb); 344 dev_kfree_skb(skb); 345} 346 347 348static void mac80211_hwsim_beacon(unsigned long arg) 349{ 350 struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; 351 struct mac80211_hwsim_data *data = hw->priv; 352 353 if (!data->started || !data->radio_enabled) 354 return; 355 356 ieee80211_iterate_active_interfaces_atomic( 357 hw, mac80211_hwsim_beacon_tx, hw); 358 359 data->beacon_timer.expires = jiffies + data->beacon_int; 360 add_timer(&data->beacon_timer); 361} 362 363 364static int mac80211_hwsim_config(struct ieee80211_hw *hw, 365 struct ieee80211_conf *conf) 366{ 367 struct mac80211_hwsim_data *data = hw->priv; 368 369 printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n", 370 wiphy_name(hw->wiphy), __func__, 371 conf->channel->center_freq, conf->radio_enabled, 372 conf->beacon_int); 373 374 data->channel = conf->channel; 375 data->radio_enabled = conf->radio_enabled; 376 data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000; 377 if (data->beacon_int < 1) 378 data->beacon_int = 1; 379 380 if (!data->started || !data->radio_enabled) 381 del_timer(&data->beacon_timer); 382 else 383 mod_timer(&data->beacon_timer, jiffies + data->beacon_int); 384 385 return 0; 386} 387 388 389static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, 390 unsigned int changed_flags, 391 unsigned int *total_flags, 392 int mc_count, 393 struct dev_addr_list *mc_list) 394{ 395 struct mac80211_hwsim_data *data = hw->priv; 396 397 printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); 398 399 data->rx_filter = 0; 400 if (*total_flags & FIF_PROMISC_IN_BSS) 401 data->rx_filter |= FIF_PROMISC_IN_BSS; 402 if (*total_flags & FIF_ALLMULTI) 403 data->rx_filter |= FIF_ALLMULTI; 404 405 *total_flags = data->rx_filter; 406} 407 408static int mac80211_hwsim_config_interface(struct ieee80211_hw *hw, 409 struct ieee80211_vif *vif, 410 struct ieee80211_if_conf *conf) 411{ 412 hwsim_check_magic(vif); 413 return 0; 414} 415 416static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, 417 struct ieee80211_vif *vif, 418 struct ieee80211_bss_conf *info, 419 u32 changed) 420{ 421 hwsim_check_magic(vif); 422} 423 424static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw, 425 struct ieee80211_vif *vif, 426 enum sta_notify_cmd cmd, 427 struct ieee80211_sta *sta) 428{ 429 hwsim_check_magic(vif); 430 switch (cmd) { 431 case STA_NOTIFY_ADD: 432 hwsim_set_sta_magic(sta); 433 break; 434 case STA_NOTIFY_REMOVE: 435 hwsim_clear_sta_magic(sta); 436 break; 437 } 438} 439 440static int mac80211_hwsim_set_tim(struct ieee80211_hw *hw, 441 struct ieee80211_sta *sta, 442 bool set) 443{ 444 hwsim_check_sta_magic(sta); 445 return 0; 446} 447 448static const struct ieee80211_ops mac80211_hwsim_ops = 449{ 450 .tx = mac80211_hwsim_tx, 451 .start = mac80211_hwsim_start, 452 .stop = mac80211_hwsim_stop, 453 .add_interface = mac80211_hwsim_add_interface, 454 .remove_interface = mac80211_hwsim_remove_interface, 455 .config = mac80211_hwsim_config, 456 .configure_filter = mac80211_hwsim_configure_filter, 457 .config_interface = mac80211_hwsim_config_interface, 458 .bss_info_changed = mac80211_hwsim_bss_info_changed, 459 .sta_notify = mac80211_hwsim_sta_notify, 460 .set_tim = mac80211_hwsim_set_tim, 461}; 462 463 464static void mac80211_hwsim_free(void) 465{ 466 struct list_head tmplist, *i, *tmp; 467 struct mac80211_hwsim_data *data; 468 469 INIT_LIST_HEAD(&tmplist); 470 471 spin_lock_bh(&hwsim_radio_lock); 472 list_for_each_safe(i, tmp, &hwsim_radios) 473 list_move(i, &tmplist); 474 spin_unlock_bh(&hwsim_radio_lock); 475 476 list_for_each_entry(data, &tmplist, list) { 477 ieee80211_unregister_hw(data->hw); 478 device_unregister(data->dev); 479 ieee80211_free_hw(data->hw); 480 } 481 class_destroy(hwsim_class); 482} 483 484 485static struct device_driver mac80211_hwsim_driver = { 486 .name = "mac80211_hwsim" 487}; 488 489 490static void hwsim_mon_setup(struct net_device *dev) 491{ 492 dev->hard_start_xmit = hwsim_mon_xmit; 493 dev->destructor = free_netdev; 494 ether_setup(dev); 495 dev->tx_queue_len = 0; 496 dev->type = ARPHRD_IEEE80211_RADIOTAP; 497 memset(dev->dev_addr, 0, ETH_ALEN); 498 dev->dev_addr[0] = 0x12; 499} 500 501 502static int __init init_mac80211_hwsim(void) 503{ 504 int i, err = 0; 505 u8 addr[ETH_ALEN]; 506 struct mac80211_hwsim_data *data; 507 struct ieee80211_hw *hw; 508 DECLARE_MAC_BUF(mac); 509 510 if (radios < 1 || radios > 100) 511 return -EINVAL; 512 513 spin_lock_init(&hwsim_radio_lock); 514 INIT_LIST_HEAD(&hwsim_radios); 515 516 hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); 517 if (IS_ERR(hwsim_class)) 518 return PTR_ERR(hwsim_class); 519 520 memset(addr, 0, ETH_ALEN); 521 addr[0] = 0x02; 522 523 for (i = 0; i < radios; i++) { 524 printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n", 525 i); 526 hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops); 527 if (!hw) { 528 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw " 529 "failed\n"); 530 err = -ENOMEM; 531 goto failed; 532 } 533 data = hw->priv; 534 data->hw = hw; 535 536 data->dev = device_create(hwsim_class, NULL, 0, hw, 537 "hwsim%d", i); 538 if (IS_ERR(data->dev)) { 539 printk(KERN_DEBUG 540 "mac80211_hwsim: device_create " 541 "failed (%ld)\n", PTR_ERR(data->dev)); 542 err = -ENOMEM; 543 goto failed_drvdata; 544 } 545 data->dev->driver = &mac80211_hwsim_driver; 546 547 SET_IEEE80211_DEV(hw, data->dev); 548 addr[3] = i >> 8; 549 addr[4] = i; 550 SET_IEEE80211_PERM_ADDR(hw, addr); 551 552 hw->channel_change_time = 1; 553 hw->queues = 4; 554 hw->wiphy->interface_modes = 555 BIT(NL80211_IFTYPE_STATION) | 556 BIT(NL80211_IFTYPE_AP); 557 hw->ampdu_queues = 1; 558 559 /* ask mac80211 to reserve space for magic */ 560 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 561 hw->sta_data_size = sizeof(struct hwsim_sta_priv); 562 563 memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); 564 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); 565 data->band.channels = data->channels; 566 data->band.n_channels = ARRAY_SIZE(hwsim_channels); 567 data->band.bitrates = data->rates; 568 data->band.n_bitrates = ARRAY_SIZE(hwsim_rates); 569 data->band.ht_info.ht_supported = 1; 570 data->band.ht_info.cap = IEEE80211_HT_CAP_SUP_WIDTH | 571 IEEE80211_HT_CAP_GRN_FLD | 572 IEEE80211_HT_CAP_SGI_40 | 573 IEEE80211_HT_CAP_DSSSCCK40; 574 data->band.ht_info.ampdu_factor = 0x3; 575 data->band.ht_info.ampdu_density = 0x6; 576 memset(data->band.ht_info.supp_mcs_set, 0, 577 sizeof(data->band.ht_info.supp_mcs_set)); 578 data->band.ht_info.supp_mcs_set[0] = 0xff; 579 data->band.ht_info.supp_mcs_set[1] = 0xff; 580 data->band.ht_info.supp_mcs_set[12] = 581 IEEE80211_HT_CAP_MCS_TX_DEFINED; 582 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; 583 584 err = ieee80211_register_hw(hw); 585 if (err < 0) { 586 printk(KERN_DEBUG "mac80211_hwsim: " 587 "ieee80211_register_hw failed (%d)\n", err); 588 goto failed_hw; 589 } 590 591 printk(KERN_DEBUG "%s: hwaddr %s registered\n", 592 wiphy_name(hw->wiphy), 593 print_mac(mac, hw->wiphy->perm_addr)); 594 595 setup_timer(&data->beacon_timer, mac80211_hwsim_beacon, 596 (unsigned long) hw); 597 598 list_add_tail(&data->list, &hwsim_radios); 599 } 600 601 hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup); 602 if (hwsim_mon == NULL) 603 goto failed; 604 605 rtnl_lock(); 606 607 err = dev_alloc_name(hwsim_mon, hwsim_mon->name); 608 if (err < 0) 609 goto failed_mon; 610 611 612 err = register_netdevice(hwsim_mon); 613 if (err < 0) 614 goto failed_mon; 615 616 rtnl_unlock(); 617 618 return 0; 619 620failed_mon: 621 rtnl_unlock(); 622 free_netdev(hwsim_mon); 623 mac80211_hwsim_free(); 624 return err; 625 626failed_hw: 627 device_unregister(data->dev); 628failed_drvdata: 629 ieee80211_free_hw(hw); 630failed: 631 mac80211_hwsim_free(); 632 return err; 633} 634 635 636static void __exit exit_mac80211_hwsim(void) 637{ 638 printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); 639 640 unregister_netdev(hwsim_mon); 641 mac80211_hwsim_free(); 642} 643 644 645module_init(init_mac80211_hwsim); 646module_exit(exit_mac80211_hwsim);