%% # 纲要 > 主干纲要、Hint/线索/路标 # Q&A #### 已明确 #### 待明确 > 当下仍存有的疑惑 **❓<font color="#c0504d"> 有什么问题?</font>** 我的困惑在于,"路由转发" 这个功能,到底应该放在 "网络设备-路由器" 这一笔记中去说,还是放在这里说? - "网络设备-路由器" 作为一个独立笔记? √ - 里面引用 "**路由转发**" 功能即可。 - 结构: - 路由器的功能 - 两个核心功能: - **路由转发**:转发源主机与目的主机之间传送的数据 - **路由表**:路由表字段、**路由类型** - **路由器中的 ARP 表** - **路由选择**:根据路由选择协议,路由器之间彼此交换路由信息,**构建维护各自的路由表**。 - 附加功能: - NAT - DHCP - "路由转发" 同样作为一个独立笔记,介绍**网络层的 "转发" 功能**。 网络层,路由器的两个核心功能: - **路由转发** - **路由选择** %% # 路由转发 「**路由转发**」是**网络层(也即路由器)** 的两个核心功能之一,即 "**转发数据包**" 的功能。 每台路由器中都存储有一张 "**==路由表==**",**当路由器接收到了一个数据包**时,其根据网络包 **IP 头部**中的 "**目的 IP 地址**" 查询该 **路由表**,从而**确定将该数据包发往目的地址,需要从该路由器的哪一个接口转发出去**,实现 "**==转发==**" 过程。 ![[_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-71B3F6DFC31D8A97733C9D7FF14D51AB.png|578]] <br> ## 路由转发的工作流程 路由转发过程可分为下列步骤: 1. **数据包接收**——**链路层帧解封装,拆卸 MAC 头部** 2. **查询路由表** 3. **更新 TTL** 4. **数据包封装——链路层帧封装,封装 MAC 头部(可能涉及 ARP 查询)** > [!summary] 路由转发过程中的 "查表" > 在路由转发过程中: > > - 路由器首先以 "**目的 IP 地址**" 查询 "**路由表**",明确「**用以==转发==该数据包的接口**」 以及 「**==下一跳设备==的 IP 地址**」; > - 路由器进而以 "**下一跳设备 IP 地址**" 查询 "**ARP 表**",获取「**下一跳设备的 ==MAC 地址==**」,从而封装 MAC 头部,进行转发。 > ^gjiwo4 > [!example] 路由转发示例 > ![[_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-8DC104B39DB7AE38F15E9C2774BADE99.png|826]] <br> ### (1)数据包接收 路由器接收到数据包,进行 "**链路层帧解封装**",并根据**末尾 FCS 进行错误校验**,而后**检查 MAC 头部的==接收方 MAC 地址==**: - 若是发给自己的,则**去除 MAC 头部,将有效载荷放入缓冲区**; - 否则,**丢弃整个数据包**。 随后,路由器**检查 IP 数据包头部**: - (1)检查 **IP 头部校验和**,确认是否有损坏,若存在错误则丢弃。 - (2)检查 "**源 IP 地址与目的 IP 地址**" 是否位于同一网段(来自**路由器同一端口**),若是则丢弃数据包,不进行转发。 > [!caution] 路由器只会 "跨网段" 进行转发,**不会在同一子网内进行路由**。 > > 当路由器收到**来自同一子网的数据包**时,该数据包**本应==由源设备直接发送给目的设备==,而不应该经过路由器**。 > 因此数据包中的 "**==目的 MAC 地址==**" 并不匹配 **==路由器接口的 MAC 地址==**,故路由器会丢弃该数据包, > > 例如下图情况:该数据包可能是由集线器广播传来的。 > > ![img|360](_attachment/02-开发笔记/07-计算机网络/总结/网络上两台主机之间的通信过程.assets/IMG-网络上两台主机之间的通信过程-0BFFD4B992899BB4A9DF9A4E04D466E6.png) > > ^8ss3i1 <br> ### (2)查询路由表 路由器获取数据包**IP 头部**中的 "**目标 IP 地址**",用以与 "**路由表**" 中各项条目的 "**子网掩码**" 进行**按位与**, 检查所得的 "**网络前缀**" 是否与路由条目中的 "**目的网络地址**" 相匹配——此过程中,遵循 "**==最长前缀匹配原则==**"。 - 若存在 "**==有效匹配项==**" 或 "**==默认路由==**",则进入下一步,**重新封装 MAC 头部**,从对应的路由器接口转发出数据包。 - 否则,**丢弃该数据包**,通过 **ICMP 消息**返回 "**不可达消息**"。 ![image-20230910193159049|540](_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-9A0B52DDFFD8E255A52DA26B55624810.png) > [!info] **"==最长前缀匹配=="原则**:当查表存在多个匹配条目时,应选择 "**==网络前缀最长==**" 的一个条目(网络前缀越长,地址块越小,路由越具体) > > ![image-20230910225429957|576](_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-FA65FE36FFA9BE771565D5C550DA2CF6.png) > <br> ### (3)更新 TTL 明确匹配项后,路由器需要**更新 IP 头部中的 TTL 字段**,令其**值减 1**。 > [!info] TTL 字段表示 "Time to Live" 生存时间,包每经过一个路由器,该值就需要减 1,**减为 0 后就需要将包丢弃**。 <br> ### (4)数据包封装——重新封装 MAC 头部(可能涉及 APR 查询) 在转发出数据包之前,需要为其**重新封装 MAC 头部**,填入新的 "**==源 MAC 地址==**" 和 "**==目的 MAC 地址==**"。 - "**源 MAC 地址**" 即**该路由器将==用于转发该数据包的 "出接口" ==的 MAC 地址**。 - "**目的 MAC 地址**" 则根据**所匹配的路由表条目,有下列两种可能情况: | | 说明 | 所需新封装的目的 MAC 地址 | | ----------------- | ----------------------------------------------------------------------- | ----------------------------------------------- | | **直连路由** <br><br> | 数据包所需发往的 "**目的地址**" 属于**路由器某接口所在网段** <br>("**网关/下一跳地址**" 字段为空 或 "在链路上") | **"==数据包 IP 头部中目标 IP 地址=="所对应的设备接口的 MAC 地址** | | **非直连路由** | 数据包还需要**经过==下一跳==路由器转发** <br>("**网关/下一跳地址**" 字段非空)<br> | "**==网关/下一跳 IP 地址==**" 所对应的**下一跳路由器接口的 MAC 地址** | **路由器需要查询其内部的 ==ARP 表==,获取上述情况中 ==IP 地址对应的设备接口的 MAC 地址==**,以此作为 "**目的 MAC 地址**"。 若 ARP 表中不存在对应条目,则**路由器需要根据 ARP 协议==广播 ARP 请求==**,从而获取应答。 完成 MAC 头部的封装后,根据匹配的路由项,从**对应路由器接口转发出数据包**。 ## 路由转发示例 ![img|613](_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-FA6F2BB5443949C87FCD850115563EC9.jpeg) 概述: - HostA 要发送给 HostB,HostA 检查自身路由表发现不在同网段,于是发送给其默认网关即路由器 A 的 E0 端口。 - 路由器 A 的 E0 端口接收到后,检查自身路由表中也没有目标网段,因此发送给其默认网关,即路由器 B 的 E1 端口(即下一跳地址 10.1.1.2/8)。 - 路由器 B 的 E1 端口接收到后,检查自身路由表,目标地址的网段正好是其 E0 端口的直连网段,进而在获取 HostB 的 MAC 地址后,从 E0 端口发出,转发给 HostB。 HostA 向 HostB 发送数据包的通信过程: - (1)**HostA 查询自身的路由表,得知 HostB 不在同网段,因此 HostA 将数据包发给默认网关——即路由器 A 的 E0 端口。** 1. **HostA 通过 ARP 广播请求获取网关路由 A 的 E0 接口的 MAC 地址**,同时存入 HostA 的 ARP 缓存表。 2. 而后,HostA在链路层**将路由器 E0 接口的 MAC 地址封装成 "目的 MAC 地址"**,而 "**源 MAC 地址**" 是 HostA 自身网卡的 MAC 地址。 - (2)路由器 A 从 E0 接口收到数据帧,去掉链路层封装后,**检查路由表**未匹配,则根据**默认路由**发送给其**默认网关**,对应**下一跳地址为`10.1.1.2/8`**(即**路由器 B 的 E1 接口**),**出接口为路由器 A 的E1 口**。 1) 若路由器 A 的 APR 缓存表中没有下一跳地址 `10.1.1.2/8` 对应的 MAC 地址,则其向 E1 接口所在的 `10.1.1.0/8` 网段发生 ARP 广播请求,**获取路由器 B 的 E1 接口的 MAC 地址**。 2) 数据在路由器 A 的 E1 口重新封装,**源 MAC 地址是路由器 A 的 E1 接口的 MAC 地址**,封装的**目标 MAC 地址则是路由器 2 的 E1 接口的 MAC 地址**。 - (3)路由器 B 的 E1 端口接收到后,检查自身路由表,**目标地址的网段正好是其 E0 端口的直连网段**,进而在**获取 HostB 的 MAC 地址后**,**从 E0 端口发出**,转发给 HostB。 - 数据包在路由器 B 的 E0 接口再次封装,源 MAC 地址是路由器 B 的 E0 接口的 MAC 地址,目标 MAC 地址是 HostB 的 MAC 地址。 <br><br><br> # 路由表 **路由表**(Routing Table),也称 **==转发表==**(Forwarding Table)。 路由表中每一行称之 "**==路由条目==**",记录了将一个数据包**传输到特定网络**,所需经过的**下一跳地址**,以及**需要从当前路由器的哪个网络接口发出**等信息。 > [!NOTE] 电脑主机中也存在路由表 <br> ## 路由表字段说明 - **==目标地址==(Destination)**:**目的网络 IP 地址**,可以是一个**具体的主机地址**(子网掩码全 1)或**网络地址** - **==子网掩码==(Netmask)**:即**目的网络 IP 地址**对应的**子网掩码** - **==网关==**(**Gateway**):即 **"==下一跳地址== Next hop"**,表示**按该条路由转发**时,**网络包将被转发至的下一个 IP 地址**。 - **==接口==**(**Interface**):表示按该条路由转发时,**本设备用以发出网络包的==网络接口==(网卡)**,该值**指示了此接口的 IP 地址**。 - ==**跃点数**==(Metric):用于**衡量路由的“成本”或“优先级”** 的度量值。 - **==路由类型==**:指示该条路由条目的来源,例如**静态路由 Static**、**直连路由 Direct**、**动态路由**(RIP、OSPF、BGP 等)。 > [!NOTE] 网关/下一跳地址 > > 网络包在传输途中的**每一次 "转发"** 都称之为**一 "跳(hop)"**, > 因此 "**==下一跳地址==**(next hop)" 即是指**将该数据包送达目的地的途中,需要转发至的下一个路由器的 IP 地址**。 > > 若**路由条目的网关字段为空**,说明**目的 IP 地址**就在 "**本地链路上**"(即该路由为直连路由),直接查询其 MAC 地址,发出即可。 <br> ## 路由表条目类型 路由表中存在几种条目类型: - **==默认路由==**(Default Route):当数据包的**目的 IP 地址未能匹配其它任何路由条目**时,则按 "**默认路由**" 进行转发 - 特征: - **目的 IP 地址** 、**子网掩码字段均为全 0**,即 `0.0.0.0/0` - **网关**字段——为所配置的 "**==默认网关==**" 的 IP 地址。 - **==直连路由==**(Direclty Connected Routes):指向**路由器各个==接口所处网段的路由==**,表示该网段**直接连接于路由器接口**。 - 来源:由 **链路层协议发现**,当路由器接口接入一个网段,并**为该接口配置了该网段下的 IP 地址**时,路由器会自动生成直连路由。 - 特征: - **网关**字段显示为 "**==在链路上==**" 或者**与 "==接口==" 字段 IP 相同**——表示 **"与本设备某个接口"** 位于同一物理链路上,**从该接口转发出即可**。 - **==静态路由==**(Static Routes) - 来源:由网络管理员**手动配置的固定路由条目**,条目信息不会改变。 - **==动态路由==**(Dynamic Routes) - 来源:通过**动态路由协议(如 RIP、OSPF、BGP 等)自动生成并更新**的路由条目。 - **==主机路由==**(Host Routes):指向**一台具体主机**的路由。 - 特征:子网掩码为 `255.255.255.255`,即网络前缀位数为 `/32`。 - **==本地路由==**(Local Routes):指向**该台路由器某一个接口的地址**,用于**确保路由器能够接收到发往其本地IP地址的数据包** - 特征:如同主机路由,**子网掩码全 1**,而**目的 IP 地址为路由器某一接口的地址**。 - **==不可达路由==**(Unreachable Routes):用以**明确标识某个目标网络或主机不可到达**。 - 说明: - 该条目通常表示网络中断、无法到达目标网络或出于安全或管理目的而设置的访问限制。 - 当路由器遇到这些路由条目时,通常会**向源设备返回 ICMP 不可达消息**。 > [!example] 示例:直连路由 > > **设备自动产生直连路由的两个条件**:**接口接入一个网络**、**接口配上该网段内有效地址**。 > > 下图中的三个网段 `10.1.1.0/24`,`10.1.2.0/24`,`10.1.3.0/24` 通过**一台路由器**直接相连, > 因此**只需要配置好==路由器三个接口的 IP== 即可互相访问**,路由器表中将被自动添加 "**直连路由**"。 > > > ![image-20230910232148822|482](_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-CF431C14A1B1CB3B13E3A73762459AA1.png) > <br> ## 路由表示例 ### Windows 主机上的路由表 > [!NOTE] Windows下通过 `route print` 命令查看本机路由表 ![image-20231225184313104|704](_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-1FE86528F1E66CEE11009EC4214D860A.png) 上图路由表中依次包含了: - **默认路由** - **环回地址相关的路由**(网段`127.0.0.0/8`,涵盖地址`127.0.0.0`~`127.255.255.255`) - **源机的各个网络接口(网卡)所在网段的路由** - **多播路由**(多播地址所在网段`224.0.0.0/4`,涵盖地址`224.0.0.0`~`239.255.255.255`) - **广播路由**(`255.255.255.255`) ## 路由条目优先级 优先级值越小则路由越优。 ![image-20230910230235877|593](_attachment/02-开发笔记/07-计算机网络/网络层/路由转发.assets/IMG-路由转发-BA069DBC46F92F0FE810EDAA5677B467.png) ### 路由协议开销 直连及静态路由的 Cost 为 0。 通过动态路由协议学习到的 Cost 则根据实际情况而定。不同的路由协议计算 Cost 的方法不同。 <br><br><br> # 路由器中的 ARP 表 路由器上的 ARP 缓存表主要用于管理 **路由器与其直连设备** 之间的通信。 ARP 缓存表:存储网络接口上**直连设备**的 **IP 地址 -> MAC 地址** 的映射; ![[02-开发笔记/07-计算机网络/网络层/路由转发#^gjiwo4]] <br><br> # Buffer ## 闪念 > sudden idea ## 候选资料 > Read it later # ♾️参考资料 [18张图带你详解IP路由表七大要素:路由前缀、协议类型、优先级等](https://zhuanlan.zhihu.com/p/405894469) [网络原理-计算机网络详解-mac表、arp表、路由表](https://www.huaijiujia.com/2018/08/03/%E7%BD%91%E7%BB%9C%E5%8E%9F%E7%90%86-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E8%AF%A6%E8%A7%A3-mac%E8%A1%A8%E3%80%81arp%E8%A1%A8%E3%80%81%E8%B7%AF%E7%94%B1%E8%A1%A8/) # Footnotes