ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【WiFi软件开发】Linux 802.11 栈(nl80211, cfg80211, mac80211) [打印本页]

作者: 南飓风    时间: 2024-7-22 11:45
标题: 【WiFi软件开发】Linux 802.11 栈(nl80211, cfg80211, mac80211)

媒介

本文告急先容linux内核中和WiFi密切干系的80211栈。80211栈包含nl80211,cfg80211和mac80211,告急用于WiFi配置和管理,本文将从功能和代码实现角度对各个模块进行解读。

一、linux WiFi架构和80211栈

首先给出Linux无线装备的软件架构图:

可以看出80211栈告急位于内核中的最上层,同时和用户空间中的应用、底层驱动、linux内核协议栈干系联,扮演了告急的承接脚色。作为这样一个脚色,80211栈需要办理一系列问题以实现WiFi管理和通讯:

下文将分别先容80211栈中的nl80211,cfg80211和mac80211模块,并基于上述问题对各个模块的功能和代码实现进行解读。
二、nl80211

1.先容

nl80211是介于用户空间与内核空间之间的 API ,可以算是 cfg80211 的前端,也会生成 “事件” (events) 信息。该模块依靠 netlink 协议来在两个空间进行信息交互,通过socket吸收上层下令,执行对应函数进行配置管理网络接口。Netlink 是一个 Linux 中的 socket 类型,用于在内核与用户空间之间通报事件。
代码参见linux-5.4.196/net/wireless/nl80211.c。nl80211的main函数告急做了以下几件事:

2.消息吸收

linux-5.4.196/net/netlink/genetlink.c中的函数genl_family_rcv_msg会吸收上层消息,进行pre_doit,doit,post_doit等处理。
代码如下:
  1. static int genl_family_rcv_msg(const struct genl_family *family,
  2.                                struct sk_buff *skb,
  3.                                struct nlmsghdr *nlh,
  4.                                struct netlink_ext_ack *extack)
  5. {
  6.     ...
  7.         if (family->pre_doit) {
  8.                 err = family->pre_doit(ops, skb, &info);
  9.                 if (err)
  10.                         goto out;
  11.         }
  12.         err = ops->doit(skb, &info);
  13.         if (family->post_doit)
  14.                 family->post_doit(ops, skb, &info);
  15.     ...
  16. }
复制代码
3.支持的消息和函数集nl80211_ops[]

nl80211通过genl_family_rcv_msg吸收来自用户态的netlink信息,通过回调函数nl80211_pre_doit, 查找cfg80211注册时的装备信息dev。 通过调用函数cfg80211函数接口大概dev钩子函数实现信息的获取或参数的设置。
此中支持的消息在nl80211_commands中给出:
  1. enum nl80211_commands {
  2. /* don't change the order or add anything between, this is ABI! */
  3.         NL80211_CMD_UNSPEC,
  4.         NL80211_CMD_GET_WIPHY,                /* can dump */
  5.         NL80211_CMD_SET_WIPHY,
  6.         NL80211_CMD_NEW_WIPHY,
  7.         NL80211_CMD_DEL_WIPHY,
  8.         ...
  9. }
复制代码
消息和对应的处理函数在nl80211_ops[]中注册:
  1. static const struct genl_ops nl80211_ops[] = {
  2.         {
  3.                 .cmd = NL80211_CMD_GET_WIPHY,
  4.                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  5.                 .doit = nl80211_get_wiphy,
  6.                 .dumpit = nl80211_dump_wiphy,
  7.                 .done = nl80211_dump_wiphy_done,
  8.                 /* can be retrieved by unprivileged users */
  9.                 .internal_flags = NL80211_FLAG_NEED_WIPHY,
  10.         },
  11. #if LINUX_VERSION_IS_GEQ(5,10,0)
  12. };
  13. static const struct genl_small_ops nl80211_small_ops[] = {
  14. #endif
  15.         {
  16.                 .cmd = NL80211_CMD_SET_WIPHY,
  17.                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  18.                 .doit = nl80211_set_wiphy,
  19.                 .flags = GENL_UNS_ADMIN_PERM,
  20.         },
  21.         {
  22.                 .cmd = NL80211_CMD_GET_INTERFACE,
  23.                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  24.                 .doit = nl80211_get_interface,
  25.                 .dumpit = nl80211_dump_interface,
  26.                 /* can be retrieved by unprivileged users */
  27.                 .internal_flags = NL80211_FLAG_NEED_WDEV,
  28.         },
  29.         ...
  30. }
复制代码
需要注意的是doit和dumpit的区别:
doit:标准下令回调函数,在当前族中收到数据时触发调用,函数的第一个入参skb中生存了用户下发的消息内容;
dumpit:转储回调函数,当genl_ops的flag标记被添加了NLM_F_DUMP以后,每次收到genl消息即会回触发这个函数。
dumpit与doit的区别是:dumpit的第一个参数skb不会携带从客户端发来的数据。相反地,开发者应该在skb中填入需要传给客户端的数据, 然后,将skb的数据长度(可以用skb->len)return。skb中携带的数据会被主动送到客户端。只要dumpit的返回值大于 0,dumpit函数就会再次被调用,并被要求在skb中填入数据。当服务端没有数据要传给客户端时,dumpit要返回0。如果函数中出错,要求返回一 个负值。
三、cfg80211

1.先容

cfg80211实现了wlan装备的注册,上可吸收用户态配置管理下令,下可通过mac80211进行和硬件交互。因为实现了装备注册,虚拟接口的区分也是在此界说实现的(struct wiphy,一个 wiphy 装备可以有一个对应 MAC)。
代码位置在linux-5.4.196/net/wireless/core.c, 文件告急提供一些干系接口函数,实现装备在cfg80211中装备的注册,并在链表cfg80211_rdev_list 中添加装备信息。
2.代码分析

cfg80211在函数cfg80211_init(void)中初始化,告急做了一下几件事:
四、mac80211

1.先容

这是最底层的模块,与 hardware offloading 关联最多。如果某些功能无法由装备硬件实现,那么就可以以纯软的方式实如今这里。别的,以软件情势实现也可以赋予开发者对逻辑有更大的控制权。其也被称为 “Soft MAC” 模块,与 “Hard MAC” (由装备固件完成全部工作)相对。现实场景中,通常是这两种方案混淆使用。802.11 协议状态机就在这里,需要处理全部类型的帧。
2.代码结构


3.数据结构


4.告急流程

1.配置


2.吸收路径


3.吸收处理钩子(invoke_rx_handlers)


4.发送路径


5.发送处理钩子(invoke_tx_handlers)


6.mangement/MLME


7.IBSS


8.创建接口路径


9.删除接口路径


10.创建station路径


11.删除station路径


12.扫描请求路径


13.扫描状态机路径



参考阅读

http://blog.chinaunix.net/uid-22510743-id-5780801.html
https://www.cnblogs.com/ink-white/p/16822559.html
https://zhuanlan.zhihu.com/p/650693108
https://blog.csdn.net/zwl1584671413/article/details/114902310
https://blog.csdn.net/zxygww/article/details/24874155

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4