netfilter中early_drop()函数中的疑问(待解决)
时间:2010-09-17
来源:互联网
在netfilter的连接跟踪模块中,初始化一个新链接时需要调用nf_conntrack_alloc()函数,在这个函数中需要判断连接数是否超过连接数的最大值(atomic_read(&net->ct.count) > nf_conntrack_max),之后调用early_drop()函数。小弟现在对early_drop()函数存在些疑问,请大家指点帮忙!
复制代码
在这个函数中的问题是:
hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
510 hnnode) {
511 tmp = nf_ct_tuplehash_to_ctrack(h);
512 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
513 ct = tmp; //当test_bit()多次满足时,ct都会发生变化,为什么要这么做? 还有就是cnt只在初始时被初始化为0,之后一直是cnt++,这样累加到8之后就跳出循环,其作用?
514 cnt++;
515 }
if (cnt >= NF_CT_EVICTION_RANGE) //cnt++,这样累加到8之后就跳出循环,不明白其含义
break;
- 498 static noinline int early_drop(struct net *net, unsigned int hash)
- 499 {
- ...
- 507 rcu_read_lock();
- 508 for (i = 0; i < net->ct.htable_size; i++) {
- 509 hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
- 510 hnnode) {
- 511 tmp = nf_ct_tuplehash_to_ctrack(h);//为什么要这么做?
- 512 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
- 513 ct = tmp;
- 514 cnt++;
- 515 }
- 516
- 517 if (ct != NULL) {
- 518 if (likely(!nf_ct_is_dying(ct) &&
- 519 atomic_inc_not_zero(&ct->ct_general.use)))
- 520 break;
- 521 else
- 522 ct = NULL;
- 523 }
- 524
- 525 if (cnt >= NF_CT_EVICTION_RANGE)
- 526 break;
- 527
- 528 hash = (hash + 1) % net->ct.htable_size;
- 529 }
- 530 rcu_read_unlock();
- 531
- 532 if (!ct)
- 533 return dropped;
- 534
- 535 if (del_timer(&ct->timeout)) {
- 536 death_by_timeout((unsigned long)ct);
- 537 dropped = 1;
- 538 NF_CT_STAT_INC_ATOMIC(net, early_drop);
- 539 }
- 540 nf_ct_put(ct);//ct上的计数减1
- 541 return dropped;
- 542 }
hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
510 hnnode) {
511 tmp = nf_ct_tuplehash_to_ctrack(h);
512 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
513 ct = tmp; //当test_bit()多次满足时,ct都会发生变化,为什么要这么做? 还有就是cnt只在初始时被初始化为0,之后一直是cnt++,这样累加到8之后就跳出循环,其作用?
514 cnt++;
515 }
if (cnt >= NF_CT_EVICTION_RANGE) //cnt++,这样累加到8之后就跳出循环,不明白其含义
break;
作者: __dreamcatcher 发布时间: 2010-09-17
本帖最后由 独孤九贱 于 2010-09-17 10:09 编辑
复制代码
这段代码的核心功能是,当会话表满了过会,清除一些半连接,为新的会话腾出空间来。它的思路很简单,就是遍历当前hash槽位的链,找到一个半连接。
这段代码由一个双重循环组成,第一重循环:
hlist_nulls_for_each_entry_rcu()遍历指定hash的槽位。当它结束时,有两种结果:
a、通过test_bit,已经找到了,此时ct就是要找的值;
b、没有找到,ct为NULL,cnt是一个计数器,累计在“当前hash槽位的查找次数”;
如果找到到后,即会判断ct的合法性:
复制代码
结果合法,或者当cnt大于一个常数(NF_CT_EVICTION_RANGE),则退出外层循环。
复制代码
ct找到了退出循环是理所当然的事情。至于cnt超限,也要退出循环,这是和下一句代码紧密相连的:
复制代码
也就是说,如果没有查找,或者cnt没有超限,hash值会往复递增,注意,是“往复”,往复的含义是:
复制代码
而不是
复制代码
。也就是说,周而复始的在下一个hash链中再找空位……这样一来,引入cnt的理由就显而意见了:必须得有一个变量来决定,如果ct一直找不到,得有一种决定退出外层循环的条件,cnt就是这个条件。所以,它只有初值会0,后面就一直递加了。作者认为,当查找的次数超过NF_CT_EVICTION_RANGE次,就必须得退出来了,不能一直占着CPU不放。你也可以自定义这个常数,4,16,32(当然,从效率的角度来讲,它不能太大了)……可以多做一些实现来得到一个经验值。我个人倒是认为8是一个比较好的值。
再退一步讲,个人认为,即使hash值不是一个“周而复始的值”,也应该有也一变量来决定查找的次数,不能长时间地占着hash表来查找……
- rcu_read_lock();
- for (i = 0; i < nf_conntrack_htable_size; i++) {
- hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
- hnnode) {
- tmp = nf_ct_tuplehash_to_ctrack(h);
- if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
- ct = tmp;
- cnt++;
- }
-
- if (ct && unlikely(nf_ct_is_dying(ct) ||
- !atomic_inc_not_zero(&ct->ct_general.use)))
- ct = NULL;
- if (ct || cnt >= NF_CT_EVICTION_RANGE)
- break;
- hash = (hash + 1) % nf_conntrack_htable_size;
- }
- rcu_read_unlock();
这段代码由一个双重循环组成,第一重循环:
hlist_nulls_for_each_entry_rcu()遍历指定hash的槽位。当它结束时,有两种结果:
a、通过test_bit,已经找到了,此时ct就是要找的值;
b、没有找到,ct为NULL,cnt是一个计数器,累计在“当前hash槽位的查找次数”;
如果找到到后,即会判断ct的合法性:
- if (ct && unlikely(nf_ct_is_dying(ct) ||
- !atomic_inc_not_zero(&ct->ct_general.use)))
- ct = NULL;
- if (ct || cnt >= NF_CT_EVICTION_RANGE)
- break;
- hash = (hash + 1) % nf_conntrack_htable_size;
- hash = (hash + 1) % nf_conntrack_htable_size
- hash = hash + 1;
- if(hash > XXX) break;
再退一步讲,个人认为,即使hash值不是一个“周而复始的值”,也应该有也一变量来决定查找的次数,不能长时间地占着hash表来查找……
作者: 独孤九贱 发布时间: 2010-09-17
你内核版本是多少?我的内核没有cnt累加。
作者: Godbach: 发布时间: 2010-09-17
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28