netlink

合集下载

linux内核通信-netlink使用例子

linux内核通信-netlink使用例子

Netlink 是一种特殊的socket,它是Linux 所特有的,类似于BSD 中的AF_ROUTE 但又远比它的功能强大,目前在最新的Linux 内核(2.6.14)中使用netlink 进行应用与内核通信的应用很多,包括:路由daemon (NETLINK_ROUTE),1-wire 子系统(NETLINK_W1),用户态socket 协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),socket 监视(NETLINK_INET_DIAG),netfilter 日志(NETLINK_NFLOG),ipsec 安全策略(NETLINK_XFRM),SELinux 事件通知(NETLINK_SELINUX),iSCSI 子系统(NETLINK_ISCSI),进程审计(NETLINK_AUDIT),转发信息表查询(NETLINK_FIB_LOOKUP),netlinkconnector(NETLINK_CONNECTOR),netfilter 子系统(NETLINK_NETFILTER),IPv6 防火墙(NETLINK_IP6_FW),DECnet 路由信息(NETLINK_DNRTMSG),内核事件向用户态通知(NETLINK_KOBJECT_UEVENT),通用netlink (NETLINK_GENERIC)。

Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的socket API 就可以使用netlink 提供的强大功能,内核态需要使用专门的内核API 来使用netlink。

Netlink 相对于系统调用,ioctl 以及/proc 文件系统而言具有以下优点:1,为了使用netlink,用户仅需要在include/linux/netlink.h 中增加一个新类型的netlink 协议定义即可,如#define NETLINK_MYTEST 17 然后,内核和用户态应用就可以立即通过socket API 使用该netlink 协议类型进行数据交换。

netlink实现分析

netlink实现分析

本文档的Copyleft归wwwlkk所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。

E-mail: wwwlkk@来源: /?business&aid=6&un=wwwlkk#7netlink实现分析(1)网络file对象。

1(2)netlink网络file对象。

3(3)netlink消息接收端。

5(3.1)内核路径注册netlink接收端。

6(3.2)用户进程注册netlink接收端。

6(3.3)内核netlink接收端接收消息。

6(3.4)用户进程netlink接收端接收消息。

6(4)通信效率分析。

7(5)实现零拷贝的两个理论方案。

7(1)网络file对象当网络双方的通信线路建立好之后,双发就可以开始互相传递数据,可以使用write()和read()传递数据。

可见网络通信也同样使用了文件系统的架构,这里的file对象是比较特殊的,结构如图1所示:图1 网络file对象结构其中static const struct file_operations socket_file_ops = {.owner = THIS_MODULE,.llseek = no_llseek,.aio_read = sock_aio_read,对应read().aio_write = sock_aio_write,对应write().poll = sock_poll,.unlocked_ioctl = sock_ioctl,.mmap = sock_mmap,.open = sock_no_open, /* special open code to disallow open via /proc */.release = sock_close,.fasync = sock_fasync,.sendpage = sock_sendpage,.splice_write = generic_splice_sendpage,.splice_read = sock_splice_read,};说明:如果file->f_op->write为空,则会调用file->f_op-> aio_write;file->f_op->read为空,则会调用file->f_op-> aio_read从sock_aio_write()开始的函数调用流程如下:sock_aio_write()→do_sock_write()→__sock_sendmsg()→sock->ops->sendmsg(iocb, sock, msg, size);从sock_aio_read()开始的函数调用流程如下:sock_aio_read()→do_sock_read()→__sock_recvmsg()→__sock_recvmsg_nosec()→sock->ops->recvmsg(iocb, sock, msg, size, flags);可见发送和接受过程最终都是调用操作函数集sock->ops,其结构如下:struct proto_ops {int family;struct module *owner;int (*release) (struct socket *sock);int (*bind) (struct socket *sock, struct sockaddr *myaddr, int sockaddr_len);int (*connect)(struct socket *sock, struct sockaddr *vaddr,int sockaddr_len, int flags);int (*socketpair)(struct socket *sock1,struct socket *sock2);int (*accept) (struct socket *sock,struct socket *newsock, int flags);int (*getname) (struct socket *sock, struct sockaddr *addr, int *sockaddr_len, int peer);unsigned int (*poll) (struct file *file, struct socket *sock, struct poll_table_struct *wait);int (*ioctl) (struct socket *sock, unsigned int cmd, unsigned long arg);int (*compat_ioctl) (struct socket *sock, unsigned int cmd, unsigned long arg);int (*listen) (struct socket *sock, int len);int (*shutdown) (struct socket *sock, int flags);int(*setsockopt)(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen);int(*getsockopt)(struct socket *sock, int level,int optname, char __user *optval, int __user *optlen); int(*compat_setsockopt)(struct socket *sock, int level,int optname, char *optval, unsigned int optlen);int(*compat_getsockopt)(struct socket *sock, int level,int optname, char *optval, int *optlen);int (*sendmsg)(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len);int(*recvmsg)(struct kiocb *iocb, struct socket *sock,struct msghdr *m, size_t total_len, int flags);int (*mmap)(struct file *file, struct socket *sock, struct vm_area_struct * vma);ssize_t (*sendpage) (struct socket *sock, struct page *page, int offset, size_t size, int flags);ssize_t(*splice_read)(struct socket *sock,loff_t *ppos,struct pipe_inode_info*pipe,size_t len, unsigned int flags);};应用程序的bind(),listen(),accept(),connect(),read(),write(),close()都最终调用struct proto_ops 内的函数。

netlink介绍

netlink介绍

netlink定义用于在内核模块与在用户地址空间中的进程之间传递消息的。

它包含了用于用户进程的基于标准套接字的接口和用于内核模块的一个内部核心API。

[--manual]Netlink是套接字家族中的一员,主要用内核与用户空间的进程间、用户进程间的通讯。

然而它并不像网络套接字可以用于主机间通讯,Netlink只能用于同一主机上进程通讯,并通过PID来标识它们。

[--wiki][see more:RFC 3549]netlink出现之前,linux是用ioctl接口控制设备参数。

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。

所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。

(相对于系统调用,ioctl 以及/proc 文件系统):1,为了使用netlink,用户仅需要在include/linux/netlink.h 中增加一个新类型的netlink 协议定义即可,如#define NETLINK_MYTEST 17 然后,内核和用户态应用就可以立即通过socket API 使用该netlink 协议类型进行数据交换。

但系统调用需要增加新的系统调用,ioctl 则需要增加设备或文件,那需要不少代码,proc 文件系统则需要在/proc 下添加新的文件或目录,那将使本来就混乱的/proc 更加混乱。

2. netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息,但系统调用与ioctl 则是同步通信机制,如果传递的数据太长,将影响调度粒度。

3.使用netlink 的内核部分可以采用模块的方式实现,使用netlink 的应用部分和内核部分没有编译时依赖,但系统调用就有依赖,而且新的系统调用的实现必须静态地连接到内核中,它无法在模块中实现,使用新系统调用的应用在编译时需要依赖内核。

NetLink使用实例(YGM)

NetLink使用实例(YGM)

如何使用Netlink Connector Author: Yang gongming简介:本文详细介绍了 Linux 2.6.34.14 内核引入的内核空间与用户空间通信的新机制连接器,并通过典型示例讲解了它的使用。

一、概述连接器是一种新的用户态与内核态的通信方式,它使用起来非常方便。

本质上,连接器是一种netlink,它的 netlink 协议号为 NETLINK_CONNECTOR,与一般的 netlink 相比,它提供了更容易的使用接口,使用起来更方便。

netlink本质上是socket,不过它可用于用户程序和内核程序的通信。

1.内核模块使用方法注册一个标识 ID 和回调函数,即可使用连接器。

cn_msg结构://标识netlink的IDstruct cb_id{__u32 idx;__u32 val;};//netlink控制信息头struct cn_msg{struct cb_id id;__u32 seq;__u32 ack;__u32 len;/* Length of the following data */__u8 data[0];};三个内核模块常用的API。

int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));void cn_del_callback(struct cb_id *id);void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);结构 cb_id 是连接器实例的标识 ID,它用于确定 netlink 消息与回调函数的对应关系。

当连接器接收到标识 ID 为 {idx,val} 的 netlink 消息时,注册的回调函数 void (*callback) (void *) 将被调用。

该回调函数的参数为结构struct cn_msg 的指针。

用户空间和内核空间通讯之【Netlink下】

用户空间和内核空间通讯之【Netlink下】

用户空间和内核空间通讯之【Netlink下】在上一篇博文中我们所遇到的情况都是用户空间作为消息进程的发起者,Netlink还支持内核作为消息的发送方的情况。

这一般用于内核主动向用户空间报告一些内核状态,例如我们在用户空间看到的USB的热插拔事件的通告就是这样的应用。

先说一下我们的目标,内核线程每个一秒钟往一个多播组里发送一条消息,然后用户空间所以加入了该组的进程都会收到这样的消息,并将消息内容打印出来。

Netlink地址结构体中的nl_groups是32位,也就是说每种Netlink协议最多支持32个多播组。

如何理解这里所说的每种Netlink 协议?在</usr/include/linux/netlink.h>里预定义的如下协议都是Netlink协议簇的具体协议,还有我们添加的NETLINK_TEST也是一种Netlink协议。

1.#define NETLINK_ROUTE 0 /*Routing/device hook */2.#define NETLINK_UNUSED 1 /*Unused number */3.#define NETLINK_USERSOCK 2 /*Reserved for user mode socket protocols */4.#define NETLINK_FIREWALL 3 /*Firewalling hook */5.#define NETLINK_INET_DIAG 4 /*INET socket monitoring */6.#define NETLINK_NFLOG 5 /*netfilter/iptables ULOG */7.#define NETLINK_XFRM 6 /* ipsec */8.#define NETLINK_SELINUX 7 /*SELinux event notifications */9.#define NETLINK_ISCSI 8 /* Open-iSCSI */10.#define NETLINK_AUDIT 9 /* auditing */11.#define NETLINK_FIB_LOOKUP 1012.#define NETLINK_CONNECTOR 1113.#define NETLINK_NETFILTER 12 /*netfilter subsystem */14.#define NETLINK_IP6_FW 1315.#define NETLINK_DNRTMSG 14 /*DECnet routing messages */16.#define NETLINK_KOBJECT_UEVENT 15 /*Kernel messages to userspace */17.#define NETLINK_GENERIC 1618./* leave room for NETLINK_DM (DM Events)*/19.#define NETLINK_SCSITRANSPORT 18 /*SCSI Transports */20.#define NETLINK_ECRYPTFS 1921.#define NETLINK_TEST 20 /* 用户添加的自定义协议 */在我们自己添加的NETLINK_TEST协议里,同样地,最多允许我们设置32个多播组,每个多播组用1个比特表示,所以不同的多播组不可能出现重复。

netlink用法

netlink用法

netlink用法1. 什么是netlinknetlink是Linux内核中一个用于内核和用户空间进程通信的机制。

它允许内核向用户空间应用程序发送消息,并提供了一种用于配置,管理和监视内核子系统的接口。

2. netlink的特性netlink的特性使其成为了Linux环境下进行内核和用户空间通信的重要工具,具有以下特点:2.1 强大而灵活netlink提供了一种灵活的通信机制,允许内核和用户空间之间进行双向通信。

应用程序可以通过发送消息给内核来请求信息,而内核也可以通过发送消息给应用程序来通知其发生的事件。

2.2 支持多种消息类型netlink支持多种消息类型,如路由信息、网络配置、接口状态等。

这使得开发者可以利用netlink来实现各种不同的功能。

2.3 可靠和高效netlink使用基于内存的套接字,相比于其他IPC机制(如管道和信号量),netlink是一种更加可靠和高效的通信机制。

它避免了不必要的内核空间与用户空间的拷贝,从而提高了系统的性能。

3. netlink的使用3.1 netlink的工作原理netlink通信的基本单位是消息(message),消息由一个头部(header)和一个有效载荷(payload)组成。

头部包含了消息的类型、源地址、目的地址等信息,有效载荷是实际的数据。

3.2 使用netlink库函数为了方便使用netlink,Linux提供了一组用户空间的库函数。

通过这些库函数,我们可以方便地发送和接收netlink消息。

3.2.1 创建netlink套接字首先,我们需要使用socket系统调用创建一个netlink套接字。

通过指定NETLINK_XXX作为协议参数,可以选择不同的netlink协议。

3.2.2 绑定套接字在创建套接字之后,我们需要使用bind函数将套接字与一个本地地址进行绑定。

这个本地地址可以是任意的netlink协议中定义的地址。

3.2.3 构造消息使用netlink库函数,我们可以方便地构造一个netlink消息。

NetLink 无线电话用户指南说明书

NetLink 无线电话用户指南说明书

NetLinkWireless TelephoneUser Guide72-0064-00-FOn/OffPress and hold PWR . Two chirps on, one chirp off Make a call Press START to get dial tone.Hang up Press END . Be sure to do this at the end of each call.Answer call Press START . Line indicator comes on steady when the call is answered.Answer Press HOLD to put your current call on hold, or second call END to hang up. Press LINE +the digit that is flashing.HoldPress HOLDTake off Hold Press LINE followed by the digit for the line on hold, which will be flashing.Mute On/Off Press FCN and then 1Function Pressing FCN while off hook allows you to scroll through menu screens.User Options Press FCN while on hook to change handset settings.Adjust VolumePress VOL while in a call to toggle between base and louder levelStatus/Tone IndicatorsNO SVC An alarm sounds when the Wireless Telephone Alarm/Restorecannot receive or place calls. You may be out-side of the coverage area. Walk back into the covered area. A restore tone indicates service is re-established.BATT Your Battery Pack charge is low. Your Battery Beep Pack needs to be recharged or replaced.MSGYou have a voice mail message.Tips For Use•Before you use the Wireless Telephone, the Battery Pack must be charged. See Battery Packs.•You can only use the Wireless Telephone with your facility’s tele-phone system. It is not a public cellular phone.•The PWR key turns the Wireless Telephone on and off. The START and END keys begin and end calls. When you finish a call, press the END key, not the PWR key.•Keep the Wireless Telephone away from your ear when it is ringing.•The microphone is in the telephone’s lower right corner. This is a sensitive microphone that works well when the telephone is correctly positioned on your ear. There is no need to speak directly into the microphone, but do not cover it with your hand or cheek when talk-ing on the Wireless Telephone.•The Wireless Telephone’s LCD panel displays information about the status of your Wireless Telephone and prompts you about features.•If the Wireless Telephone’s Battery Pack is low, you will hear a soft beep and see the BATT or Low Battery message in the display.•Improper disposal of Battery Packs can damage the environment.Dispose of batteries properly.•You can control the Wireless Telephone’s volume level and the type of ring. See Setting User Preferences.•To protect the Wireless Telephone, use a carrying case.General Care of the Wireless Telephone and ChargersThe Wireless Telephone and Chargers have been designed to withstand the wear and tear of normal use; however, avoid dropping the Wireless Telephone or knocking it against hard surfaces. Carrying the Wireless Telephone in a holster or carrying case will help to protect it.There are no serviceable parts in the Wireless Telephone or Chargers.You should not open the Wireless Telephone case nor disassemble the Chargers. Doing so will void your warranty.Turn off the Wireless Telephone and unplug the Charger before you clean them. Never immerse either in water. Clean the exterior surfaces,including the charging contacts, with a cloth that has been slightly mois-tened with water. Take care not to exert undue pressure on the Charger electrical contacts while wiping.Wiping the handset surface with a water-dampened cloth or paper towel will remove most films or residues. If the soiling is too stubborn for plain water, a mild detergent solution may be used. Be sure to wipe away any detergent residue with a clean water-dampened cloth.The Wireless Telephone may be cleaned with any general-purpose house-hold glass and surface-type cleaner. DO NOT SPRAY THE HANDSET DIRECTLY! Isopropyl alcohol may be used occasionally applied by a cloth or paper towel. When using alcohol, do not rub the keypad charac-ters vigorously. Doing so will significantly degrade legibility.Do not use any chemical cleaners. They can harm the plastic shell. If necessary, a small amount of mild surface or window cleaner can be applied to the cloth, but do not spray the cleaner onto the Wireless Telephone or Charger.123456789NO SVC BATTMSGExt. 1231MSG Ext. 12321ABC START PWR END#LINEVOL FCN HOLD 3DEF 5JKL 4GHI 6MNO 80TUV 7PRS9WXYLine Indicators Headset JackEarpiecePower Previous MenuHold Function LCD PanelStart End Line Next Menu Volume MicrophoneStatus IndicatorsNOTE:It is recommended that standard acceptance procedures be followed prior to operating this equipment in proximity of life-support systems.To minimize risk of interference, pacemaker users should not carry the Wireless Telephone next to the pacemaker.Earpiece may retain magnetic objects.Operation of the Wireless Telephone may produce an audible noise noticeable to hearing aid users. It is recommended that a SpectraLink headset be used by hearing aid users.This device complies with part 15 of the FCC Rules. Operation is subject to the following two conditions: (1) This device may not cause harmful interference, and (2) this device must accept any interference received, including interference that may cause undesired operation.Note : The functions on your Wireless Telephone may differ from theabove. Contact your system administrator for custom setting information.The Wireless Telephone HeadsetSpectraLink offers optional headsets for use in noisy environments or if you need to have your hands free while talking on the Wireless Telephone.To use the headset, simply plug it into the jack on the side of the Wireless Telephone. The headset is specially designed to work properly with The NetLink Wireless Telephone. We do not recommend using other headsets.The volume level can be adjusted separately for headset use. Plug the headset in and follow the directions on the other side for Adjust V olume. Battery PacksAbout Battery PacksThe Wireless Telephone will need to have its Battery Pack recharged periodically. The Nickel Metal Hydride (NiMH) rechargeable Wireless Telephone Battery Pack gives you two hours of talk time or 80 hours of stand-by time. Stand-by time is when the handset is turned on, but you are not using it.Indications of Low BatteryThe Wireless Telephone will notify you when the charge on the Battery Pack becomes low. If the Wireless Telephone is in use, the BA TT mes-sage will display and you will hear a soft beep through the earpiece every six seconds. You have approximately two minutes to complete the call.If the Wireless Telephone is idle, you will hear a brief modulated ring signal and the Low Battery message will display. Your Wireless Telephone will not operate until you replace the Battery Pack. Depending on the charging equipment you have purchased, you will either place the Wireless Telephone in a Charging Stand to charge the Battery Pack, or you will remove the Pack from the Wireless Telephone and install it in the Charger.Removing and Replacing the Battery Pack on the Wireless TelephoneTo remove the Battery Pack, press down on the oval button above the Battery Pack on the back of the telephone. Slide the Pack toward the bottom of the Wireless Telephone until it stops, then lift up.To replace the Battery Pack, first properly align the top of the Battery Pack with the arrows on the label on the back of the Wireless Telephone. Gently press and slide the Pack toward the top of the Wireless Telephone until it snaps into place. You should not have to force it against the Wireless Telephone.The Battery Pack may be changed while the call is still in progress. If you are using the NetLink Telephony Gateway in your telephone sys-tem, do not press END on the Wireless Telephone. Quickly remove the discharged Battery Pack and replace with a charged Battery Pack, press PWR, and then press START to resume the call in progress. Users of IP telephony interfaces not requiring the NetLink Telephony Gateway should Park a call prior to changing the Battery Pack during an active call. The call should then be retrieved after the Battery Pack is replaced to rejoin the conversation. Check with the switch administrator for instruction on how to perform this or a similar process on your particu-lar telephone system.Take care not to short the Battery contacts on the Pack with metal objects such as coins, keys or paper clips. Shorting the contacts can cause permanent damage.Charging the Wireless TelephoneChargers are shipped with the appropriate power supply for the site’s location. Connect the Stand or Charger to an appropriate wall outlet via its power supply and it’s ready for use. Chargers operate in a 50° to 85°F (10° to 30° C) environment. Do not expose them to freezing tempera-tures or direct sunlight.The Dual Charging StandThe SpectraLink Dual Charging Stand is a two-slot desktop charger designed to charge the Nickel Metal Hydride (NiMH) Battery Packs required to operate Wireless Telephones. Full charging is accomplished in approximately two hours.Only NiMH Battery Packs with a YELLOW label on the handset con-tact side may be charged in the Dual Charging Stand. Older Battery Packs with a GREEN label will not charge. If the indicator light is fast flashing with a Battery Pack or handset in the slot, check to make sure the Battery Pack has a YELLOW label.The Dual Charging Stand should not be used to charge Nickel-Cadmium (NiCd) Battery Packs.When you are not using your Wireless Telephone keep it turned off and in the Stand.Do not place anything in the Dual Charging Stand other than the Wireless Telephone. You might damage the contacts. Bent contacts can keep the Wireless Telephone from charging.Using the Dual Charging StandPlace the Dual Charging Stand on a flat, horizontal surface.The user must end any call in progress by pressing the END key on the Wireless Telephone before placing the handset into the Charger. Place the Wireless Telephone in the front compartment facing forward. It may be on or off during charging. A single spare Battery Pack may be placed in the rear slot. Either slot can be chosen to take priority. The first Battery Pack placed into either slot is charged first.There are two indicator lights, one for each charging slot. A solid light indicates the Battery Pack in the corresponding slot is charging. A solid dim light indicates that the slot is waiting to charge while the Battery Pack in the other slot is charging. The light turns off when the Charger is finished charging the Battery Pack. A fast flash indicates the Battery Pack is not charging and must be replaced. If the light is off, it indicates that the slot is empty, not charging or the unit is powered off. Cleaning the Dual Charging StandClean the Dual Charging Stand by wiping the surface with a clean, water-dampened cloth or paper towel. A mild detergent solution may be used. Be sure to wipe away any detergent residue with a plain water dampened cloth. DO NOT IMMERSE THE DUAL CHARGING STAND IN WATER OR OTHER LIQUID.The Battery Pack contacts may be cleaned with isopropyl (rubbing) alcohol applied with a cotton swab, cloth, or paper towel. Do not push or pull the exposed Battery Pack contacts. DO NOT POUR LIQUIDS INTO THE SLOTS.The Quick ChargerThe Quick Charger holds a single Battery Pack and can charge it in approximately one hour.Using the Quick ChargerPlace the Battery Pack on the Charger by gently sliding the Pack upward into the Charger in a manner similar to installing it on the Wireless Telephone. If placed correctly, the light on the Quick Charger will shine solid green. When the Battery Pack is fully charged, the green light will begin to flash.Every 11th charge the Quick Charger will automatically recondition the Battery Pack, as indicated by the flashing amber light. This may take from three to six hours depending on the state of the Battery Pack. To enter or exit the reconditioning mode, press the Mode button while the Battery Pack is on the Quick Charger.Part Number: 72-0064-00-F©Copyright 2002 SpectraLink Corporation. All rights reserved.。

Rtnetlink描述

Rtnetlink描述

Rtnetlink描述针对路由控制的netlink接口,Linux IPv4 routing socketsRtnetlink基于netlink,允许对内核的路由表进行读写。

主要用来进行内核与用户空间的通信以及内核中子系统间的通信。

Rtnetlink是Linux2.2及其以后的版本中的一个新的特征。

Rtnetlink消息在初始头后可以有一些属性。

结构:struct{unsigned short rta_len; //属性的长度unsigned short rta_type; //属性类型/*属性数据跟随在这个结构之后*/}这些属性用RTA_*宏或者libnetlink来进行修改。

RTA_*宏:#define RTA_ALIGNTO 4#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) ) /*对齐*/#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \(rta)->rta_len >= sizeof(struct rtattr) && \(rta)->rta_len <= (len)) /*判断长度是否有len长*/#define RTA_NEXT(rta,attrlen)((attrlen) -= RTA_ALIGN((rta)->rta_len), \(struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len))) /*下一个的首地址*/#define RTA_LENGTH(len)(RTA_ALIGN(sizeof(struct rtattr)) + (len)) /*计算总长度*/#define RTA_SPACE(len)RTA_ALIGN(RTA_LENGTH(len)) /*返回数据的对齐的最小数值*/#define RTA_DATA(rta)((void*)(((char*)(rta)) + RTA_LENGTH(0))) /*取得数据部分首地址*/#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) /*payload总长度*/除了标准的netlink消息外,rtnetlink主要由以下的消息类型组成:1、RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK 创建,删除或者获取网络设备的信息这些消息包含一个ifinfomsg结构以及多个rtattr结构。

linux下netlink的使用简介

linux下netlink的使用简介

linux下netlink的使⽤简介⼀、什么是netlinkNetlink套接字是⽤以实现⽤户进程与内核进程通信的⼀种特殊的进程间通信(IPC) ,也是⽹络应⽤程序与内核通信的最常⽤的接⼝。

在Linux 内核中,使⽤netlink 进⾏应⽤与内核通信的应⽤有很多,如路由 daemon(NETLINK_ROUTE)⽤户态 socket 协议(NETLINK_USERSOCK)防⽕墙(NETLINK_FIREWALL)netfilter ⼦系统(NETLINK_NETFILTER)内核事件向⽤户态通知(NETLINK_KOBJECT_UEVENT)通⽤netlink(NETLINK_GENERIC)Netlink 是⼀种在内核与⽤户应⽤间进⾏双向数据传输的⾮常好的⽅式,⽤户态应⽤使⽤标准的 socket API 就可以使⽤ netlink 提供的强⼤功能,内核态需要使⽤专门的内核 API 来使⽤ netlink。

⼀般来说⽤户空间和内核空间的通信⽅式有三种:/proc、ioctl、Netlink。

⽽前两种都是单向的,⽽Netlink可以实现双⼯通信。

Netlink 相对于系统调⽤,ioctl 以及 /proc⽂件系统⽽⾔,具有以下优点:netlink使⽤简单,只需要在include/linux/netlink.h中增加⼀个新类型的 netlink 协议定义即可,(如 #define NETLINK_TEST 20然后,内核和⽤户态应⽤就可以⽴即通过socket API 使⽤该 netlink 协议类型进⾏数据交换)netlink是⼀种异步通信机制,在内核与⽤户态应⽤之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,⽽不需要等待接收者收到消息使⽤ netlink 的内核部分可以采⽤模块的⽅式实现,使⽤ netlink 的应⽤部分和内核部分没有编译时依赖netlink ⽀持多播,内核模块或应⽤可以把消息多播给⼀个netlink组,属于该neilink 组的任何内核模块或应⽤都能接收到该消息,内核事件向⽤户态的通知机制就使⽤了这⼀特性内核可以使⽤ netlink ⾸先发起会话Netlink协议基于BSD socket和AF_NETLINK地址簇,使⽤32位的端⼝号寻址,每个Netlink协议通常与⼀个或⼀组内核服务/组件相关联,如NETLINK_ROUTE⽤于获取和设置路由与链路信息、NETLINK_KOBJECT_UEVENT⽤于内核向⽤户空间的udev进程发送通知等。

Linux中与内核通信的Netlink机制

Linux中与内核通信的Netlink机制

Linux中与内核通信的Netlink机制Netlink在2.6版本的内核中变化也是很大的,在最新的2.6.37内核中,其定义已经改成下面这种形式,传递的参数已经达到6个。

其中第一个参数和mutex参数都是最新添加的。

Mutex 也可以为空。

这里主要是关于内核空间中的netlink函数的使用。

extern struct sock *netlink_kernel_create(struct net *net,int unit,unsigned int groups,void (*input)(struct sk_buff *skb),struct mutex *cb_mutex,struct module *module);struct net是一个网络名字空间namespace,在不同的名字空间里面可以有自己的转发信息库,有自己的一套net_device等等。

默认情况下都是使用init_net这个全局变量,下面是内核中调用netlink_kernel_create()函数的一个示例。

在内核中,audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,audit_receive, NULL, THIS_MODULE);模块调用函数netlink_unicast 来发送单播消息:int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock)参数ssk为函数netlink_kernel_create()返回的socket,参数skb存放消息,它的data字段指向要发送的netlink消息结构,而skb的控制块保存了消息的地址信息,前面的宏NETLINK_CB(skb)就用于方便设置该控制块,参数pid为接收消息进程的pid,参数nonblock 表示该函数是否为非阻塞,如果为1,该函数将在没有接收缓存可利用时立即返回,而如果为0,该函数在没有接收缓存可利用定时睡眠。

