当前位置: 首页 > news >正文

Linux网络设备驱动—netlink

1.netlink的内核套接字建立

在用户层, socket ()函数用于建立 netlink 套接字,其中的协议类型应该也为 NETLINK_TEST 。内核空间建立此套接字的函数为:Netlink

netlink_kernel_create 是 Linux 内核中的一个函数,主要用于创建 Netlink 套接字,以便于内核与用户空间的通信。

 /* net: net指向所在的网络命名空间, 一般默认传入&init_net;  定义在  net_namespace.c(extern struct net init_net);unit:netlink协议类型cfg: cfg存放的是netlink内核配置参数*/
static inline struct sock *netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg);
​参数 unit ,是 netlink 协议类型,例如为 NETLINK_TEST
参数 cfg,存放的是netlink内核配置参数,包括主要的回调处理函数指针等

netlink_kernel_cfg这个结构的定义:

 /* optional Netlink kernel configurationparameters */struct netlink_kernel_cfg {unsigned int    groups; unsigned int    flags; /* input 回调函数,收到的消息在此函数中处理 */void       (*input)(struct sk_buff *skb);struct mutex    *cb_mutex;void       (*bind)(int group);bool       (*compare)(struct net *net, struct sock *sk);};

建立 netlink 套接字函数在成功的时候,返回一个 structure sock 指针类型的值,之后可以用这个值对 netlink 套接字进行处理;当返回值为 NULL 的时候,套接字建立失败了,需要进行资源的释放。

单播netlink_unicast()
int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock);ssk: netlink socket skb: skb buff 指针portid: 通信的端口号,对应用态的端口号nonblock:表示该函数是否为非阻塞,如果为1(MSG_DONTWAIT),
该函数将在没有接收缓存可利用时立即返回,而如果为0(MSG_WAITALL),
该函数在没有接收缓存可利用 定时睡眠
 多播netlink_broadcast()
int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid,__u32 group, gfp_t allocation);ssk: 同上(对应netlink_kernel_create 返回值)、skb: 内核skb buffportid: 通信的端口号,对应用态的端口号group: 是所有目标多播组对应掩码的"OR"操作的合值。allocation: 指定内核内存分配方式,通常GFP_ATOMIC用于中断上下文,
而GFP_KERNEL用于其他场合。这个参数的存在是因为该API可能需要分配一个
或多个缓冲区来对多播消息进行clone
 nlmsg_hdr()获取netlink消息的头部指针nlmsg_new()分配一个新的netlink消息
struct sk_buff *nlmsg_new(size_t payload, gfp_t flags)payload : 分配的大小flags:进程上下文,可以睡眠:GFP_KERNEL进程上下文,不可以睡眠:GFP_ATOMIC中断处理程序:GFP_ATOMIC软中断:GFP_ATOMICTasklet:GFP_ATOMIC用于DMA的内存,可以睡眠:GFP_DMA | GFP_KERNEL用于DMA的内存,不可以睡眠:GFP_DMA |GFP_ATOMIC
向skb缓冲区中获取消息头空间并且初始化netlink消息头,入参中的第5个参数为netlink消息头的总空间。

-----------------------------------------------------------

 struct sk_buf 结构体

用作套接字缓存,作为网络数据包的存放地点,使得协议栈中每个层都可以对数据进行操作,从而实现了数据包自底向上的传递。

struct  sk_buff
{struct  sk_buff *next;struct  sk_buff *prev;struct  sock *sock ; //struct sock是socket在网络层的表示,其中存放了网络层的信息unsigned  int  len; //表示当前协议数据包的长度。它包括主缓冲区中的数据长度(data指针指向它)和分片中的数据长度。unsigned  int  data_len;  //和len不同,data_len只计算分片中数据的长度__u16   mac_len ;  //数路链路层的头长度__u16   hdr_len ;  //writable header length of cloned skbunsigned  int  truesize ;  //socket buffer(套接字缓存区的大小)atomic_t users ;  //对当前的struct sk_buff结构体的引用次数;__u32   priority ;  //这个struct sk_buff结构体的优先级sk_buff_data_t transport_header ;  //传输层头部的偏移量sk_buff_data_t network_header ;    //网络层头部的偏移量sk_buff_data_t mac_header ;        //数据链路层头部的偏移量char  *data ;  //socket buffer中数据的起始位置;sk_buff_data_t tail ;  //socket buffer中数据的结束位置;char  *head ;  //socket buffer缓存区的起始位置;sk_buffer_data_t end ;  //socket buffer缓存区的终止位置;struct  net_device *dev;  //将要发送struct sk_buff结构体的网络设备或struct sk_buff的接收网络设备int  iif;   //网络设备的接口索引号;   struct  timeval tstamp ;  //用于存放接受的数据包的到达时间;__u8  local_df : 1 ,   //allow local fragmentaion;cloned   : 1 ,  // head may be cloned;__u8  pkt_type : 3 ,  //数据包的类型;fclone   : 2,   // struct sk_buff clone status   
}

====================================

2. netlink 的应用层数据接收


