netlink分析介绍

article/2025/9/11 12:11:54

netlink socket是一种用于用户态进程和内核态进程之间的通信机制。它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket接口的方式,实现了全双工的通讯连接。

特点:

  • 双向传输,异步通信
  • 用户空间中使用标准socket API
  • 内核空间中使用专门的API
  • 支持多播
  • 可由内核端发起通信
  • 支持32种协议类型

netlink仅支持32种协议类型,这在实际应用中可能并不足够,因此产生了generic netlink(以下简称为genl), 
generic netlink支持1023个子协议号,弥补了netlink协议类型较少的缺陷。

netlink通信架构

Netlink子系统:所有genl通信的基础,Netlink子系统中收到的所有Generic类型的netlink数据都被送到genl总线上;从内核发出的数据也经由genl总线送至netlink子系统,再打包送至用户空间

Generic Netlink控制器:作为内核的一部分,负责动态地分配genl通道(即genl family id),并管理genl任务,genl控制器是一个特殊的genl内核用户,它负责监听genl bus上的通信通道

genl通信建立在一系列的通信通道的基础上,每个genl family对应多个通道,这些通道由genl控制器动态分配

相关结构体

genl family
Generic Netlink是基于客户端-服务端模型的通信机制,服务端注册family(family是对genl服务的各项定义的集合),控制器和客户端都通过已注册的信息与服务端通信。

//genl_family主要字段
struct genl_family
{unsigned int        id;    //family idunsigned int      hdrsize;  //用户自定议头部长度char              name[GENL_NAMSIZ]; //family名,要求不同的family使用不同的名字unsigned int      version;    //版本unsigned int      maxattr;    //最大attr类型数,使用netlink标准的attr来传输数据genl_ops             *ops;        // 操作集合
};

genl_ops
定义了netlink family相关的操作

// genl_ops主要字段
struct genl_ops
{u8                 cmd;    //命令名,用于识别genl_opsunsigned int       flags;    //设置属性struct nla_policy  *policy; //定义了attr规则,genl在触发事件处理程序之前,会用其进行attr校验int                (*doit)(struct sk_buff *skb, struct genl_info *info);int                (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
};
  • doit:回调函数,在generic netlink收到数据时触发,运行在进程上下文
  • dumpit:回调函数,当genl_ops的flag标志被添加了NLM_F_DUMP以后,每次收到genl消息即会回触发这个函数

dumpit与doit的区别是:dumpit的第一个参数skb不会携带从客户端发来的数据。相反地,开发者应该在skb中填入需要传给客户端的数据,skb中携带的数据会被自动送到客户端。只要dumpit的返回值大于0,dumpit函数就会再次被调用,并被要求在skb中填入数据。当服务端没有数据要传给客户端时,dumpit要返回0。如果函数中出错,要求返回一个负值。

nal_policy
定义了attr规则

struct nla_policy
{u16     type;    //attr中的数据类型u16     len;    //如果在type字段配置的是字符串有关的值,要把len设置为字符串的最大长度
};

genl_info
内核在接收到用户的genetlink消息后,会对消息解析并封装成genl_info结构

struct genl_info
{u32                     snd_seq;  //发送序号  u32                     snd_pid;  //发送客户端的PIDstruct nlmsghdr *       nlhdr;      //netlink header的指针struct genlmsghdr *     genlhdr;  //genl头部的指针(即family头部)void *                  userhdr;  //用户自定义头部指针  struct nlattr **        attrs;    //如果定义了genl_ops->policy,保存被policy过滤以后的结果
};

Generic Netlink服务端(内核)初始化

这里以OVS中packet的处理为例:

1. 定义family

//定义packet family
static struct genl_family dp_packet_genl_family __ro_after_init = {.hdrsize = sizeof(struct ovs_header), .name = OVS_PACKET_FAMILY,  .version = OVS_PACKET_VERSION, .maxattr = OVS_PACKET_ATTR_MAX, .netnsok = true,.parallel_ops = true,.ops = dp_packet_genl_ops,      //操作集合.n_ops = ARRAY_SIZE(dp_packet_genl_ops),.module = THIS_MODULE,
};

2. 定义operation