netlink介绍

netlink介绍

netlink定义用于在内核模块与在用户地址空间中的进程之间传递消息的。

它包含了用于用户进程的基于标准套接字的接口和用于内核模块的一个内部核心API。

[--manual]Netlink是套接字家族中的一员,主要用内核与用户空间的进程间、用户进程间的通讯。

然而它并不像网络套接字可以用于主机间通讯,Netlink只能用于同一主机上进程通讯,并通过PID来标识它们。

[--wiki][see more:RFC 3549]netlink出现之前,linux是用ioctl接口控制设备参数。

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。

所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。

(相对于系统调用,ioctl 以及/proc 文件系统):1,为了使用netlink,用户仅需要在include/linux/netlink.h 中增加一个新类型的netlink 协议定义即可,如#define NETLINK_MYTEST 17 然后,内核和用户态应用就可以立即通过socket API 使用该netlink 协议类型进行数据交换。

但系统调用需要增加新的系统调用,ioctl 则需要增加设备或文件,那需要不少代码,proc 文件系统则需要在/proc 下添加新的文件或目录,那将使本来就混乱的/proc 更加混乱。

2. netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息,但系统调用与ioctl 则是同步通信机制,如果传递的数据太长,将影响调度粒度。

3.使用netlink 的内核部分可以采用模块的方式实现,使用netlink 的应用部分和内核部分没有编译时依赖,但系统调用就有依赖,而且新的系统调用的实现必须静态地连接到内核中,它无法在模块中实现,使用新系统调用的应用在编译时需要依赖内核。

netlink用法

netlink用法

Netlink是Linux内核提供的一种进程间通信机制,用于完成内核与用户空间之间的通信。

常用于协议实现、网络管理、虚拟网络等场景。

下面是netlink的常用用法:
创建Socket:使用socket()系统调用来创建一个Netlink 的Socket。

绑定Socket:使用bind()系统调用将Socket与Netlink协议族绑定。

创建Netlink消息:通过Netlink的数据结构来创建Netlink 消息,并填充消息头部和传输数据部分。

发送Netlink消息:使用sendmsg()系统调用来发送Netlink 消息。

接收Netlink消息:使用recvmsg()系统调用来接收Netlink 消息。

解析Netlink消息:使用Netlink的数据结构来解析接收到的Netlink消息,包括消息头部和传输数据部分。

处理Netlink消息:根据不同的消息类型和操作,使用Netlink 的数据结构来处理接收到的Netlink消息。

关闭Socket:使用close()系统调用来关闭Netlink Socket。

总的来说,Netlink是Linux内核中非常重要的IPC机制之一,常被用于内核与用户空间之间的通信,可用于协议实现与管理等多个场景。

【IT专家】如何在内核和用户空间之间创建“netlink”?

【IT专家】如何在内核和用户空间之间创建“netlink”?

本文由我司收集整编,推荐下载,如有疑问,请与我司联系如何在内核和用户空间之间创建“netlink”?如何在内核和用户空间之间创建“netlink”?[英]How do I create a “netlink”between kernel and userspace? I want to use netlink to communicate between anapplication and kernel space. My Linux kernel version is 2.6.28, and the following is my wrong code:我想使用netlink 在应用程序和内核空间之间进行通信。

我的Linux 内核版本是2.6.28,以下是我的错误代码:nf_sock=netlink_kernel_create(NL_PROTO,0,nl_user_skb,THIS_MODULE); The abbreviated error message is:缩写错误消息是:error: too few arguments to function ‘netlink_kernel_create’ In the file linux/netlink.h , the function netlink_kernel_create() is defined as在文件中,函数netlink_kernel_create()定义为extern struct sock *netlink_kernel_create(struct net *net,int unit,unsigned int groups,void (*input)(struct sk_buff *skb),struct mutex *cb_mutex,struct module *module) I don’t understand what to use for the first argument, net. Can someone explain what Ishould use here?我不明白第一个参数net 用什么。

Generic Netlink详解

Generic Netlink详解

∙双向传输,异步通信∙用户空间中使用标准socket API∙内核空间中使用专门的API∙支持多播∙可由内核端发起通信∙支持32种协议类型netlink仅支持32种协议类型,这在实际应用中可能并不足够。

因此产生了generic netlink(以下简称为genl)。

generic netlink支持1023个子协议号,弥补了netlink协议类型较少的缺陷。

支持协议号自动分配。

它基于netlink,但是在内核中,generic netlink的接口与netlink并不相同。

1. Generic Netlink框架概述图1表示了Generic Netlink框架。

Kernel socket API向用户空间和内核空间分别提供接口。

Netlink子系统(1)是所有genl通信的基础。

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

Generic Netlink控制器(4)作为内核的一部分,负责动态地分配genl通道(即genl family id),并管理genl任务。

genl控制器是一个特殊的genl内核用户,它负责监听genl bus上的通信通道。

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

+---------------------+ +---------------------+| (3) application "A" | | (3) application "B" |+------+--------------+ +--------------+------+| |\ /\ /| |+-------+--------------------------------+-------+| : : |user-space=====+ : (5) Kernel socket API :+================| : : |kernel-space+--------+-------------------------------+-------+| |+-----+-------------------------------+----+| (1) Netlink subsystem |+---------------------+--------------------+|+---------------------+--------------------+| (2) Generic Netlink bus |+--+--------------------------+-------+----+| | |+-------+---------+ | || (4) Controller | / \+-----------------+ / \| |+------------------+--++--+------------------+| (3) kernel user "X" | | (3) kernel user "Y" | +---------------------++---------------------+图1:generic netlink框架2 Generic Netlink相关结构体2.1 genl familyGeneric Netlink是基于客户端-服务端模型的通信机制。

NETLINK有三种应用

NETLINK有三种应用

一、概述Hilscher NETLINK用于将西门子MPI协议转换为以太网TCP/IP协议,并提供公开的无需授权的驱动函数库。

NETLINK有三种应用:1、对于仅仅需要STEP7编程监控和WINCC监控,安装IBHNET127驱动即可,该驱动安装后将在控制面板的Set PG/PC Interface中添加IBHNetMPI/PPI/Profibus三个驱动连接;将STEP7(S7 ONLINE)和WINCC(MPI)的访问点指向以上驱动连接即可。

2、对于第三方组态软件(如KingView、iFix等)通过NETLINK访问PLC,选择我公司开发的OPCServer。

3、对于VB或者VC++(6.0以上版本)的自行开发界面,有两种方法实现通讯:l 调用Hilscher提供的IP Driver驱动函数库进行通讯;l 使用winsock控件进行通讯;本文对在VB6.0中通过Hilscher IP Driver驱动库读写S7300/400 PLC数据的基本开发步骤作简要描述,具体资料可以参考NETLINK光盘netDEVICE System Software中的Nlmpi_pie.pdf和Drv_Ip.pdf文件,该光盘可到/co/beichen-automation/index_download.asp 页面中下载。

二、平台和配置1、平台:WINDOW2000+SP4,Microsoft VB6.0;2、软件和驱动安装:Hilscher SYCON软件和IP Driver;3、硬件要求:NETLINK电缆一根,西门子S7300 CPU一台(如CPU314),以太网交换机一台(如TP-LINK),以太网电缆;4、系统配置:如下图所示三、NETLINK参数配置如上图所示,将计算机网卡的IP地址配置为192.168.1.10,将NETLINK的RJ45端口链接到交换机端口上,另一端插入CPU314的MPI通讯口,NETLINK是由CPU314的MPI口供电的。

ip命令的netlink实现

ip命令的netlink实现

Ip命令的netlink实现ip命令通过netlink 与内核通信形成命令的实现,下面就具体就route命令来说明实现流程。

1.skb内核中接受的数据和存储发送的数据都是放在了skb_buff结构体中。

struct netlink_skb_parms{struct ucred creds; /* Skb credentials */__u32 pid;__u32 dst_pid;__u32 dst_group;kernel_cap_t eff_cap;__u32 loginuid; /* Login (audit) uid */};使用下面的宏获取skb_bff中的数据部分#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))2.接收在/kernel/net/core/rtnetlink.c文件中,有一个接收从用户空间过来的Netlink消息的函数。

static void rtnetlink_rcv(struct sock *sk, int len)上面的内核函数就是用来接收用户路由方面Netlink消息的,当我们使用route命令添加一条路由时,就会调用该函数接收。

该函数是在netlink的初始化是注册的。

在netlink_kernel_create函数中,可以看到内核接收用户空间传过来的消息的接收函数,struct sock * netlink_kernel_create(int unit, unsigned int groups void (*input)(struct sock *sk, int len), struct module *module)input就是内核接受netlink消息的函数3.处理数据接受完成之后就将对接受的数据进行处理,当我们添加一条新路由时,在接函数rtnetlink_rcv中的循环中,会从一个队列中调用实际的接收处理函数,这里为rtnetlink_rcv_msg函数。

Netlink内核实现分析1

Netlink内核实现分析1

Netlink内核实现分析1Netlink 是⼀种IPC(Inter Process Commumicate)机制,它是⼀种⽤于内核与⽤户空间通信的机制,在⼀般情况下,⽤户态和内核态通信会使⽤传统的Ioctl、sysfs属性⽂件或者procfs属性⽂件,这3种通信⽅式都是同步通信⽅式,由⽤户态主动发起向内核态的通信,内核⽆法主动发起通信。

Netlink是⼀种异步全双⼯的通信⽅式,它⽀持由内核态主动发起通信,内核为Netlink通信提供了⼀组特殊的API接⼝,⽤户态则基于socket API,内核发送的数据会保存在接收进程socket 的接收缓存中,由接收进程处理。

netlink 优点:可以由内核发起,⽤户进程可以使⽤IO复⽤模型⽀持组播,即内核态可以将消息发送给多个接收进程Netlink ⼦系统初始化流程netlink 内核⼦接⼝初始化实在 net/netlink/af_netlink.c中初始化完成static const struct rhashtable_params netlink_rhashtable_params = {.head_offset = offsetof(struct netlink_sock, node),.key_len = netlink_compare_arg_len,.obj_hashfn = netlink_hash,.obj_cmpfn = netlink_compare,.automatic_shrinking = true,};/*这⾥的hash(哈希表)⽤来索引同种协议类型的不同netlink套接字实例,mc_list为多播使⽤的sock散列表,listeners为监听者掩码,groups为协议⽀持的最⼤多播组数量,同时还定义了⼀些函数指针,它们会在内核⾸次创建netlink时被赋值,后续应⽤层创建和绑定socket时调⽤到。

回到初始化函数中,接下来初始化应⽤层使⽤的NETLINK_USERSOCK协议类型的netlink(⽤于应⽤层进程间通信);然后调⽤sock_register向内核注册协议处理函数,即将netlink的socket创建处理函数注册到内核中,如此以后应⽤层创建netlink类型的socket时将会调⽤该协议处理函数,其中*/static int __init netlink_proto_init(void){int i;int err = proto_register(&netlink_proto, 0);if (err != 0)goto out;BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));//之开辟了MAX_LINKS个na_talbe指针空间nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);if (!nl_table)goto panic;//分配MAX_LINKS个netlink表结构, nl_table, 每个成员代表⼀种协议类型for (i = 0; i < MAX_LINKS; i++) {if (rhashtable_init(&nl_table[i].hash,&netlink_rhashtable_params) < 0) {rhashtable_destroy(&nl_table[i].hash);kfree(nl_table);goto panic;}}INIT_LIST_HEAD(&netlink_tap_all);netlink_add_usersock_entry();sock_register(&netlink_family_ops);//将netlink socket 创建函数注册到内核中,即创建netlink socket 时回调函数为 netlink_family_ops->create 回调register_pernet_subsys(&netlink_net_ops);/* The netlink device handler may be needed early. */rtnetlink_init();out:return err;panic:panic("netlink_init: Cannot allocate nl_table\n");}core_initcall(netlink_proto_init本初始化函数⾸先向内核注册netlink协议;然后创建并初始化了nl_table表数组,这个表是整个netlink实现的最关键的⼀步,每种协议类型占数组中的⼀项,后续内核中创建的不同种协议类型的netlink都将保存在这个表中.struct netlink_table {struct rhashtable hash;// hash表控制块,内部的hash表记录了已经创建的同种协议类型的所有netlink套接字struct hlist_head mc_list; // 这个hash表头节点⽤于记录同种协议类型下所有阅订了组播功能的套接字struct listeners __rcu *listeners; // 记录了同种协议类型下所有被阅订了的组播消息集合为监听者掩码unsigned int flags;unsigned int groups;// 记录了该协议类型⽀持的最⼤组播数量(通常就是32个)struct mutex *cb_mutex;struct module *module;//函数指针会在内核⾸次创建netlink时被赋值,后续应⽤层创建和绑定socket时调⽤到int (*bind)(struct net *net, int group);void (*unbind)(struct net *net, int group);bool (*compare)(struct net *net, struct sock *sock);int registered;};/*应⽤层创建PF_NETLINK(AF_NETLINK)类型的socket()系统调⽤时将由netlink_create()函数负责处理*/static const struct net_proto_family netlink_family_ops = {.family = PF_NETLINK,.create = netlink_create,.owner = THIS_MODULE, /* for consistency 8) */};Netlink 套接字对于每个类型都会创建⼀个内核的netlink 套接字⽤于和应⽤层通信;以NETLINK_ROUTE为例static int __net_init rtnetlink_net_init(struct net *net){struct sock *sk;struct netlink_kernel_cfg cfg = {.groups = RTNLGRP_MAX,.input = rtnetlink_rcv,.cb_mutex = &rtnl_mutex,.flags = NL_CFG_F_NONROOT_RECV,};sk = netlink_kernel_create(net, NETLINK_ROUTE, &cfg);if (!sk)return -ENOMEM;net->rtnl = sk;return 0;}/*定义了⼀个netlink_kernel_cfg结构体实例,设置groups为RTNLGRP_MAX后指定消息接收处理函数为rtnetlink_rcv,并设置flag为NL_CFG_F_NONROOT_RECV,这表明⾮超级⽤户可以绑定到多播组,但是没有设置NL_CFG_F_NONROOT_SEND,这表明⾮超级⽤户将不能发送组播消息。

