具体概念性的内容,以及mac80211的框架,可以参看:
http://blog.csdn.net/zxygww/article/details/24874155
WLAN
linux下wlan总体架构如图所示:
mac80211架构,如图所示:
用户空间:
配置:wpa_supplicant和hostapd:
所有直接与用户交互的应用程序都在这里。 例如可以基于GUI / CLI。 在Ubuntu / Fedora发行版本的网络管理器是基于GUI的,但最核心的部分是基于命令行的。例如,使用wpa_supplicant用于控制STA的部分和使用hostapd用于控制AP的部分。
两者都是可通过其CLI版本(wpa_cli,hostapd_cli)配置的。
用户空间和内核空间之间的桥
如何在用户空间中的各种应用程序和内核中的核心实体之间进行沟通呢? 我们有不同的方法,但都是基于不同的套接字接口。
WExt ==> 通用无线扩展:IOCTL接口
NL80211==> Netlink套接字
HostAP ==> 原始数据包套接字
特定于芯片组:
Atheros==> IOCTL 接口
Prism,IPW etc.
内核空间
配置和UMAC
对于开源世界来说,内核的WLAN架构是mac80211,它分成2个内核模块。
cfg80211.ko:它处理所有的配置,和用户空间的交互。
mac80211.ko:协议:上层的MAC,和驱动程序的交互。
大部分功能和管理是由具有mac80211模块在底层的MAC协助下处理的。
低层的Mac驱动程序
低层的MAC驱动担任UMAC和芯片组(固件和硬件)之间的桥梁。 他们通过Linux内核提供的服务来执行所有的设备初始化,注册到操作系统上,错误注册,中断注册等。
一个精心编写的驱动程序遵循这些约定:
- 保持一个操作系统无关层:方便移植到不同的操作系统。
- 保持一个UMAC无关层:方便移植到不同的UMAC上:专有,开源,第三方等。
- 总线抽象层:保持不同的物理总线之间,如PCI,PCIe,AHB,SDIO等的相容性
芯片组:固件和硬件
完整的802.11协议的功能在这里实现。
固件可能是运行在一个单独的处理器/微控制器上,它配置和控制硬件,同时还通过一个芯片组(控制路径)特定的通讯接口与主机(驱动程序)进行交互。
数据路径通常包括一个硬件上的DMA控制器,它负责产生中断给主处理器和从/至主机传输数据包到硬件队列。
mac80211:auth-assoc-deauth
This is copied from Documentation/networking/mac80211-auth-assoc-deauth.txt in the kernel sources
文件
查看源码,记住各个源码文件的作用:
- ieee80211_i.h(主要数据结构)
- main.c(主函数入口)
- iface.c(虚拟接口处理)
- key.c,key.h(密钥管理)
- sta_info.c,sta_info.h(用户管理)
- pm.c(功率管理)
- rate.c,rate.h(速率控制函数)
- rc80211*(速率控制算法)
- rx.c(帧接收路径代码)
- tx.c(帧发送路径代码)
- scan.c(软件扫描代码)
- mlme.c(station/managed模式MLME)
- ibss.c(IBSSMLME)
- cfg.c,cfg.h,wext.c(配置入口代码)
- aes*,tkip*,wep*,michael*,wpa*(WPA/RSN/WEP代码)
- wme.c,wme.h(QoS代码)
- util.c(公共函数)
结构体
记住重要的结构体以及结构体的作用:
- ieee80211_local/ieee80211_hw
每个数据结构代表一个无线设备(ieee80211_hw嵌入到ieee80211_local)
ieee80211_hw是ieee80211_local在驱动中的可见部分
包含无线设备的所有操作信息
struct ieee80211_hw {
struct ieee80211_conf conf;
struct wiphy *wiphy;
const char *rate_control_algorithm;
void *priv;
u32 flags;
unsigned int extra_tx_headroom;
unsigned int extra_beacon_tailroom;
int vif_data_size;
int sta_data_size;
int chanctx_data_size;
u16 queues;
u16 max_listen_interval;
s8 max_signal;
u8 max_rates;
u8 max_report_rates;
u8 max_rate_tries;
u8 max_rx_aggregation_subframes;
u8 max_tx_aggregation_subframes;
u8 offchannel_tx_hw_queue;
u8 radiotap_mcs_details;
u16 radiotap_vht_details;
netdev_features_t netdev_features;
u8 uapsd_queues;
u8 uapsd_max_sp_len;
u8 n_cipher_schemes;
const struct ieee80211_cipher_scheme *cipher_schemes;
};
- sta_info/ieee80211_sta
代表每一个station
可能是mesh,IBSS,AP,WDS
ieee80211_sta是驱动可见部分
struct ieee80211_sta {
u32 supp_rates[IEEE80211_NUM_BANDS];
u8 addr[ETH_ALEN];
u16 aid;
struct ieee80211_sta_ht_cap ht_cap;
struct ieee80211_sta_vht_cap vht_cap;
bool wme;
u8 uapsd_queues;
u8 max_sp;
u8 rx_nss;
enum ieee80211_sta_rx_bandwidth bandwidth;
enum ieee80211_smps_mode smps_mode;
struct ieee80211_sta_rates __rcu *rates;
bool tdls;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
- ieee80211_conf
硬件配置
当前信道是最重要的字段
硬件特殊参数
struct ieee80211_conf {
u32 flags;
int power_level, dynamic_ps_timeout;
int max_sleep_period;
u16 listen_interval;
u8 ps_dtim_period;
u8 long_frame_max_tx_count, short_frame_max_tx_count;
struct cfg80211_chan_def chandef;
bool radar_enabled;
enum ieee80211_smps_mode smps_mode;
};
- ieee80211_bss_conf
BSS配置
多BSSes类型(IBSS/AP/managed)
包含比如基础速率位图
perBSS parameters in case hardware supports creating/associating withmultiple BSSes
struct ieee80211_bss_conf {
const u8 *bssid;
/* association related data */
bool assoc, ibss_joined;
bool ibss_creator;
u16 aid;
/* erp related data */
bool use_cts_prot;
bool use_short_preamble;
bool use_short_slot;
bool enable_beacon;
u8 dtim_period;
u16 beacon_int;
u16 assoc_capability;
u64 sync_tsf;
u32 sync_device_ts;
u8 sync_dtim_count;
u32 basic_rates;
struct ieee80211_rate *beacon_rate;
int mcast_rate[IEEE80211_NUM_BANDS];
u16 ht_operation_mode;
s32 cqm_rssi_thold;
u32 cqm_rssi_hyst;
struct cfg80211_chan_def chandef;
__be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
int arp_addr_cnt;
bool qos;
bool idle;
bool ps;
u8 ssid[IEEE80211_MAX_SSID_LEN];
size_t ssid_len;
bool hidden_ssid;
int txpower;
struct ieee80211_p2p_noa_attr p2p_noa_attr;
};
- ieee80211_key/ieee80211_key_conf
代表加密/解密密钥
ieee80211_key_conf提供给驱动用于硬件加速
ieee80211_key包含book-keeping和软件解密状态
struct ieee80211_key_conf {
u32 cipher;
u8 icv_len;
u8 iv_len;
u8 hw_key_idx;
u8 flags;
s8 keyidx;
u8 keylen;
u8 key[0];
};
- ieee80211_tx_info
大部分复杂数据结构
skb内部控制缓冲区(cb)
经历三个阶段:1、由mac80211初始化;2、由驱动使用;3、由发送状态通告使用
struct ieee80211_tx_info {
/* common information */
u32 flags;
u8 band;
u8 hw_queue;
u16 ack_frame_id;
union {
struct {
union {
/* rate control */
struct {
struct ieee80211_tx_rate rates[
IEEE80211_TX_MAX_RATES];
s8 rts_cts_rate_idx;
u8 use_rts:1;
u8 use_cts_prot:1;
u8 short_preamble:1;
u8 skip_table:1;
/* 2 bytes free */
};
/* only needed before rate control */
unsigned long jiffies;
};
/* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;
struct ieee80211_key_conf *hw_key;
u32 flags;
/* 4 bytes free */
} control;
struct {
struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
s32 ack_signal;
u8 ampdu_ack_len;
u8 ampdu_len;
u8 antenna;
void *status_driver_data[21 / sizeof(void *)];
} status;
struct {
struct ieee80211_tx_rate driver_rates[
IEEE80211_TX_MAX_RATES];
u8 pad[4];
void *rate_driver_data[
IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)];
};
void *driver_data[
IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];
};
};
- ieee80211_rx_status
包含接收帧状态
驱动通过接收帧传给mac80211
struct ieee80211_rx_status {
u64 mactime;
u32 device_timestamp;
u32 ampdu_reference;
u32 flag;
u16 freq;
u8 vht_flag;
u8 rate_idx;
u8 vht_nss;
u8 rx_flags;
u8 band;
u8 antenna;
s8 signal;
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];
u8 ampdu_delimiter_crc;
};
- ieee80211_sub_if_data/ieee80211_vif
包含每个虚拟接口信息
ieee80211_vifis passed to driver for those virtual interfaces the driver knowsabout (no monitor,VLAN)
包含的sub-structures取决于模式
struct ieee80211_vif {
enum nl80211_iftype type;
struct ieee80211_bss_conf bss_conf;
u8 addr[ETH_ALEN];
bool p2p;
bool csa_active;
u8 cab_queue;
u8 hw_queue[IEEE80211_NUM_ACS];
struct ieee80211_chanctx_conf __rcu *chanctx_conf;
u32 driver_flags;
#ifdef CPTCFG_MAC80211_DEBUGFS
struct dentry *debugfs_dir;
#endif
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
main.c
mac80211的main.c,module入口文件
#include <net/mac80211.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/bitmap.h>
#include <linux/pm_qos.h>
#include <linux/inetdevice.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include <net/addrconf.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
#include "rate.h"
#include "mesh.h"
#include "wep.h"
#include "led.h"
#include "cfg.h"
#include "debugfs.h"
void ieee80211_configure_filter(struct ieee80211_local *local)
{
u64 mc;
unsign