网络[四补]:路由表补充(2)

而当在路由缓存中没有查找到缓存项时,会进行路由表查询,还是以IP层协议中的代码段为例[net/ipv4/route.c],fib_lookup()会在MAIN和LOCAL两张表中进行查找。

if ((err = fib_lookup(net, &fl, &res)) != 0) {       if (!IN_DEV_FORWARD(in_dev))           goto e_hostunreach;       goto no_route;   }  

    如果主机配置成了支持转发,则无论在路由表中找到与否,都会生成这次查询的一个缓存,包括源IP、目的IP、接收的网卡,插入路由缓存中:

hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));   err = rt_intern_hash(hash, rth, NULL, skb, fl.iif);  

      不同的是,如果在路由表中查询失败,即数据包不是发往本机,也不能被本机转发,则会设置插入路由缓存的缓存项u.dst.input=ip_error,而u.dst.input即为IP层处理完后向上传递的函数,而ip_error()会丢弃数据包,被发送相应的ICMP错误报文。不在路由表中的路由项也要插入路由缓存,这可以看作路由学习功能,下次就可以直接在路由缓存中找到。

rth->u.dst.input= ip_error;   rth->u.dst.error= -err;   rth->rt_flags    &= ~RTCF_LOCAL;  

      但如果主机不支持转发,即没有路由功能,则只有在找到时才会添加路由缓存项,都不会生成路由缓存项。这是因为在LOCAL表中没有找到,表明数据包不是发往本机的,此时缓存这样的路由项对于主机的数据包传输没有一点意义。它只需要知道哪些数据包是发给它的,其余的一律不管!

       路由查询整合起来,就是由ip_route_input()引入,然后依次进行路由缓存和路由表查询,并对路由缓存进行更新。路由缓存在每个数据包到来时都可能发生更新,但路由表则不一样,只能通过RTM机制更新,LOCAL表是在网卡配置时更新的,MAIN表则是由人工插入的(inet_rtm_newroute)。
       ip_route_input()
         - 路由缓存查询
         - 路由表查询:ip_route_input_slow() -> fib_lookup()

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypjjf.html