NETLINK光纤收发器使用方法

NETLINK光纤收发器使用方法
存储温度:-20 ~ 70℃
湿度:5% ~ 90%
体积:26×70×94mm(高×宽×长
FX Link/Act:灯常亮表示光纤链路连接正确;灯闪亮表示光纤中有数据在传输;
Fdx:灯亮表示光纤以全双工方式传输数据;
TX 100:灯亮表示双绞线传输速率为100Mbps;
灯不亮表示双绞线传输速率为10Mbps;
TX Link/Act:灯常亮表示双绞线链路连接正确;灯闪亮表示双绞线中有数据在传输。
HTB-1100S是单模单纤收发器。
单纤双向收发器有1个RJ45接口和1个SC单芯接口,分别用来连接双绞线和光纤。
单纤收发器有6个LED指示灯:POWER、FX 100、TX 100、FX Link/Act、TX Link/Act、Fdx。
1。将光纤跳线或尾纤从同一根光纤两端的光纤终端盒分别连接到对端光纤收发器的SC口。
2。将UTP跳线从网络设备连接到单纤收发器的RJ45接口,本收发器电口能自适应直通线或交叉线。
3。将电源适配器的DC插头接到光纤收发器的DC插座上,再将电源适配器的AC插头插入AC插座,接通电源,此时光纤收发器的POWER灯亮,其它指示灯先按自检顺序依次闪亮,自检完成后将根据光纤收发器所检测到与之对接网络设备的电口状态来决定收发器电口的工作状态。如果检测不到对接设备(例如对接设备未开机等),收发器电口的状态为自适应,即不确定,所以TX LINK和TX 100指示灯均不亮。而光纤口因为已设定为100M全双工状态,所以FX 100和FX FDX指示灯将亮。
四。 技术参数
标准:IEEE 802.3 10BaseT, IEEE 802.3u
100Base-TX, 100Base-FX

netlink学习

netlink学习

Netlink开发和维护内核是一件很繁杂的工作,因此,只有那些最重要或者与系统性能息息相关的代码才将其安排在内核中。

其它程序,比如GUI,管理以及控制部分的代码,一般都会作为用户态程序。

在linux系统中,把系统的某个特性分割成在内核中和在用户空间中分别实现一部分的做法是很常见的(比如linux系统的防火墙就分成了内核态的Netfilter和用户态的iptables)。

然而,内核程序与用户态的程序又是怎样行通讯的呢?答案就是通过各种各样的用户态和内核态的IPC(interprocess communication )机制来实现。

比如系统调用,ioctl接口,proc文件系统以及netlink socket,本文就是要讨论netlink socekt并向读者展示这种用网络通讯接口方式实现的IPC机制的优点。

介绍:netlink socekt是一种用于在内核态和用户态进程之间进行数据传输的特殊的IPC。

它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket 接口的方式,实现了一种全双工的通讯连接。

类似于TCP/IP中使用AF_INET地址族一样,netlink socket使用地址族AF_NETLINK。

每一个netlinksocket在内核头文件include/linux/netlink.h中定义自己的协议类型。

下面是netlink socket 目前的特性集合以及它支持的协议类型:NETLINK_ROUTE 用户空间的路由守护程序之间的通讯通道,比如BGP,OSPF,RIP以及内核数据转发模块。

用户态的路由守护程序通过此类型的协议来更新内核中的路由表。

NETLINK_FIREWALL:接收IPV4防火墙代码发送的数据包。

NETLINK_NFLOG:用户态的iptables管理工具和内核中的netfilter模块之间通讯的通道。

NETLINK_ARPD:用来从用户空间管理内核中的ARP表。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

netlink socket编程why & how作者: Kevin Kaichuan He@2005-1-5翻译整理:duanjigang @2008-9-15<duanjigang1983@>原文:/article/7356开发和维护内核是一件很繁杂的工作,因此,只有那些最重要或者与系统性能息息相关的代码才将其安排在内核中。

其它程序,比如GUI,管理以及控制部分的代码,一般都会作为用户态程序。

在linux系统中,把系统的某个特性分割成在内核中和在用户空间中分别实现一部分的做法是很常见的(比如linux系统的防火墙就分成了内核态的Netfilter和用户态的iptables)。

然而,内核程序与用户态的程序又是怎样行通讯的呢?答案就是通过各种各样的用户态和内核态的IPC(interprocess communication )机制来实现。

比如系统调用,ioctl接口,proc文件系统以及netlink socket,本文就是要讨论netlink socekt并向读者展示这种用网络通讯接口方式实现的IPC机制的优点。

介绍:netlink socekt是一种用于在内核态和用户态进程之间进行数据传输的特殊的IPC。

它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket 接口的方式,实现了一种全双工的通讯连接。

类似于TCP/IP中使用AF_INET地址族一样,netlink socket使用地址族AF_NETLINK。

每一个netlink socket在内核头文件include/linux/netlink.h中定义自己的协议类型。

下面是netlink socket 目前的特性集合以及它支持的协议类型:¾NETLINK_ROUTE: 用户空间的路由守护程序之间的通讯通道,比如BGP,OSPF,RIP以及内核数据转发模块。

用户态的路由守护程序通过此类型的协议来更新内核中的路由表。

¾NETLINK_FIREWALL:接收IPV4防火墙代码发送的数据包。

¾NETLINK_NFLOG:用户态的iptables管理工具和内核中的netfilter模块之间通讯的通道。

¾NETLINK_ARPD:用来从用户空间管理内核中的ARP表。

为什么以上的功能在实现用户程序和内核程序通讯时,都使用netlink方法而不是系统调用,ioctls或者proc文件系统呢?原因在于:为新的特性添加一个新的系统调用,ioctls或者一个proc文件的做法并不是很容易的一件事情,因为我们要冒着污染内核代码并且可能破坏系统稳定性的风险去完成这件事情。

然而,netlink socket却是如此的简单,你只需要在文件netlink.h中添加一个常量来标识你的协议类型,然后,内核模块和用户程序就可以立刻使用socket风格的API进行通讯了!Netlink提供了一种异步通讯方式,与其他socket API一样,它提供了一个socket队列来缓冲或者平滑瞬时的消息高峰。

发送netlink消息的系统调用在把消息加入到接收者的消息对列后,会触发接收者的接收处理函数。

接收者在接收处理函数上下文中,可以决定立即处理消息还是把消息放在队列中,在以后其它上下文去处理它(因为我们希望接收处理函数执行的尽可能快)。

系统调用与netlink不同,它需要一个同步的处理,因此,当我们使用一个系统调用来从用户态传递消息到内核时,如果处理这个消息的时间很长的话,内核调度的粒度就会受到影响。

内核中实现系统调用的代码都是在编译时静态链接到内核的,因此,在动态加载模块中去包含一个系统调用的做法是不合适的,那是大多数设备驱动的做法。

使用netlink socket时,动态加载模块中的netlink 程序不会和linux内核中的netlink部分产生任何编译时依赖关系。

Netlink优于系统调用,ioctls和proc文件系统的另外一个特点就是它支持多点传送。

一个进程可以把消息传输给一个netlink组地址,然后任意多个进程都可以监听那个组地址(并且接收消息)。

这种机制为内核到用户态的事件分发提供了一种近乎完美的解决方案。

系统调用和ioctl都属于单工方式的IPC,也就是说,这种IPC会话的发起者只能是用户态程序。

但是,如果内核有一个紧急的消息想要通知给用户态程序时,该怎么办呢?如果直接使用这些IPC的话,是没办法做到这点的。

通常情况下,应用程序会周期性的轮询内核以获取状态的改变,然而,高频度的轮询势必会增加系统的负载。

Netlink 通过允许内核初始化会话的方式完美的解决了此问题,我们称之为netlink socket的双工特性。

最后,netlink socket提供了一组开发者熟悉的BSD风格的API函数,因此,相对于使用神秘的系统调用API或者ioctl而言,netlink开发培训的费用会更低些。

与BSD的Routing socket的关系在BSD TCP/IP的协议栈实现中,有一种特殊的socket叫做Routing socket.它的地址族为AF_ROUTE, 协议族为PF_ROUTE, socket类型为SOCK_RAW. 这种Routing socket是用户态进程用来向内核中的路由表增加或者删除路由信息用的。

在Linux系统中,netlink socket通过协议类型NETLINK_ROUTE实现了与Routing socket相同的功能,可以说,netlink socket提供了BSD Routing socket功能的超集。

Netlink Socket 的API标准的socket API函数-socket(), sendmsg(), recvmsg()和close()-都能够被用户态程序直接调用来访问netlink socket.你可以访问man手册来获取这些函数的详细定义。

在本文,我们只讨论怎样在netlink socket的上下文中为这些函数选择参数。

这些API对于使用TCP/IP socket写过一些简单网络程序的读者来说应该很熟悉了。

使用socket()函数创建一个socket,输入:int socket(int domain, int type, int protocol)socket域(地址族)是AF_NETLINK,socket的类型是SOCK_RAW或者SOCK_DGRAM,因为netlink是一种面向数据包的服务。

协议类型选择netlink要使用的类型即可。

下面是一些预定义的netlink协议类型:NETLINK_ROUTE, NETLINK_FIREWALL, NETLINK_ARPD, NETLINK_ROUTE6和 NETLINK_IP6_FW. 你同样可以很轻松的在netlink.h中添加自定义的协议类型。

每个netlink协议类型可以定义高达32个多点传输的组。

每个组用一个比特位来表示,1<<i,0<=i<=31.当一组用户态进程和内核态进程协同实现一个相同的特性时,这个方法很有用,因为发送多点传输的netlink消息可以减少系统调用的次数,并且减少了相关应用程序的个数,这些程序本来是要用来处理维护多点传输组之间关系而带来的负载的。

bind()函数跟TCP/IP中的socket一样,netlink的bind()函数把一个本地socket地址(源socket地址)与一个打开的socket进行关联,netlink地址结构体如下:struct sockaddr_nl{sa_family_t nl_family; /* AF_NETLINK */unsigned short nl_pad; /* zero */__u32 nl_pid; /* process pid */__u32 nl_groups; /* mcast groups mask */} nladdr;当上面的结构体被bind()函数调用时,sockaddr_nl的nl_pid属性的值可以设置为访问netlink socket的当前进程的PID,nl_pid作为这个netlink socket的本地地址。

应用程序应该选择一个唯一的32位整数来填充nl_pid的值。

NL_PID 公式 1: nl_pid = getpid();公式一使用进程的PID作为nl_pid的值,如果这个进程只需要一个该类型协议的netlink socket的话,选用进程pid作为nl_pid是一个很自然的做法。

换一种情形,如果一个进程的多个线程想要创建属于各个线程的相同协议类型的netlink socket的话,公式二可以用来为每个线程的netlink socket产生nl_pid值。

NL_PID 公式 2: pthread_self() << 16 | getpid();采用这种方法,同一进程的不同线程都能获取属于它们的相同协议类型的不同netlink socket。

事实上,即便是在一个单独的线程里,也可能需要创建同一协议类型的多个netlink socket。

所以开发人员需要更多聪明才智去创建不同的nl_pid值,然而本文中不会就如何创建多个不同的nl_pid的值进行过多的讨论如果应用程序想要接收特定协议类型的发往指定多播组的netlink消息的话,所有接收组的比特位应该进行与运算,形成sockaddr_nl的nl_groups域的值。

否则的话,nl_groups应该设置为0,以便应用程序只能够收到发送给它的netlink消息。

在填充完结构体nladdr后,作如下的绑定工作:bind(fd, (struct sockaddr*)&nladdr, sizeof(nladdr));发送一个netlink 消息为了能够把一个netlink消息发送给内核或者别的用户进程,类似于UDP数据包发送的sendmsg()函数一样,我们需要另外一个结构体struct sockaddr_nl nladdr作为目的地址。

如果这个netlink消息是发往内核的话,nl_pid属性和nl_groups属性都应该设置为0。

如果这个消息是发往另外一个进程的单点传输消息,nl_pid应该设置为接收者进程的PID,nl_groups 应该设置为0,假设系统中使用了公式1。

如果消息是发往一个或者多个多播组的话,应该用所有目的多播组的比特位与运算形成nl_groups的值。

然后我们就可以将netlink地址应用到结构体struct msghdr msg中,供函数sendmsg()来调用:struct msghdr msg;msg.msg_name = (void *)&(nladdr);msg.msg_namelen = sizeof(nladdr);netlink消息同样也需要它自身的消息头,这样做是为了给所有协议类型的netlink消息提供一个通用的背景。

相关文档
最新文档