Chinaunix首页 | 论坛 | 博客
  • 博客访问: 41876
  • 博文数量: 9
  • 博客积分: 1557
  • 博客等级: 上尉
  • 技术积分: 124
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-06 17:06
文章分类
文章存档

2011年(2)

2010年(7)

我的朋友

分类: LINUX

2010-08-08 21:22:01

    前些天开始看netfilter的连接跟踪模块,看了2.4内核后再看2.6内核,发现差别很大,到现在为止还没有弄明白,一点点总结,今天先把这两天理解的东西写出来。我是在Hereltls兄大作指点下对2.6的conntrack进行学习的。参考文章为:http://blog.chinaunix.net/u3/110948/showart_2166654.html
    本文内容基于内核2.6.33.2
    作者:bbo

    conntrack的初始化过程如下,先从nf_conntrack_standalone_init()开始入手
static int __init nf_conntrack_standalone_init(void)
{
return register_pernet_subsys(&nf_conntrack_net_ops);
}

nf_conntrack_net_ops的定义为:
static struct pernet_operations nf_conntrack_net_ops = {
.init = nf_conntrack_net_init, /* 其调用了nf_conntrack_init接口 ,对于每一个 net都要调用这个接口的*/
.exit = nf_conntrack_net_exit,
};

nf_conntrack_init接口的实现如下,
466 static int nf_conntrack_net_init(struct net *net)
467 {
468     int ret;
469
470     ret = nf_conntrack_init(net);//调用了nf_conntrack_init_net()函数,完成对连接跟踪的一些参数的初始化
471     if (ret < 0)
472         goto out_init;
473     ret = nf_conntrack_standalone_init_proc(net);//暂时不清楚这函数和下一个函数的具体作用
474     if (ret < 0)
475         goto out_proc;
476     net->ct.sysctl_checksum = 1;
477     net->ct.sysctl_log_invalid = 0;
478     ret = nf_conntrack_standalone_init_sysctl(net);
479     if (ret < 0)
480         goto out_sysctl;
481     return 0;
482
483 out_sysctl:
484     nf_conntrack_standalone_fini_proc(net);
485 out_proc:
486     nf_conntrack_cleanup(net);
487 out_init:
488     return ret;
489 }

进入nf_conntrack_init函数,函数如下:
1375 int nf_conntrack_init(struct net *net)
1376 {
1377     int ret;
1378   
1379     if (net_eq(net, &init_net)) {
1380         ret = nf_conntrack_init_init_net();//初始化hashtable_size , nf_conntrack_max, proto_init(), helper_init()
1381         if (ret < 0)
1382             goto out_init_net;
1383     }
1384     ret = nf_conntrack_init_net(net);
1385     if (ret < 0)
1386         goto out_net;
1387
1388     if (net_eq(net, &init_net)) {
1389         /* For use by REJECT target */
1390         rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);//暂时不清楚其作用
1391         rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
1392
1393         /* Howto get NAT offsets */
1394         rcu_assign_pointer(nf_ct_nat_offset, NULL);
1395     }
1396     return 0;
1397
1398 out_net:
1399     if (net_eq(net, &init_net))
1400         nf_conntrack_cleanup_init_net();
1401 out_init_net:
1402     return ret;
1403 }

static int nf_conntrack_init_init_net(void)
1248 {
1249     int max_factor = 8;
1250     int ret;
1251
1252       //初始化hatables_size,不过本人暂时还没有来得及分析该算法
1254     if (!nf_conntrack_htable_size) {
1255         nf_conntrack_htable_size
1256             = (((totalram_pages << PAGE_SHIFT) / 16384)
1257                / sizeof(struct hlist_head));
1258         if (totalram_pages > (1024 * 1024 * 1024 / PAGE_SIZE))
1259             nf_conntrack_htable_size = 16384;
1260         if (nf_conntrack_htable_size < 32)
1261             nf_conntrack_htable_size = 32;
1262
            //默认情况下将max_factor设为4,但当用户给出htable_size的值时则用旧版本中的值8
1267         max_factor = 4;
1268     }
1269     nf_conntrack_max = max_factor * nf_conntrack_htable_size;

1275     ret = nf_conntrack_proto_init();//初始化proto
1278
1279     ret = nf_conntrack_helper_init();//初始化helper
1282
1287     atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
1288     /*  - and look it like as a confirmed connection */
1289     set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
1290
1291     return 0;
1292
1293 err_helper:
1294     nf_conntrack_proto_fini();
1295 err_proto:
1296     return ret;
1297 }

1305 static int nf_conntrack_init_net(struct net *net)
1306 {
1307     int ret;
1308
1309     atomic_set(&net->ct.count, 0);
1310     INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, UNCONFIRMED_NULLS_VAL);
1311     INIT_HLIST_NULLS_HEAD(&net->ct.dying, DYING_NULLS_VAL);
1312     net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
1317
1324     net->ct.nf_conntrack_cachep = kmem_cache_create(net->ct.slabname,
1325                             sizeof(struct nf_conn), 0,
1326                             SLAB_DESTROY_BY_RCU, NULL);
1332
1333     net->ct.htable_size = nf_conntrack_htable_size;
1334     net->ct.hash = nf_ct_alloc_hashtable(&net->ct.htable_size,
1335                          &net->ct.hash_vmalloc, 1);

1341     ret = nf_conntrack_expect_init(net);//初始化expect链表

1344     ret = nf_conntrack_acct_init(net);//初始化acct扩展模块

1347     ret = nf_conntrack_ecache_init(net);
1350
1351     return 0;
1352
1353 err_ecache:
1354     nf_conntrack_acct_fini(net);
1355 err_acct:
1356     nf_conntrack_expect_fini(net);
1357 err_expect:
1358     nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1359                  net->ct.htable_size);
1360 err_hash:
1361     kmem_cache_destroy(net->ct.nf_conntrack_cachep);
1362 err_cache:
1363     kfree(net->ct.slabname);
1364 err_slabname:
1365     free_percpu(net->ct.stat);
1366 err_stat:
1367     return ret;
1368 }
    这是第一次正点的写东西,虽然这次基本没有自己的内容。这次只是对初始化的框架进行了总结,并未对具体内容做太多分析,主要是由于鄙人刚开始学,能力暂时有限,望谅解,我会对其进行慢慢改正和补充。给自己打打气,争取早日把netfilter/iptables拿下!加油!
阅读(1714) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~