dst_entry,neighbour,和hh_cache之间的关系

由ip_finish_output2处理.

/*
 *ip_finish_output2:把做为参数传进来的skb传到链路层.此时的skb没有L2 header,但是需要的路由信息已经知道.
 * 如果可以找到dst_entry对应的hh_cache.则把路由需要的L2头加到skb中.然后调用相关函数hh->hh_output.
 * 如果找不到对应的hh_cache,则需要通过其nerghbour找到下一跳地址,交由相应的处理函数dst->neighbour->output.
 */

static inline int ip_finish_output2( struct sk_buff * skb)
{
    /*dst_entry可以理解为路由表的缓冲区,每次主机发送数据时询问路由表后,都会将记录记在一个cache内.*/
    /*dst中有能指向其neighbour的指针,通过neighbour可以找到下一跳地址*/
    struct dst_entry * dst = skb- > dst;
    /*hh_cache中存储的是链路头的一些相关信息,可以加快数据包的传输(因为有些情况下不用查看路由表,直接到此缓冲区查看).*/
    struct hh_cache * hh = dst- > hh;

# ifdef CONFIG_NETFILTER_DEBUG
    nf_debug_ip_finish_output2( skb) ;
# endif /*CONFIG_NETFILTER_DEBUG*/
    
    if ( hh) {
        read_lock_bh( & hh- > hh_lock) ;
          memcpy ( skb- > data - 16, hh- > hh_data, 16) ;
        read_unlock_bh( & hh- > hh_lock) ;
     skb_push( skb, hh- > hh_len) ;
        return hh- > hh_output( skb) ;
    } else if ( dst- > neighbour)
        return dst- > neighbour- > output( skb) ;

    if ( net_ratelimit( ) )
        printk( KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!/n" ) ;
    kfree_skb( skb) ;
    return - EINVAL;
}

要想看明白此函数,需要先知道dst_entry,neighbour,和hh_cache之间的关系.如下图:

(转)2.4内核数据报的接收过程学习笔记---网络层 - wangdq - Wangdq Blog 500)this.width=500;" width="500" border="0">

det_entry为路由表的cache,也就是说每次发送数据包询问完路由表后,都会将结果保存在这个cache中, 以便在以后的发送中相同的操作可以快速执行而不必每次都询问路由表.由于数据包传送到ip_finish_output2后,还没有L2头,所以需要加上 相应的链路层头.知道了这三者的关系,再由上面的代码可知,如果dst->hh非空,说明以前传输过相似的数据包,可以直接到相应的 hh_cache中去找对应的L2头,然后加到skb中,调用hh->hh_output将数据包发送出去.

如果没有相应的hh指针,则说明去往的目的地以前没有去过,这时候dst_cache中没有相关记录信息,不能根据以往的经验快速发送.这时候就要将数据包传送到Neighbouring Subsystem去查找相关信息.

由于Neighbouring Subsystem也是一个很大的子系统,代码量也很多,因为也不做为此篇笔记的研究重点,在此只知道个大概过程即可.在以后研究 Neighbouring Subsystem源代码的时候,再把相关总结贴上来.在此,我们只需要知道,dst->neighbour->output会通过arp来 解决ip地址和mac地址对应的问题,然后经过一系列处理,最后会调用dev_queue_xmit.dev_queue_xmit之后的事情我们已经知 道了.ok,这条道路已经打通了.
 
如果dst->hh非空,即以前发送过目的地址为此skb目的地址的情况,则直接到cache中去查找相关L2头信息,加到skb上,然后调用hh->hh_output发送出去,此函数初始化为dev_queue_xmit.这样,这条道路也通了.
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值