Routing Table Calculation

最短路径计算的基础知识。

路由表计算

链路状态数据库描述了相互连接且适合转发的路由器与链路。它还包含每条链路的 cost(度量值)。此度量值用于计算到目标网络的最短路径。

每台路由器可以为其自身的链路方向通告不同的 cost。这会形成非对称链路,即发往目标的数据包走一条路径,而响应走另一条路径。非对称路径会加大故障排查的难度。 在 /routing/ospf/interface-template 菜单中修改 cost 值,或在 /routing/ospf/interface 菜单中创建静态 OSPF 接口。例如,要匹配 ether2 接口并设置 cost 为 100:

/routing/ospf/interface-template
add interfaces=ether2 cost=100 area=backbone_v2

Cisco 路由器上接口的 cost 与该接口的带宽成反比。带宽越高表示 cost 越低。如果需要在 RouterOS 上使用类似的 cost,请使用公式 Cost = 100000000/bw_in_bps。

OSPF 路由器使用 Dijkstra 的最短路径优先(SPF)算法来计算最短路径。该算法将路由器置于树的根,并根据到达目标所需的累计 cost 计算到每个目标的最短路径。尽管所有路由器使用相同的链路状态数据库,但每台路由器都会计算自己的树。

SPT 计算

假设有如下网络。该网络由 4 台路由器组成。出接口的 OSPF cost 显示在代表链路的连线旁。要为路由器 R1 构建最短路径树,需将 R1 作为根,并计算到每个目标的最小 cost。

graph LR

    R1[R1]
    R2[R2]
    R3[R3]
    R4[R4]
    N1[192.168.1.0]:::N1
    N2[172.16.1.0]:::N2
    N3[192.168.2.0]:::N3

    %% Connections within 192.168.1.0
    R1 -- "cost:10" --> N1
    N1 --- R2
    N1 --- R3

    R2 -- "cost:10" --> N2
    R4 -- "cost:4" --> N2

    R3 -- "cost:6" --> N3
    N3 --> R4

%% Style the network node
    classDef N1,N2,N3 stroke:#4682b4,stroke-width:3px,rx:50%,ry:30%

已找到通往 172.16.1.0 网络的多条最短路径。这允许对发往该目标的流量进行负载均衡。此类路由称为等价多路径(ECMP)。构建最短路径树后,路由器会相应地构建路由表。网络根据树中计算出的 cost 到达。

graph 

    R1[R1]
    R2[R2]
    R3[R3]
    R4[R4]
    N1[192.168.1.0]:::N1
    N2[172.16.1.0]:::N2
    N3[192.168.2.0]:::N3

    %% Connections within 192.168.1.0
    R1 -- "cost:10" --> N1
    R1 -- "cost:10" --> R3
    R1 -- "cost:10" --> R2

    R2 -- "cost:10" --> N2
    R4 -- "cost:4" --> N2

    R3 -- "cost:6" --> N3
    R3 -- "cost:6" --> R4

    R1 -- "Total cost:16" --> N3
    R1 --> R2
    R2 -- "Total cost:20" --> N2

    R1 --> R4
    R4 -- "Total cost:20" --> N2

%% Style all dotted lines red (including the new one)
    linkStyle 7,8,9,10,11 stroke:#ff0000,stroke-width:2px,stroke-dasharray:5,5,color:#ff0000

%% Style the network node
    classDef N1,N2,N3 stroke:#4682b4,stroke-width:3px,rx:50%,ry:30%

路由表计算看起来很简单;然而,当使用某些 OSPF 扩展或计算 OSPF area 时,路由计算会变得更加复杂。

转发地址

OSPF 路由器可以将 forwarding-address 设置为自身以外的地址,表示可以使用备选下一跳。在大多数情况下,转发地址设置为 0.0.0.0,这表示该路由只能通过通告该路由的路由器到达。

如果满足以下条件,则会在 LSA 中设置转发地址:

  • 必须在下一跳接口上启用 OSPF。
  • 下一跳地址落在 OSPF networks 所提供的网络内。

收到此类 LSA 的路由器,如果 OSPF 能够解析转发地址,就可以使用该转发地址。如果转发地址无法直接解析,路由器会将 LSA 中该转发地址的下一跳设置为网关。如果转发地址完全无法解析,网关将是 originator-id。解析仅通过 OSPF 实例路由进行,而不是通过整个路由表。

考虑以下示例设置:

路由器 R1 有一条通往外部网络 192.168.0.0/24 的静态路由。OSPF 运行在 R1、R2 和 R3 之间,该静态路由被分发到整个 OSPF 网络。

这种设置中的问题显而易见。R2 无法直接到达外部网络。从 R2 发往该 LAN 网络的流量将通过路由器 R1 转发,但网络图显示 R2 可以直接到达连接到该 LAN 网络的路由器。

了解了转发地址的条件后,你可以让路由器 R1 设置转发地址。将 10.1.101.0/24 网络添加到路由器 R1 配置的 OSPF networks 中:

/routing/ospf/interface-template add area=backbone_v2 networks=10.1.101.0/24

现在验证转发地址是否生效:

[admin@r2] /ip/route> print where dst-address=192.168.0.0/24
Flags: D - DYNAMIC; A - ACTIVE; o, y - COPY
Columns: DST-ADDRESS, GATEWAY, DISTANCE
    DST-ADDRESS       GATEWAY            DISTANCE
DAo 192.168.0.0/24    10.1.101.1%ether1       110

在所有 OSPF 路由器上,你将看到该 LSA 设置的转发地址不是 0.0.0.0。

[admin@r2] /routing/ospf/lsa> print where id=192.168.0.0
Flags: S - self-originated, F - flushing, W - wraparound; D - dynamic 

 1  D instance=default_ip4 type="external" originator=10.1.101.10 id=192.168.0.0 
      sequence=0x80000001 age=19 checksum=0xF336 body=
        options=E
        netmask=255.255.255.0
        forwarding-address=10.1.101.1
        metric=10 type-1
        route-tag=0

提示

不要求 10.1.101.0/24 网络中路由器之间的 OSPF 邻接关系。