linux路由实现分析Series—(1)
引子:记得大学快毕业时,我想考CCNP,感觉有了那东西应该很好找工作的。现在想想很好笑的。CCNA,CCNP,CCNE这些东西,仔细想一想都是CISCO公司的产品,你即使学通了,也只说明你对CISCO产品应用的好。如果你了解了网络产品的实现,应用这些东西,不是小儿科么。对Hitachi和SISCO的Router的OS的应用比较,可以说,基本使用方法没什么大的区别。使用界面都是CLI .它们只是在一些自己的产品上追加了些特有的功能。本系列文章详细介绍linux路由的实现.
路由器, 路由与路由表的定义
路由器(Router):一台配备有多个网络接口卡(Network Interface Card ——NIC),
利用网络知识正确转发ingress流量的网络设备。
路由(Route):决定一个ingress 数据包应当送给本机还是转发
路由表(routing table):路由所需要的信息,都存储在一个被称为转发信息库(Forwarding Information Base——FIB)的
数据库中,它通常被简称为路由表(routing table)。
linux路由命令的格式如下,有些参数被我省略了。
route add [-net|-host] target [netmask Nm] [gw Gw] [[dev] If]
例如:
route add -net 113.20.0.0 netmask 255.255.0.0 gw 100.150.0.125 eth2
目标为113.20.0.0/16的数据包都将利用eth2这个NIC设备,发送到ip 地址为100.150.0.125的gateway上。
所以一条路由命令,基本包括目标网络,目标网络的网络掩码,下一跳地址,出口设备。
那么linux 是如何保存这些数据呢,最简单的就是把以上一条路由项以一跳数据形势保存起来。
当路由项很多时,执行效率就会很低下了。因为路由查找会很慢的。
而linux 是把以上路由拆分,分别保存起来。这样路由项就可以共享一些数据了。
路由表
路由在网络栈中处于核心地位以及路由表的容量可能很大,因而设计出高效的路由表来加快各种操作,特别是路由查找操作就很重要。下面介绍Linux是如何来组织路由表,如何利用各种hash表来访问路由表里的各个数据结构,每一种hash表都是为了用不同方式,不同条件的查找而专门设计的。
路由表的整体关系图如下
为了能够针对各种各样的操作而快速搜索到相关信息,Linux中采用了将一条路由信息,分割成几部分,分别链接到不同的hash表里。主要的hash表如下:
① 以网络掩码长度为索引的hash表
② 搜索fib_info结构的hash表
③ 以网络设备为索引,搜索路由项下一跳的hash表
④ 以本地首选源ip地址为索引,搜索fib_info结构的hash表
⑤ 搜索fib_node结构的hash表
路由表是由fib_table数据结构来描述。路由表的定义如下
- struct fib_table {
- struct hlist_node tb_hlist;
- u32 tb_id; //路由表标识
- int tb_default;
- unsigned char tb_data[0];
- };
- -----------