计算机网络:网络层 - IP数据报的转发
基于终点转发
路由器转发报文时,是通过报文中的目的地址
字段来转发的,也即是说路由器只知道终点的IP地址
,根据这个地址来进行转发,这叫做基于终点转发
。
路由器拿到报文后,决定把这个报文向哪一个路由器转发,下一个收到报文的路由器也执行一样的操作,通过一个一个路由器的接力传送,直到分组的到达目的网络。
路由器内部存储了很多条目,每个条目代表一个网络,网络通常以
网络地址/前缀长度
或者是网络地址 网络掩码
的形式
接下来我就用一个案例,来介绍路由器是如何决定把数据报转发到下一个路由器的:
源主机H1
想要把数据报传输给主机H2
,源地址
为128.1.2.193
,目的地址
为128.1.1.132
。
第一步:先检测
目的主机
与源主机
是否在同一个网络中
这个步骤是由源主机
自己完成的,如果在同一个网络中,那么直接在网络内部通信即可,无需路由器。
整个网络N1
的网络前缀为128.1.2.192/26
,子网掩码为255.255.255.192
。
源主机H1
处于N1
中,将目的地址与源地址的子网掩码进行按位与,看结果是否与源地址所处的网络N1
相同,从而判断目的主机与源主机是否在一个网络:
cpp
128. 1. 1.132 //目的地址
255.255.255.192 // 子网掩码
----------------
128. 1. 1.128 // 结果
最终结果为128.1.1.128
,与N1
的网络前缀128..1.2.192
不同,所以不处于一个网络,此时要交给路由器转发。
假设现在把报文已经递交给了路由器R1
,R1
的转发表如下:
第二步:当路由器转发报文时,根据自己的路由表,一一进行网络前缀匹配
从上往下,首先拿目的地址128.1.1.132
与128.1.2.64/26
进行前缀匹配,/26
的子网掩码为255.255.255.192
,进行计算:
cpp
128. 1. 1.132 //目的地址
255.255.255.192 // 子网掩码
----------------
128. 1. 1.128 // 结果
结果128.1.1.128
与128.1.2.64/26
不匹配,说明不是通过该路由。
随后拿第二条进行匹配,网络前缀为128.1.2.128/26
,子网掩码为255.255.255.192
,进行计算:
cpp
128. 1. 1.132 //目的地址
255.255.255.192 // 子网掩码
----------------
128. 1. 1.128 // 结果
结果128.1.1.128
与1288.1.1.128/26
匹配,说明可以通过该路由转发,于是通过该路由通过该接口把数据报转发出去。
如果下一个节点还是路由器,则重复以上过程,如果已经到达指定网络,那么路由器的任务就结束了。
最长前缀匹配
有的时候,路由器内部可能会有多个条目匹配,此时要选择网络前缀最长的接口进行转发。
某个路由器转发数据报时,目的地址为206.0.71.130
,该路由器的路由表如下:
cpp
206.0.68.0/22 R1
206.0.71.128/25 R2
先匹配第一条,网络前缀206.0.68.0/22
,子网掩码为255.255.252.0
,将目的地址
与子网掩码
进行按位与:
cpp
206. 0. 71.130 //目的地址
255.255.252. 0 // 子网掩码
----------------
206. 0. 68. 0 // 结果
结果206.0.68.0
和网络前缀206.0.68.0/22
匹配,说明可以通过路由器R1
转发。
随后再匹配第二条,网络前缀206.0.71.128/25
,子网掩码为255.255.255.128
,将目的地址
与子网掩码
进行按位与:
cpp
206. 0. 71.130 //目的地址
255.255.252.128 // 子网掩码
----------------
206. 0. 68.128 // 结果
结果206.0.68.128
与网络前缀206.0.71.128/25
也匹配,可以通过路由器R2
转发。
此时既可以通过R1
也可以通过R2
,但是R1
的网络前缀长度为/22
,而R2
的网络前缀长度为/25
,所以选择R2
进行转发,这就是最长前缀匹配
。
通过匹配更长的网络,可以确保数据包被转发到最具体的网络,而不是更广泛的网络。
为了提高最长前缀匹配的效率,路由器会对条目排序,把前缀长的条目放在前面
这样进行匹配时,只需要从上往下匹配即可,第一个匹配的网络一定是最长的,无需在往下匹配了。
二叉线索树路由表
当转发表的项目数很大时,为了进行更加有效的查找,通常是将无分类编址的转发表存放在一种层次的数据结构中,然后自上而下地按层次进行查找。这里最常用的就是二叉线索树(binary trie)
,它是一种特殊结构的树。
IP 地址中从左到右的比特值决定了从根节点逐层向下延伸的路径,而二叉线索中的各个路径就代表转发表中存放的各个网络前缀
。
为了简化二叉线索的结构,用每条路由中网络前缀
的唯一前缀
来构造二叉线索。在进行查找时,只要和唯一前缀
相匹配,就表示和这条路由相匹配。
比如下图:
对于第一条地址,其网络前缀为01000110.0.0.0
,现在确定该网络前缀的唯一前缀:
- 第一位
0
:该路由表中有其它的地址第一位也是0
,不是唯一前缀 - 前两位
01
:该路由表中有其它的地址前两位也是01
,不是唯一前缀 - 前三位
010
:该路由表中有其它的地址前三位也是010
,不是唯一前缀 - 前四位
0100
:该路由表中没有其它的地址前四位是0100
,是唯一前缀
因此第一个条目的唯一前缀就是0100
,利用这个前缀构建节点,也就是图中的蓝色路径。
要将二叉线索用于转发表中,还必须使二叉线索中的每一个叶节点包含对应的网络前缀
和子网掩码
。当搜索到一个叶节点时,就必须将目的 IP 地址
和该叶节点的子网掩码
进行按位与运算,看结果是否与对应的网络前缀相匹配。若匹配,就按下一跳的接口转发该分组;否则,就丢弃该分组。
特殊路由
在路由表中,还存在两种特殊的路由:特定主机路由
和默认路由
特定主机路由
特定主机路由是指针对特定 IP 地址
的路由条目。它明确指定了到达该主机的路径,包括下一跳路由器和网络接口。这种路由的子网掩码为255.255.255.255
相比于一般的路由,特定主机路由
的优先级是最高的,这可以从最长前缀匹配
的角度理解,其前缀长度为/32
应用场景
- 当需要与特定主机建立直接连接时,例如访问特定服务器或设备。
- 当需要优化特定主机的网络性能时,例如将数据包直接转发到目标主机,避免经过其他路由器。
默认路由
默认路由是指当路由器无法找到与目的 IP 地址
匹配的路由时,会使用的路由条目。它通常指向一个默认网关,负责将数据包转发到其他网络。
该路由的网络前缀为0.0.0.0/0
,一般是最后一个匹配的路由,只有当前所有的条目都匹配不上,才会走这个条目。
IP多播
如图所示:
现在一个服务器要同时给90
台主机提供相同的服务,如果采用单播的方式,那么同样一份数据就要拷贝90
份发送出去,这会造成大量资源浪费,对此我们会采用IP多播
的方式。
如图所示:
在服务器发送数据报时,只发送一份,随后路由器根据多播,将其复制多分发送给指定的路由器,后面的路由器也重复该过程。直到该数据报传输到一个局域网内部。
IP 多播
所传送的分组需要使用多播 IP 地址
,也就是 D 类IP 地址
。多播地址只能用于目的地址,而不能用于源地址。
IP 多播
可以分为两种,一种是只在本局域网上进行硬件多播,另一种则是在互联网的范围进行多播。在互联网上进行多播的最后阶段,还是要把多播数据报在局域网上用硬件多播交付多播组的所有成员。