zoukankan      html  css  js  c++  java
  • netlink机制

    一、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)正确计算边界。一个消息的长度不应该超过一页,这样对内存分配的压力较小。

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

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

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

     二、编程接口

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

    1 net/netlink/af_netlink.c
    2 struct sock *
    3 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指针,那么套接字将只能从内核向用户层传输数据,发过来就不行了。

     1 kernel/audit.c
     2 
     3 static void audit_receive_skb(struct sk_buff *skb)
     4 {
     5      int err;
     6      u32 rlen;
     7      struct nlmsghdr *nlh;
     8 
     9      while(skb->len >= NLMSG_SPACE(0))
    10      {
    11            nlh = nlmsg_hdr(skb);
    12            ……
    13            rlen = NLMSG_ALIGN(nlh->nlmsg_len);
    14            ……
    15            if((err = audit_receive_msg(skb, nlh)))
    16            {
    17                   netlink_ack(skb, nlh, err);
    18             }
    19             else if (nlh->nlmsg_flags & NLM_F_ACK)
    20                    netlink_ack(skb, nlh, 0);
    21             skb_pull(skb, rlen);
    22       }
    24 }
  • 相关阅读:
    MP3 Lame 转换 参数 设置(转)
    数据库SQL优化大总结之 百万级数据库优化方案(转)
    IndexedDB:浏览器里内置的数据库(转)
    【译】微型ORM:PetaPoco【不完整的翻译】(转)
    'NoneType' object has no attribute '__getitem__'
    关于python的整形(int)自动转长整形(long)的问题
    1-redis使用笔记
    Flask deployment on gunicorn with flask script
    Celery从入门到放弃
    SELECT中的CAST
  • 原文地址:https://www.cnblogs.com/Huluwa-Vs-Aoteman/p/3496552.html
Copyright © 2011-2022 走看看