linux网络协议栈分析笔记11-路由1-路由缓存

本文深入探讨Linux网络协议栈中的路由机制,重点关注ip_route_input()函数及其在处理路由查找、缓存和多播输入时的角色。通过分析路由查找过程,包括rt_hash_table的使用和fib_lookup函数,解释了如何确定数据包是本地处理还是转发,并介绍了ip_local_deliver和ip_forward两个关键输入函数的选择依据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来吧,路由
路由是网络的核心,是linux网络协议栈的核心,我们找个入口进去看看

还记得在笔记5-IP层的处理1中ip_rcv_finish走到过一个岔口
->ip_rcv_finish()
     -> ip_route_input()  查找路由信息
     ->if (iph->ihl > 5 && ip_rcv_options(skb))  如果IP头部大于20字节,则表示IP头部包含IP选项,需要进行选项处理.
          goto drop;
     ->dst_input(skb);       dst_input实际上会调用skb->dst->input(skb).input函数会根据路由信息设置为合适的函数指针,
                                      如果是则递交到本地的 则为ip_local_deliver,若是转发则为ip_forward
两条路径:
1)  ip_local_deliver
2) ip_forward

是什么导致路径不同呢,我们看一看 ip_route_input()  干了啥

int  ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
             u8 tos, struct net_device *dev)
     ->net = dev_net(dev);
     ->hash =  rt_hash(daddr, saddr, iif, rt_genid(net));         计算hash值,注意hash因子    
     ->                                                                              既然hash值算出来了,我们就去找吧
     rcu_read_lock();
     for (rth = rcu_dereference( rt_hash_table[hash].chain ); rth;      
          rth = rcu_dereference(rth-> u.dst.rt_next )) {
          if (((rth->fl.fl4_dst ^ daddr) |                     异或 相同为0                        
               (rth->fl.fl4_src ^ saddr) |
               (rth->fl.iif ^ iif) |
               rth->fl.oif |
               (rth->fl.fl4_tos ^ tos)) == 0 &&
              rth->fl.mark == skb->mark &&
              net_eq(dev_net(rth->u.dst.dev), net) &&            判断路由和报文的struct net指针地址是否相同
              !rt_is_expired(rth)) {                                         路由项是否过期 
                            找到了
               dst_use(&rth->u.dst, jiffies);                             表示路由的使用时间
               RT_CACHE_STAT_INC(in_hit);
               rcu_read_unlock();
               skb_dst_set(skb, &rth->u.dst);                          设置到skb中去
               return 0;
          }
          RT_CACHE_STAT_INC(in_hlist_search);
     }
     rcu_read_unlock();
static struct  rt_hash_bucket      *rt_hash_table __read_mostly;

struct  rt_hash_bucket {
     struct  rtable     *chain;
};

struct  rtable
{
     union
     {
          struct dst_entry     dst;
     } u;
     /* Cache lookup keys */
     struct flowi        &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值