// 定义packet family 的操作 --- packet类型的操作只支持OVS_PACKET_CMD_EXECUTE
static struct genl_ops dp_packet_genl_ops[] = {{ .cmd = OVS_PACKET_CMD_EXECUTE, .flags = GENL_UNS_ADMIN_PERM, .policy = packet_policy,  .doit = ovs_packet_cmd_execute    //接受数据包时,调用ovs_packet_cmd_execute进行处理}
};// 定义packet family 的过滤规则
static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {[OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN },[OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED },[OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },[OVS_PACKET_ATTR_PROBE] = { .type = NLA_FLAG },[OVS_PACKET_ATTR_MRU] = { .type = NLA_U16 },
};

3. 注册family

genl_register_family(&dp_packet_genl_family); 

Generic Netlink客户端(用户空间)初始化

struct sockaddr_nl saddr;    
int                sock;
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); //创建一个netlink类型的socketif (sock < 0) {return -1;
}memset(&saddr, 0, sizeof(saddr));
saddr.nl_family = AF_NETLINK;
saddr.nl_pid = getpid();    //获取family id
if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) {    //绑定printf("bind fail!\n");close(*p_sock);return -1;
}

内核空间接受发送数据

接受数据:内核端一旦收到generic netlink数据,会触发doit函数运行,通过回调函数进行处理
发送数据:将数据打包好之后,可通过单播(genlmsg_unicast)或多播()的形式进行发送

用户空间接受发送数据

接受数据:调用recv函数即可完成从内核来的数据的接收
发送数据:调用sendto来发送数据


http://chatgpt.dhexx.cn/article/231gND77.shtml

相关文章

netlink实现与使用方法详解(用户态/内核态)

一、什么是netlink Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。 在Linux 内核中&#xff0c;使用netlink 进行应用与内核通信的应用有很多&#xff0c;如 路由 daemon&#xff08;NETLINK_ROUTE…

火狐插件RESTClient测试接口

正文 {"username":"chen","password":"123"}后端 PostMapping("/login")ResponseBodypublic ReturnObj login(RequestBody JSONObject params) {String username params.getString("username");String passwor…

火狐插件

chrome插件要过墙啊好烦&#xff0c;老老实实用火狐吧&#xff0c;而且json样式也好看。 一.效果图 &#xff08;首页&#xff09; &#xff08;标签页&#xff09; &#xff08;搜索&#xff09; &#xff08;翻译&#xff09; 除此外还有一些乱七八糟的样式就不一一做展…

FireFox插件RESTClient

火狐FireFox插件RESTClient 一、功能二、安装三、使用说明 一、功能 使用FireFox插件RESTClient、HttpRequester模拟http(get post)请求 二、安装 1.点击火狐浏览器右侧按钮 2.进入获取附加组件页面 3.点击查看更多附加组件 4.右侧查找附件组件输入框&#xff0c;输入RES…

YApi 使用Firefox插件cross-request关于cookie的问题

环境信息 我用的Firefox目前是最新版本的&#xff0c;109.0.1 (64 位)版本。 cross-request插件就是打包的Firefox插件。 cookie的值是浏览器根据host的信息自己匹配上去的&#xff0c;属于浏览器的行为 cookie功能验证 我测试了一下&#xff0c;接口服务代码就是读取和写入coo…

介绍 GTK#

介绍 GTK# [ 纯Windows 用户就可以跳过。 也未测试。 ] GTK# 是对流行的跨平台图形用户界面库&#xff08;GUI&#xff09;GTK 的包装。如果打算构建一个本地应用程序&#xff0c;并想让它运行在非 Windows 平台上&#xff0c;GTK 可能是一个合理的选择。GTK# 的运行类似于…

gtk/gtk.h: no such file or directory

linux上运行创建界面的例程报错&#xff1a; 是因为没有安装 GTK。GTK 是 基于界面底层库 x11 的一个界面库&#xff0c;用于在 linux 系统中绘制窗口界面。 $ sudo apt-get install libgtk2.0-dev #安装gtk运行环境 $ sudo apt-get install gnome-devel #安装gtk开发环境…

GTK编程基础---入门篇(helloworld)

相关代码可以在github上下载&#xff1a;https://github.com/jin13417/GTK 下面来介绍GTK编程入门&#xff0c;你的第一个程序hellowoeld。直接通过程序来讲解吧。 /*File:helloworld.c*Date:2013-11-23*Author:sjin*Mail:413977243qq.com*//*my first test program*/ #includ…

GTK+ 3 基础知识学习

1.启动程序 以前的版本要写一个GTK程序都是按照以下流程 int main(int argc, char *argv[]) {GtkWidget *window;gtk_init(&argc,&argv);... ...gtk_main();return 0; } 现在最新的GTK 3.20的版本一般是按照以下格式初始&#xff0c;main函数里新建一个GtkApplicati…

GTK+系列---Windows下的GTK+开发平台搭建(Win7 64位)

注意&#xff1a;这些说明适用于希望基于GTK开发应用程序的开发人员&#xff0c;而不适用于终端用户。 必要条件 Windows版本&#xff1a;GTK需要Windows 7或更高版本。对于旧版本的Windows&#xff0c;您应该自定义构建旧版本的glib和gtk。 我的安装平台为win7_64位&#x…

GTK+开发环境搭建

一般讲到GUI程序开发&#xff0c;大家都会想到C等面向对象的高级语言&#xff0c;而认为C语言不能做界面。C语言也可以用来写界面&#xff0c;GTK就是一个用来写界面的库&#xff0c;它本身就是用C语言写的&#xff0c;而且实现了面向对象的设计。对于一个C语言程序员来说&…

GTK官方教程

前言&#xff1a; 让你在开发中爱不释手的 GT 包。关注GSLS官网&#xff0c;查看更多源码 ヾ(✿&#xff9f;▽&#xff9f;)ノ工具包。 所有文章 小编尽量让读者可以 直接 读懂 与 完全 复制粘贴&#xff0c;其中复杂或较多 的源码 会有 源码 并 贴上 github 网址。 GT 类 里面…

GTK+入门教程

GTK入门教程&#xff08;一&#xff09; 1. 显示一个窗口 #include <gtk/gtk.h>int main(int argc, char *argv[]) {GtkWidget *window;gtk_init(&argc, &argv);window gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_widget_show(window);g_signal_connect(window,…

学习使用GTK+

学习使用GTK 0.概述 原文地址&#xff1a;http://blog.programet.org/2010/08/gtk-0.html GTK是当下流行的图形界面库之一&#xff0c;使用GTK可以方便地构造出应用程序界面。叶子觉得GTK很好用&#xff0c;在这里推荐给大家&#xff0c;并留下自己的一些使用心得。希望你也喜欢…

GTK+:GTK+的简介、安装、使用方法之详细攻略

GTK&#xff1a;GTK的简介、安装、使用方法之详细攻略 目录 GTK的简介 1、GTK特点 GTK的安装 1、基于Windows平台安装 第一步、下载GTK 第二步、安装GTK 第三步、加载系统环境变量 第四步、运行命令测试 第五步、利用python预测测试 GTK的使用方法 1、C语言实现 2、…

【Linux】特别篇--GTK界面设计

【Linux】特别篇--GTK界面设计 一、GTK界面常用函数1、控件大小设置2、创建窗口3、创建控件&#xff08;1&#xff09;标签label&#xff08;2&#xff09;按键button&#xff08;3&#xff09;行辑器 二、GTK常用布局方法1、布局的使用方法&#xff08;以水平布局为例&#xf…

GTK入门教程

GTK入门教程 1.GTK简介 GTK&#xff08;GIMP Toolkit)是一套源码以LGPL许可协议分发、跨平台的图形工具包。最初是为GIMP写的&#xff0c;已成为一个功能强大、设计灵活的一个通用图形库&#xff0c;是GNU/Linux下开发图形界面的应用程序的主流开发工具之一。当然&#xff0c;…

gtk学习总结:GTK从入门到放弃,三天包教包会

今天花了一些时间复习之前学习过的gtk&#xff0c;感觉东西光学不用忘得好快啊&#xff0c;在这做个之前学过的内容的备份&#xff0c;希望对大家有用&#xff0c;也希望大家不要从入门到放弃。文中有些代码例子可能来自《GTK从入门到精通》吧&#xff0c;我不记得了&#xff0…

gcc下载地址

网上看到有提供的http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/&#xff0c;可以打开&#xff0c;但是下载太慢了 这里记录一个下载很快的地址https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/&#xff0c;为清华大学的开源镜像网站 想要找其他的开源软件&#xff0c;…

如何安装GCC

现在的CentOs8上没有自带的gcc编译器因此需要下载&#xff08;注意&#xff1a;这里的下载是指在虚拟机中下载&#xff0c;不是指在电脑上下载&#xff09; 若运行gcc时出现appstream 下载元数据失败则表明没有安装gcc。 1 首先需要获得root权限**** 在终端模式下输入su&…