linux无线网络系统
Cfg80211
下面是网络的对cfg80211的描述: cfg80211 is the Linux 802.11 configuration API. cfg80211 replaces Wireless-Extensions. nl80211 is used to configure a cfg80211 device and is used for kernel <–> userspace communication. Wireless extensions is now in maintenance mode, no new features will be added to it, we'll only fix bugs for it. cfg80211 is now feature-par complete with wireless-extensions, it actually has a lot more features that are simply not available and will never be available through wireless extensions. When implementing a cfg80211 driver wireless extensions support is still provided automatically for you through cfg80211 through CONFIG_CFG80211_WEXT. Distributions no longer needing wireless extensions can remove this and are encouraged to do so. cfg80211 also provides full regulatory support, this is done through wireless-regdb and the usage of CRDA. All new Linux wireless drivers should be written targeting either cfg80211 for fullmac devices or mac80211 for softmac devices. 参考:http://wireless.kernel.org/en/developers/Documentation/cfg80211
关键数据结构: 头文件:
Cfg80211.h (include\\net):cfg80211 is the configuration API for 802.11 devices in Linux. It bridges userspace and drivers, and offers some utility functionality associated with 802.11 Core.h (net\\wireless):Wireless configuration interface internals.
Nl80211.h (include\\linux):定义的netlink接口函数(接收netlink命令,发送netlink事件) Regulatory.h (include\\net):regulatory support structures。
数据结构:
struct cfg80211_registered_device :设备注册的时用,包含注册的struct cfg80211_ops,供上层应用通过nl80211_ops供上层应用调用.包含了struct wiphy结构实体。
struct net_device :The DEVICE structure,网络设备结构,网卡名,包含了共享内核资源,中断号,网卡操作函数接口:(struct net_device_ops *netdev_ops,struct ethtool_ops *ethtool_ops,),设备地址,广播地址,net__namespace, sys文件结构,协议相关设备(struct wireless_dev,struct in_device,struct inet6_dev)。等等
struct wireless_dev :wireless device state:包含struct wiphy,接口类型(AP.STA,AD-HOC,P2P-GO, P2P-GC,),网络设备指针(struct net_device*),SME状态,ssid,
支持的信道类型(enum nl80211_channel_type), cfg80211连接状态(struct cfg80211_conn),
struct wiphy:wireless hardware description。定义在Cfg80211.h (include\\net),
struct cfg80211_ops mac80211_config_ops:无线设备驱动需要实现的函数功能,在cfg80211驱动层通过struct genl_ops nl80211_ops[]供调用。 struct genl_ops nl80211_ops[]:通过genl_register_family_with_ops函数注册的netlink接口操作数组。接收wpa_supplicant下发的命令。
struct ieee80211_ops:具体芯片驱动实现的功能,如TI驱动为:struct ieee80211_ops wl1271_ops。
Cfg80211注册的class
参考代码:
static struct device_attribute ieee80211_dev_attrs[] = { __ATTR_RO(index), __ATTR_RO(macaddress), __ATTR_RO(address_mask), __ATTR_RO(addresses), __ATTR_RO(name), {} };
struct class ieee80211_class = { .name = \ .owner = THIS_MODULE, .dev_release = wiphy_dev_release, .dev_attrs = ieee80211_dev_attrs, #ifdef CONFIG_HOTPLUG .dev_uevent = wiphy_uevent, #endif .suspend = wiphy_suspend, .resume = wiphy_resume, .ns_type = &net_ns_type_operations, .namespace = wiphy_namespace, };
int wiphy_sysfs_init(void) { return class_register(&ieee80211_class); }
注册class:是为了绑定无线网络设备与cfg80211关系。参考sysfs中class的作用:根据device类型来区分。
struct class ieee80211_class的属性在具体的设备中生效
这里生效的是底层调用了struct wiphy *wiphy_new()函数来实现的。 #define PHY_NAME \
struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) { static int wiphy_counter;
}
rdev = kzalloc(alloc_size, GFP_KERNEL);
dev_set_name(&rdev->wiphy.dev, PHY_NAME \device_initialize(&rdev->wiphy.dev);
rdev->wiphy.dev.class = &ieee80211_class; rdev->wiphy.dev.platform_data = rdev; return &rdev->wiphy;
而wiphy_new可以在mac80211模块(soft MAC)或者无线网卡驱动(full MAC)调用。 下面分别以博通芯片为例说明:soft MAC和full MAC的调用过程。
Cfg80211通信接口
1. struct cfg80211_ops :backend description for wireless configuration。
通过struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)来注册。一般是通过mac80211(soft MAC)或者是设备驱动直接调用来注册的函数接口。 2. struct class ieee80211_class = { .name = \ … .dev_attrs = ieee80211_dev_attrs, .ns_type = &net_ns_type_operations, .namespace = wiphy_namespace, };
Sysfs文件系统,组织设备类的通用接口函数。为用户空间提供接口。
3. static struct genl_ops nl80211_ops[] :用与接收用户层的netlink command,对应
wpa_supplicant drivers_nl80211.c中的函数接口。
4. static int cfg80211_netdev_notifier_call(struct notifier_block *nb, unsigned long state, void
*ndev):用于监听底层上报的event
5. struct notifier_block nl80211_netlink_notifier:接收底层
6. int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 pid):发送nlmsg给上层应用 int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb, u32 pid, unsigned int group, gfp_t flags) 7.
数据帧的传输(这里包括控制帧,管理帧,数据帧)
发送:probe request, probe response;authentication request, authentication response; association request, association response;
实际发送的帧:deauthenticate;disassociate;authenticate;associate;数据帧 接收的帧:
Regulatory domain:
参考:http://wireless.kernel.org/en/developers/Regulatory Regulatory.txt (documentation\\networking)
目前支持两种方式:
1. Keeping regulatory domains in userspace using the CRDA package provided with their distribution,Essentially the kernel will send a udev event when it knows it needs a new regulatory domain. A udev rule can be put in place to trigger crda to send the respective regulatory domain for a specific ISO/IEC 3166 alpha2。Userspace gets a regulatory domain in the kernel by having a userspace agent build it and send it via nl80211.
2. Statically compiled regulatory database To account for this situation, a configuration option has been provided (i.e. CONFIG_CFG80211_INTERNAL_REGDB). With this option enabled, the wireless database information contained in net/wireless/db.txt is used to generate a data structure encoded in net/wireless/regdb.c.
Essentially the kernel will send a udev event when it knows it needs a new regulatory domain.
CRDA
CRDA是一个daemon程序(后台守护进程):根据平台的COUNTRY环境变量,解析regulatory.bin,获取regulatory domain信息,从而发送给驱动。 参考文档:http://wireless.kernel.org/en/developers/Regulatory/CRDA CRDA源代码下载路径:http://github.com/mcgrof/crda 或者http://wireless.kernel.org/download/crda/
由下图可知:CRDA是一个daemon程序(后台守护进程)。会解析regulatory.bin文件。 流程如下:
1. 当内核需要用新的regulatory domain时,会发送一个udev event
2. 上层接收到udev event后,就会触发crda发送相应的regulatory domain 3. CRDA daemon通过getenv函数获取“COUNTRY”环境变量的具体值
4. 解析regulatory.bin文件,搜索与从“COUNTRY”环境变量中的国家信息匹配的值,从而
获取regulatory domain结构的信息。
5. 通过netlink机制发送给nl80211(即cfg80211模块) 注:步骤3至步骤5是CRDA daemon执行的过程 关键技术点:
1. python脚本生成regulatory.bin 2. 解析regulatory.bin
3. netlink发送封装好的信息给cfg80211 4. 数字签名:
struct ieee80211_reg_rule { struct ieee80211_freq_range freq_range; struct ieee80211_power_rule power_rule; uint32_t flags; };
struct ieee80211_regdomain { uint32_t n_reg_rules; char alpha2[2]; uint8_t dfs_region; struct ieee80211_reg_rule reg_rules[]; };
下面是一个例子:
struct ieee80211_regdomain mydriver_jp_regdom = { .n_reg_rules = 3, .alpha2 = \ //.alpha2 = \ .reg_rules = { /* IEEE 802.11b/g, channels 1..14 */ REG_RULE(2412-20, 2484+20, 40, 6, 20, 0), /* IEEE 802.11a, channels 34..48 */ REG_RULE(5170-20, 5240+20, 40, 6, 20, NL80211_RRF_PASSIVE_SCAN), /* IEEE 802.11a, channels 52..64 */ REG_RULE(5260-20, 5320+20, 40, 6, 20, NL80211_RRF_NO_IBSS | NL80211_RRF_DFS),
} };
03_wireless网络系统



