QUOTE:原帖由 springwind426 于 2008-6-26 16:24 发表

我的理解:
1、关于hash的入口点,是 srcip:srcport:dstip:dstport的组合,经过特殊的算法,得到一个值,如果srcip,srcport,dstip,dstport中某个值没有指定,就使用0(端口)或者0.0.0.0(IP)
2、信元, ...
QUOTE:1、hash入口:
if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DIP)
dst.dst_ip = skb->nh.iph->daddr;
if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SIP)
dst.src_ip = skb->nh.iph->saddr;
if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT
||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) {
u_int16_t ports[2];
if (get_ports(skb, offset, ports)) {
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
*hotdrop = 1;
return 0;
}
if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT)
dst.src_port = ports[0];
if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT)
dst.dst_port = ports[1];
}
复制代码
因为主要讨论令牌桶算法,没有讨论hash表。这个是由用户指定的,可以是来源地址/目的地址/来源端口或目的端口,或者是它们的组合,hash算法,是内核通用的jhash_3words() 。
QUOTE:2、信元,它经过换算,折算成每个jiffy(计算机时钟的最小计时单位)折合多少信元
估计你说的信元,就是我说的令牌吧。
QUOTE:3、信元分配:
不是周期性的刷新,而是每个数据包到来的时候,进行计算,分配的方式是按照从上个数据包到这个数据包之间的时间间隔来分配信元,如果超过最大信元,就把超过部分溢出。
我仍然保留我的看法,的确是周期性刷新。因为:
A、这是TBF本身要求令牌的产生应该在^T时间(三角形符号打不出来,用^代替)周期内。
B、从代码来看:
static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
{
dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
* CREDITS_PER_JIFFY;
if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
dh->rateinfo.credit = dh->rateinfo.credit_cap;
}
复制代码
虽然表面上rateinfo_recalc是每个包进来都会被调用,但是事实上,令牌的递增credit +=N是有条件也,也就是在时间周期jiffy变化后才会变,否则它是0,也就是说,在“同一个时间周期内,并不产生新的令牌。”
QUOTE:4、时钟的作用,目的是减少hash表的容量,因为有可能某个入口点有很长时间没有数据包了,因此需要把这个入口点从hash表中删除,以减少查找的时间(hash表越大,查找时间越长,因为它采用的是从前向后遍历的方式。)
hash表的节点是需要一些定时器来处理回收,超时等等东东,没有讨论hash表,因为它跟内核其它的hash表没有区别。呵呵。
欢迎讨论。
5、你5楼的回复没有看懂,user2credits()在计算的时候的确是有一个防止溢出的计算。但偶没有明白你的意思。
[ 本帖最后由 独孤九贱 于 2008-6-27 09:47 编辑 ]