linux网络协议栈(二)用户配置方式(netlink套接字)

2024-05-09 22:32

本文主要是介绍linux网络协议栈(二)用户配置方式(netlink套接字),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

二、2.10代码用户进程配置方式:

2.1、查改内核方式的比较:

查改内核有如下几种方式:

1、  直接通过文件系统(procfs/sysfs);

2、  增加自己的系统调用;

3、  使用统一系统调用(ioctl);

4、  netlink;

第一种方式的好处是无需增加用户态代码,直接通过cat或echo可配置,但缺点是在内核里要是加太多比较乱,另外,总在linux shell下操作在某些场景不适合;

第二种的问题是加系统调用本身就比较麻烦,导致管理起来复杂;

第三种有效解决了第二种的问题,可以集中系统调用,但还是系统调用,这种用户态主动发起系统调用(类似查询的方式),效率比较低;

第四种方式实现了类似中断的方式,相对第二、三种形成了同步和异步的差异(注意netlink方式的收发是用户进程和内核,而第二、三种不存在收发双方,只是用户进程自己),明显提高效率,另外ioctl系统调用仅linux特有这将不利于程序移植,不过netlink使用起来更复杂;

综上所述,对于配置条目较少的情况下用第一、三种比较合适,对于配置条目较多的情况下netlink方式比较合适,至于第二种在某些特殊的情况会比较方便(OPL)。

2.2、netlink原理和使用:

2.2.1、netlink详述:

2.2.1.1、netlink简介:

与ioctl不同,netlink是基于socket,并且是内核和用户进程都创建各自的socket,这样双方都使用基于socket的收发缓冲队列,这一点最大的好处是内核和用户进程都可以发起向对方发送消息,准确的说用户进程和内核进程(内核在系统中事实上也可以看做一个进程,其进程tgid为0)都可以是消息的发送者,而ioctl只能是用户进程主动对内核,从始至终都只是用户进程在运行。这避免了进程(包括内核)的盲目轮询,真正实现了双向异步访问,是访问效率的的本质性提高。

此外netlink还可以进行“组播”,即可以给多个其他进程(包括内核)发送消息。另外通过某些方式还可以实现netlink套接字的CPU间传输,不过应该没有这样的使用。

了解一种类型套接字的根本在于了解它的“N元组”(如IPV4套接字的五元组源目的地址和端口+传输层协议类型、原始套接字的二元组以太网类型和收发接口),这样就能确定访问对象;netlink套接字的“N元组”是进程id和协议类型,进程id是该netlink套接字创建进程的tgid(在同协议情况下会有所调整),协议类型包括系统默认创建的类型,也可自定义,使用netlink的二元组即可唯一的确定一个netlink对象。2.10代码的netlink协议类型如下:


Netlink协议类型最多可定义到32种,上图中的NETLINK_CTRL(17)、NETLINK_KDNS(20)、NETLINK_KCAP(21)为自定义的类型,其中最重要的是NETLINK_CTRL,这是2.10代码中配置管理内核的ctrl_rtnetlink模块定义的netlink协议类型。

在系统中netlink的实际使用情况如下图所示:


第二列的“Eth”标识协议类型,第三列的“Pid”标识进程tgid,注意同一进程下创建不止一个的相同类型的netlink套接字时,“Pid”会在bind时修改为由-4097依次减小的值,至于为什么上图出现的负值不按顺序是因为某些进程在创建完netlink并使用后又把netlink释放了所致。注意“Pid”为924的是pon进程创建的netlink套接字。

2.2.1.2、netlink使用详解:
netlink作为套接字的一种,必须也遵循socket标准接口,其sockaddr的结构体实现包括:协议族(AF_NETLINK)、进程tgid、组播组,如下图:


2.2.1.2.1、套接字创建与bind:

netlink套接字的创建和其他类型套接字道理一样,需要注意的是用户进程和内核创建netlink的区别,区别并不大,内核netlink的创建会在sock层描述符(netlink_sock)中加入标志位(NETLINK_KERNEL_SOCKET)来标识该netlink套接字是内核创建的,此外内核创建的netlink会挂接其报文处理函数(netlink_rcv)来处理。

对于netlink套接字必须bind,描述bind之前首先描述netlink套接字的管理方式,在系统中根据不同的协议类型创建32个hash表(nl_table),hash表以其pid为基值计算hash键值,每个hash条目包括netlink套接字的创建进程pid(tgid)和其sock层描述符,如下图:


netlink套接字的bind过程就是把创建netlink的进程(包括内核)的tgid及其sock层描述符注册进系统(这和IPV4和原始套接字的道理是一样的),具体就是即注册进系统netlink管理链表nl_table,这样,当发送报文时,系统可以根据接收方的tgid得知接收方的sock层描述符,进而知道将报文发往哪个socket接收缓冲队列,否则接收方无法收到报文。

2.2.1.2.2、报文收发处理:
作为套接字的一种,netlink的收发同样使用标准socket接口的send/recv函数族,注意除非是给内核发送报文,发送者必须使用sendto即手动指定目的套接字的进程tgid(或者在发送之前对目的套接字进程tgid使用connect),否则系统只会把报文发给相应类型的内核netlink套接字,分别以用户进程发起和内核发起为例,如下图:


