linux路由相关函数,Linux 路由 学习笔记 之十一 输入、输出路由查找相关的接口函数...

本文详细分析了Linux内核中路由功能模块的输入和输出路由查找接口,包括`ip_route_input`和`ip_route_output_key`函数。这两个函数分别处理输入数据包和输出数据包的路由查找,涉及路由缓存、策略规则、路由项的查找。在输入路由查找中,当路由缓存未命中时,会调用`ip_route_input_slow`进行路由表查找和路由缓存创建。输出路由查找同样涉及类似流程,通过`ip_route_output_slow`实现。本文旨在揭示这些模块如何协同工作,为路由模块学习提供综合理解。
摘要由CSDN通过智能技术生成

对于路由功能模块的学习,也已经很长时间了。关于路由项的创建与查找、策略规则相关的创建与查找、路由缓存的创建与查找,都是分开来分析的,没有说明这些模块是如何配合使用的,以及模块之间的联系。本节就分析一下这几个模块是如何联系在一起的,也作为路由模块学习的小结。

对于协议栈而言,内核中的路由功能模块主要就是提供路由查找功能,而查找功能就集合了策略规则、路由项、路由缓存的查找,而路由功能模块的查找接口对外是统一的。

目前而言,对于输入数据包与输出数据包,路由功能模块提供了两个接口函数,即ip_route_input和ip_route_output_key。下面就分两部分分析一下这两个函数。

1.1 输入路由查找相关的接口

输入路由查找相关的接口有ip_route_input,下面分析一下这个函数。

该函数主要对输入数据包进行路由查找(即netif_receive_skb->ip_rcv->ip_rcv_finish).

对于输入的数据包,会有三个输出结果:

1.本机接收

2.本机转发

3.丢掉数据包

这个函数根据不同的查找结果,会有两个分支:

1.当路由缓存中已存在该数据包对应的路由,则通过查找相应的路由缓存表即可

(rt_hash_table[hash].chain)

2.当路由缓存中不存在该数据包对应的路由时,则通过调用ip_route_input_slow,通过查找路由表,来决定数据包的命运。

这个函数就综合了策略规则的查找、路由项的查找、路由缓存的查找、路由缓存的生成、路由缓存与arp邻居项的绑定。

*/

int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,

u8 tos, struct net_device *dev)

{

struct rtable * rth;

unsigned hash;

int iif = dev->ifindex;

tos &= IPTOS_RT_MASK;

hash = rt_hash(daddr, saddr, iif);

/*加上读锁*/

rcu_read_lock();

/*在hash数组rt_hash_table中,根据hash值找到相应的hash链表,遍历链表中的所用rtable成员

,查找符合条件的路由缓存,若找到的则返回0,并将skb->dst指向该路由缓存。

ip_rcv_finish就会调用skb->dst->input,对数据包进行处理,而在创建路由缓存时,已经将

dst->input的值设置为ip_local_deliver或者ip_forward,根据skb->dst->input函数,就决定了数据包是

发送给本机上层协议进行处理还是转发出去。

*/

for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;

rth = rcu_dereference(rth->u.dst.rt_next)) {

if (rth->fl.fl4_dst == daddr &&

rth->fl.fl4_src == saddr &&

rth->fl.iif == iif &&

rth->fl.oif == 0 &&

rth->fl.mark == skb->mark &&

rth->fl.fl4_tos == tos) {

rth->u.dst.lastuse = jiffies;

dst_hold(&rth->u.dst);

rth->u.dst.__use++;

RT_CACHE_STAT_INC(in_hit);

rcu_read_unlock();

skb->dst = (struct dst_entry*)rth;

return 0;

}

RT_CACHE_STAT_INC(in_hlist_search);

}

rcu_read_unlock();

/* Multicast recognition logic is moved from route cache to here.

The problem was that too many Ethernet cards have broken/missing

hardware multicast filters :-( As result the host on multicasting

network acquires a lot of useless route cache entries, sort of

SDR messages from all the world. Now we try to get rid of them.

Really, provided software IP multicast filter is organized

reasonably (at least, hashed), it does not result in a slowdown

comparing with route cache reject entries.

Note, that multicast routers are not affected, because

route cache entry is created eventually.

*/

/*路由缓存没有命中,且目的地址为组播地址时,则进入组播处理流程*/

if (MULTICAST(daddr)) {

struct in_device *in_dev;

rcu_read_lock();

if ((in_dev = __in_dev_get_rcu(dev)) != NULL) {

int our = ip_check_mc(in_dev, daddr, saddr,

skb->nh.iph->protocol);

if (our

#ifdef CONFIG_IP_MROUTE

|| (!LOCAL_MCAST(daddr) && IN_DEV_MFORWARD(in_dev))

#endif

) {

rcu_read_unlock();

return ip_route_input_mc(skb, daddr, saddr,

tos, dev, our);

}

}

rcu_read_unlock();

return -EINVAL;

}

/*当路由缓存查找没有命中,且目的地址不是组播地址时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值