目录

Linux-无线网络驱动开发-之-子系统源码框架nl80211cfg80211mac80211

Linux 无线网络驱动开发 之 子系统源码框架(nl80211、cfg80211、mac80211)

基础框架

https://i-blog.csdnimg.cn/direct/2b1b1ff95cc9491e877fbe90c10f6757.png

基础概念

  • nl80211
    作用:用户空间与内核空间无线配置的接口(Netlink API)
    功能:提供基于 netlink 的通信机制,允许用户空间工具配置和管理无线设备
    代码位置:net/wireless/nl80211.c
  • cfg80211
    作用:无线配置框架,管理所有无线设备和驱动
    功能
    1)提供统一的无线配置接口(如设置频段、信道、功率等)
    2)管理 mac80211 和直接支持 FullMAC 的硬件
    3)处理 MLME(MAC Layer Management Entity)逻辑(如认证、关联)
    代码位置:net/wireless/
  • mac80211
    作用:driver开发者可用于为SoftMAC无线设备写驱动的框架,处理大部分 802.11 MAC 层功能
    功能
    1)实现 Beacon 处理、ACK 管理、速率控制、加密(WPA/WPA2) 等
    2)依赖硬件驱动实现 PHY 层操作(如发送/接收数据包)
    3)支持 AP、STA、Monitor、Mesh 等多种模式
    代码位置:net/mac80211/

理解

  • nl80211是介于用户空间与内核空间之间的 API ,可以算是 cfg80211 的前端
  • cfg80211 是设备和用户空间之间的桥梁,工作则是跟踪 WLAN 设备所处的实际状态
  • mac80211 的工作是给出硬件的所有功能和与硬件进行交互
  • 如果某些功能无法由设备硬件实现,那么就可以以纯软的方式实现,其也被称为 “Soft MAC” 模块,与 “Hard MAC” (由设备固件完成所有工作)相对。实际项目中通常是这两种方案混合使用的
那我们怎么去代码理解这几个组件呢,下面我将用一个管理路径的方式,去分析理解

iw dev wlan1 scan命令是如何调用到wifi驱动的

基本调用框架图
https://i-blog.csdnimg.cn/direct/4a6c92cfc57b4c26a4b528d8062bc250.png

  1. 首先是iw工具
    iw 源码获取:git clone
    编译完成后进行源码跟踪,将iw工具编译后命名为iw-debug.
  2. 添加打印
    https://i-blog.csdnimg.cn/direct/ea7b0055ea8b426c8a8c2c8ef6ab002f.png
  3. 使用strace命令跟踪iw调用
    sudo strace -e socket,sendmsg,recvmsg iw dev wlan1 scan
    https://i-blog.csdnimg.cn/direct/8fbb5e495f324646893278582aef9f59.png
    消息的构造发生在iw工具,从下面的棘突也能看出,并且对应的是scan指令
    https://i-blog.csdnimg.cn/direct/647f01ffe5f34641b93630aecf9c7dc6.png
    libnl我们就不跟踪了,我们知道是一个非常好用的库就行了
  4. nl80211接收来自应用层的netlink消息
    内核源码中,genl_init 是 Linux 内核中 Generic Netlink(通用 Netlink)框架的初始化函数,负责在系统启动时注册 Generic Netlink 的核心组件
    https://i-blog.csdnimg.cn/direct/392d3ae21011469795206a894da84db4.png
    nl80211通过genl_family_rcv_msg接收netlink信息,通过回调函数nl80211_pre_doit, 查找cfg80211注册时的设备信息dev
    https://i-blog.csdnimg.cn/direct/e5cf7ffe6d884c9fbdc0574a07274918.png
  5. nl80211初始化
    https://i-blog.csdnimg.cn/direct/86c7bea580ed4d59a9afe5e120779348.png
    https://i-blog.csdnimg.cn/direct/97621ac902654a1d97e514bfcdabc754.png
    https://i-blog.csdnimg.cn/direct/15f0f817258d4567bf1fd3ad07703644.png
    https://i-blog.csdnimg.cn/direct/d2c10233bae44cdcb16230a2419d1b4a.png
  6. nl80211消息传递给cfg80211
    https://i-blog.csdnimg.cn/direct/ee92a0a9baf14b8f82a07f123737f7b7.png
    rdev_scan 函数已经属于 cfg80211 组件的范畴
    https://i-blog.csdnimg.cn/direct/c08c56ba1d9f4bbd9221d6f91db487f8.png
  7. ops直接调用到mac80211
    https://i-blog.csdnimg.cn/direct/fcddaf3786094363bc003aeaf11545bf.png
    https://i-blog.csdnimg.cn/direct/eae83b6f2fe741c7a58b779057e734e8.png
    https://i-blog.csdnimg.cn/direct/da79fc1047934938804517cd153cd313.png
  8. 调用到驱动函数
    https://i-blog.csdnimg.cn/direct/c147d1041e4844d5b19bd8a20f063877.png
    驱动扫描函数实现
    https://i-blog.csdnimg.cn/direct/3d58c543c8934991a4cad51bbc7c8fcd.png
    有管理路径针对管理帧,数据路径针对数据帧,所以还有数据路径,数据和管理路径在 mac80211 里面是分开实现的。

数据路径发送

  1. 内核协议栈 → mac80211
    调用逻辑
 neigh_resolve_output()
     dev_queue_xmit()          
       __dev_xmit_skb()
         sch_direct_xmit()
           dev_hard_start_xmit()
             netdev_start_xmit() 

