* mac80211_hwsim - simulator of 802.11 radios for mac80211 @ 2008-06-10 10:50 Jouni Malinen 2008-06-10 11:16 ` Johannes Berg 2008-06-10 14:22 ` Dan Williams 0 siblings, 2 replies; 17+ messages in thread From: Jouni Malinen @ 2008-06-10 10:50 UTC (permalink / raw) To: linux-wireless hostapd and wpa_supplicant include a test driver interface that allows them to be tested on a single host without any wireless hardware for development purposes. I have found this very valuable both for developing new functionality and for testing existing code. In order to provide similar mechanism for mac80211 developers and to extend the scope of suitable test cases for hostapd/wpa_supplicant, I've written a Linux kernel module that provides a similar test interface at a lower layer. mac80211_hwsim simulates WLAN hardware and the air interface between the radios by acting as a low-level radio driver for mac80211. Neither mac80211 nor user space programs need any changes to work with the simulated radios. The initial version of mac80211_hwsim is available from the mac80211_hwsim subdirectory of my hostap Git tree: git://w1.fi/srv/git/hostap.git http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=tree;f=mac80211_hwsim If there is interest in moving mac80211_hwsim module into the Linux kernel tree, I'm open to doing that, too. I've included some more information about the code in the README file (see below) and there are also example configuration files for hostapd and wpa_supplicant to show how a WPA2-Personal connection can be opened with mac80211_hwsim. mac80211_hwsim is still very minimal, but I have added couple of TODO comments to the source code to indicate areas that I'm hoping to add for more complete support of mac80211 features. I would also be interested in feedback from other mac80211 developers on what kind of functionality would be useful to have in this kind of simulated test setup. I'm first looking into using this to develop IEEE 802.11w (management frame protection) support into mac80211 and I would expect that the current minimal design is enough for that, but there is certainly room for much more, e.g., in the area of simulating signal strength and packet loss for testing TX rate control, retransmission, and power save functionality. README: Introduction mac80211_hwsim is a Linux kernel module that can be used to simulate arbitrary number of IEEE 802.11 radios for mac80211 on a single device. It can be used to test most of the mac80211 functionality and user space tools (e.g., hostapd and wpa_supplicant) in a way that matches very closely with the normal case of using real WLAN hardware. From the mac80211 view point, mac80211_hwsim is yet another hardware driver, i.e., no changes to mac80211 are needed to use this testing tool. The main goal for mac80211_hwsim is to make it easier for developers to test their code and work with new features to mac80211, hostapd, and wpa_supplicant. The simulated radios do not have the limitations of real hardware, so it is easy to generate an arbitrary test setup and always reproduce the same setup for future tests. In addition, since all radio operation is simulated, any channel can be used in tests regardless of regulatory rules. mac80211_hwsim kernel module has a parameter 'radios' that can be used to select how many radios are simulates (default 2). This allows configuration of both very simply setups (e.g., just a single access point and a station) or large scale tests (multiple access points with hundreds of stations). mac80211_hwsim works by tracking the current channel of each virtual radio and copying all transmitted frames to all other radios that are currently enabled and on the same channel as the transmitting radio. Software encryption in mac80211 is used so that the frames are actually encrypted over the virtual air interface to allow more complete testing of encryption. Simple example This example shows how to use mac80211_hwsim to simulate two radios: one to act as an access point and the other as a station that associates with the AP. hostapd and wpa_supplicant are used to take care of WPA2-PSK authentication. In addition, hostapd is also processing access point side of association. Please note that the currently released Linux kernel (2.6.25) does not enable AP mode, so a simple patch is needed to enable AP mode selection: http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch # Build mac80211_hwsim: make # Load the module insmod ./mac80211_hwsim.ko # Run hostapd (AP) for wlan0 hostapd hostapd.conf # Run wpa_supplicant (station) for wlan1 wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 10:50 mac80211_hwsim - simulator of 802.11 radios for mac80211 Jouni Malinen @ 2008-06-10 11:16 ` Johannes Berg 2008-06-10 12:30 ` John W. Linville 2008-06-10 12:47 ` mac80211_hwsim - simulator of 802.11 radios for mac80211 Jouni Malinen 2008-06-10 14:22 ` Dan Williams 1 sibling, 2 replies; 17+ messages in thread From: Johannes Berg @ 2008-06-10 11:16 UTC (permalink / raw) To: Jouni Malinen; +Cc: linux-wireless [-- Attachment #1: Type: text/plain, Size: 1651 bytes --] On Tue, 2008-06-10 at 13:50 +0300, Jouni Malinen wrote: > hostapd and wpa_supplicant include a test driver interface that allows > them to be tested on a single host without any wireless hardware for > development purposes. I have found this very valuable both for > developing new functionality and for testing existing code. > > In order to provide similar mechanism for mac80211 developers and to > extend the scope of suitable test cases for hostapd/wpa_supplicant, I've > written a Linux kernel module that provides a similar test interface at > a lower layer. mac80211_hwsim simulates WLAN hardware and the air > interface between the radios by acting as a low-level radio driver for > mac80211. Neither mac80211 nor user space programs need any changes to > work with the simulated radios. Way cool! > The initial version of mac80211_hwsim is available from the > mac80211_hwsim subdirectory of my hostap Git tree: > git://w1.fi/srv/git/hostap.git > http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=tree;f=mac80211_hwsim > > If there is interest in moving mac80211_hwsim module into the Linux > kernel tree, I'm open to doing that, too. I think that would make sense, yes, especially since one look at the code already tells me that it needs to follow large API changes to work with the current mac80211. One thing caught my eye: you use GFP_KERNEL in the tx routine, that's not good, it is running under a spinlock. One thing that I'd like to add is a having a "global" monitor interface that is registered by the hwsim module and not mac80211 and shows all frames, regardless of channel etc. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 11:16 ` Johannes Berg @ 2008-06-10 12:30 ` John W. Linville 2008-06-10 13:11 ` Johannes Berg 2008-06-10 12:47 ` mac80211_hwsim - simulator of 802.11 radios for mac80211 Jouni Malinen 1 sibling, 1 reply; 17+ messages in thread From: John W. Linville @ 2008-06-10 12:30 UTC (permalink / raw) To: Johannes Berg; +Cc: Jouni Malinen, linux-wireless On Tue, Jun 10, 2008 at 01:16:15PM +0200, Johannes Berg wrote: > On Tue, 2008-06-10 at 13:50 +0300, Jouni Malinen wrote: > > hostapd and wpa_supplicant include a test driver interface that allows > > them to be tested on a single host without any wireless hardware for > > development purposes. I have found this very valuable both for > > developing new functionality and for testing existing code. > > > > In order to provide similar mechanism for mac80211 developers and to > > extend the scope of suitable test cases for hostapd/wpa_supplicant, I've > > written a Linux kernel module that provides a similar test interface at > > a lower layer. mac80211_hwsim simulates WLAN hardware and the air > > interface between the radios by acting as a low-level radio driver for > > mac80211. Neither mac80211 nor user space programs need any changes to > > work with the simulated radios. > > Way cool! Yes, awesome! > > The initial version of mac80211_hwsim is available from the > > mac80211_hwsim subdirectory of my hostap Git tree: > > git://w1.fi/srv/git/hostap.git > > http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=tree;f=mac80211_hwsim > > > > If there is interest in moving mac80211_hwsim module into the Linux > > kernel tree, I'm open to doing that, too. > > I think that would make sense, yes, especially since one look at the > code already tells me that it needs to follow large API changes to work > with the current mac80211. ACK > One thing that I'd like to add is a having a "global" monitor interface > that is registered by the hwsim module and not mac80211 and shows all > frames, regardless of channel etc. That sounds like a great idea. A mechanism for injecting frames from an external source might be useful as well...? Jouni this looks great. Let's get this into the kernel. John -- John W. Linville linville@tuxdriver.com ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 12:30 ` John W. Linville @ 2008-06-10 13:11 ` Johannes Berg 2008-06-10 15:24 ` John W. Linville 0 siblings, 1 reply; 17+ messages in thread From: Johannes Berg @ 2008-06-10 13:11 UTC (permalink / raw) To: John W. Linville; +Cc: Jouni Malinen, linux-wireless [-- Attachment #1: Type: text/plain, Size: 577 bytes --] > > One thing that I'd like to add is a having a "global" monitor interface > > that is registered by the hwsim module and not mac80211 and shows all > > frames, regardless of channel etc. > > That sounds like a great idea. A mechanism for injecting frames from > an external source might be useful as well...? Using the same interface maybe? We can work on it. > Jouni this looks great. Let's get this into the kernel. I wonder where to stick it. net/mac80211/virtual-hw.c? Or drivers/net/wireless/mac80211-virt.c? Heh. Not that it matters :) johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 13:11 ` Johannes Berg @ 2008-06-10 15:24 ` John W. Linville 2008-06-10 18:37 ` [PATCH RFC] mac80211_hwsim Jouni Malinen 0 siblings, 1 reply; 17+ messages in thread From: John W. Linville @ 2008-06-10 15:24 UTC (permalink / raw) To: Johannes Berg; +Cc: Jouni Malinen, linux-wireless On Tue, Jun 10, 2008 at 03:11:09PM +0200, Johannes Berg wrote: > > Jouni this looks great. Let's get this into the kernel. > > I wonder where to stick it. net/mac80211/virtual-hw.c? Or > drivers/net/wireless/mac80211-virt.c? Heh. Not that it matters :) drivers/net/wireless seems appropriate to me. -- John W. Linville linville@tuxdriver.com ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH RFC] mac80211_hwsim 2008-06-10 15:24 ` John W. Linville @ 2008-06-10 18:37 ` Jouni Malinen 2008-06-10 19:00 ` Johannes Berg 0 siblings, 1 reply; 17+ messages in thread From: Jouni Malinen @ 2008-06-10 18:37 UTC (permalink / raw) To: John W. Linville; +Cc: Johannes Berg, linux-wireless On Tue, Jun 10, 2008 at 11:24:18AM -0400, John W. Linville wrote: > drivers/net/wireless seems appropriate to me. Here's a completely untested (well, it compiles) patch against wireless-test. I'll try to do some testing tomorrow, but if someone is interested in taking a closer look at a version that is converted to use the new data structures for channel/rate configuration, here's a preliminary version. All comments are welcome. As far as functionality is concerned, this is supposed to match with the 2.6.25-based version I have in hostap.git, i.e., the only changes are to convert the newer version of mac80211 API. Since I'm frequently using the latest 2.6.x release kernel instead of wireless-test (and would assume I'm not the only one doing that), I'm thinking of maintaining two versions of the module. One would be in wireless-test and maintained just like any other in-tree driver. The other one is in my hostap.git repository and is maintained as an out-of-tree version that is based on the latest (or well, relatively close to the latest, i.e., whatever I happen to be using ;-) released kernel. Of course, once the in-tree version hits a released kernel, out-of-tree version can die. PS. The URL in Kconfig is just a placeholder and I'll add the information in README and hostapd/wpa_supplicant example configuration files there before this gets submitted properly. diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 86323c8..91e197d 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -681,6 +681,19 @@ config ADM8211 Thanks to Infineon-ADMtek for their support of this driver. +config MAC80211_HWSIM + tristate "Simulated radio testing tool for mac80211" + depends on MAC80211 && WLAN_80211 + ---help--- + This driver is a developer testing tool that can be used to test + IEEE 802.11 networking stack (mac80211) functionality. This is not + needed for normal wireless LAN usage and is only for testing. See + http://w1.fi/mac80211_hwsim/ for more information on how to use + this tool. + + To compile this driver as a module, choose M here: the module will be + called mac80211_hwsim. If unsure, say N. + source "drivers/net/wireless/p54/Kconfig" source "drivers/net/wireless/ath5k/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 5026268..72c314e 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -64,3 +64,5 @@ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54/ obj-$(CONFIG_ATH5K) += ath5k/ + +obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c new file mode 100644 index 0000000..03bbc7a --- /dev/null +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -0,0 +1,536 @@ +/* + * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 + * Copyright (c) 2008, Jouni Malinen <j@w1.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * TODO: + * - IBSS mode simulation (Beacon transmission with competition for "air time") + * - IEEE 802.11a and 802.11n modes + */ + +#include <net/mac80211.h> +#include <net/ieee80211_radiotap.h> +#include <linux/if_arp.h> +#include <linux/rtnetlink.h> +#include <linux/etherdevice.h> + +MODULE_AUTHOR("Jouni Malinen"); +MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211"); +MODULE_LICENSE("GPL"); + +static int radios = 2; +module_param(radios, int, 0444); +MODULE_PARM_DESC(radios, "Number of simulated radios"); + + +static struct class *hwsim_class; + +static struct ieee80211_hw **hwsim_radios; +static int hwsim_radio_count; +static struct net_device *hwsim_mon; /* global monitor netdev */ + + +static const struct ieee80211_channel hwsim_channels[] = { + { .center_freq = 2412 }, + { .center_freq = 2417 }, + { .center_freq = 2422 }, + { .center_freq = 2427 }, + { .center_freq = 2432 }, + { .center_freq = 2437 }, + { .center_freq = 2442 }, + { .center_freq = 2447 }, + { .center_freq = 2452 }, + { .center_freq = 2457 }, + { .center_freq = 2462 }, + { .center_freq = 2467 }, + { .center_freq = 2472 }, + { .center_freq = 2484 }, +}; + +static const struct ieee80211_rate hwsim_rates[] = { + { .bitrate = 10 }, + { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 60, .flags = IEEE80211_RATE_ERP_G }, + { .bitrate = 90, .flags = IEEE80211_RATE_ERP_G }, + { .bitrate = 120, .flags = IEEE80211_RATE_ERP_G }, + { .bitrate = 180, .flags = IEEE80211_RATE_ERP_G }, + { .bitrate = 240, .flags = IEEE80211_RATE_ERP_G }, + { .bitrate = 360, .flags = IEEE80211_RATE_ERP_G }, + { .bitrate = 480, .flags = IEEE80211_RATE_ERP_G }, + { .bitrate = 540, .flags = IEEE80211_RATE_ERP_G } +}; + +struct mac80211_hwsim_data { + struct device *dev; + struct ieee80211_supported_band band; + struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)]; + struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; + + struct ieee80211_channel *channel; + int radio_enabled; + unsigned long beacon_int; /* in jiffies unit */ + unsigned int rx_filter; + int started; + struct timer_list beacon_timer; +}; + + +struct hwsim_radiotap_hdr { + struct ieee80211_radiotap_header hdr; + u8 rt_flags; + u8 rt_rate; + __le16 rt_channel; + __le16 rt_chbitmask; +} __attribute__ ((packed)); + + +static int hwsim_mon_xmit(struct sk_buff *skb, struct net_device *dev) +{ + /* TODO: allow packet injection */ + dev_kfree_skb(skb); + return 0; +} + + +static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, + struct sk_buff *tx_skb) +{ + struct mac80211_hwsim_data *data = hw->priv; + struct sk_buff *skb; + struct hwsim_radiotap_hdr *hdr; + u16 flags; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb); + struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); + + if (!netif_running(hwsim_mon)) + return; + + skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); + if (skb == NULL) + return; + + hdr = (struct hwsim_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); + hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION; + hdr->hdr.it_pad = 0; + hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); + hdr->hdr.it_present = __constant_cpu_to_le32( + (1 << IEEE80211_RADIOTAP_FLAGS) | + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_CHANNEL)); + hdr->rt_flags = 0; + hdr->rt_rate = txrate->bitrate / 5; + hdr->rt_channel = data->channel->center_freq; + flags = IEEE80211_CHAN_2GHZ; + if (txrate->flags & IEEE80211_RATE_ERP_G) + flags |= IEEE80211_CHAN_OFDM; + else + flags |= IEEE80211_CHAN_CCK; + hdr->rt_chbitmask = cpu_to_le16(flags); + + skb->dev = hwsim_mon; + skb_set_mac_header(skb, 0); + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = __constant_htons(ETH_P_802_2); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); +} + + +static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct mac80211_hwsim_data *data = hw->priv; + struct ieee80211_rx_status rx_status; + int i, ack = 0; + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_info *txi; + + mac80211_hwsim_monitor_rx(hw, skb); + + if (skb->len < 10) { + /* Should not happen; just a sanity check for addr1 use */ + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + if (!data->radio_enabled) { + printk(KERN_DEBUG "%s: dropped TX frame since radio " + "disabled\n", wiphy_name(hw->wiphy)); + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + hdr = (struct ieee80211_hdr *) skb->data; + if (is_multicast_ether_addr(hdr->addr1)) + ack = 1; + + memset(&rx_status, 0, sizeof(rx_status)); + /* TODO: set mactime */ + rx_status.freq = data->channel->center_freq; + rx_status.band = data->channel->band; + rx_status.rate_idx = info->tx_rate_idx; + /* TODO: simulate signal strength (and optional packet drop) */ + + /* Copy skb to all enabled radios that are on the current frequency */ + for (i = 0; i < hwsim_radio_count; i++) { + struct mac80211_hwsim_data *data2; + struct sk_buff *nskb; + + if (hwsim_radios[i] == NULL || hwsim_radios[i] == hw) + continue; + data2 = hwsim_radios[i]->priv; + if (!data2->started || !data2->radio_enabled || + data->channel->band != data2->channel->band || + data->channel->center_freq != data2->channel->center_freq) + continue; + + nskb = skb_copy(skb, GFP_ATOMIC); + if (nskb == NULL) + continue; + + if (memcmp(hdr->addr1, hwsim_radios[i]->wiphy->perm_addr, + ETH_ALEN) == 0) + ack = 1; + ieee80211_rx_irqsafe(hwsim_radios[i], nskb, &rx_status); + } + + txi = IEEE80211_SKB_CB(skb); + memset(&txi->status, 0, sizeof(txi->status)); + if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { + if (ack) + txi->flags |= IEEE80211_TX_STAT_ACK; + else + txi->status.excessive_retries = 1; + } + ieee80211_tx_status_irqsafe(hw, skb); + return NETDEV_TX_OK; +} + + +static int mac80211_hwsim_start(struct ieee80211_hw *hw) +{ + struct mac80211_hwsim_data *data = hw->priv; + printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); + data->started = 1; + return 0; +} + + +static void mac80211_hwsim_stop(struct ieee80211_hw *hw) +{ + struct mac80211_hwsim_data *data = hw->priv; + data->started = 0; + printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); +} + + +static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", + wiphy_name(hw->wiphy), __func__, conf->type, + print_mac(mac, conf->mac_addr)); + return 0; +} + + +static void mac80211_hwsim_remove_interface( + struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) +{ + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", + wiphy_name(hw->wiphy), __func__, conf->type, + print_mac(mac, conf->mac_addr)); +} + + +static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, + struct ieee80211_vif *vif) +{ + struct ieee80211_hw *hw = arg; + struct mac80211_hwsim_data *data = hw->priv; + struct sk_buff *skb; + struct ieee80211_rx_status rx_status; + int i; + struct ieee80211_tx_info *info; + + if (vif->type != IEEE80211_IF_TYPE_AP) + return; + + skb = ieee80211_beacon_get(hw, vif); + if (skb == NULL) + return; + info = IEEE80211_SKB_CB(skb); + + mac80211_hwsim_monitor_rx(hw, skb); + + memset(&rx_status, 0, sizeof(rx_status)); + /* TODO: set mactime */ + rx_status.freq = data->channel->center_freq; + rx_status.band = data->channel->band; + rx_status.rate_idx = info->tx_rate_idx; + /* TODO: simulate signal strength (and optional packet drop) */ + + /* Copy skb to all enabled radios that are on the current frequency */ + for (i = 0; i < hwsim_radio_count; i++) { + struct mac80211_hwsim_data *data2; + struct sk_buff *nskb; + + if (hwsim_radios[i] == NULL || hwsim_radios[i] == hw) + continue; + data2 = hwsim_radios[i]->priv; + if (!data2->started || !data2->radio_enabled || + data->channel->band != data2->channel->band || + data->channel->center_freq != data2->channel->center_freq) + continue; + + nskb = skb_copy(skb, GFP_ATOMIC); + if (nskb == NULL) + continue; + + ieee80211_rx_irqsafe(hwsim_radios[i], nskb, &rx_status); + } + + dev_kfree_skb(skb); +} + + +static void mac80211_hwsim_beacon(unsigned long arg) +{ + struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; + struct mac80211_hwsim_data *data = hw->priv; + + if (!data->started || !data->radio_enabled) + return; + + ieee80211_iterate_active_interfaces(hw, mac80211_hwsim_beacon_tx, hw); + + data->beacon_timer.expires = jiffies + data->beacon_int; + add_timer(&data->beacon_timer); +} + + +static int mac80211_hwsim_config(struct ieee80211_hw *hw, + struct ieee80211_conf *conf) +{ + struct mac80211_hwsim_data *data = hw->priv; + + printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n", + wiphy_name(hw->wiphy), __func__, + conf->channel->center_freq, conf->radio_enabled, + conf->beacon_int); + + data->channel = conf->channel; + data->radio_enabled = conf->radio_enabled; + data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000; + if (data->beacon_int < 1) + data->beacon_int = 1; + + if (!data->started || !data->radio_enabled) + del_timer(&data->beacon_timer); + else + mod_timer(&data->beacon_timer, jiffies + data->beacon_int); + + return 0; +} + + +static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + int mc_count, + struct dev_addr_list *mc_list) +{ + struct mac80211_hwsim_data *data = hw->priv; + + printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); + + data->rx_filter = 0; + if (*total_flags & FIF_PROMISC_IN_BSS) + data->rx_filter |= FIF_PROMISC_IN_BSS; + if (*total_flags & FIF_ALLMULTI) + data->rx_filter |= FIF_ALLMULTI; + + *total_flags = data->rx_filter; +} + + + +static const struct ieee80211_ops mac80211_hwsim_ops = +{ + .tx = mac80211_hwsim_tx, + .start = mac80211_hwsim_start, + .stop = mac80211_hwsim_stop, + .add_interface = mac80211_hwsim_add_interface, + .remove_interface = mac80211_hwsim_remove_interface, + .config = mac80211_hwsim_config, + .configure_filter = mac80211_hwsim_configure_filter, +}; + + +static void mac80211_hwsim_free(void) +{ + int i; + + for (i = 0; i < hwsim_radio_count; i++) { + if (hwsim_radios[i]) { + struct mac80211_hwsim_data *data; + data = hwsim_radios[i]->priv; + ieee80211_unregister_hw(hwsim_radios[i]); + if (!IS_ERR(data->dev)) + device_unregister(data->dev); + ieee80211_free_hw(hwsim_radios[i]); + } + } + kfree(hwsim_radios); + class_destroy(hwsim_class); +} + + +static struct device_driver mac80211_hwsim_driver = { + .name = "mac80211_hwsim" +}; + + +static void hwsim_mon_setup(struct net_device *dev) +{ + dev->hard_start_xmit = hwsim_mon_xmit; + dev->destructor = free_netdev; + ether_setup(dev); + dev->tx_queue_len = 0; + dev->type = ARPHRD_IEEE80211_RADIOTAP; + memset(dev->dev_addr, 0, ETH_ALEN); + dev->dev_addr[0] = 0x12; +} + + +static int __init init_mac80211_hwsim(void) +{ + int i, err = 0; + u8 addr[ETH_ALEN]; + struct mac80211_hwsim_data *data; + struct ieee80211_hw *hw; + DECLARE_MAC_BUF(mac); + + if (radios < 1 || radios > 65535) + return -EINVAL; + + hwsim_radio_count = radios; + hwsim_radios = kcalloc(hwsim_radio_count, + sizeof(struct ieee80211_hw *), GFP_KERNEL); + if (hwsim_radios == NULL) + return -ENOMEM; + + hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); + if (IS_ERR(hwsim_class)) { + kfree(hwsim_radios); + return PTR_ERR(hwsim_class); + } + + memset(addr, 0, ETH_ALEN); + addr[0] = 0x02; + + for (i = 0; i < hwsim_radio_count; i++) { + printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n", + i); + hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops); + if (hw == NULL) { + printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw " + "failed\n"); + err = -ENOMEM; + goto failed; + } + hwsim_radios[i] = hw; + + data = hw->priv; + data->dev = device_create(hwsim_class, NULL, 0, "hwsim%d", i); + if (IS_ERR(data->dev)) { + printk(KERN_DEBUG "mac80211_hwsim: device_create " + "failed (%ld)\n", PTR_ERR(data->dev)); + err = -ENOMEM; + goto failed; + } + data->dev->driver = &mac80211_hwsim_driver; + dev_set_drvdata(data->dev, hw); + + SET_IEEE80211_DEV(hw, data->dev); + addr[3] = i >> 8; + addr[4] = i; + SET_IEEE80211_PERM_ADDR(hw, addr); + + hw->channel_change_time = 1; + hw->queues = 1; + + memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); + memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); + data->band.channels = data->channels; + data->band.n_channels = ARRAY_SIZE(hwsim_channels); + data->band.bitrates = data->rates; + data->band.n_bitrates = ARRAY_SIZE(hwsim_rates); + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; + + err = ieee80211_register_hw(hw); + if (err < 0) { + printk(KERN_DEBUG "mac80211_hwsim: " + "ieee80211_register_hw failed (%d)\n", err); + goto failed; + } + + printk(KERN_DEBUG "%s: hwaddr %s registered\n", + wiphy_name(hw->wiphy), + print_mac(mac, hw->wiphy->perm_addr)); + + setup_timer(&data->beacon_timer, mac80211_hwsim_beacon, + (unsigned long) hw); + } + + hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup); + if (hwsim_mon == NULL) + goto failed; + + rtnl_lock(); + + err = dev_alloc_name(hwsim_mon, hwsim_mon->name); + if (err < 0) { + goto failed_mon; + } + + err = register_netdevice(hwsim_mon); + if (err < 0) + goto failed_mon; + + rtnl_unlock(); + + return 0; + +failed_mon: + rtnl_unlock(); + free_netdev(hwsim_mon); + +failed: + mac80211_hwsim_free(); + return err; +} + + +static void __exit exit_mac80211_hwsim(void) +{ + printk(KERN_DEBUG "mac80211_hwsim: unregister %d radios\n", + hwsim_radio_count); + + unregister_netdev(hwsim_mon); + mac80211_hwsim_free(); +} + + +module_init(init_mac80211_hwsim); +module_exit(exit_mac80211_hwsim); -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH RFC] mac80211_hwsim 2008-06-10 18:37 ` [PATCH RFC] mac80211_hwsim Jouni Malinen @ 2008-06-10 19:00 ` Johannes Berg 2008-06-11 6:57 ` Jouni Malinen 0 siblings, 1 reply; 17+ messages in thread From: Johannes Berg @ 2008-06-10 19:00 UTC (permalink / raw) To: Jouni Malinen; +Cc: John W. Linville, linux-wireless [-- Attachment #1: Type: text/plain, Size: 3778 bytes --] > Here's a completely untested (well, it compiles) patch against > wireless-test. I'll try to do some testing tomorrow, but if someone is > interested in taking a closer look at a version that is converted to use > the new data structures for channel/rate configuration, here's a > preliminary version. All comments are welcome. > > As far as functionality is concerned, this is supposed to match with the > 2.6.25-based version I have in hostap.git, i.e., the only changes are to > convert the newer version of mac80211 API. Since I'm frequently using > the latest 2.6.x release kernel instead of wireless-test (and would > assume I'm not the only one doing that), I'm thinking of maintaining two > versions of the module. One would be in wireless-test and maintained > just like any other in-tree driver. The other one is in my hostap.git > repository and is maintained as an out-of-tree version that is based on > the latest (or well, relatively close to the latest, i.e., whatever I > happen to be using ;-) released kernel. Of course, once the in-tree > version hits a released kernel, out-of-tree version can die. Sounds good to me. > PS. > > The URL in Kconfig is just a placeholder and I'll add the information in > README and hostapd/wpa_supplicant example configuration files there > before this gets submitted properly. Should we add it to Documentation/networking/ instead? Don't care much, but it might be easier to track version changes that way. > +static const struct ieee80211_rate hwsim_rates[] = { > + { .bitrate = 10 }, > + { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, > + { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, > + { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, > + { .bitrate = 60, .flags = IEEE80211_RATE_ERP_G }, You don't need to add the ERP flag manually, it'll be added based on the rate automatically. > + if (is_multicast_ether_addr(hdr->addr1)) > + ack = 1; That seems a bit weird to me. mac80211 shouldn't request an ACK for mcast, but why fake one? > ... beacon ... > + if (vif->type != IEEE80211_IF_TYPE_AP) > + return; That could support mesh as well, in mesh-beacon-like-AP mode rather than mesh-beacon-like-IBSS. > + data->channel->band != data2->channel->band || > + data->channel->center_freq != data2->channel->center_freq) The band check is useless since the frequency is in MHz, it's mostly to know which band table to look up things in if necessary. > +static void mac80211_hwsim_beacon(unsigned long arg) > +{ > + struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; > + struct mac80211_hwsim_data *data = hw->priv; > + > + if (!data->started || !data->radio_enabled) > + return; > + > + ieee80211_iterate_active_interfaces(hw, mac80211_hwsim_beacon_tx, hw); Cool, another user of this API :) > + data->rx_filter = 0; > + if (*total_flags & FIF_PROMISC_IN_BSS) > + data->rx_filter |= FIF_PROMISC_IN_BSS; > + if (*total_flags & FIF_ALLMULTI) > + data->rx_filter |= FIF_ALLMULTI; > + > + *total_flags = data->rx_filter; You don't actually seem to use these flags though. Should be added at some point, I think. > + memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); > + memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); > + data->band.channels = data->channels; > + data->band.n_channels = ARRAY_SIZE(hwsim_channels); > + data->band.bitrates = data->rates; > + data->band.n_bitrates = ARRAY_SIZE(hwsim_rates); You shouldn't need to memcpy these, just point to the static allocations. > + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; You can even allocate the band struct statically. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH RFC] mac80211_hwsim 2008-06-10 19:00 ` Johannes Berg @ 2008-06-11 6:57 ` Jouni Malinen 2008-06-11 12:07 ` Johannes Berg 0 siblings, 1 reply; 17+ messages in thread From: Jouni Malinen @ 2008-06-11 6:57 UTC (permalink / raw) To: Johannes Berg; +Cc: John W. Linville, linux-wireless On Tue, Jun 10, 2008 at 09:00:44PM +0200, Johannes Berg wrote: > Should we add it to Documentation/networking/ instead? Don't care much, > but it might be easier to track version changes that way. That's fine, too. I'll add a subdirectory there for the readme and example configuration files. > > +static const struct ieee80211_rate hwsim_rates[] = { > > + { .bitrate = 60, .flags = IEEE80211_RATE_ERP_G }, > > You don't need to add the ERP flag manually, it'll be added based on the > rate automatically. That sounds better. net/wireless.h was bit confusing on this part since it has the "filled by the core" notice only for IEEE80211_RATE_MANDATORY_* flags, not for IEEE80211_RATE_ERP_G. Looks like this should be added to the ERP flag, too. > > + if (is_multicast_ether_addr(hdr->addr1)) > > + ack = 1; > > That seems a bit weird to me. mac80211 shouldn't request an ACK for > mcast, but why fake one? That was leftover from the previous version that did not check whether IEEE80211_TX_CTL_NO_ACK was used. I'll remove it. > > > ... beacon ... > > + if (vif->type != IEEE80211_IF_TYPE_AP) > > + return; > > That could support mesh as well, in mesh-beacon-like-AP mode rather than > mesh-beacon-like-IBSS. Yes. I'm not yet very familiar with the mesh implementation in mac80211 and did not want to enable things before having had chance to test them. > > + data->channel->band != data2->channel->band || > > + data->channel->center_freq != data2->channel->center_freq) > > The band check is useless since the frequency is in MHz, it's mostly to > know which band table to look up things in if necessary. OK, I'll remove it. With the current bands this seems to be fine, but how would that work with 10 MHz and 5 MHz channels? I haven't verified, but I would assume they could use same center frequency with 20 MHz channels.. > > + ieee80211_iterate_active_interfaces(hw, mac80211_hwsim_beacon_tx, hw); > > Cool, another user of this API :) I was first assuming that I have to implement some sort of data structure to store all vifs in the driver code to do this, but this one came in quite handy.. > > + data->rx_filter = 0; > > + if (*total_flags & FIF_PROMISC_IN_BSS) > > + data->rx_filter |= FIF_PROMISC_IN_BSS; > You don't actually seem to use these flags though. Should be added at > some point, I think. Yes, I left it there for future implementation of the actually filtering logic. > > + memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); > You shouldn't need to memcpy these, just point to the static > allocations. > > + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; > > You can even allocate the band struct statically. Hmm.. Aren't the channel and rate structures being modified by mac80211/wireless code? Sharing the same global data area for all radios might not be desired if there will be different "hw" capabilities as far as supported channels/rates/bands are concerned. In addition, the static data structures were marked 'const' which would at least be somewhat confusing if the data ends up changing. -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH RFC] mac80211_hwsim 2008-06-11 6:57 ` Jouni Malinen @ 2008-06-11 12:07 ` Johannes Berg 2008-06-11 12:54 ` Tomas Winkler 0 siblings, 1 reply; 17+ messages in thread From: Johannes Berg @ 2008-06-11 12:07 UTC (permalink / raw) To: Jouni Malinen; +Cc: John W. Linville, linux-wireless Jouni Malinen wrote: > That sounds better. net/wireless.h was bit confusing on this part since > it has the "filled by the core" notice only for > IEEE80211_RATE_MANDATORY_* flags, not for IEEE80211_RATE_ERP_G. Looks > like this should be added to the ERP flag, too. good point. > OK, I'll remove it. With the current bands this seems to be fine, but > how would that work with 10 MHz and 5 MHz channels? I haven't verified, > but I would assume they could use same center frequency with 20 MHz > channels.. Yeah... that isn't really supported yet. > Hmm.. Aren't the channel and rate structures being modified by > mac80211/wireless code? Sharing the same global data area for all radios > might not be desired if there will be different "hw" capabilities as far > as supported channels/rates/bands are concerned. In addition, the static > data structures were marked 'const' which would at least be somewhat > confusing if the data ends up changing. They're only modified all the same, so it's fine to share unless you have different capabilities. Yeah, you should removed the const then. johannes ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH RFC] mac80211_hwsim 2008-06-11 12:07 ` Johannes Berg @ 2008-06-11 12:54 ` Tomas Winkler 0 siblings, 0 replies; 17+ messages in thread From: Tomas Winkler @ 2008-06-11 12:54 UTC (permalink / raw) To: Johannes Berg; +Cc: Jouni Malinen, John W. Linville, linux-wireless On Wed, Jun 11, 2008 at 3:07 PM, Johannes Berg <johannes@sipsolutions.net> wrote: > Jouni Malinen wrote: >> That sounds better. net/wireless.h was bit confusing on this part since >> it has the "filled by the core" notice only for >> IEEE80211_RATE_MANDATORY_* flags, not for IEEE80211_RATE_ERP_G. Looks >> like this should be added to the ERP flag, too. > > good point. > >> OK, I'll remove it. With the current bands this seems to be fine, but >> how would that work with 10 MHz and 5 MHz channels? I haven't verified, >> but I would assume they could use same center frequency with 20 MHz >> channels.. > > Yeah... that isn't really supported yet. > We've added support for FAT channels 40Mhz, but that uses negative logic i.e. whether it's not supported. This is due to fact that FAT channel may expand to above or bellow channel. Isn't usage of 10Mhz and 5Mz being slowly deprecated anyway? Tomas. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 11:16 ` Johannes Berg 2008-06-10 12:30 ` John W. Linville @ 2008-06-10 12:47 ` Jouni Malinen 2008-06-10 13:09 ` Johannes Berg 1 sibling, 1 reply; 17+ messages in thread From: Jouni Malinen @ 2008-06-10 12:47 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless On Tue, Jun 10, 2008 at 01:16:15PM +0200, Johannes Berg wrote: > On Tue, 2008-06-10 at 13:50 +0300, Jouni Malinen wrote: > > If there is interest in moving mac80211_hwsim module into the Linux > > kernel tree, I'm open to doing that, too. > > I think that would make sense, yes, especially since one look at the > code already tells me that it needs to follow large API changes to work > with the current mac80211. I'm currently running Linux 2.6.25 on my laptop and as such, this is indeed not based on the latest changes. I'll fix couple of issues in the current code with 2.6.25-based version and then look into making a submission against wireless-testing (or if there are large, pending patches that are not yet there, against something including those changes). > One thing caught my eye: you use GFP_KERNEL in the tx routine, that's > not good, it is running under a spinlock. Thanks, I'll fix that. I was trying to follow the documentation in net/mac80211.h to verify that it is correct, but clearly I missed the comment on tx() about the handler having to be atomic. > One thing that I'd like to add is a having a "global" monitor interface > that is registered by the hwsim module and not mac80211 and shows all > frames, regardless of channel etc. Yes, I've been thinking of something similar, too. I'll add a netdev that gets all frames with radiotap header. -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 12:47 ` mac80211_hwsim - simulator of 802.11 radios for mac80211 Jouni Malinen @ 2008-06-10 13:09 ` Johannes Berg 2008-06-10 13:12 ` Johannes Berg 2008-06-10 15:02 ` Jouni Malinen 0 siblings, 2 replies; 17+ messages in thread From: Johannes Berg @ 2008-06-10 13:09 UTC (permalink / raw) To: Jouni Malinen; +Cc: linux-wireless [-- Attachment #1: Type: text/plain, Size: 1592 bytes --] > I'm currently running Linux 2.6.25 on my laptop and as such, this is > indeed not based on the latest changes. I'll fix couple of issues in the > current code with 2.6.25-based version and then look into making a > submission against wireless-testing (or if there are large, pending > patches that are not yet there, against something including those > changes). I don't think there are large pending changes, but there were large changes in the way channels are registered, tx control works etc. > > One thing caught my eye: you use GFP_KERNEL in the tx routine, that's > > not good, it is running under a spinlock. > > Thanks, I'll fix that. I was trying to follow the documentation in > net/mac80211.h to verify that it is correct, but clearly I missed the > comment on tx() about the handler having to be atomic. You should probably use the _irqsafe versions of rx and txstatus too. > > One thing that I'd like to add is a having a "global" monitor interface > > that is registered by the hwsim module and not mac80211 and shows all > > frames, regardless of channel etc. > > Yes, I've been thinking of something similar, too. I'll add a netdev > that gets all frames with radiotap header. Maybe it could support injection on that too, so you can test against a userspace agent. The design I had come up with a long time ago allowed userspace to control each radio by having each _radio_ have a raw netdev like this and not doing forwarding in the kernel but relying on some userspace tool, but I guess that much more complicated. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 13:09 ` Johannes Berg @ 2008-06-10 13:12 ` Johannes Berg 2008-06-10 15:02 ` Jouni Malinen 1 sibling, 0 replies; 17+ messages in thread From: Johannes Berg @ 2008-06-10 13:12 UTC (permalink / raw) To: Jouni Malinen; +Cc: linux-wireless [-- Attachment #1: Type: text/plain, Size: 385 bytes --] > The design I had come up with a long time ago allowed userspace to > control each radio by having each _radio_ have a raw netdev like this > and not doing forwarding in the kernel but relying on some userspace > tool, but I guess that much more complicated. I should mention that I have notes on that: http://kernelnewbies.org/KernelProjects/Mac80211TestDriver johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 13:09 ` Johannes Berg 2008-06-10 13:12 ` Johannes Berg @ 2008-06-10 15:02 ` Jouni Malinen 2008-06-10 15:11 ` Johannes Berg 1 sibling, 1 reply; 17+ messages in thread From: Jouni Malinen @ 2008-06-10 15:02 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless On Tue, Jun 10, 2008 at 03:09:38PM +0200, Johannes Berg wrote: > I don't think there are large pending changes, but there were large > changes in the way channels are registered, tx control works etc. OK. > You should probably use the _irqsafe versions of rx and txstatus too. Hmm.. That was interesting.. Changing txstatus to use _irqsafe is was fine, but changing ieee80211_rx to ieee80211_rx_irqsafe triggers something bad.. Loadavg jumps sky high the moment I kill hostapd and ksoftirqd/0 and rmmod (which I ran after killing hostapd) are taking all CPU.. I can hardly type a command at that point. Looks like something goes horribly wrong with the extra queuing with ieee80211_rx_irqsafe. Maybe sending something to a netdev that is down ends up in a busy loop with a frame or something. In other words, I did not change to use _irqsafe yet, but will do once I have more time to figure out what on earth is going on here. > > Yes, I've been thinking of something similar, too. I'll add a netdev > > that gets all frames with radiotap header. > > Maybe it could support injection on that too, so you can test against a > userspace agent. Yes, I added the global radiotap monitor to hwsim (ifname=hwsim#) and left the hard_xmit function empty with a TODO comment.. The netdev from outside mac80211 is quite useful since it can be set up before any of the mac80211 netdevs and it is possible to capture all frames from the beginning.. If needed, we could add some more flags to the radiotap header for indicating what was done with the frame, but that is something that can easily be added later. > The design I had come up with a long time ago allowed userspace to > control each radio by having each _radio_ have a raw netdev like this > and not doing forwarding in the kernel but relying on some userspace > tool, but I guess that much more complicated. That might be useful for some of the tests. I was interested in adding some kind of interface to make it easy to design test cases from user space, but the current code was so simple that I did not want to make it any more complex in the first version. Anyway, it might make sense to provide option mechanism to allow more user space control since I'm also interested in things like testing rate control with a programmable signal strength/channel quality and I do not really want to see the controller for that simulation in the kernel.. -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 15:02 ` Jouni Malinen @ 2008-06-10 15:11 ` Johannes Berg 2008-06-10 16:31 ` Jouni Malinen 0 siblings, 1 reply; 17+ messages in thread From: Johannes Berg @ 2008-06-10 15:11 UTC (permalink / raw) To: Jouni Malinen; +Cc: linux-wireless [-- Attachment #1: Type: text/plain, Size: 2679 bytes --] > > You should probably use the _irqsafe versions of rx and txstatus too. > > Hmm.. That was interesting.. Changing txstatus to use _irqsafe is was > fine, but changing ieee80211_rx to ieee80211_rx_irqsafe triggers > something bad.. Loadavg jumps sky high the moment I kill hostapd and > ksoftirqd/0 and rmmod (which I ran after killing hostapd) are taking all > CPU.. I can hardly type a command at that point. Looks like something > goes horribly wrong with the extra queuing with ieee80211_rx_irqsafe. > Maybe sending something to a netdev that is down ends up in a busy loop > with a frame or something. In other words, I did not change to use > _irqsafe yet, but will do once I have more time to figure out what on > earth is going on here. Hmm. I suspect you called rx_irqsafe _after_ the radio was stopped (via mac80211's stop callback), and at stop time we also disable the tasklet, so something probably goes haywire if you tasklet_schedule a disabled tasklet. > Yes, I added the global radiotap monitor to hwsim (ifname=hwsim#) and > left the hard_xmit function empty with a TODO comment.. The netdev from > outside mac80211 is quite useful since it can be set up before any of > the mac80211 netdevs and it is possible to capture all frames from the > beginning.. If needed, we could add some more flags to the radiotap > header for indicating what was done with the frame, but that is > something that can easily be added later. Yeah, true, good to have the simpler code in place first anyway. > > The design I had come up with a long time ago allowed userspace to > > control each radio by having each _radio_ have a raw netdev like this > > and not doing forwarding in the kernel but relying on some userspace > > tool, but I guess that much more complicated. > > That might be useful for some of the tests. I was interested in adding > some kind of interface to make it easy to design test cases from user > space, but the current code was so simple that I did not want to make it > any more complex in the first version. Anyway, it might make sense to > provide option mechanism to allow more user space control since I'm also > interested in things like testing rate control with a programmable > signal strength/channel quality and I do not really want to see the > controller for that simulation in the kernel.. Heh, yeah. I'd like to have it more dynamically configurable too, but we can add that later as well. Maybe some debugfs stuff or so that allows disconnecting a radio from the "virtual air" at which point a hwsim per-radio netdev shows up for that one. Anyway, future, when needed. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 15:11 ` Johannes Berg @ 2008-06-10 16:31 ` Jouni Malinen 0 siblings, 0 replies; 17+ messages in thread From: Jouni Malinen @ 2008-06-10 16:31 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless On Tue, Jun 10, 2008 at 05:11:21PM +0200, Johannes Berg wrote: > Hmm. I suspect you called rx_irqsafe _after_ the radio was stopped (via > mac80211's stop callback), and at stop time we also disable the tasklet, > so something probably goes haywire if you tasklet_schedule a disabled > tasklet. Yes, that caused it. I added a new flag based on start/stop for determining which interface are ready to accept new frames. I was already doing this based on radio_enabled flag, but apparently that is left set when setting the interface down. -- Jouni Malinen PGP id EFC895FA ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: mac80211_hwsim - simulator of 802.11 radios for mac80211 2008-06-10 10:50 mac80211_hwsim - simulator of 802.11 radios for mac80211 Jouni Malinen 2008-06-10 11:16 ` Johannes Berg @ 2008-06-10 14:22 ` Dan Williams 1 sibling, 0 replies; 17+ messages in thread From: Dan Williams @ 2008-06-10 14:22 UTC (permalink / raw) To: Jouni Malinen; +Cc: linux-wireless On Tue, 2008-06-10 at 13:50 +0300, Jouni Malinen wrote: > hostapd and wpa_supplicant include a test driver interface that allows > them to be tested on a single host without any wireless hardware for > development purposes. I have found this very valuable both for > developing new functionality and for testing existing code. > > In order to provide similar mechanism for mac80211 developers and to > extend the scope of suitable test cases for hostapd/wpa_supplicant, I've > written a Linux kernel module that provides a similar test interface at > a lower layer. mac80211_hwsim simulates WLAN hardware and the air > interface between the radios by acting as a low-level radio driver for > mac80211. Neither mac80211 nor user space programs need any changes to > work with the simulated radios. Awesome. I was going to write a basic WEXT driver so I could get some better tests going for NetworkManager, but you've beaten me to it :) Thanks! Dan > The initial version of mac80211_hwsim is available from the > mac80211_hwsim subdirectory of my hostap Git tree: > git://w1.fi/srv/git/hostap.git > http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=tree;f=mac80211_hwsim > > If there is interest in moving mac80211_hwsim module into the Linux > kernel tree, I'm open to doing that, too. > > I've included some more information about the code in the README file > (see below) and there are also example configuration files for hostapd > and wpa_supplicant to show how a WPA2-Personal connection can be opened > with mac80211_hwsim. > > mac80211_hwsim is still very minimal, but I have added couple of TODO > comments to the source code to indicate areas that I'm hoping to add for > more complete support of mac80211 features. I would also be interested > in feedback from other mac80211 developers on what kind of functionality > would be useful to have in this kind of simulated test setup. I'm first > looking into using this to develop IEEE 802.11w (management frame > protection) support into mac80211 and I would expect that the current > minimal design is enough for that, but there is certainly room for much > more, e.g., in the area of simulating signal strength and packet loss > for testing TX rate control, retransmission, and power save > functionality. > > > > README: > > Introduction > > mac80211_hwsim is a Linux kernel module that can be used to simulate > arbitrary number of IEEE 802.11 radios for mac80211 on a single > device. It can be used to test most of the mac80211 functionality and > user space tools (e.g., hostapd and wpa_supplicant) in a way that > matches very closely with the normal case of using real WLAN > hardware. From the mac80211 view point, mac80211_hwsim is yet another > hardware driver, i.e., no changes to mac80211 are needed to use this > testing tool. > > The main goal for mac80211_hwsim is to make it easier for developers > to test their code and work with new features to mac80211, hostapd, > and wpa_supplicant. The simulated radios do not have the limitations > of real hardware, so it is easy to generate an arbitrary test setup > and always reproduce the same setup for future tests. In addition, > since all radio operation is simulated, any channel can be used in > tests regardless of regulatory rules. > > mac80211_hwsim kernel module has a parameter 'radios' that can be used > to select how many radios are simulates (default 2). This allows > configuration of both very simply setups (e.g., just a single access > point and a station) or large scale tests (multiple access points with > hundreds of stations). > > mac80211_hwsim works by tracking the current channel of each virtual > radio and copying all transmitted frames to all other radios that are > currently enabled and on the same channel as the transmitting > radio. Software encryption in mac80211 is used so that the frames are > actually encrypted over the virtual air interface to allow more > complete testing of encryption. > > > Simple example > > This example shows how to use mac80211_hwsim to simulate two radios: > one to act as an access point and the other as a station that > associates with the AP. hostapd and wpa_supplicant are used to take > care of WPA2-PSK authentication. In addition, hostapd is also > processing access point side of association. > > Please note that the currently released Linux kernel (2.6.25) does not > enable AP mode, so a simple patch is needed to enable AP mode selection: > http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch > > > # Build mac80211_hwsim: > make > > # Load the module > insmod ./mac80211_hwsim.ko > > # Run hostapd (AP) for wlan0 > hostapd hostapd.conf > > # Run wpa_supplicant (station) for wlan1 > wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf > ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2008-06-11 12:54 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-06-10 10:50 mac80211_hwsim - simulator of 802.11 radios for mac80211 Jouni Malinen 2008-06-10 11:16 ` Johannes Berg 2008-06-10 12:30 ` John W. Linville 2008-06-10 13:11 ` Johannes Berg 2008-06-10 15:24 ` John W. Linville 2008-06-10 18:37 ` [PATCH RFC] mac80211_hwsim Jouni Malinen 2008-06-10 19:00 ` Johannes Berg 2008-06-11 6:57 ` Jouni Malinen 2008-06-11 12:07 ` Johannes Berg 2008-06-11 12:54 ` Tomas Winkler 2008-06-10 12:47 ` mac80211_hwsim - simulator of 802.11 radios for mac80211 Jouni Malinen 2008-06-10 13:09 ` Johannes Berg 2008-06-10 13:12 ` Johannes Berg 2008-06-10 15:02 ` Jouni Malinen 2008-06-10 15:11 ` Johannes Berg 2008-06-10 16:31 ` Jouni Malinen 2008-06-10 14:22 ` Dan Williams
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).