当内核使用 netlink kernel_create (函数建立一个 NETLINK_TEST 类型的协议之后,当用户空间向内核空间通过之前的 netlink 套接字发送消息的时候, cfg 中函数注册的回调函数 input 会被调用,下面是一个 netlink_recv_msg 函数的实现代码:

static void netlink_recv_msg(struct sk_buff *__skb)
{struct nlmsghdr *nlhdr = NULL;struct sk_buff *skb = NULL;u8 *payload = NULL;u32 user_pid = 0;if (NULL == __skb){return;}skb = skb_get(__skb);if (NULL == skb){return;}//数据长度大于头长度if (skb->len >= NLMSG_SPACE(0)){//这个 user_pid 可以用来在内核回复消息时使用user_pid = nlhdr->nlmsg_pid;nlhdr = nlmsg_hdr(skb);switch (nlhdr->nlmsg_type){case 1:{//取出负载数据payload = (u8 *)NLMSG_DATA(nlhdr);//处理 type 为 1的数据break;}defaule:break;}kfree_skb(skb);
}
  nlmsg_put()

向skb缓冲区中获取消息头空间并且初始化netlink消息头,入参中的第5个参数为netlink消息头的总空间。

struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,int type, int payload, int flags)
portid:与 netlink消息头 中的 nlmsg_pid 对应
seq:与 netlink消息头 中的 nlmsg_seq 对应
type:与 netlink消息头 中的 nlmsg_type 对应
payload:与 netlink消息头 中的 nlmsg_len 对应
flags:与 netlink消息头 中的 nlmsg_flags 对应

3.netlink 的套接字关闭


关闭 netlink 套接字,使用 sock_release()函数来进行。主要进行内存等资源的释放,将一些指针进行重置的操作。函数的原型如下

void sock_release ( struct socket * sock );

netlink_kernel_create ()函数建立成功套接字的返回值为 struct *sock , sock_release()函数释放套接字时传入的参数是 struct *socket 类型,类型 struct *socket 是 struct *sock 的一个成员,所以可以使用如下方式来释放套接字:

 sock_release(nl_sk->socket);

文章转载自:

http://Q7lv36T8.rgkcf.cn
http://CvPcCmz1.rgkcf.cn
http://MpGrxuXB.rgkcf.cn
http://21kwCAZo.rgkcf.cn
http://t0FgROSR.rgkcf.cn
http://kcLfqceL.rgkcf.cn
http://OMhzoekn.rgkcf.cn
http://iWrJDF3Q.rgkcf.cn
http://y79nBVLG.rgkcf.cn
http://nAeLWQEI.rgkcf.cn
http://kEA7LKhM.rgkcf.cn
http://mLLouh7i.rgkcf.cn
http://imw9oT3d.rgkcf.cn
http://DvHDkUiD.rgkcf.cn
http://tK6guNDT.rgkcf.cn
http://1iqGSygN.rgkcf.cn
http://8PAyndC0.rgkcf.cn
http://3ucRGMb5.rgkcf.cn
http://EgeSLuqY.rgkcf.cn
http://N6RfHWjv.rgkcf.cn
http://vDymlNtI.rgkcf.cn
http://ndwYkikr.rgkcf.cn
http://Uhs90bXA.rgkcf.cn
http://NKQiOHQN.rgkcf.cn
http://rQ6QP2JM.rgkcf.cn
http://wq2ZfyQM.rgkcf.cn
http://kIWVXqkU.rgkcf.cn
http://BCGBwIw2.rgkcf.cn
http://dm08KtQF.rgkcf.cn
http://ZjstZRwc.rgkcf.cn
http://www.dtcms.com/a/386180.html

相关文章:

  • C# 导出 Excel 时并行处理数据:10 万条数据分批次并行转换,导出时间缩短 60%
  • 设计模式(java实现)----原型模式
  • VBA 将多个相同格式EXCEL中内容汇总到一个EXCEL文件中去
  • Android系统基础:底层状态监听UEvent之UEventObserver源码分析
  • windows 平台下 ffmpeg 硬件编解码环境查看
  • 构建基石:Transformer架构
  • Chapter7—建造者模式
  • 到底什么是智能网联汽车??第二期——决策与控制
  • 将普通Wpf项目改成Prism项目
  • 微硕WINSOK高性能N沟道场效应管WSD3040DN56,助力汽车中控散热风扇静音长寿命
  • nextjs+shadcn+tailwindcss实现博客中的overview
  • cursor-关于自定义指令的问题处理
  • Vision Transformer (ViT) :Transformer在computer vision领域的应用(四)
  • 【开题答辩全过程】以 “今天吃什么”微信小程序为例,包含答辩的问题和答案
  • iOS App 内存泄漏与性能调优实战 如何排查内存问题、优化CPU与GPU性能、降低耗电并提升流畅度(uni-app iOS开发优化指南)
  • 从 Token 拦截器到 Web 配置
  • Next.js 的原理和它的使用场景
  • SPAR模型优化思路
  • pycharm+miniconda cursor+miniconda配置
  • windows在pycharm中为项目添加已有的conda环境
  • 微信小程序实现-单选-以及全选功能。
  • 知识点19:生产环境的安全与治理
  • 软件开源协议(Open Source License)介绍
  • SAP HANA Scale-out 04:缓存
  • ios制作storyboard全屏启动图
  • 2025高教杯数学建模大赛全流程,从数据处理、建模到模型评价
  • 点拨任务应用于哪些业务场景
  • 墨色规则与血色节点:C++红黑树设计与实现探秘
  • C#语言入门详解(19)委托详解
  • 【数字展厅】企业展厅设计怎样平衡科技与人文呈现?