免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: wojiaohesen
打印 上一主题 下一主题

再谈 NETLINK [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-09-04 10:47 |只看该作者
原帖由 Godbach 于 2009-9-4 10:42 发表
白金兄,你的头像现在显示不出来,而且显示的还是游客

哈哈,一个能发贴的、称谓是“老法王”的、且还能管理版块的游客,多 COOL 啊!
留着吧,挺好的

论坛徽章:
0
12 [报告]
发表于 2009-09-04 10:50 |只看该作者
原帖由 wojiaohesen 于 2009-9-3 21:33 发表
写了这么多东西,竟然没有人看,难道这些东西都没有什么用吗?看见别的人发的帖子,我忍不住鄙视,可是想想到底论坛该是什么样子的呢?我没有答案


看来LZ和我一样喜欢臭屁,按我同事的观点,会用就行了管那么多做什么,
这是篇很不错的文章,虽然我还没有完全看懂(有不少错别字影响理解)
我有进一步几个疑问:
>>在某一个时刻inet发送他的recv类对中有信息需要处理,那么他就会处理该信息,然后发送给用户空间一个响应,这种响应的方式和用户的socket找到inet的方式是一样的,
这里是不是一直不用那个send队列?send队列又是在什么情况下使用.
这个处理又是在什么上下问执行的?进程上下问,中断上下文,子系统发现rev有消息的触发点在哪里?

还有LZ你这是哪个版本的?我的2.6.13.2和你的结构不一样.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
13 [报告]
发表于 2009-09-04 11:08 |只看该作者

回复 #11 platinum 的帖子

现在好像好了。昨晚到刚才一直有问题。

论坛徽章:
0
14 [报告]
发表于 2009-09-04 13:31 |只看该作者
原帖由 epegasus 于 2009-9-4 10:50 发表


看来LZ和我一样喜欢臭屁,按我同事的观点,会用就行了管那么多做什么,
这是篇很不错的文章,虽然我还没有完全看懂(有不少错别字影响理解)
我有进一步几个疑问:
>>在某一个时刻inet发送他的recv类 ...

简单来说:
         首先声明的是-》我说的recv和send列队只是个假设,真实的名字在sock结构体中的sk_receive_queue & sk_write_queue中。为了能说明这个东西到底是如何使用的,那我就来介绍一下rtnetlink的简单使用。

         在rtnetlink中有三个消息模式:RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK.

         RTM-GETLINK:
                     是用来获取网卡的信息的。让我们看看该过程是怎么样使用的?
                     当用户空间发送该请求的时候,请注意,netlink_sendmsg会一直找到rtnetlink注册的那个函数rtnetlink_rcv,然后rtnetlink_rcv执行,因为网卡的信息都是固定存在的,所以rtnetlink_rcv几乎是用一种近似非阻塞的方式来获取这些网卡的数据,然后把这些数据追加到`recv`列队上,问题是它怎么知道哪个socket(pid)发送过来的,这个问题很简单socket被sock这个结构包含,而netlink_sock这个结构体包含sock,在netlink_sock这个结构体中又包括一个字段pid,这个pid就是用户空间的socket在nl_pid_hash中的索引,当netlink_sendmsg在根据目标pid(0)为0的时候调用netlink_unicast_kernel,让后再调用rtnetlink_rcv这个函数,而在此过程中sock这个结构体一直都是被传递的,根据sock这个结构题可以很方便的访问netlink_sock和socket这几个结构体。而这个时候,bind的地址几句是根本没有必要的,因为当用户空间在send返回的时候,它的接受列队上实际上就已经有数据了。而当send返回的时候,接着就可以调用recv来获取数据了。几乎可以想象整个过程都是无阻塞的。

         在来看看那些异步的:
                      异步的事件如:网络地址的更改,arp缓冲区的修改等
                      相对于上面的GETLINK,这些则完全都是异步的,也就是说你完全不能说我发送一个请求说:send 内核,你赶紧的让ip地址修改,我要接受。这几乎是完全不可能的,而要接受这样的事件,你可以用setsockopt来调用NETLINK_ADD_MEMBERSHIP来告诉内核当什么事情发生的时候,让内核告诉你。然后你就可以用epoll来监听上面的事情了。当一个你希望的事情发生的时候,那个事情就加入到用户空间的socket的recv列队,然后epoll返回,获知当前有事。你甚至可以通过sk_filter来更细致的过滤你想要的事件。


  参考资料:
          rtnetlink_event
          rtnl_register
          rtnetlink_init
          sk_filter

[ 本帖最后由 wojiaohesen 于 2009-9-4 13:34 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2009-09-04 13:36 |只看该作者
原帖由 platinum 于 2009-9-4 10:41 发表
实验了一下

测试方法:
A、userspace ---> kernelspace
B、kernelspace ---> userspace

1、userspace 不 bind
A:成功
B:成功

2、userspace 用 0 做 pid 发送给 kernelspace,kernelspace 发回时 ...



你说的那个不成功,就是kernle---》userspace是用的什么样的方式,当时的场景是怎么样?我并不认为如此》我觉得你实际上是在用户空间没有请求的情况下直接给用户空间发的消息,这样内核当然是找不到那个userspac的socket了

论坛徽章:
0
16 [报告]
发表于 2009-09-04 14:11 |只看该作者
原帖由 wojiaohesen 于 2009-9-4 13:36 发表



你说的那个不成功,就是kernle---》userspace是用的什么样的方式,当时的场景是怎么样?我并不认为如此》我觉得你实际上是在用户空间没有请求的情况下直接给用户空间发的消息,这样内核当然是找不到那 ...

最简单的测试,从 kernelspace -> userspace 发数据时,调用 netlink_unicast 函数

  1. 函数原型:

  2. int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock);
复制代码

如果其中 pid 不是 userspace 的,那么 userspace 就收不到
你自己可以测试一下

至于你说的“用户空间没有主动请求的情况下”我不理解

[ 本帖最后由 platinum 于 2009-9-4 14:13 编辑 ]

论坛徽章:
0
17 [报告]
发表于 2009-09-04 20:56 |只看该作者
原帖由 platinum 于 2009-9-4 14:11 发表

最简单的测试,从 kernelspace -> userspace 发数据时,调用 netlink_unicast 函数

函数原型:

int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock);

如果其中 pid ...



U are right!这中情况发生在广播的情况下。谢谢!

论坛徽章:
0
18 [报告]
发表于 2009-09-05 06:46 |只看该作者
无论如何,bind 确实没必要!

论坛徽章:
0
19 [报告]
发表于 2009-09-05 08:25 |只看该作者
正确的说法应该是:如果通信的方式是用户空间的程序和用户空间程序通信的话,那就需要pid,否则则完全没有必要。

论坛徽章:
0
20 [报告]
发表于 2009-09-05 11:41 |只看该作者
原帖由 wojiaohesen 于 2009-9-5 08:25 发表
正确的说法应该是:如果通信的方式是用户空间的程序和用户空间程序通信的话,那就需要pid,否则则完全没有必要。

兄台说的 pid 指的是 bind 时候的 pid 吧,而不是 kernel -> user 时候单播函数的 pid,是这样的吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP