免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1119 | 回复: 0
打印 上一主题 下一主题

nfnetlink和ip_queue [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-17 11:12 |只看该作者 |倒序浏览
nfnetlink和ip_queue

本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严
禁用于任何商业用途。
msn:
yfydz_no1@hotmail.com
来源:
http://yfydz.cublog.cn
1. 前言
netlink是linux中实现内核与用户空间通信的一种方法,数据以类似网络数据包的形式在两者间传输,
这和以前所介绍的/proc,ioctl和setsockopt方式是不同的,另外一个区别是以前这几种方法都是用户
空间程序主动向内核发出请求,相当于客户端,内核相当于一个服务器;而netlink方法则是内核和用
户空间都可以主动向对方发送数据。
netlink现在已经是Linux内核中网络部分的一个基本协议族,具体代码在net/netlink中定义。
最初netlink接口主要是提供给路由程序来和内核通信修改系统的路由表的,从2.2内核开始在防火墙模
块中也有了netlink的支持。在2.4内核中,netlink支持是在ip_queue中实现的,另一种实现方式是
nfnetlink的,但只在POM中有补丁,没加入官方内核中;到了2.6,nfnetlink纳入官方内核中,并成为
推荐的防火墙模块的netlink支持,ip_queue虽然还在内核代码中,但已经不推荐使用(obsolete)。
通过netlink接口,netfilter可以向用户空间发送网络数据包,防火墙日志信息等,并能进行netlink
的连接跟踪,相关代码在net/netfilter/nfnetlink.c, net/netfilter/nfnetlink_conntrack.c,
net/netfilter/nfnetlink_queue.c, net/netfilter/nfnetlink_log.c等文件中。
以下内核代码版本为2.6.19.2。
2. netfilter中的netlink初始化
2.1 nfnetlink初始化
/* net/netfilter/nfnetlink.c */
static int __init nfnetlink_init(void)
{
printk("Netfilter messages via NETLINK v%s.\n", nfversion);
// 建立NETFILTER的NETLINK接口,组号是NFNLGRP_MAX
// 接收用户空间数据包函数是nfnetlink_rcv
nfnl = netlink_kernel_create(NETLINK_NETFILTER, NFNLGRP_MAX,
                              nfnetlink_rcv, THIS_MODULE);
if (!nfnl) {
  printk(KERN_ERR "cannot initialize nfnetlink!\n");
  return -1;
}
return 0;
}
2.3 nfnetlink_queue的初始化
/* net/netfilter/nfnetlink_queue.c */
static int __init nfnetlink_queue_init(void)
{
int i, status = -ENOMEM;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_nfqueue;
#endif

for (i = 0; i

2.3 ip_queue的初始化
/* net/ipv4/netfilter/ip_queue.c */
static int __init ip_queue_init(void)
{
int status = -ENOMEM;
struct proc_dir_entry *proc;

netlink_register_notifier(&ipq_nl_notifier);
// 建立FIREWALL类型的NETLINK接口,组号是0
// 接收用户空间数据包函数是ipq_rcv_sk
ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk,
          THIS_MODULE);
if (ipqnl == NULL) {
  printk(KERN_ERR "ip_queue: failed to create netlink socket\n");
  goto cleanup_netlink_notifier;
}
......
}
2.4 小结
由此可见,nfnetlink和ip_queue两者都是通过调用 netlink_kernel_create函数来初始化netlink套接口的,ip_queue功能比较单纯,就是传输网络数据包,而nfnetlink有所扩展,不光是传递数据包,还
可传递其他数据,如日志信息的,不同类型数据处理是通过netlink子系统来区分的,不仅包括了
ip_queue的功能,还进行了扩展,这可能就是ip_queue被废的原因。
3. netlink_kernel_create
/* net/netlink/af_netlink.c */
/*
* We export these functions to other modules. They provide a
* complete set of kernel non-blocking support for message
* queueing.
*/
struct sock *
netlink_kernel_create(int unit, unsigned int groups,
// unit即netlink接口类型,有ROUTE,FIREWALL,IP6_FW,XFRM等
// 最大值为MAX_LINKS
// groups为具体各种类型netlink接口中的组号
                      void (*input)(struct sock *sk, int len),
                      struct module *module)
{
struct socket *sock;
struct sock *sk;
struct netlink_sock *nlk;
unsigned long *listeners = NULL;
BUG_ON(!nl_table);
// unit范围检查
if (unit=MAX_LINKS)
  return NULL;
// 建立netlink的socket
if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
  return NULL;
// 建立unit类型的netlink的sock
if (__netlink_create(sock, unit)
// 小于32的组号都设置为32
// ip_queue中该参数为0, nfnetlink中该参数为NFNLGRP_MAX,都不超过32
// 所以实际两者等价
if (groups
// 监听者
listeners = kzalloc(NLGRPSZ(groups), GFP_KERNEL);
if (!listeners)
  goto out_sock_release;
sk = sock->sk;
sk->sk_data_ready = netlink_data_ready;
// netlink接口输入函数,也就是处理用户空间发送到内核方向的数据
if (input)
  nlk_sk(sk)->data_ready = input;
// 将该sock插入HASH表
if (netlink_insert(sk, 0))
  goto out_sock_release;
// 设置该netlink sock的一些基本参数
nlk = nlk_sk(sk);
nlk->flags |= NETLINK_KERNEL_SOCKET;
netlink_table_grab();
nl_table[unit].groups = groups;
nl_table[unit].listeners = listeners;
nl_table[unit].module = module;
nl_table[unit].registered = 1;
netlink_table_ungrab();
return sk;
out_sock_release:
kfree(listeners);
sock_release(sock);
return NULL;
}
4. 结论
nfnetlink使用NETFILTER类型的netlink套接口,ip_queue都使用FIREWALL类型的netlink接口,理论上是可以区分的。但因为nfnetlink已经包含了ip_queue的功能并进行了扩展,使用推荐只使用nfnetlink即可。



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12313/showart_260387.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP