第13章 IP选路
所属:TCP/IP详解 卷2:实现 来源:TCP/IP详解 卷2:实现
本章描述内核中IP选路的实现,包括选路表结构、选路算法、IP转发、ICMP重定向等。
13.1 引言
选路的作用
选路(Routing):
- 决定分组从哪个接口发出去
- 决定下一跳是谁
- IP转发的核心功能
- 所有IP分组都要经过选路
选路是IP层的核心功能之一。
本章讨论的内容
本章讨论的内容:
- 选路表结构(rtentry)
- 选路算法
- IP转发(ip_forward)
- ICMP重定向
- 选路表的维护
本章讨论内核中的选路实现。
13.2 选路表
选路表的作用
选路表的作用:
- 存储路由信息
- 查找目的地址对应的路由
- 确定输出接口和下一跳
- 支持各种类型的路由
选路表是选路的基础。
路由类型
按目的类型分:
| 类型 | 说明 | 例子 |
|---|---|---|
| 主机路由 | 单个IP地址 | 192.168.1.100/32 |
| 网络路由 | 整个网络 | 192.168.1.0/24 |
| 默认路由 | 兜底路由 | 0.0.0.0/0 |
按下一跳分:
- 直连路由:目的在直连网络上,下一跳就是目的
- 间接路由:需要经过路由器,下一跳是路由器
不同类型的路由,优先级不同。
选路原则
选路的基本原则:
-
最长匹配
- 找最具体的路由
- 前缀越长越优先
- 主机路由 > 网络路由 > 默认路由
-
管理距离
- 不同来源的路由优先级不同
- 直连 > 静态 > 动态
-
度量值
- 同类型路由比较度量
- 度量越小越优先
最长匹配是最基本的原则。
13.3 rtentry结构
路由项结构
每个路由项是一个rtentry结构:
struct rtentry {
u_long rt_hash; /* 哈希值 */
struct rtentry *rt_next; /* 哈希链表 */
struct sockaddr rt_dst; /* 目的地址 */
struct sockaddr rt_gateway; /* 网关(下一跳) */
short rt_flags; /* 标志 */
short rt_refcnt; /* 引用计数 */
u_long rt_use; /* 使用计数 */
struct ifnet *rt_ifp; /* 输出接口 */
struct sockaddr rt_genmask; /* 网络掩码 */
/* ... 其他字段 ... */
};字段说明
| 字段 | 说明 |
|---|---|
| rt_hash | 哈希值,用于哈希表 |
| rt_next | 哈希链表指针 |
| rt_dst | 目的地址 |
| rt_gateway | 网关(下一跳)地址 |
| rt_flags | 路由标志 |
| rt_refcnt | 引用计数 |
| rt_use | 使用计数(统计用) |
| rt_ifp | 输出接口指针 |
| rt_genmask | 网络掩码 |
rtentry是选路表的基本单元。
rt_flags标志
常见的路由标志:
| 标志 | 说明 |
|---|---|
| RTF_UP | 路由可用 |
| RTF_GATEWAY | 网关路由(间接路由) |
| RTF_HOST | 主机路由 |
| RTF_REJECT | 拒绝路由(丢弃) |
| RTF_DYNAMIC | 动态创建(重定向) |
| RTF_MODIFIED | 被修改过(重定向) |
标志描述路由的属性。
13.4 选路算法
哈希表组织
选路表的组织:
- 用哈希表组织
- 目的地址的哈希值作为索引
- 冲突用链表解决
- 提高查找效率
哈希表加快查找速度。
选路查找过程
查找路由的步骤:
-
计算哈希值
- 根据目的地址计算哈希
- 找到对应的哈希桶
-
遍历链表
- 遍历哈希桶中的链表
- 比较目的地址和掩码
- 记录匹配的路由
-
找最匹配的
- 最长前缀匹配
- 主机路由优先
- 返回最佳匹配
最长匹配是核心原则。
最长匹配
最长匹配(Longest Prefix Match):
- 前缀越长,路由越具体
- 具体的路由优先
- 例如:
- 192.168.1.100/32(主机路由)
- 192.168.1.0/24(网络路由)
- 0.0.0.0/0(默认路由)
- 目的192.168.1.100,匹配第一个
找最具体的路由。
13.5 IP转发
ip_forward函数
IP转发(ip_forward):
- 目的地址不是本机
- 需要转发出去
- 路由器的核心功能
转发的条件:
- 目的不是本机
- 系统配置了转发(GATEWAY)
- 有合适的路由
转发是路由器的基本功能。
转发流程
IP转发的步骤:
收到IP数据报
|
v
目的是本机?
|
+---> 是 → 上交上层
|
+---> 否 → 转发
|
v
检查转发允许?
|
+---> 否 → 丢弃,发ICMP不可达
|
+---> 是 → 继续
|
v
递减TTL
|
v
TTL为0?
|
+---> 是 → 丢弃,发ICMP超时
|
+---> 否 → 继续
|
v
查找选路表
|
v
找到路由?
|
+---> 否 → 丢弃,发ICMP不可达
|
+---> 是 → 继续
|
v
确定下一跳和输出接口
|
v
可能需要分片
|
v
调用接口输出
转发的细节
TTL处理:
- 转发时TTL减1
- TTL为0则丢弃
- 发送ICMP超时报文
重新计算校验和:
- TTL改变了,IP首部校验和要重新计算
- 可以用增量计算,提高效率
源地址选择:
- ICMP错误报文的源地址
- 用输出接口的地址
转发时要处理TTL、校验和等。
13.6 ICMP重定向
什么是重定向
ICMP重定向(Redirect):
- 路由器发现主机选路不佳
- 发送ICMP重定向报文
- 告诉主机更好的路由
- 主机更新路由表
重定向用于优化主机的路由。
重定向的类型
重定向的类型:
| 类型 | 代码 | 说明 |
|---|---|---|
| 重定向 | 0 | 网络重定向 |
| 重定向 | 1 | 主机重定向 |
| 重定向 | 2 | 服务类型和网络 |
| 重定向 | 3 | 服务类型和主机 |
最常用的是主机重定向。
重定向的条件
发送重定向的条件:
- 收到需要转发的分组
- 输入接口和输出接口是同一个
- 源主机在直连网络上
- 路由不是重定向创建的
- 源地址不是多播或广播
满足这些条件才发送重定向。
重定向的处理
发送方(路由器):
- 转发分组
- 检查是否需要重定向
- 满足条件则发送ICMP重定向
- 告诉主机更好的下一跳
接收方(主机):
- 收到ICMP重定向
- 验证合法性
- 更新或添加路由
- 设置RTF_DYNAMIC或RTF_MODIFIED标志
重定向让主机的路由更优。
13.7 选路表的维护
路由的添加和删除
路由的管理方式:
- 系统调用:ioctl(SIOCADDRT, SIOCDELRT)
- 选路套接字:AF_ROUTE
- 路由守护进程:routed、gated等
route命令:
- route add:添加路由
- route delete:删除路由
- route change:修改路由
- route get:查询路由
多种方式管理选路表。
路由的来源
路由的来源:
-
直连路由
- 接口配置时自动添加
- 优先级最高
- 接口UP时存在
-
静态路由
- 手动配置
- 管理员添加
- 不会自动变化
-
动态路由
- 路由协议学习
- RIP、OSPF、BGP等
- 自动更新
不同来源的路由优先级不同。
路由的老化
动态路由的老化:
- 有超时时间
- 一段时间没更新就删除
- 防止路由过期
静态路由:
- 不会老化
- 手动删除才消失
动态路由需要老化机制。
13.8 小结
选路表
-
作用
- 存储路由信息
- 查找路由
- 确定输出接口和下一跳
-
路由类型
- 主机路由、网络路由、默认路由
- 直连路由、间接路由
-
选路原则
- 最长匹配
- 管理距离
- 度量值
rtentry结构
-
结构定义
- rt_dst:目的地址
- rt_gateway:下一跳
- rt_flags:标志
- rt_ifp:输出接口
- rt_genmask:掩码
-
rt_flags标志
- RTF_UP:可用
- RTF_GATEWAY:网关
- RTF_HOST:主机路由
- RTF_DYNAMIC:动态
选路算法
-
哈希表组织
- 提高查找效率
- 链表解决冲突
-
查找过程
- 计算哈希
- 遍历链表
- 最长匹配
-
最长匹配
- 最具体的路由优先
- 主机 > 网络 > 默认
IP转发
-
ip_forward
- 目的不是本机
- 转发出去
- 路由器功能
-
转发流程
- 检查转发允许
- 递减TTL
- 查找路由
- 输出
-
TTL和校验和
- TTL减1
- 重新计算校验和
ICMP重定向
-
作用
- 优化主机路由
- 告诉主机更好的路由
-
条件
- 输入输出接口相同
- 源在直连网络
- 不是重定向路由
-
处理
- 路由器发送
- 主机更新路由
选路表维护
-
管理方式
- ioctl
- 选路套接字
- 路由守护进程
-
路由来源
- 直连
- 静态
- 动态
-
老化
- 动态路由老化
- 静态路由不老化
关键概念
-
选路表
- rtentry结构
- 哈希表组织
- 最长匹配
-
IP转发
- ip_forward
- TTL处理
- 查找路由
-
ICMP重定向
- 优化路由
- 主机更新路由表
-
路由维护
- 添加删除
- 静态动态
- 老化