netlink通信的流程(3.14内核)

前言

netlink的通信方式可以类比TCP/IP协议族,类比如下:

  • netlink——TCP/IP协议族
  • NETLINK_ROUTE——UDP协议
  • 内核态socket(端口为0)——UDP服务器
  • 用户态socket(端口一般为进程的pid)——UDP客户端

netlink协议初始化

netlink_proto_init,分配MAX_LINKS个nl_table并初始化,在3.14内核中,netlink支持32个协议,通过 cat /proc/net/netlink 可以查看已经创建的netlink协议及端口号(包含用户态和内核态)

内核态创建AF_NETLINK类型的socket

内核态调用netlink_kernel_create创建netlink的socket

  • sock_create_lite:创建"struct socket"
  • __netlink_create:将netlink_ops存入"struct socket"中,创建"struct sock",并设置sk的协议号
  • netlink_insert:将socket插入nl_table的对应协议号中,因为portid写死为0,所以每个协议只能在内核态创建一次。

用户态创建AF_NETLINK类型的socket

调用顺序为socket——>sock_create——>netlink_create

  • __sock_create:创建"struct socket"
  • __netlink_create:将netlink_ops存入"struct socket"中,创建"struct sock",并设置sk的协议号

到这里,用户态已经可以给内核态发送消息了,但是需要绑定之后才能收来自内核的消息。。。

用户态绑定端口号

调用顺序为bind——>netlink_bind

  • netlink_insert:如果指定了端口号,将socket插入nl_table的对应协议号中,否则调用netlink_autobind自动生成端口号

用户态向内核态发送消息(同步调用)

调用顺序为sendto——>sock_sendmsg——>__sock_sendmsg——>__sock_sendmsg_nosec——>netlink_sendmsg——>netlink_unicast——>netlink_unicast_kernel——>nlk->netlink_rcv

  • sendto:nl_family为AF_NETLINK,nl_pid为0(因为内核创建的端口是0),nl_groups为0(表示单播)
  • netlink_getsockbyportid:根据源sock的协议号和目的端口来找到内核态的sock,所以用户态创建socket时需要与内核态使用相同的协议号。

内核态向用户态发送消息(异步调用)

调用顺序为netlink_unicast——>netlink_sendskb——>__netlink_sendskb_——>skb_queue_tail

  • netlink_getsockbyportid:根据源sock的协议号和目的端口来找到用户态的sock
  • skb_queue_tail:将skb加入用户态sock的收包队列中。
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值