第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

按下一跳分:

  • 直连路由:目的在直连网络上,下一跳就是目的
  • 间接路由:需要经过路由器,下一跳是路由器

不同类型的路由,优先级不同。


选路原则

选路的基本原则:

  1. 最长匹配

    • 找最具体的路由
    • 前缀越长越优先
    • 主机路由 > 网络路由 > 默认路由
  2. 管理距离

    • 不同来源的路由优先级不同
    • 直连 > 静态 > 动态
  3. 度量值

    • 同类型路由比较度量
    • 度量越小越优先

最长匹配是最基本的原则。


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 选路算法

哈希表组织

选路表的组织:

  • 用哈希表组织
  • 目的地址的哈希值作为索引
  • 冲突用链表解决
  • 提高查找效率

哈希表加快查找速度。


选路查找过程

查找路由的步骤:

  1. 计算哈希值

    • 根据目的地址计算哈希
    • 找到对应的哈希桶
  2. 遍历链表

    • 遍历哈希桶中的链表
    • 比较目的地址和掩码
    • 记录匹配的路由
  3. 找最匹配的

    • 最长前缀匹配
    • 主机路由优先
    • 返回最佳匹配

最长匹配是核心原则。


最长匹配

最长匹配(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服务类型和主机

最常用的是主机重定向。


重定向的条件

发送重定向的条件:

  1. 收到需要转发的分组
  2. 输入接口和输出接口是同一个
  3. 源主机在直连网络上
  4. 路由不是重定向创建的
  5. 源地址不是多播或广播

满足这些条件才发送重定向。


重定向的处理

发送方(路由器):

  1. 转发分组
  2. 检查是否需要重定向
  3. 满足条件则发送ICMP重定向
  4. 告诉主机更好的下一跳

接收方(主机):

  1. 收到ICMP重定向
  2. 验证合法性
  3. 更新或添加路由
  4. 设置RTF_DYNAMIC或RTF_MODIFIED标志

重定向让主机的路由更优。


13.7 选路表的维护

路由的添加和删除

路由的管理方式:

  • 系统调用:ioctl(SIOCADDRT, SIOCDELRT)
  • 选路套接字:AF_ROUTE
  • 路由守护进程:routed、gated等

route命令:

  • route add:添加路由
  • route delete:删除路由
  • route change:修改路由
  • route get:查询路由

多种方式管理选路表。


路由的来源

路由的来源:

  1. 直连路由

    • 接口配置时自动添加
    • 优先级最高
    • 接口UP时存在
  2. 静态路由

    • 手动配置
    • 管理员添加
    • 不会自动变化
  3. 动态路由

    • 路由协议学习
    • RIP、OSPF、BGP等
    • 自动更新

不同来源的路由优先级不同。


路由的老化

动态路由的老化:

  • 有超时时间
  • 一段时间没更新就删除
  • 防止路由过期

静态路由:

  • 不会老化
  • 手动删除才消失

动态路由需要老化机制。


13.8 小结

选路表

  1. 作用

    • 存储路由信息
    • 查找路由
    • 确定输出接口和下一跳
  2. 路由类型

    • 主机路由、网络路由、默认路由
    • 直连路由、间接路由
  3. 选路原则

    • 最长匹配
    • 管理距离
    • 度量值

rtentry结构

  1. 结构定义

    • rt_dst:目的地址
    • rt_gateway:下一跳
    • rt_flags:标志
    • rt_ifp:输出接口
    • rt_genmask:掩码
  2. rt_flags标志

    • RTF_UP:可用
    • RTF_GATEWAY:网关
    • RTF_HOST:主机路由
    • RTF_DYNAMIC:动态

选路算法

  1. 哈希表组织

    • 提高查找效率
    • 链表解决冲突
  2. 查找过程

    • 计算哈希
    • 遍历链表
    • 最长匹配
  3. 最长匹配

    • 最具体的路由优先
    • 主机 > 网络 > 默认

IP转发

  1. ip_forward

    • 目的不是本机
    • 转发出去
    • 路由器功能
  2. 转发流程

    • 检查转发允许
    • 递减TTL
    • 查找路由
    • 输出
  3. TTL和校验和

    • TTL减1
    • 重新计算校验和

ICMP重定向

  1. 作用

    • 优化主机路由
    • 告诉主机更好的路由
  2. 条件

    • 输入输出接口相同
    • 源在直连网络
    • 不是重定向路由
  3. 处理

    • 路由器发送
    • 主机更新路由

选路表维护

  1. 管理方式

    • ioctl
    • 选路套接字
    • 路由守护进程
  2. 路由来源

    • 直连
    • 静态
    • 动态
  3. 老化

    • 动态路由老化
    • 静态路由不老化

关键概念

  1. 选路表

    • rtentry结构
    • 哈希表组织
    • 最长匹配
  2. IP转发

    • ip_forward
    • TTL处理
    • 查找路由
  3. ICMP重定向

    • 优化路由
    • 主机更新路由表
  4. 路由维护

    • 添加删除
    • 静态动态
    • 老化

IP选路