一、netlink机制简介

  netlink是一种基于网络的机制,允许在内核内部以及内核与用户之间进行通信。正式定义见RFC3549。手册见netlink(3)和netlink(7)。netlink(3)描述了内核中用于操作、访问、创建netlink数据报的宏。netlink(7)包含了netlink套接字的一般性信息,并给出了这里使用的数据结构的文档。

  该机制不仅仅用于网络通信,更重要的用户是通用对象类型。

  netlink机制比procfs或sysfs中文件想必有下列优势:

    1. 任何一方都不需要轮询,如果使用文件传递状态消息,那么用户层需要不断的检查是否有新消息到达。

    2. 系统调用和ioctl也能够从用户态向内核传递信息,但比简单的netlink连接更难与实现

    3. 内核可以直接向用户层发送消息,无需用户层事先请求。使用文件也可以做到,但系统调用和ioctl是不可能的。

    4. 除了简单的套接字,用户空间应用程序不需要使用其他东西来与内核交互。

二、数据结构

  指定地址

  类似于其他网络协议,每个netlink套接字都需要分配一个地址。struct sockaddr:

  

<netlink.h>

struct sockaddr_nl
{
sa_family_t nl_family; /* AF_NETLINK *//*区分内核不同部分使用各个不同的netlink通道*/
unsigned short nl_pad; /* 0 *//**/
__u32 nl_pid; /* 端口ID *//*nl_pid此类套接字唯一标示符,对内核自身来讲,该字段始终是0,用户应用程序通常使用其线程组ID,不强求,可以是任何唯一值*/
__u32 nl_groups; /* 多播组掩码 *//*nl_groups是一个位图,属于该套接字所属的多播地址,如果不允许多播,该字段为0*/
};

  消息格式

每个消息由两部分组成:首部和净荷。首部表示为struct nlmsghdr,而净荷可以是任意的。netlink消息的各部分,对齐到NLMSG_ALIGNTO(通常是4)字节边界。查询netlink(3)正确计算边界。一个消息的长度不应该超过一页,这样对内存分配的压力较小。

 <netlink.h>
struct nlmsghdr
{
__u32 nlmsg_len; /*消息长度,包含首部在内*/
__u32 nlmsg_type; /*消息内容的类型*/
__u32 nlmsg_flags; /*附加的标志*/
__u32 nlmsg_seq; /*序列号*/
__u32 nlmsg_pid; /*发送进程的端口ID*/
};

  各种标志可以保存在nlmsg_flags,所有可能的值都在netlink.h中。主要关注两个标志:如果消息包含一个请求,要求执行某个特定的操作(而不是传输一些状态信息),那么NLM_F_REQUEST将置位,而NLM_F_ACK要求在接收到上述消息并成功处理请求后发送一个确认消息。

  nlmsg_seq包含一个序列号,表示一系列消息之间在时间上的前后关系。

二、编程接口

  netlink套接字既可以从内核打开,也可以从用户层打开。前一种使用了netlink_kernel_create,在后一种情况下,将通过标准的网络编程接口出发netlink_ops的bind方法。

 net/netlink/af_netlink.c
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);

net表示网络命名空间,unit制定所属协议族成员,而input是一个回调函数,在数据到达该套接字将调用input。如果对input指定了NULL指针,那么套接字将只能从内核向用户层传输数据,发过来就不行了。

 kernel/audit.c

 static void audit_receive_skb(struct sk_buff *skb)
{
int err;
u32 rlen;
struct nlmsghdr *nlh; while(skb->len >= NLMSG_SPACE())
{
nlh = nlmsg_hdr(skb);
……
rlen = NLMSG_ALIGN(nlh->nlmsg_len);
……
if((err = audit_receive_msg(skb, nlh)))
{
netlink_ack(skb, nlh, err);
}
else if (nlh->nlmsg_flags & NLM_F_ACK)
netlink_ack(skb, nlh, );
skb_pull(skb, rlen);
}
}

最新文章

  1. [moka同学笔记]window下.htacess文件 与linux下.htacess文件
  2. redmin3 忘记管理密码找回方法
  3. 用Java开发代理服务器
  4. 解决Asp.net中的Chart控件运行出现错误提示“ ChartImg.axd 执行子请求时出错”
  5. RichTextBox 右键显示 ContextMenuTrip 分类: C# 2014-10-16 10:43 337人阅读 评论(0) 收藏
  6. jquery1.9学习笔记 之层级选择器(二)
  7. css学习笔记四
  8. 【从翻译mos文章】不再用par file如果是,export or import 包含大写和小写表名称表
  9. MongoDB深圳用户组线下活动召集
  10. mvc路由参数注解
  11. MySQL binlog相关分析
  12. ROM、SDRAM、RAM、DRAM、SRAM、FLASH区别
  13. [SHOI2008]小约翰的游戏John
  14. oracle循环插入1万条数据
  15. 配置wildfly10为linux的服务,并开机启动
  16. Python学习笔记 -- 第六章 文件操作
  17. 手机APP UI设计尺寸基础知识
  18. Lambda表达式语法2
  19. 2018年湘潭大学程序设计竞赛G又见斐波那契
  20. RabbitMQ消息可靠性分析

热门文章

  1. 设置Excel的自动筛选功能
  2. LPC1768之中断
  3. eclipse中输入@符号自动提示Annotation
  4. ajax实现的无刷新分页代码实例
  5. Shell中set用法(转载)
  6. memcached客户端的使用
  7. spring mvc视频
  8. ServiceBroker创建流程
  9. source insight新建工程,添加文件时出现“no files found”
  10. C++学习29 重载[](下标运算符)