IP数据包的传输过程(路由)
IP协议的一个核心任务就是数据报的路由,即决定发送数据报到目标机器的路径。当一个IP数据报从数据链路层传输到IP模块的时候,IP模块的工作流程如下:
-
当IP模块接收到IP数据报,先对数据报的头部做CRC校验,确认无误之后就分析其头部的具体信息
-
如果该数据报设置了源站路由选项(头部选项字段中的松散源路由选择或严格源路由选择),则IP模块就调用数据报转发子模块来处理该数据报
-
IP模块会先查看头部信息中的目的IP地址,如果该数据报头部中的目的IP地址是本机的某个IP地址,或者是广播地址,即是发送给本机的,则根据头部信息中的协议字段具体交给上层的某个协议。如果不是本机的IP,则也调用数据报转发子模块来处理该数据报(就不往上层协议上发送了)
-
数据报转发模块将检测系统是否允许转发,如果不允许,IP模块就将数据报丢弃。
-
如果允许,就要计算IP数据报的下一跳节点。IP数据报应该发送给哪个下一跳的节点(路由或主机),以及经过哪个网卡来发送,就是IP的路由过程。这个计算过程的核心数据结构是路由表。这个表按照数据报的目标IP地址进行分类,同一类型的IP数据报将被发送到相同的下一跳节点。计算好了以后,放到IP输出队列中
-
IP输出队列中存放的是所有等待发送的IP数据报,其中除了需要转发的IP数据报以外,还包括了封装本机上层数据的IP数据报
-
重复上述过程,一直到发送到目的IP
如何判断这个数据包该发往哪里?
依靠每个节点内部维护一个路由表(注意是节点,包括主机和路由器)
-
路由表由route命令查看,路由表的内容信息如下
字段
|
含义
|
Destination
| 目标网络或主机 |
Gateway
|
网关地址,*表示目标地址和本机在同一个网络,不需要路由
|
Genmask
|
子网掩码
|
Flags
|
U:该路由项是有效的
H:该路由项的目标是一台主机
G:该路由项的目标是某个路由器的地址
D:该路由项是由重定向生成的
M:该路由项被重定向修改过
|
Metric
|
路由举例,即到达指定网络所需的中转数
|
Ref
|
路由项被引用的次数(Linux中未使用)
|
Use
|
该路由项被使用的次数
|
Iface
|
该路由项对于的输出网卡接口
|
-
如果目的IP命中了路由表,就直接转发即可,不用路由
-
路由表的default一行,是所谓的默认路由项,该项包含一个G标志,说明路由的下一跳目标是路由器,该地址就是本机所在子网的路由器的IP地址,当目的地址与路由表中其他节点不匹配时,就按默认路由条目规定的接口发送到下一跳地址
IP路由机制的过程分为下面三个步骤(按照IP地址分类)
-
查找路由表中和数据报的目的IP地址完全匹配的IP地址。如果找到,就是用该路由项
-
如果没找到,查找路由表中和数据报的目的IP地址具有相同网络ID的网络IP地址(即网段地址,如上图的192.168.224.0/24就是网段地址)。如果找到,就是用该路由项
-
选择默认路由项,这通常意味着下一跳的地址是路由器。
因此,对于我的机器而言,所有发送到IP地址为192.168.224.*的机器的IP数据包都可以直接发送到目标机器而不需要经过路由(发送到本机的数据报根本不会进入都计算下一跳地址这一步,在处理IP头部信息的时候如果匹配了IP就直接交给上层协议了),而所有其他访问请求都将通过默认路由项来转发。
如果要发送的数据包地址是192.168.224.3
-
跟每个子网掩码进行按位与,发现与最后一个192.168.224.0的目的网络地址相同,于是由接口ens33发送出去
-
由于192.168.224.0正是与ens33接口直接相连的网络,所以不用经过路由,直接发送到目标主机
如果要发送的数据包地址是200.10.1.2
-
跟每个子网掩码进行按位与,发现没有一个的目的网络地址相同,按默认路由条目,从ens33接口发出去,发往192.168.224.2路由器
-
由192.168.224.2路由器根据它的路由表决定下一跳地址
路由表更新
路由表必须能够更新,以反映网络连接的变化,这样IP模块才能准确、高效地转发数据报。
route命令可以修改路由表,这是属于静态的路由更新方式。对于大型的路由器,常常通过BGP(Border Gateway Protocol,边际网关协议)和RIP(Routing Information Protocol,路由信息协议)、OSPF等协议来发现路径,并更新自己的路由表,这种更新方式是动态的、自动的。
sudo route add -host 192.168.224.138 dev ens33
上面的命令表示添加主机192.168.224.138对应的路由项,设置以后会有H标志
可以在通过下面的命令来删除刚添加进去的路由项
sudo route del 192.168.224.138
IP转发
不是本机的IP数据报都交给数据报转发子模块来处理。路由器都能执行转发操作,而主机一般只发送和接收数据报,不支持转发。这意味着,如果IP数据报发送到主机,而主机不允许转发,那么主机就将丢弃该数据报。我们可以通过修改下面文件的内容来让主机支持转发。
这个文件中的值是0,改为1表示支持转发。
对于允许转发的节点(主机或路由器),数据报转发子模块将对数据报执行下面的操作
-
检查头部的TTL值。如果TTL的值已经是0,则丢弃该数据报
-
查看头部的严格源路由选择选项。如果该选项已被设置,则检测数据报的目标IP地址是否是本地的某个目标IP地址,如果不是,则发送一个ICMP源站选路失败报文给发送端
-
如果有必要,则给源端发送一个ICMP重定向报文,以告诉它一个更合理的下一跳路由器
-
将TTL值-1
-
处理IP头部选项
-
如果有必要,执行IP分片操作