内核向用户进程发送


用户进程发送

2.2.1.2.3、netlink报文格式:

事实上netlink报文没有固定规定的格式,但是内核默认创建的netlink(如路由使用的rtnetlink,netfilter使用的nfnetlink)都遵循一个固定的报文格式,所以自定义的netlink协议类型也应该遵循该格式,如下:

struct req

{

struct nlmsghdr nlh;

char buf[XXXXX];

};

struct nlmsghdr

{

         __u32                nlmsg_len;       /* Length of message including header */

         __u16                nlmsg_type;     /* Message content */

         __u16                nlmsg_flags;    /* Additional flags */

         __u32                nlmsg_seq;      /* Sequence number */

         __u32                nlmsg_pid;       /* Sending process port ID */

};

netlink报文首先应该是一个nlmsghdr结构的报文头,指定报文长度、消息类型(API ID)、报文标志(指示报文的需求,如是否需要回复、是否是请求、设置型还是打印型等)、报文序号(用于检验再收到的报文是否是本次请求的回应)、发送者pid(无意义未被应用);重点需注意的是报文标志,内核规定了如下几种报文标志:


不同的报文标志的处理都可以在实际代码中再理解其用途和含义,这里只介绍下最基本的如NLM_F_REQUEST标识这是一个请求报文、NLM_F_ACK标识这是一个需要回复的报文、NLM_F_DUMP标识这个报文应该首先调用显示hook,注意每个netlink的hook遵循如下数据结构,它应是“设置型”或“显示型”的hook:


不一定肯定都要实现两种类型的hook,这完全根据具体实现。

2.2.2、2.10代码的使用实例:

2.10代码中所有业务均通过netlink配置管理,在内核空间自定义了私有的netlink协议类型NETLINK_CTRL(见2.2.1.1),见rcios/include/ctrlnetlink.h文件中定义的枚举类型,涵盖路由、安全、语音、pon、设备管理等多种业务类型,挂接各类业务的hook处理函数;在用户空间,以库函数方式封装了netlink访问内核的函数方法,由各个业务进程统一使用。

此外用户还以其他netlink协议类型与内核一些模块进行交互,如ipsec部分使用了协议类型NETLINK_XFRM,路由和dhcp部分使用了协议类型NETLINK_ROUTE等。

下面依次举两个例子分别说明用户进程配置内核资源和内核异步通知用户进程:

2.2.2.1、在转发过程中按源mac地址过滤:
在转发过程中(ip_forward)可配置丢弃特定源MAC的报文,通过在转发过程中的netfilter hook点中加入相关的过滤代码即可,其逻辑如下图:


具体过滤逻辑并不复杂,在一个hash表中可配置是否过滤、mac过滤表,当执行过滤netfilter时,若使能过滤则检查mac过滤表即可,具体实现不详细描述。这里的重点是配置mac filter模块的过程,2.10设备通过命令行和web为用户配置接口,分别如下图:



如上图,命令行发送netlink报文的消息类型是CTRL_MACADDR_FILTER_ADDR,并要求接收者回复该报文(含义报文标志NLM_F_ACK);它在内核模块中对应的条目的“设置型”hook函数是ctrlnetlink_macaddr_handle,它将实现把命令行中MAC地址加入MAC过滤表。


上图是命令行下的配置过程,web配置在xml_XXXXX.c文件中,道理相同过程略。

2.2.2.2、GPON PLOAM报文接收:

GPON的PLOAM报文实际在内核驱动中接收处理,SDK并未提供用户空间接收PLOAM报文,为实现故障定位接收PLOAM报文,可以使用ioctl方式获取不仅比较麻烦,还易出问题,因为PLOAM互通很快,用iotcl的方式还必须暂存收到的所有PLOAM报文等待用户主动获取,而使用netlink方式主动发给用户空间则是最优选择,方式如下:

1、  pon进程启动后创建NETLINK_CTRL类型netlink套接字并bind;

2、  把pon进程tgid作为内容发送给内核netlink套接字;



3、  pon进程创建线程监听第一步创建的netlink套接字;


4、 每当内核gpon驱动收到PLOAM报文则发送给pon进程tgid对应的sock接收缓冲队列并唤醒pon进程去接收;


这篇关于linux网络协议栈(二)用户配置方式(netlink套接字)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974679

相关文章

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

Mybatis官方生成器的使用方式

《Mybatis官方生成器的使用方式》本文详细介绍了MyBatisGenerator(MBG)的使用方法,通过实际代码示例展示了如何配置Maven插件来自动化生成MyBatis项目所需的实体类、Map... 目录1. MyBATis Generator 简介2. MyBatis Generator 的功能3

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

Python数据处理之导入导出Excel数据方式

《Python数据处理之导入导出Excel数据方式》Python是Excel数据处理的绝佳工具,通过Pandas和Openpyxl等库可以实现数据的导入、导出和自动化处理,从基础的数据读取和清洗到复杂... 目录python导入导出Excel数据开启数据之旅:为什么Python是Excel数据处理的最佳拍档