ip命令手册《二》

时间:2021-08-13 05:30:55
这一部分是关于使用ip命令管理系统路由的内容。

------------------------------------------------------------------------
--------
By nixe0n



7.路由表管理


7.1.缩写

  route、ro、r


7.2.对象

  路由条目保存在内核的路由表中,它们包含寻找到其它网络节点的路径信息。
路由表条目都包括一对网络地址/掩码长度以及可选的TOS值等信息。如果数据包目
的地址位于属于路由条目的的范围,以及路由的TOS等于0或者等于数据包的TOS,
它就匹配路由条目。如果一个数据包匹配多个路由条目,系统内核将按照以下规则
决定选择哪个路由:

  注:作者在文中把地址被子网掩码屏蔽后的部分/掩码长度这种表达方式叫做
前缀(prefix)。例如:10/8表示网络10.0.0.0,子网掩码长度是8位;10.1/16表
示网络10.1.0.0,子网掩码长度是16位;

范围最小的优先匹配,较大的放弃;
路由TOS等于数据包TOS的匹配,不等于的放弃;
如果经过上面两步的选择,还有数个路由,就选择优先值最高的路由;
如果还有数个路由可供选择,就重复进行第一步。


  为了简化,我们使用{prefix,tos,preference}来标记每个路由。


7.3.路由属性

  路由条目提供IP数据包投递所需的路由信息、数据(例如:输出设备、下一跳
的路由器)和一些可选属性(例如:路径的最大传输单元MTU或者源地址等)。这些属
性将在后面的章节详细介绍。


7.4.路由类型

  路由的设置以及其它的可选属性都依赖于路由类型。最重要的路由类型是
unicast路由,这种类型的路由表示到另外主机的真实路由。一般情况下,通常的
路由表只有这种类型的路由条目。不过,还存在其它类型的路由,使用的语法也不
相同。Linux-2.2理解以下几种类型的路由:

unicast 这种类型的路由描述到目的地址的真实路径。  
unreachable 这些目的地址是不可达的。如果发过去的数据包都被丢弃并且收到
ICMP信息host unreachable,目的地址就会被标记为不可达。在这种情况下,本地
发送者将返回EHOSTUNREACH错误。  
blackhole 这些目的地址不可达,而且发过去的数据包都被丢弃。在这种情况下,
本地发送者将返回EINVAL错误。  
prohibit 这些路由是不可达的。发过去的数据包都被丢弃,而且产生ICMP信息
communication administratively prohibited 。本地发送者会返回EACCESS错误
。  
local 目的地址被分配给本机。数据包通过回环被投递到本地。  
broadcast 目的地址是广播地址,数据包作为链路广播发送。  
throw 和策略规则(policy rule)一块使用的控制路由。如果选择了这种路由,就
会认为没有发现路由,在这个表中的查询就会被终止。没有找到策略路由就相当于
在路由表中没有找到路由,数据包会被丢弃,并产生ICMP信息net unreachable。
本地发送者会返回ENETUNREACH错误。  
nat 特定的NAT路由。目标地址属于哑地址(或者称为外部地址),在转发前需要
进行地址转换。  
anycast 目标是anycast地址,被分配给本机。这类地址和本地地址大同小异,不
同的是这类地址不能用于任何数据包的源地址。  
multicast 使用多播路由。在普通的路由表中,这种路由并不存在。  


7.5.路由表

  从Linux-2.2开始,内核把路由归纳到许多路由表中,这些表都进行了编号,
编号数字的范围是1到255。另外,为了方便,还可以在/etc/iproute2/rt_tables
中为路由表命名。默认情况下,所有的路由都会被插入到表main(编号254)中。在
进行路由查询时,内核只使用路由表main。

  实际上,还有另外一个路由表也一直存在,这个表是不可见的,而且极为重要
。这就是表local。这个表保存本地和广播路由。内核会自动维护这个路由表,通
常系统管理员没有必要对它进行修改,甚至不必看到。

  在使用策略路由(policy routing)时,我们将使用多个路由。在这种情况下
,表识别符有很多参数,因此需要使用{prefix,tos,preference}的形式唯一地识
别每个路由。


7.6.ip route add -- 添加新路由
ip route change -- 修改路由
ip route replace -- 替换已有的路由




缩写:add、a;change、chg;replace、repl


参数

to PREFIX或者to TYPE PREFIX(default) 路由的目标前缀(prefix)。如果TYPE被
忽略,ip命令就会使用默认的类型unicast。其它的类型在上一节都有介绍。
PREFIX是一个IP或者IPv6地址,也可以跟着一个斜杠和掩码长度。如果没有掩码长
度,ip命令就假定是一个单一ip地址。另外,还有一个特殊的PREFIX--default(
缺省路由),它等于IPv4的0/0,或者IPv6的::/0。  
tos TOS 或者defield TOS 定义服务类型关键词。在进行路由匹配时,内核首先比
较数据包的TOS和route的TOS,如果没有和数据包TOS相同的路由,还可以选择TOS
等于0的路由。TOS或者是一个十六进制的数字,或者是一个由
/etc/iproute2/rt_dsfield文件定义的识别符。  
metric NUMBER或者preference NUMBER 定义路由的优先值,NUMBER时一个任意的
32位数字。  
table TABLEID 路由要加入的表。TABLEID或者是一个数字或者是
/etc/iproute2/rt_tables文件定义的一个字符串。如果没有这个参数,ip命令就
会把路由加入到表main中,本地(local)、广播(broadcast)和网络地址转换(nat)
路由除外。在默认情况下,这些类型的路由都会被加入表local中。  
dev NAME 输出设备的名字  
via ADDRESS 指定下一跳路由器的地址。实际上,这个域的可靠性取决于路由类型
。对于通常的unicast路由,它或者是真正的下一跳路由器地址,或者如果它是
BSD兼容模式安装的直接路由,它可以是一个网络接口的本地地址。对于NAT路由,
它是转换后的地址。  
src ADDRESS 在向目的prefix发送数据包时选择的源地址。  
realm REALMID 指定路由分配的realm。REALM可以是一个数字或者
/etc/iproute2/rt_realms文件定义的一个字符串。有关realm更为详细的信息请看
附录(Route realms and policy propagation, rtacct)。  
mtu MTU或者mtu lock MTU 设置到达目的路径的最大传输单元(MTU)。如果没有使
用修饰符lock,内核会通过路径最大传输单元发现(Path MTU Discovery)机制更
新MTU;如果使用了修饰符lock,内核就不会测试路径的最大传输单元。在这种情
况下,发出的所有IPv4数据包DF域都会被设置为0(允许分片),对于IPv6数据包
也允许分片。  
window NUMBER 设置到目的地址TCP连接的最大窗口值,以字节为单位。使用这个
参数可以限制对端发送数据的速率。  
rtt NUMBER 估算初始往返时间(Round Trip Time)  
rttvar NUMBER 估算初始往返时间偏差(RTT variance)  
ssthresh NUMBER 估算慢启动阀值(slow start threshould)  
cwnd NUMBER 把拥挤窗口(congestion window)值锁定为NUMBER。如果没有lock标
记,这个值会被忽略。  
advmss NUMBER 设置在建立TCP连接时,向目的地址声明的最大报文段大小
(Maximal Segment Size,MSS)。如果没有设置,Linux内核会使用计算第一跳的最
大传输单元得到的数值。  
nexthop NEXTHOP 设置多路径路由的下一跳地址。NEXTHOP比较复杂,它的语法和
以下高层参数类似:

via ADDRESS--表示下一跳路由器;
dev NAME--表示输出设备;
weight NUMBER--在多路由路径中,这个元素的权重。表示相对带宽或者服务质量


scope SCOPE_VAL 路由前缀(prefix)覆盖的范围。SCOPE_VAL可以是一个数字,也
可以是/etc/iproute2/rt_scope文件定义的一个字符串。如果没有这个参数,ip命
令就会根据具体情况猜测:对于经过网关的unicast路由,就设置为global;对于
直连的unicast路由和广播路由,就设置为link;对于本地路由,就设置为host。

protocol RTPROTO 本条路由得路由协议识别符。RTPROTO可以是一个数字,也可以
是/etc/iproute2/rt_protos文件定义的一个字符串。如果使用时没有提供这个参
数,ip命令就使用默认值boot(也就是说,ip命令认为添加路由的人不知道自己做
了些什么)。有些协议值有其固定的解释:

redirect--路由是由ICMP重定向加入的;
kernel--路由是由内核在自动配置期间加入的;
boot--路由是启动过程中加入的。如果一个路由监控程序将要启动,这些路由都会
被清除;
static--为了覆盖动态路由,由系统管理员手工添加的路由。路由监控程序也会优
先考虑这类路由,甚至可能通告给其对端;
ra--路由是通过路由发现协议加入的(Router Discovery Protocol)。
其它的值没有保留,系统管理员可以*分配(或者不分配)给协议标记。至少,路
由监控程序应该注意对一些唯一协议值的设置,这些协议值在rtnetlink.h文件或
者rt_protos数据库中分配。

onlink 假装和下一跳路由器是直接相连的,即使它没有匹配任何接口前缀
(prefix)。  
equalize 允许把数据包随机从多个路由发出。如果没有这个路由修饰符,内核就
会冻结下一跳路由的地址。  



示例

设置到网络10.0.0/24的路由经过网关193.233.7.65
ip route add 10.0.0/24 via 193.233.7.65

修改到网络10.0.0/24的直接路由,使其经过设备dummy
ip route chg 10.0.0/24 dev dummy

加入缺省多路径路由,让ppp0和ppp1分担负载(注意:scope值并非必需,它只不过
是告诉内核,这个路由要经过网关而不是直连的。实际上,如果你知道远程端点的
地址,使用via参数来设置就更好了)。
ip route add default scope global nexthop dev ppp0
                                 nexthop dev ppp1

设置NAT路由。在转发来自192.203.80.144的数据包之前,先进行网络地址转换,
把这个地址转换为193.233.7.83(回来的转换将会在后面的章节路由策略中介绍)

ip route add nat 192.203.80.142 via 193.233.7.83




7.7.ip route delete-- 删除路由



缩写:delete、del、d


参数

  ip route del使用和ip route add相同的参数,不过语法稍有不同。这个命令
使用关键词(to、tos、preference和table)选择要删除的路由。如果命令中使用
了可选属性,ip命令会校验这个属性和要删除的路由是否一致;如果没有给定关键
词或者属性不一致,ip route del会执行失败。



示例

删除上一节命令加入的多路径路由
ip route del default scope global nexthop dev ppp0
                                 nexthop dev ppp1




7.8.ip route show -- 列出路由



缩写:show、list、sh、ls、l


简介

  使用这个命令,你可以看到路由表的内容,或者查询符合某些条件的路由。



参数

to SELECTOR(default) 只选择到给定地址的路由。 SELECTOR由修饰符(root、
match、exact,可选)和一个前缀(prefix)组成。root PREFIX表示选择前缀
(prefix)不短于PREFIX的路由,例如:root 0/0将选在路由表里面的全部路由;
match PREFIX表示选择前缀(prefix)不长于PREFIX的路由,match 10.1/16会选择
前缀(prefix)是10.1/16、10./8和0/0的全部路由;而exact PREFIX(或者just
PREFIX)表示精确匹配。如果没有这些选项(ip route ls),ip命令就假定是ip
route ls to root 0/0,将列出系统的所有路由。  
tos TOS或者dsfield TOS 只列出tos等于TOS的路由  
table TABLEID 列出路由表TABLEID里面的路由。缺省设置是table main。
TABLEID或者是一个真正的路由表ID或者是/etc/iproute2/rt_tables文件定义的字
符串,或者是以下的特殊值:

all -- 列出所有表的路由;
cache -- 列出路由缓存的内容。

cloned或者cached 列出被克隆出来的路由(由于某些路由属性改变,例如:MTU,
而由某些路由派生出来的路由)。实际上,它的内容和表缓存的内容是一样的。

from SELECTOR 和to的语法是相同的,只不过由目的地址换为源地址而已。注意:
这个选项之适用于被克隆出来的路由。  
protocol RTPROTO 只列出协议是RTPROTO的路由  
scope SCOPE_VAL 只列出范围是SCOPE_VAL的路由  
type TYPE 只列出类型为TYPE的路由  
dev NAME 只列出通过设备NAME的路由  
via PREFIX 只列出下一跳通过PREFIX的路由  
src PREFIX 只列出源地址属于PREFIX的路由  
realm REALMID或者raalm FROMREALM/TOREALM 只列出realm为REALMID的路由  



示例

计算使用gated/bgp协议的路由个数
kuznet@amber:~ $ ip route ls proto gated/bgp |wc
  1413    9891    79010
kuznet@amber:~ $

计算路由缓存里面的条数,由于被缓存路由的属性可能大于一行,以此需要使用
-o选项
uznet@amber:~ $ ip -o route ls cloned |wc
  159    2543    18707
kuznet@amber:~ $





输出格式

  通常,在这个命令输出的信息中,每个路由纪录占一行。不过,有时某些纪录
可能会超过一行,例如被克隆出来的路由或者包含一些额外的信息。如果在命令中
使用了-o选项,在每个纪录中,会使用代替回车作为回行标记。例如:

kuznet@amber:~ $ ip ro ls 193.233.7/24
193.233.7.0/24 dev eth0 proto gated/conn scope link src 193.233.7.65
realms inr.ac
kuznet@amber:~ $



如果是列出被克隆的条目,输出信息将是另外的形式。例如:

kuznet@amber:~ $ ip ro ls 193.233.7.82 tab cache
193.233.7.82 from 193.233.7.82 dev eth0 src 193.233.7.65 realms inr.
ac/inr.ac
   cache <src-direct,redirect>  mtu 1500 rtt 300 iif eth0
193.233.7.82 dev eth0  src 193.233.7.65 realms inr.ac
   cache  mtu 1500 rtt 300
kuznet@amber:~ $



  输出信息的第二行是以关键词cache开头的,显示路由的其它缓存标记和属性
。本行的第一个域是cache <缓存标记>,缓存标记包括:

local 数据包被投递到本地。它适用于本地回环单向传播(unicast)路由,如果这
个主机是对应广播组的一个成员,它也适用于广播路由何多播路由。  
reject 路径无效。任何试图通过这个路由的企图都会导致错误。  
mc 目的是多播地址(multicast)。  
brd 目的是广播地址(broadcast)。  
src-direct 源地址是在一个直接连接的接口。  
redirected 路由是由ICMP重定向建立的。  
redirect 数据包通过这个路由将触发ICMP重定向。  
fastroute 路由适合用于快速路由(fastroute)。  
equalize 使数据包随机地通过这个路由。  
dst-nat 目的地址需要进行地址转换。  
src-nat 源地址需要进行地址转换。  
masq 源地址需要伪装(masquerading)。  
notify 修改/删除这个路由将触发RTNETLINK报警。  

  接着是一些路由属性,支持的属性如下:

error 对于reject路由,这是返回给本地发送者的错误码。这些错误码也会被转换
为ICMP错误码,发送给远程发送者。  
expires 到了超时时间,这个条目就会消失。  
iif 需要这个路由的数据包如期到达这接口。  



统计选项

  如果在命令中使用-statistics选项,ip命令会给出一些更为详尽的信息:

users 使用这个路由的用户数。  
age 显示这个路由最后使用时的时间。  
used 自从建立这个路由以来,它被查询的次数。  


7.9.ip route flush -- 擦除路由表



缩写:flush、f



简介


  使用这个命令,可以很方便地删除符合某些条件的路由。



参数

  这个命令的参数和ip route show命令的参数相同,只不过被操作的路由表不
会被显示出来。它和ip route show命令唯一的区别是它们的缺省操作,ip
route show会显示出路由表main的所有条目,而ip route flush只会给出帮助信息
,不对路由表进行任何操作。至于这个区别的原因,恐怕不必多做解释了吧?



统计选项

  如果在这个命令中使用了-statistics选项,它就会显示一些冗余信息。这些
信息包括:被删除的路由数和删除过程中遍历路由表的次数。如果这个选项使用了
两次,ip还会输出被删除路由的详细信息。



示例

  第一个例子是删除路由表main中的所有网关路由(例如:在路由监控程序挂掉
之后):

netadm@amber:~ # ip -4 ro flush scope global type unicast



  第二个例子是清除所有被克隆出来的IPv6路由:

netadm@amber:~ # ip -6 -s -s ro flush cache
3ffe:2400::220:afff:fef4:c5d1 via 3ffe:2400::220:afff:fef4:c5d1
 dev eth0  metric 0
   cache  used 2 age 12sec mtu 1500 rtt 300
3ffe:2400::280:adff:feb7:8034 via 3ffe:2400::280:adff:feb7:8034
 dev eth0  metric 0
   cache  used 2 age 15sec mtu 1500 rtt 300
3ffe:2400::280:c8ff:fe59:5bcc via 3ffe:2400::280:c8ff:fe59:5bcc
 dev eth0  metric 0
   cache  users 1 used 1 age 23sec mtu 1500 rtt 300
3ffe:2400:0:1:2a0:ccff:fe66:1878 via 3ffe:2400:0:1:2a0:ccff:fe66:1878
 dev eth1  metric 0
   cache  used 2 age 20sec mtu 1500 rtt 300
3ffe:2400:0:1:a00:20ff:fe71:fb30 via 3ffe:2400:0:1:a00:20ff:fe71:fb30
 dev eth1  metric 0
   cache  used 2 age 33sec mtu 1500 rtt 300
ff02::1 via ff02::1 dev eth1  metric 0
   cache  users 1 used 1 age 45sec mtu 1500 rtt 300

*** Round 1, deleting 6 entries ***
*** Flush is complete after 1 round ***
netadm@amber:~ # ip -6 -s -s ro flush cache
Nothing to flush.
netadm@amber:~ #



  第三个例子是在gated程序挂掉之后,清除所有的BGP路由:

netadm@amber:~ # ip ro ls proto gated/bgp |wc
  1408   9856   78730
netadm@amber:~ # ip -s ro f proto gated/bgp
*** Round 1, deleting 1408 entries ***
*** Flush is complete after 1 round ***
netadm@amber:~ # ip ro f proto gated/bgp
Nothing to flush.
netadm@amber:~ # ip ro ls proto gated/bgp
netadm@amber:~ #




7.10.ip route get -- 获得单个路由



缩写:get、g


简介

  使用这个命令可以获得到达目的地址的一个路由以及它的确切内容。


参数

to ADDRESS(default) 目标地址  
from ADDRESS 源地址  
tos TOS或者dsfield TOS 服务类型  
iif NAME 数据包进来的设备  
oif NAME 数据包出去的设备  
connected ip route get命令至少要有参数to ADDRESS。使用connected参数,如
果没有给出源地址(from ADDRESS),ip就会重新在路由表中查询能够到达目的地址
的源地址,给出获得的第一个源地址到目的地址的路由。如果使用了策略路由,会
有所不同。  

  ip route get命令和ip route show命令执行的操作是不同的。ip route
show命令只是显示现有的路由,而ip route get命令在必要时会派生出新的路由。




输出格式

  这个命令的输出格式和ip route ls相同。



示例

搜索到193.233.7.82的路由
kuznet@amber:~ $ ip route get 193.233.7.82
193.233.7.82 dev eth0  src 193.233.7.65 realms inr.ac
   cache  mtu 1500 rtt 300
kuznet@amber:~ $

搜索目的地址是193.233.7.82,来自193.233.7.82,从eth0设备到达的路由(这条
命令会产生一条非常有意思的路由,这是一条到193.233.7.82的回环路由)
kuznet@amber:~ $ ip r g 193.233.7.82 from 193.233.7.82 iif eth0
193.233.7.82 from 193.233.7.82 dev eth0  src 193.233.7.65
 realms inr.ac/inr.ac
   cache <src-direct,redirect>  mtu 1500 rtt 300 iif eth0
kuznet@amber:~ $

获得一个多播路由,数据包来自主机193.233.7.82,从eth0设备进入,目的地址是
多播组地址224.2.127.254(需要运行多播路由监控程序pimd)。这个命令产生的
路由与上面的不大相同,它包含常规部分和多播部分。常规部分用于把数据包投递
到本地ip监控程序。这里,本地地址不是多播组的成员,因此这个路由没有local
标记,只用于转发数据包。这个路由的输出设备是回环设备。多播部分包含额外的
输出接口。
kuznet@amber:~ $ ip r g 224.2.127.254 from 193.233.7.82 iif eth0
multicast 224.2.127.254 from 193.233.7.82 dev lo  
 src 193.233.7.65 realms inr.ac/cosmos
   cache <mc> iif eth0 Oifs: eth1 pimreg
kuznet@amber:~ $



  下面我们举一个复杂一些的例子。我们首先为一个目标地址添加一个无效的网
关路由,而实际上和这个地址是直连的。

netadm@alisa:~ # ip route add 193.233.7.98 via 193.233.7.254
netadm@alisa:~ # ip route get 193.233.7.98
193.233.7.98 via 193.233.7.254 dev eth0  src 193.233.7.90
   cache  mtu 1500 rtt 3072
netadm@alisa:~ #



  然后,我们ping一下193.233.7.98:

netadm@alisa:~ # ping -n 193.233.7.98
PING 193.233.7.98 (193.233.7.98) from 193.233.7.90 : 56 data bytes
From 193.233.7.254: Redirect Host(New nexthop: 193.233.7.98)
64 bytes from 193.233.7.98: icmp_seq=0 ttl=255 time=3.5 ms
From 193.233.7.254: Redirect Host(New nexthop: 193.233.7.98)
64 bytes from 193.233.7.98: icmp_seq=1 ttl=255 time=2.2 ms
64 bytes from 193.233.7.98: icmp_seq=2 ttl=255 time=0.4 ms

64 bytes from 193.233.7.98: icmp_seq=3 ttl=255 time=0.4 ms
64 bytes from 193.233.7.98: icmp_seq=4 ttl=255 time=0.4 ms
^C
--- 193.233.7.98 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.4/1.3/3.5 ms
netadm@alisa:~ #



  输出结果可以看出,路由器193.233.7.254知道有更好的路由,因此送回一个
ICMP重定向信息。然后,我们再看看路由表的情况:

netadm@alisa:~ # ip route get 193.233.7.98
193.233.7.98 dev eth0  src 193.233.7.90
   cache <redirected>  mtu 1500 rtt 3072
netadm@alisa:~ #
--