https://i-blog.csdnimg.cn/direct/d8a808b9608c47b3931b484a27c7509d.png
https://i-blog.csdnimg.cn/direct/971e0502a6fd4a0badd27fafe0b4bfc3.png
https://i-blog.csdnimg.cn/direct/8c623558e36f4a2f98c9ea7b83587780.png
https://i-blog.csdnimg.cn/direct/25449010e2934c66a76fe8e3b9d8b846.png
https://i-blog.csdnimg.cn/direct/fee3a202c1a840c3961c59f77d0887ca.png
https://i-blog.csdnimg.cn/direct/21f71822c98f43b9860bedbb5326304c.png
https://i-blog.csdnimg.cn/direct/7ae560f7f7494feb8e0bb65a9f792876.png
2. mac80211 → 驱动(ath9k/ath9k_htc)
调用路径:

ieee80211_subif_start_xmit()//mac802111入口函数
 -->__ieee80211_subif_start_xmit()
 		-->ieee80211_xmit()
 			-->ieee80211_tx()
 				-->__ieee80211_tx()
					 -->ieee80211_tx_frags()
						 -->drv_tx()
 							-->[local->ops->tx()]

https://i-blog.csdnimg.cn/direct/3c2cb1ada18642e6a8bd5d242c378f25.png
https://i-blog.csdnimg.cn/direct/126bee6340264572be27aa291e5d406f.png
https://i-blog.csdnimg.cn/direct/e72096be65224dd39008de091d85aaa8.png
https://i-blog.csdnimg.cn/direct/958d2febe62047419ecf63d5120f6afd.png
https://i-blog.csdnimg.cn/direct/515b66593c414ef5b534408499000205.png
https://i-blog.csdnimg.cn/direct/16e1c16908904a2d926966b738803378.png
调用drv_tx(),把帧传递给驱动
https://i-blog.csdnimg.cn/direct/94fd6d27cdf4426d8a211daeaa7c370c.png
https://i-blog.csdnimg.cn/direct/21f1b665784a4570999b0a89a6ebad17.png

  1. 驱动(ath9k/ath9k_htc)
    https://i-blog.csdnimg.cn/direct/84bf5210b04340349893bdf249d461a9.pnghttps://i-blog.csdnimg.cn/direct/e558f17c6ad3417bbe7a0cbda96b0eb0.png
  2. 驱动 → 硬件
    USB 设备(ath9k_htc):
    通过 USB Bulk 传输发送 HTC 协议封装的数据包。

数据路径接收

  1. 硬件中断 → 驱动
    中断处理:网卡收到数据后触发中断。
    USB 设备:USB 回调函数
  2. 驱动 → mac80211
    https://i-blog.csdnimg.cn/direct/97c812d105b343a89c29c30d2d9b5903.png
    https://i-blog.csdnimg.cn/direct/b8ee5feec67247a88b2688de6d1ce984.png
    如下是ieee80211_rx的源码解释:
    https://i-blog.csdnimg.cn/direct/3413f0c4805d405d969ca6fe41f1d326.png
  3. mac80211 → 内核协议栈
    解密和校验:处理 WPA/WPA2 解密、校验帧完整性。
    协议栈上传:通过 netif_receive_skb() 将数据包传递给 TCP/IP 协议栈
    https://i-blog.csdnimg.cn/direct/6b550960bb6543029bfe894241b3e0a2.png
    https://i-blog.csdnimg.cn/direct/df625d3a331748879044f71005524195.png
    https://i-blog.csdnimg.cn/direct/5d08edf1e6ae4d86968c80706cd3cd95.png
    https://i-blog.csdnimg.cn/direct/27d6d7527fe64733ab9342d43ab2ed05.png
    https://i-blog.csdnimg.cn/direct/92a62a0c83bf4f748581867a4b0c012e.png
    https://i-blog.csdnimg.cn/direct/3f0dbd4f0e6c4203a418c114dbb495eb.png
    https://i-blog.csdnimg.cn/direct/74ca356bb28e4d7bb64f0d5e8fbe3562.png
    https://i-blog.csdnimg.cn/direct/cca852eedb7e4c87bdaf13c422384ac7.png
    如果收到的帧是数据,它将被转换成 802.3 数据帧(通过 __ieee80211_data_to_8023 实现),然后该数据帧将通过 netif_receive_skb 交付到网络协议栈。在协议栈中,各层网络协议将会对数据进行解析,识别协议首部。
    https://i-blog.csdnimg.cn/direct/bba16ff8712a48bebed4627cc26c6d64.png
    https://i-blog.csdnimg.cn/direct/8fed681d1284463fa3082f01e1f08f76.png
    https://i-blog.csdnimg.cn/direct/15008573302145ecabc9e4b8f545ccee.png
    https://i-blog.csdnimg.cn/direct/eb181051552f45a485fdc696480e5e76.png
  4. 协议栈 → 用户空间
    Socket 接收:用户程序通过 recv() 或 read() 读取数据。

什么是MLME

即MAC(Media Access Control ) Layer Management Entity,它管理物理层MAC状态机,负责 认证、关联、扫描、省电模式 等

如何理解MLME

  • MLME 功能(扫描、认证、关联、省电模式等)由 mac80211 在软件中实现
  • mac80211 不参与管理,仅通过 cfg80211 去操作MLME功能
  • 简单点理解可以为 cfg80211负责管理,mac80211负责实现MLME功能

疑问?

  1. 既然iw工具可以创建socket并连接netlink,为什么要需要调用libnl去发送消息给nl80211?
    若直接使用原生 Socket,代码量可能增加 3-5 倍,且难以维护,安全性、稳定性也难以保证
  2. MLME跟wifi状态机有什么关系?
    mlme是管理wifi 状态机的,wifi状态机是 MLME 的具体实现方式

这里是简单的框架梳理,希望能够抛砖引玉,谢谢
https://i-blog.csdnimg.cn/direct/46f67ef26cb24eccb3cd273af87e12de.jpeg