> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man8/routed.8.md).

# routed.8

`routed`, `rdisc` — 网络 RIP 和路由器发现路由守护进程

## 名称

`routed`, `rdisc`

## 弃用通知

`routed` 和 `rdisc` 工具已弃用，将在 FreeBSD 16.0 中移除。

## 概要

`routed [-isqdghmpAtv] [-T tracefile] [-F net[/mask][,metric]] [-P parms]`

## 描述

`routed` 工具是一个在系统启动时调用的守护进程，用于管理网络路由表。它使用路由信息协议（Routing Information Protocol，RIPv1，RFC 1058）、RIPv2（RFC 1723）和 Internet 路由器发现协议（RFC 1256）来维护内核路由表。RIPv1 协议基于 4.3BSD 参考守护进程。

它在 [udp(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/udp.4.md) 套接字上监听 [route(8)](/man/man8/route.8.md) 服务（参见 [services(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/services.5.md)）的路由信息协议数据包。它还发送和接收多播的路由器发现 ICMP 消息。如果主机是路由器，`routed` 会定期将其路由表的副本提供给所有直接连接的主机和网络。它还使用路由器发现 ICMP 消息来通告或请求默认路由。

启动时（或稍后启用网络接口时），`routed` 使用 AF\_ROUTE 地址族设施来查找配置到系统中并标记为 "up" 的那些直接连接的接口。它将接口的必要路由添加到内核路由表中。首次启动后不久，只要至少有一个接口未禁用 RIP，`routed` 就会删除内核表中所有预先存在的非静态路由。内核表中的静态路由会被保留，并且如果它们具有有效的 RIP 跳数（参见 [route(8)](/man/man8/route.8.md)），则会包含在 RIP 响应中。

如果存在多个接口（不包括环回接口），则假定主机应在连接的网络之间转发数据包。在通过新接口发送 RIP *request* 和路由器发现通告或请求后，守护进程进入循环，监听来自其他主机的 RIP 请求和响应以及路由器发现数据包。

当收到 *request* 数据包时，`routed` 根据其内部表中维护的信息生成回复。生成的 *response* 数据包包含已知路由列表，每条路由都标有"跳数"度量值（16 或更大的值被视为"无穷大"）。路由的通告度量值反映了与接收和发送该路由的接口相关联的度量值（参见 [ifconfig(8)](/man/man8/ifconfig.8.md)），因此在接口上设置度量值是引导流量的有效方式。另见下文的 `adj_inmetric` 和 `adj_outmetric` 参数。

响应不包含第一跳在请求网络上的路由，以部分实现 *split-horizon*（水平分割）。来自查询程序（如 rtquery(8)）的请求会以完整表作为回复。

守护进程维护的路由表为每个目的地包含多个网关的空间，以加快从故障路由器中恢复。收到的 RIP *response* 数据包用于更新路由表，前提是它们来自当前已识别的几个网关之一，或者通告的度量值优于至少一个现有网关。

应用更新时，`routed` 在自己的表中记录更改，并在到目的地的最佳路由发生变化时更新内核路由表。内核路由表中的更改反映在下一批发送的 *response* 数据包中。如果下一个响应尚未计划，则会发送一个仅包含最近更改路由的 *flash update*（闪现更新）响应。

除了处理传入数据包外，`routed` 还会定期检查路由表条目。如果某条目在 3 分钟内未更新，则其度量值被设置为无穷大并标记为删除。删除操作会延迟到该路由以无穷大度量值通告之后，以确保失效信息在整个本地互联网中传播。这是 *poison reverse*（毒性逆转）的一种形式。

内核表中由于 ICMP 重定向消息而添加或更改的路由会在一段时间后被删除，以尽量减少 *black-holes*（黑洞）。当 TCP 连接超时时，内核会通知 `routed`，它会删除通过相关网关的所有重定向路由，推进通过该网关的所有 RIP 路由的年龄以允许选择替代路由，并推进任何相关的路由器发现协议默认路由的年龄。

充当互联网路由器的主机会每 30 秒向所有直接连接的主机和网络无偿提供其路由表。这些 RIP 响应被发送到支持广播的网络上的广播地址、点对点链路上的目标地址以及其他网络上路由器自身的地址。如果启用了 RIPv2，则在支持多播的接口上发送多播数据包。

如果在远程接口上未收到响应，或者在发送响应时出错，或者错误多于输入或输出（参见 [netstat(1)](/man/man1/netstat.1.md)），则假定电缆或接口的某些其他部分已断开或损坏，并相应地调整路由。

*Internet 路由器发现协议* 的处理方式类似。当守护进程提供 RIP 路由时，它还监听路由器发现请求并发送通告。当它静默并监听其他 RIP 路由器时，它发送请求并监听通告。如果它收到一个好的通告并且不是多宿主的，它会停止监听广播或多播 RIP 响应。它跟踪多个通告路由器，以便在当前选择的路由器死亡时加快恢复速度。如果所有发现的路由器都消失，守护进程将恢复监听 RIP 响应。如果多宿主，它在使用路由器发现时会继续监听 RIP，以确保使用所有接口。

路由器发现标准要求通告的默认"生命周期"为 30 分钟。这意味着如果发生某些事情，客户端可能会在 30 分钟内没有好的路由。建议在命令行上使用 `-P` `rdisc_interval=45` 或在 **/etc/gateways** 文件中设置 `rdisc_interval=45` 将默认值降低到 45 秒。

使用路由器发现时（当系统具有单个网络接口并收到路由器发现通告时，默认会发生此情况），内核表中有一个默认路由和数量可变的重定向主机路由。在具有多个网络接口的主机上，此默认路由将仅通过其中一个接口。因此，使用 `-q` 运行的多宿主主机可能需要下文描述的 `no_rdisc`。

参见下文描述的 `pm_rdisc` 机制，以支持既不能处理 RIPv2 也不能处理路由器发现的"旧式"系统。

默认情况下，路由器发现通告和请求都不会通过点对点链路（例如 PPP）发送。与点对点链路（如 SLIP 或 PPP，带有 IFF\_POINTOPOINT 标志）关联的网络掩码由 `routed` 用于在使用 RIPv1 时推断远程系统使用的网络掩码。

可用选项如下：

**`-i`** 允许 `routed` 接受来自非路由器节点的 RIP 请求。指定一次时，`routed` 回复来自邻居节点的路由信息查询。指定两次时，还回复来自远程节点的查询。可以使用 rtquery(8) 工具发送请求。此功能默认禁用，因为存在反射攻击的风险，尽管它对调试很有用。

**`-s`** 强制 `routed` 提供路由信息。如果存在多个未禁用 RIP 或路由器发现的网络接口，且内核开关 ipforwarding=1，则这是默认行为。

**`-q`** 与 `-s` 选项相反。当只有一个接口时，这是默认行为。使用此显式选项时，守护进程始终处于 RIP 的"安静模式"，不向其他计算机提供路由信息。

**`-d`** 不在后台运行。此选项用于交互式使用。

**`-g`** 在互联网路由器上使用，提供到"默认"目的地的路由。它等效于 `-F` `0/0,1`，主要是出于历史原因而保留。更好的选择是在命令行上使用 `-P` `pm_rdisc` 或在 **/etc/gateways** 文件中设置 `pm_rdisc`，因为会使用更大的度量值，从而减少潜在危险的默认路由的传播。这通常用于到 Internet 的网关，或使用另一个路由协议（其路由不报告给其他本地路由器）的网关。注意，由于使用度量值 1，此功能是危险的。它更常被意外用于创建路由循环的混乱，而不是解决问题。

**`-h`** 使主机或点对点路由不被通告，前提是有一个同方向的网络路由。这是一种有限的聚合形式。此选项在到以太网的网关上很有用，这些网关有通过点对点链路（如 SLIP）连接的其他网关机器。

**`-m`** 使机器向其主接口通告主机或点对点路由。它在多宿主机器（如 NFS 服务器）上很有用。除非它生成的主机路由的开销由服务器的流行程度证明是合理的，否则不应使用此选项。它仅在机器提供路由信息（因为有多个接口）时有效。`-m` 选项在通告主机路由的有限范围内覆盖 `-q` 选项。

**`-A`** 如果我们不关心 RIPv2 认证，则不忽略 RIPv2 认证。此选项是符合 RFC 1723 所必需的。然而，当本机不关心认证时，忽略所有携带认证的 RIPv2 数据包是没有意义的，并且会破坏使用 RIP 作为发现协议的能力。

**`-t`** 提高调试级别，使更多信息记录到由 `-T` 指定的跟踪文件或标准输出中。调试级别可以通过 *SIGUSR1* 或 *SIGUSR2* 信号或 rtquery(8) 命令来提高或降低。

**`-T`** `tracefile` 将调试级别提高到至少 1，并使调试信息附加到跟踪文件中。注意，由于安全考虑，最好不要常规性地运行 `routed` 并将跟踪定向到文件。

**`-v`** 显示并记录守护进程的版本。

**`-F`** `net[/mask][,metric]` 通过地址匹配 *net/mask* 的接口最小化传输中的路由，并使用 *metric* 合成一条到此机器的默认路由。其目的是通过用包含"虚假"默认路由的单个小数据包替换许多大的 RIP 信息 UDP 数据包，来减少慢速点对点链路（如 PPP 链路）上的 RIP 流量。如果省略 *metric*，则假定值为 14，以限制"虚假"默认路由的传播。这是一个危险的功能，如果使用不慎会导致路由循环。还要注意，多个接口可以匹配指定的网络号和掩码。另见 `-g`。

**`-P`** `parms` 等效于将参数行 *parms* 添加到 **/etc/gateways** 文件中。

提供的任何其他参数被解释为记录 `routed` 操作的文件名。最好使用 `-T`，而不是在命令后附加跟踪文件名。

`routed` 工具还支持"远程" *passive*（被动）或 *active*（主动）网关的概念。`routed` 启动时，它会读取 **/etc/gateways** 文件来查找那些仅使用路由套接字信息可能无法定位的远程网关，发现某些本地网关是否是 *passive* 的，并获取其他参数。以这种方式指定的网关，如果不期望交换路由信息，则应标记为 passive；而标记为 active 的网关应愿意交换 RIP 数据包。通过 *passive* 网关的路由在启动时一次性安装到内核路由表中，并且不包含在传输的 RIP 响应中。

远程主动网关被视为网络接口。RIP 响应被发送到远程 *active* 网关。如果未收到响应，则从内核表中删除关联的路由，并通过其他接口通告 RIP 响应。如果远程网关恢复发送 RIP 响应，则恢复关联的路由。

这样的网关在不支持广播或多播但其他方面像经典共享媒体（如以太网）那样工作的媒体上很有用，例如某些 ATM 网络。可以在 **/etc/gateways** 中用一系列 "host" 行列出在 HIPPI 或 ATM 网络上可达的所有 RIP 路由器。注意，在这种情况下通常希望使用 RIPv2，以避免生成推断的主机路由列表。

标记为 *external* 的网关也是被动的，但既不放入内核路由表，也不包含在路由更新中。外部条目的功能是指示另一个路由进程将在必要时安装此类路由，而 `routed` 不应安装到该目的地的其他路由。只有当两个路由器都可能获知到同一目的地的路由时，才需要此类条目。

**/etc/gateways** 文件由一系列行组成，每行采用以下两种格式之一或由下文描述的参数组成。空行和以 '#' 开头的行是注释。

```sh
net Nname[/mask] gateway Gname metric value <passive | active | extern>
```

```sh
host Hname gateway Gname metric value <passive | active | extern>
```

`Nname` 或 `Hname` 是目标网络或主机的名称。它可以是符号网络名称或以"点分"表示法指定的 Internet 地址（参见 inet(3)）。（如果是名称，则它必须在 **/etc/networks** 或 **/etc/hosts** 中定义，或者 [nsswitch.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/nsswitch.conf.5.md) 中的某种方法必须能够解析它。）

`Mask` 是 1 到 32 之间的可选数字，表示与 `Nname` 关联的网络掩码。

`Gname` 是应将 RIP 响应转发到的网关的名称或地址。

`Value` 是到目标主机或网络的跳数。

`Host` `hname` 等效于 `net` `nname/32`。

必须存在 `passive`、`active` 或 `external` 关键字之一，以指示网关应被视为 `passive` 或 `active`（如上所述），还是该网关在 RIP 协议范围之外是 `external` 的。

如使用 `-t` 打开调试时所见，这些行创建伪接口。要为远程或外部接口设置参数，应使用以 `if=alias(Hname)`、`if=remote(Hname)` 等开头的行。

### 参数

既不以 "net" 也不以 "host" 开头的行必须由以下一个或多个参数设置组成，以逗号或空格分隔：

**`if=ifname`** 表示该行上的其他参数应用于接口名 `ifname`。

**`subnet=nname[/mask][,metric]`** 通告一条到网络 `nname` 的路由，掩码为 `mask`，度量为提供的 `metric`（默认为 1）。这用于填充 CIDR 分配中的"空洞"。此参数必须单独出现在一行上。网络号必须指定完整的 32 位值，如 192.0.2.0 而不是 192.0.2。除非必要，不要使用此功能。它是危险的。

**`ripv1_mask=nname/mask1,mask2`** 指定 `nname`/`mask1` 所属网络的网络掩码应为 `mask2`。例如，"`ripv1_mask=192.0.2.16/28,27`" 将 192.0.2.16/28 标记为 192.0.2.0/27 的子网，而不是 192.0.2.0/24。最好使用 `ripv2_out` 等启用 RIPv2，而不是使用此功能。

**`passwd=XXX[|KeyID[start|stop]]`** 指定一个 RIPv2 明文密码，该密码将包含在所有发送的 RIPv2 响应中，并在所有接收的 RIPv2 响应上进行检查。密码中的任何空格、制表符、逗号或 '#'、'|' 或 NULL 字符必须用反斜杠（**\\**）转义。常见的转义序列 **\n**、**\r**、**\t**、**\b** 和 **\xxx** 具有通常的含义。`KeyID` 必须唯一，但对于明文密码会被忽略。如果存在，`start` 和 `stop` 是格式为 year/month/day\@hour:minute 的时间戳。它们指定密码的有效时间。输出数据包使用具有最远未来的有效密码，除非所有密码都已过期（在这种情况下使用最近过期的密码），或者除非还没有有效的密码（在这种情况下不输出密码）。传入数据包可以携带任何有效的密码、将在未来 24 小时内有效的密码，或者在过去 24 小时内有效的密码。为了保护密钥，passwd 设置仅在 **/etc/gateways** 文件中有效，且仅当该文件只能由 UID 0 读取时有效。

**`md5_passwd=XXX|KeyID[start|stop]`** 指定一个 RIPv2 MD5 密码。除了需要 `KeyID` 外，此关键字类似于 `passwd`。

**`no_ag`** 关闭 RIPv1 和 RIPv2 响应中子网的聚合。

**`no_super_ag`** 关闭 RIPv2 响应中网络到超网的聚合。

**`passive`** 标记接口不在通过其他接口发送的更新中通告，并关闭通过该接口的所有 RIP 和路由器发现。

**`no_rip`** 禁用指定接口上的所有 RIP 处理。如果不允许任何接口处理 RIP 数据包，`routed` 纯粹充当路由器发现守护进程。注意，关闭 RIP 而不使用 `rdisc_adv` 或 `-s` 显式启用路由器发现通告，会导致 `routed` 充当客户端路由器发现守护进程，不进行通告。

**`no_rip_mcast`** 使 RIPv2 数据包以广播而非多播方式发送。

**`no_rip_out`** 使不发送 RIP 更新。

**`no_ripv1_in`** 使忽略接收的 RIPv1 响应。

**`no_ripv2_in`** 使忽略接收的 RIPv2 响应。

**`ripv2_out`** 启用 RIPv2 输出，并使 RIPv2 通告在可能时以多播方式发送。

**`ripv2`** 等效于 `no_ripv1_in` 和 `no_ripv1_out`。这会启用 RIPv2。

**`no_rdisc`** 禁用 Internet 路由器发现协议。

**`no_solicit`** 禁用路由器发现请求的传输。

**`send_solicit`** 指定应发送路由器发现请求，即使在点对点链路上（默认情况下仅监听路由器发现消息）。

**`no_rdisc_adv`** 禁用路由器发现通告的传输。

**`rdisc_adv`** 指定应发送路由器发现通告，即使在点对点链路上（默认情况下仅监听路由器发现消息）。

**`bcast_rdisc`** 指定路由器发现数据包应以广播而非多播方式发送。

**`rdisc_pref=N`** 将路由器发现通告中的偏好设置为可选带符号整数 `N`。默认偏好为 0。偏好更小或更负的默认路由更受客户端青睐。

**`rdisc_interval=N`** 将路由器发现通告的传输标称间隔设置为 N 秒，其生命周期设置为 3\*N。

**`fake_default=metric`** 与 `-F` `net[/mask][=metric]` 具有相同的效果，其中网络和掩码来自指定接口。

**`pm_rdisc`** 类似于 `fake_default`。当 RIPv2 路由以多播方式发送时，RIPv1 监听者无法接收它们，此功能使 RIPv1 默认路由广播给 RIPv1 监听者。除非用 `fake_default` 修改，否则默认路由以度量值 14 广播。这充当"穷人的路由器发现"协议。

**`adj_inmetric=delta`** 通过 `delta` 调整接收的 RIP 路由的跳数或度量值。每条接收的 RIP 路由的度量值增加与接口关联的两个值之和。一个是 adj\_inmetric 值，另一个是用 [ifconfig(8)](/man/man8/ifconfig.8.md) 设置的接口度量值。

**`adj_outmetric=delta`** 通过 `delta` 调整通告的 RIP 路由的跳数或度量值。每条接收的 RIP 路由的度量值增加与接收该路由的接口关联的度量值，或者如果接口没有非零度量值，则增加 1。然后，接收的路由的度量值增加与接口关联的 adj\_outmetric。每条通告的路由总共增加四个值：用 [ifconfig(8)](/man/man8/ifconfig.8.md) 为接收接口设置的度量值、接收接口的 `adj_inmetric` `delta`、用 [ifconfig(8)](/man/man8/ifconfig.8.md) 为传输接口设置的度量值，以及传输接口的 `adj_outmetric` `delta`。

**`trust_gateway=rname[|net1/mask1|net2/mask2|...]`** 使来自路由器 `rname` 和其他 `trust_gateway` 关键字中指定的其他路由器的 RIP 数据包被接受，而来自其他路由器的数据包被忽略。如果指定了网络，则来自该路由器的到其他网络的路由将被忽略。

**`redirect_ok`** 允许内核在系统充当路由器并转发数据包时监听 ICMP 重定向消息。否则，当系统充当路由器时，ICMP 重定向消息会被覆盖并删除。

## 文件

**/etc/gateways** 用于远程网关

## 参见

[icmp(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/icmp.4.md), [udp(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/udp.4.md), rtquery(8)

> "Internet Transport Protocols", XSIS 028112, Xerox System Integration Standard.

## 历史

`routed` 工具出现在 4.2BSD 中。

## 缺陷

它并不总是能检测到网络接口中的单向故障，例如输出端发生故障时。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man8/routed.8.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
