免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1978 | 回复: 4

[网络子系统] netfilter NF_QUEUE 实现 [复制链接]

论坛徽章:
0
发表于 2017-07-18 09:10 |显示全部楼层
Hi,all.我使用的是内核版本3.4,我想跟踪内核中 netfilter 里面对于return NF_QUEUE的包的处理。查看了资料后,发现内核是将 NF_QUEUE的包通过 netlink 与用户态通信将数据包发送到用户空间。我理解的是,这中间总会存在一个 queue用来存储数据包,然后我想定位到这个queue 怎么被操作使用的。
在跟踪内核实现后,大概的流程是:NF_HOOK -> nf_hook_slow(在这里面判断 verdict变量,如果是 NF_QUEUE,就调用nf_queue) -> nf_queue(里面会回调到 nfqnl_enqueue_packet) -> nfqnl_enqueue_packet -> __nfqnl_enqueue_packet -> nfnetlink_unicast(这个时候是要把包发送到用户态,我继续跟踪进去) -> netlink_unicast -> netlink_sendskb -> __netlink_sendskb.
代码到了 __netlink_sendskb 后,里面的代码是:
  1. static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
  2. {
  3.         int len = skb->len;

  4.         skb_queue_tail(&sk->sk_receive_queue, skb);
  5.         sk->sk_data_ready(sk, len);
  6.         return len;
  7. }
复制代码
在这里是有将 skb 插入 sk的receive_queue 里面的。但后面调用了 sk_data_ready 来处理这个 queue,但是我跟到这里的时候断掉了。找不到 sk_data_ready的实现。我查找跟 netlink 有关的 code,在 netlink_kernel_create里面有:
  1. sk->sk_data_ready = netlink_data_ready;
  2.         if (input)
  3.                 nlk_sk(sk)->netlink_rcv = input;
复制代码
但是呢,netlink_data_ready 实现是空的:
  1. static void netlink_data_ready(struct sock *sk, int len)
  2. {
  3.         BUG();
  4. }
复制代码
所以我就不知道如何继续往下分析了,另外一条思路是 netlink_kernel_create 的input的参数 是否会跟这个有关系呢?  就是:
  1. if (input)
  2. nlk_sk(sk)->netlink_rcv = input;
复制代码
有哪位了解这块的,可以给点思路吗?

论坛徽章:
0
发表于 2017-07-18 13:22 |显示全部楼层
netlink_kernel_create()创建的netlink scoket是在内核空间用的,用户空间的netlink socket是通过 netlink_create() 函数创建的。

论坛徽章:
0
发表于 2017-07-18 16:50 |显示全部楼层
回复 2# anbutu

嗯呀,我现在就是跟踪内核态的实现呀。

论坛徽章:
0
发表于 2017-07-18 18:07 |显示全部楼层
回复 3# 时有无

NFQUEUE的数据包会暂存到打开这个QUEUE的用户空间sk的sk->sk_receive_queue上,你说的那个kernel空间的nfqueue netlink sock,是用来处理用户空间向内核空间通信(例如配置QUEUE,返回数据包的VERDICT等)的。

论坛徽章:
7
IT运维版块每日发帖之星
日期:2016-05-27 06:20:00IT运维版块每日发帖之星
日期:2016-06-09 06:20:00操作系统版块每日发帖之星
日期:2016-06-12 06:20:00程序设计版块每日发帖之星
日期:2016-06-12 06:20:00操作系统版块每日发帖之星
日期:2016-06-13 06:20:00IT运维版块每日发帖之星
日期:2016-06-17 06:20:002015-2016NBA季后赛纪念章
日期:2016-06-28 17:42:27
发表于 2017-07-24 16:54 |显示全部楼层
netlink_data_ready() 没有实现,什么都没有做。
  1. static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb)
  2. {
  3.         int len = skb->len;

  4.         skb_queue_tail(&sk->sk_receive_queue, skb);
  5.         sk->sk_data_ready(sk, len); // 没干活
  6.         return len;
  7. }
复制代码


核心就是skb_queue_tail, 件数据防盗接收队列,等待用户层的netlink收取。

再往下应该有一次,如果用户层没有收取,这个队列什么时候满? 受到多少的数据停止?丢前面的数据还是后面没有入队的数据?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP