jiufei19 发表于 2015-05-13 15:36

rt_fast_clean函数的疑问

本帖最后由 jiufei19 于 2015-05-13 15:39 编辑

内核版本2.6.23

static __inline__ int rt_fast_clean(struct rtable *rth)
{

    return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST) )
               && rth->fl.iif
               && rth->u.dst.rt_next;
}

根据该函数的注释,可以知道本地外出分组,单播转发分组都需要进行ARP查询以获得该路由下一跳的物理地址,所以代价都较大,这类路由缓存应尽量不能被删除,如下代码所示:
static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
{
    ...
    if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
         int err = arp_bind_neighbour(&rt->u.dst);
    ...
}

所以该函数首先对此路由rth的广播或组播标记进行检查,这一点可以理解,但是后面两个红色字体的判断条件就有点不甚清楚了,其中rth->fl.iif若为真,表示此路由代表一个转发路由,那么此时为啥就不进行ARP查询了呢,例如网络拓扑如下:

                                 +=======+
                                 +                +
------R1-------R2-----+   Net      +
                                 +                +
                                 +=======+

如果上述代码运行在R1上,则rth->fl.iif即为真,但是R2是R1的下一跳,而此rth路由假定仍然是一个组播路由,那么显然仍然需要执行ARP查询以获得R2的物理地址,则如果此时标记该路由可被回收,那岂不是错误了?

另外,rth->u.dst.rt_next为真,表示该rth不是此哈希表对应某个chain链的唯一条目,所以似乎表示若只有此唯一rth存在的话,则不能标记回收,对此逻辑,我有点不明白呢?难道说存在于此chain链上的所有条目都是等价的?

nswcfd 发表于 2015-05-13 17:23

注释里写的很清楚了,在某些条件下优先回收广播、多播的cache。
        /* Kill broadcast/multicast entries very aggresively, if they
           collide in hash table with more useful entries */

没看出来跟arp有什么关系?

能不能回收主要看引用计数,就是是单播的entry,有arp neighbour存在,如果其ref为0,在回收的时候也会有可能被选中的。
rt_may_expire有两个参数,tmo1和tmo2,tmo1<=tmo2,
如果entry不足够活跃(age>tmo2),则单播、多播一视同仁。
如果是一个较新的entry(age<tmo1),rt_fast_clean保证单播不会被选中,但是某些多播就有可能不幸命中(比如不是chain里的最后一个)。

jiufei19 发表于 2015-05-14 20:43

本帖最后由 jiufei19 于 2015-05-15 09:13 编辑

回复 2# nswcfd


    感谢nswcfd的解答,但是似乎你并没有针对我的问题进行解释。

    请看如下说明,该说明是我摘抄自《understanding linux network Internal》一书的相关章节内容 :

   527* Most routing cache entries are bound to the ARP cache entry of the
   528* route's next hop. This means that a routing cache entry requires
   529* either an existing ARP cache entry or a successful ARP lookup for
   530* the same next hop. In particular, the binding is done for output
   531* routes used to route locally generated packets (identified by a
   532* NULL ingress device identifier), and for unicast forwarding routes.
   533* In both cases, ARP is asked to resolve the next hop's L2 address.
   534* Forwarding to broadcast addresses, multicast addresses, and local
   535* host addresses does not require an ARP resolution because the addresses
   536* are resolved using other means.

这段文字很明确说明了为啥可以回收广播和组播路由缓存条目。因此你说没有看出来和arp有什么关系,是不正确的,的确这段代码和arp没有直接关系,但是我之前给出了和arp相关的代码,在那里是和arp有关的,因此最终也是和arp发生了关联,所以才有上面的原文说明

另外,我的问题是并不是不知道组播和广播被优先回收的原因,而是对后面两个&&的条件感到有点困惑,我知道肯定是我对路由的某些机制概念不清造成了这个问题,希望能有人继续解答我的疑问。
页: [1]
查看完整版本: rt_fast_clean函数的疑问