ip是iproute2软件包里面的一个强大的网络配置工具,本文将介绍ip命令及其选项。
Ip命令的语法:
ip [OPTIONS] OBJECT [COMMAND [ARGUMENTS]]
OPTIONS:
其中,OPTIONS是一些修改ip行为或者改变其输出的选项。所有的选项都是以-字符开头,分为长、短两种形式。目前,ip支持如下选项:
-V,-Version: 打印ip的版本并退出。
-s,-stats,-statistics: 输出更为详尽的信息。如果这个选项出现两次或者多次,输出的信息将更为详尽。
-f,-family: 这个选项后面接协议种类,包括:inet、inet6或者link,强调使用的协议种类。如果没有足够的信息告诉ip使用的协议种类,ip就会使用默认值。inet或者any。link比较特殊,它表示不涉及任何网络协议。
-4 是-family inet的简写。
-6 是-family inet6的简写。
-0 是-family link的简写。
-o,-oneline 对每行记录都使用单行输出,回行用字符代替。如果你需要使用wc、grep等工具处理ip的输出,会用到这个选项。
-r,-resolve 查询域名解析系统,用获得的主机名代替主机IP地址.
OBJECT :
OBJECT是你要管理或者获取信息的对象。目前ip认识的对象包括:
link: 网络设备
address: 一个设备的协议(IP或者IPV6)地址
neighbour: ARP或者NDISC缓冲区条目
route: 路由表条目
rule: 路由策略数据库中的规则
maddress: 多播地址
mroute: 多播路由缓冲区条目
tunnel IP:上的通道
tuntap:管理 TUN/TAP 设备
netns:管理网络空间
COMMAND :
另外,所有的对象名都可以简写,例如:address可以简写为addr,甚至是a。COMMAND 设置针对指定对象执行的操作,它和对象的类型有关。一般情况下,ip支持对象的增加(add)、删除(delete)和展示(show或者list)。有些对象不支持所有这些操作,或者有其它的一些命令。对于所有的对象,用户可以使用help命令获得帮助。这个命令会列出这个对象支持的命令和参数的语法。如果没有指定对象的操作命令,ip会使用默认的命令。一般情况下,默认命令是list,如果对象不能列出,就会执行help命令。
ARGUMENTS:
ARGUMENTS是命令的一些参数,它们倚赖于对象和命令。ip支持两种类型的参数:flag和parameter。flag由一个关键词组成; parameter由一个关键词加一个数值组成。为了方便,每个命令都有一个可以忽略的默认参数。例如,参数dev是ip link命令的默认参数,因此ip link ls eth0等于ip link ls dev eth0。我们将在后面的章节详细介绍每个命令的使用,命令的默认参数将使用default标出。几乎所有的关键词都可以简写为前几个字母。在交互工作时,简写的方式非常方便,但是我们不建议在脚本中使用简写形式。另外,在讲述过程中,所有的“官方”简写方式都会在文章中列出。
COMMAND :
3.ip的错误信息
由于以下原因,ip可能会操作失败:
命令行语法错误:一个未知的关键词(an unknown keyword);错误的IP地址格式(incorrectly formated IP address)。在这种情况下,ip会打印出错误信息然后退出,在错误信息中会包含失败的原因。有时ip也会打印帮助信息。参数不能通过一致性校验。由于用户没有提供足够的信息,造成ip无法从参数中编译出内核请求。内核返回某些系统调用的错误。ip使用perror(3)输出错误信息,因此输出的错误信息包含一段注释以及系统调用号。内核返回RTNETLINK请求错误。这类错误信息以"RTNETLIK answers"开头。
ip的所有操作都是原子操作。例如,如果ip执行失败,它不会系统的任何东西,ip link command例外,它会修改某些设备参数。
我们无法列出所有的错误信息,尤其是语法错误。不过,错误信息的意思都非常明确。下面,我们列举一些经常出现的错误信息:内核不支持netlink(netlink用于在内核模块和用户之间传递信息),会出现以下错误信息:
Cannot open netlink socket: Invalid value
内核不支持RTNETLINK,会出现以下错误信息:
Cannot talk to rtnetlink: Connect refused
Cannot send dump request: Connect refused
如果在编译内核时没有配置CONFIG_IP_MULTIPLE_TABLES选项。在使用ip规则时会
出现和下面的信息类似的错误信息:
[email=kuznet@kaise]kuznet@kaise[/email]
$ ip rule list
RTNETLINK error: Invalid argument
dump terminated
4.ip link--配置网络设备
对象 link由网络设备,对应的命令显示以及设备的状态变化组成。
命令 set和show(或者list)
4.1.ip link set--改变设备的属性
缩写:set、s
参数:
dev NAME(default) 指定进行操作的网络设备
up/down 起动/关闭设备。
例如:ip link set dev eth0 up
arp on/off 改变网络设备的NOARP选项。
如果设备处于UP状态,不允许进行这个操作。不过,内核和ip都不会对在这种情
况下的这个操作进行检查。在设备处于运行状态下改变这个选项会造成无法预料
的后果。
multicast on/off 改变网络设备的MULTICAST选项。
dynamic on/off 改变网络设备的DYNAMIC选项。
name NAME 把设备的名字改为NAME(例如:eth0)。如果设备处于运行状态或者已
经配置了地址,建议不要进行这个操作。
txqueuelen NUMBER或者txqlen NUMBER 改变设备传输队列的长度。
例如:ip link set dev eth0 txqueuelen 100
mtu NUMBER 改变网络设备MTU(最大传输单元)的值。
例如:ip link set dev eth0 mtu 1500
address LLADDRESS 修改网络设备的MAC地址。
例如:ip link set dev eth0 address 00:01:4f:00:15:f1
broadcat LLADDRESS或者brd LLADDRESS 修改数据链路层广播地址。
注意:对于大多数的网络设备(例如:以太网),修改链路层广播地址会对网络造
成破坏。因此,如果对此没有很深的理解,最好不要使用这个操作。
peer LLADDRESS 当使用点对点连接时,使用这个操作可以修改对端的数据链路层
地址。
注意:ip不能修改PROMISC或者ALLMULTI选项。这两个选项已经比较陈旧,而
且也不应该随便修改。
如果同时修改多个参数,任何一个修改失败,ip都会立即取消操作。这种情况可
能使系统进入无法预料的状态。为了避免出现这种情况,尽量不要使用ip link
set同时修改多个参数,例如:ip link set dev eth0 mtu 1500 txqueuelen 100
。
4.2.ip link show--显示设备属性
缩写:show、list、lst、sh、ls、l
参数
dev NAME(default) NAME指定网络设备名称,例如:eth0。如果省略了这个参数
,所有的设备属性就都会被列出。
up 只显示处于活动状态网络接口的信息。
输出格式
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $ ip link ls eth0
3: eth0: mtu 1500 qdisc cbq qlen 100
link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff:
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $ ip link ls sit0
5:
[email=sit0@NOME]sit0@NOME[/email]
: mtu 1480 qdisc noqueue
link/sit 0.0.0.0 brd 0.0.0.0
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $ ip link ls dummy
2: dummy: mtu 1500 qdisc noop
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $
在显示的信息中,每个引号之前的数字是一个接口索引,用于识别网络接口。这个数字后面是网络接口的名字(例如:eth0、dummy等),它也和网络接口一一对应。不过,在某些情况下,例如:驱动模块被卸载,对应的接口名就会从列表中消失,而其它新创建的接口就会使用相同的名字。系统管理员可以ip link set name修改接口的名字。接口名可以是别的,或者是@NONE。这意味着这个设备被绑定到其它的设备,例如数据包被发送到这个设备,由这个设备封装,并从master设备发出。如果设备名字是NONE,就表示master设备是未知的。接着,我们看到的是mtu(Maximal Transfer Unit,最大传输单元)。它决定这个接口单个数据包能够传输多少数据。qdisc(queuing discipline)显示这个网络接口使用的排队算法。noqueue表
示不对数据包进行排队;noop表示这个网络接口出于黑洞模式,也就是所有进入本网络设备的数据会直接被丢弃。qlen是网络接口传输队列的默认长度。网络接口可以有如下标志:
UP: 这个设备处于运行状态,可以接收、发送数据包。
LOOPBACK: 这个接口不能用于和其它的主机通讯,所有发送到这个接口的数据包都会返回,而且这种接口只能接收反弹回来的数据包。
BROADCAST: 这个设备具有把数据包发送到所有主机的能力。以太网连接是一个很典型的例子。
POINTTOPOINT: 两个节点之间是直接连接的。某个接点发出的所有数据包都会发到对端节点,接收到的所有数据包也都是从对端节点发过来的。
MULTICAST: 这个标志表示设备具有多播能力,能够把数据包发送到某些相邻的网络节点。实际上,广播是多播的一个特例,它的多播组包括连接上的所有节点
。
从定义上,POINTTOPOINT和BROADCAST连接都属于多播。如果网络接口的标志不属于LOOPBACK、BROADCAST和POINTTOPOINT的任何一个,就假定是NMBA(Non-Broadcast Multi-Access)类型。这是最为普遍的一个标志。
PROMISC: 设备处于混杂模式,接收连接上的所有数据,不管目的地址是否是自己。通常,这种模式主要用于网桥和网络监视。
ALLMULTI: 设备接收连接上的所有多播数据包,多播路由器(muliticastrouter)使用这种模式。
NOARP: 这个标志和其它的标志不同,它的含义和涉及的网络协议有关。它一般表示这个设备无需地址解析,软件或者硬件不必借助于系统协议栈的帮助就知道如何把数据包投递到目的地。
DYNAMIC: 这个标志表示这个网络接口是动态建立和撤消的。
SLAVE: 表示这个接口被绑定到其它的网络接口。除此之外,还有其它一些标志。这些标志或者已经过时(例如:NOTRAILERS),或者还没有实现(如:DEBUG),或者只是特定于某些设备(例如:MASTER、AUTOMEDIA、PORTSEL)。因此,在此我们不作讨论。对于PROMISC和ALLMULTI标志,ifconfig和ip显示的值是不同的。ip link ls命令显示的是设备的真正状态,而ifconfig显示的是自己设置的虚拟设备状态。
显示信息的第二行包含和链路层地址(MAC地址)相关的信息。其中,第一个词(ether、sit)定义接口的硬件类型。而接口的硬件类型又决定MAC 地址的格式和语法。默认的格式是硬件的MAC地址和广播地址(如果是点对点连接方式,就是对端的地址),地址是用冒号隔开的16进制数字。不过,默写类型的连接有其特定的地址格式,例如:IP通道的地址格式是用点分开的IP地址。NBMA(Non-Broadcast Multi-Access)连接没有明确定义的广播地址和对端地址。不过,这个域包含一些有用的信息,例如:倚赖于ARP服务器的广播地址。使用这个命令不会显示多播地址,需要使用ip maddr ls命令。详情请参考第9节ip maddr ls。统计信息使用-statistics选项,ip命令会打印出网络接口的统计信息,例如:
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $ ip -s link ls eth0
3: eth0: mtu 1500 qdisc cbq qlen 100
link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
2449949362 2786187 0 0 0 0
TX: bytes packets errors dropped carrier collsns
178558497 1783946 332 0 332 35172
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $
RX:和TX:分别是接收和发送统计信息的开头。得到的统计信息包括:bytes 网络接口发送或者收到的字节数。如果字节数超过数据类型能够表示的最大数值,就会造成回卷。因此,你如果想连续监视这个指标,需要一个用户空间的监控进程周期性地保存这个数据。
packets 网络接口收到或者发送的数据包个数。
errors 发生错误的次数
dropped 由于系统资源限制,而丢弃数据包的数量。
overrun 由于发生堵塞,收到的数据包被丢弃的数量。如果接口发生堵塞,就意味着内核或者你的机器太慢,无法处理收到的数据。
mcast 收到的多播数据包数量,只有很少的设备支持这个选项。
carrier 连接介质出现故障的次数,例如:网线接触不好。
collsns 以太网类型介质发生冲突的事件次数。
compressed 压缩数据包的总数。这个指标只适用于使用VJ头压缩的网络接口。
如果-s选项出现两次或者更多次,ip会输出更为详细的错误信息统计。
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $ ip -s -s link ls eth0
3: eth0: mtu 1500 qdisc cbq qlen 100
link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
2449949362 2786187 0 0 0 0
RX errors: length crc frame fifo missed
0 0 0 0 0
TX: bytes packets errors dropped carrier collsns
178558497 1783946 332 0 332 35172
TX errors: aborted fifo window heartbeat
0 0 0 332
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $
这些错误的名字是纯以太化的,对于其它种类的设备,这些域可能有不同的解释。
5.ip address--协议地址管理
缩写 address、addr、a对象 这里的地址是绑定到网络设备上的协议(IP或者IPv6)地址。每个网络设备至少应该有一个协议地址。而且,一个网络设备可以绑定多个协议地址。
ip addr命令能够显示网络设备的协议地址及其性质,添加新的地址,删除旧的地
址。
命令 add、delete、flush和show(或者list)
5.1.ip address add--添加一个新的协议地址
缩写:add、a
参数
dev NAME 被操作的设备名
local ADDRESS(default) 接口的地址,地址格式和协议有关。IPv4地址使用.进行分隔,而IPv6地址使用冒号分隔。ADDRESS可以跟着一个斜杠和表示掩码位数的十进制数字。
peer ADDRESS 点对点接口对端的地址。ADDRESS也可以跟着一个斜杠和表示掩码位数的十进制数字。
broadcast ADDRESS 接口的广播地址。为了方便,可以使用+和-(注1)代替广播地址。例如:
ip addr add local 192.168.1.1/24 brd + dev eth0
ip addr add local 192.168.1.1/28 brd - dev eth0
label NAME 为每个地址设置一个字符串作为标签。为了和Linux-2.0的网络别名兼容,这个字符串必须以设备名开头,接着一个冒号,例如:
ip addr add local 192.168.4.1/28 brd + label eth0:1 dev eth0
scope SCOPE_VALUE(注2) 设置地址的有效范围,它用于内核为数据包设置源地址。有效的范围在/etc/iproute2/tr_scopes文件列出,系统预先设定了一些范围值:
global 这个地址全局有效。
site 这个地址是局部连接,也就是只有目标地址是这个设备地址时,才有效。
site (只适用于IPv6)地址在站点内部有效。
host 地址在主机内部有效。
注1:使用-,ip addr ls显示的是网络地址;使用+,ip addr ls显示的是广播地址。
注2:有关scope,在附录A中有更为详细的解释。示例
在回环设备上添加一个回环地址:
#ip addr add 127.0.0.1/8 dev lo brd + scope host
在以太网接口eth0上增加一个地址10.0.0.1,掩码长度为24位(155.155.155.0),
标准广播地址,标签为eth0:Alias:
#ip addr add 10.0.0.1/24 brd + dev eth0 label eth0:Alias
5.2.ip address delete--删除一个协议地址
缩写:delete、del、d
参数
这个命令的参数和ip addr add命令的参数一致。其中,只有设备名是必需的参数,其它都是可选的。如果没有给定除设备名之外的其它参
数,ip就会删除这个设备的第一个地址示例
删除回环设备的一个回环地址。不过,最好不要作这种尝试。
#ip addr del 127.0.0.1/8 dev lo
以下shell代码可以取消设备上的所有IP地址。
while ip -f inet add del dev eth0;do
:nothing
done
另外,可以使用ip addr flush命令取消IP地址
5.3.ip address show--显示协议地址
缩写:show、list、lst、sh、ls、l
参数
dev NAME(default) 设备的名字
scope SCOPE_VAL 只列出这个范围的地址
to PREFIX 只列出和PREFIX匹配的地址,例如:
ip addr ls to 192.168.1.1
label PATTERN 只列出标签匹配PATTERN的地址,PATTERN是一个shell风格的正则表达式。
dynamic和permanent 这两个参数只适用于IPv6。使用dynamic,ip就只列出动态地址;使用permanent,ip就只列出固定地址。
tentative 这个参数只适用于IPv6,只列出没有通过重复地址检测[参考2]的地址。
deprecated 这个参数只适用于IPv6,只列出deprecated[参考2]地址。
primary和secondary 只列出主(primary)或从(secondary)地址。输出格式
[email=duznet@alisa]duznet@alisa[/email]
:~ $ ip addr ls eth0
3: eth0: mtu 1500 qdisc cbq qlen 100
link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff
inet 193.233.7.90/24 brd 193.233.7.255 scope global eth0
inet6 3ffe:2400:0:1:2a0:ccff:fe66:1878/64 scope global dynamic
valid_lft forever preferred_lft 604746sec
inet6 fe80::2a0:ccff:fe66:1878/10 scope link
[email=duznet@alisa]duznet@alisa[/email]
:~ $
输出的头两行和ip link ls的输出是相同的。接着是IP和IPv6地址、广播地址以及其它的地址属性:范围(scope)、标志(flag)和标签(label)。地址标志由内核设置,系统管理员不能修改。目前,内核定义了以下标志:
secondary 为输出的数据包选择默认源地址时,内核不使用这个地址。如果一个设备已经有了一个地址,又给它设置了同一网段的不同地址,第二个地址就成为从 (secondary)地址。例如:eth0已经有一个地址192.168.1.108/24,如果又给它一个地址192.168.1.3/24, 192.168.1.3/24的就会被内核标记为从地址。
dynamic 这个地址是通过无状态的自动配置建立的(stateless autoconfiguration)[参考2]。如果地址仍然有效,在输出中,还包括两个时间信
息。preferred_lft期满后,地址就会变成 deprecated状态;valiid_lft期满后,地址将失效。deprecated 这个地址是不允许的,也就是说,地址虽然有效,但是不能使用它建立新的连接。
tentative 由于重复地址监测[参考2]还没有完成或者监测失败,这个地址不能使用。
5.4.ip address flush--清除协议地址
缩写:flush、f
简介
这个命令可以清除按照某种条件选择的协议地址。参数
这个命令的参数和ip address show相同。唯一的区别是,如果不给定参数它什么都不会做。警告:这个命令(和后面讨论的所有flush命令)非常危险。如果出现错误,将无法恢,它会清除被操作的地址。statistics选项
如果在ip addr flush命令中使用了-statistics选项,命令将输出更为详尽的信息。输出的信息包括删除地址的数目和清理地址列表的圈数。如果使用了两次-s选项,ip addr flush会按照上节叙述的格式输出所有被删除的地址。
示例
删除属于私网10.0.0.0/8的所有地址:
[email=netadm@amber]netadm@amber[/email]
:~ # ip -s -s a f to 10/8
2: dummy inet 10.7.7.7/16 brd 10.7.255.255 scope global dummy
3: eth0 inet 10.10.7.7/16 brd 10.10.255.255 scope global eth0
4: eth1 inet 10.8.7.7/16 brd 10.8.255.255 scope global eth1
*** Round 1,deleting 3 addresses ***
*** Flush is complete after 1 round ***
[email=netadm@amber]netadm@amber[/email]
:~ #
取消所有以太网卡的IP地址
[email=netadm@amber]netadm@amber[/email]
:~ # ip -4 addr flush label "eth0"
最后一个例子是对IPv6地址的操作。在启动了转发或者关闭了自动配置之后,你需要取消通过无状态地址自动配置获得的主机地址:
[email=netadm@amber]netadm@amber[/email]
:~ # ip -6 addr flush dynamic
6.ip neighbour--neighbour/arp表管理命令
缩写 neighbour、neighbor、neigh、n
对象 邻接(neighbour)对象实现同一网段协议地址和链路层地址的绑定。在内核中,这些条目被组织到表中。IPv4的相邻表也被叫做ARP表。
ip neighbour命令支持对条目及其属性的显示、添加和删除。
命令 add、change、replace、delete、fulsh、show(或者list)
6.1.ip neighbour add -- 添加一个新的邻接条目
ip neighbour change--修改一个现有的条目
ip neighbour replace--替换一个已有的条目
缩写:add、a;change、chg;replace、repl
简介:这三个命令用来建立一个邻接表的条目或者更新现有的邻接表条目。
参数
to ADDRESS(default) 相邻的协议地址。可以是IPv4或者IPv6。
dev NAME 和相邻节点连接的设备。
lladdr LLADDRESS 邻居的链路层地址。LLADDRESS可以为空。
nud NUD_STATE 邻接条目的状态。nud是Neighbour Unreachability Detection的
缩写。可能的状态包括:
permanent--邻接条目永远有效并且只能由管理员删除。
noarp--邻接条目有效,不必对其有效性进行确认。在其生命期期满时会被删除。
reachable--在超时时间之内,这个邻接条目是有效的。
stale--这个邻接条目是有效的,但是比较可疑。如果条目是有效的,ip neigh不
会改变邻接状态,也不会修改其地址。
示例
在设备eth0上,为地址10.0.0.3添加一个permanent ARP条目:
ip neigh add 10.0.0.3 lladdr 0:0:0:0:0:1 dev eth0 nud perm
把状态改为reachable
ip neigh chg 10.0.0.3 dev eth0 nud reachable
6.2.ip neighbour delete--删除一个邻接条目
缩写:delete、del、d
简介
这个命令用来删除一个邻接条目参数
这个命令的参数和ip neigh add命令的相同,只不过lladdr和nud将被忽略。
示例
删除设备eth0上的一个ARP条目10.0.0.3
ip neigh del 10.0.0.3 dev eth0
执行了删除命令之后,被删除的条目不会马上消失,它会在系统的下次垃圾收集时被删除。如果被操作的条目正在使用,将不能被删除。
警告:如果试图删除或者手工修改一个由内核建立的noarp条目,会导致一些不可预知的行为。
6.3.ip neighbour show--显示网络邻居的信息
缩写:show、list、sh、ls
简介
这个命令用于显示网络邻居信息。
参数
to ADDRESS(default): 指定要显示的地址。
dev NAME: 只显示设备NAME的邻居。
Unused: 只显示当前没有使用的邻居
nud NUD_STATE: 只列出处于NUD_STATE状态的邻接条目。NUD_STATE的值下面将会介绍。nud all表示所有的状态。这个选项可以使用多次。如果缺少这个选项,ip会列出除none和noarp状态的所有条目。
输出格式
[email=duznet@alisa]duznet@alisa[/email]
:~ $ ip neigh ls
:: dev lo lladdr 00:00:00:00:00:00 nud noarp
fe80::200:cff:fe76:3f85 dev eth0 lladdr 00:00:0c:76:3f:86 router
nud stale
0.0.0.0 dev lo lladdr 00:00:00:00:00:00 nud noarp
193.233.7.254 dev eth0 lladdr 00:00:0c:76:3f:85 nud reachable
193.233.7.85 dev eth0 lladdr 00:e0:1e:63:39:00 nud stale
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $
每行的第一部分是网络邻居的协议地址。第二部分是设备名。省下的部分是
这个邻接条目的信息。
lladdr是这个设备的链路层地址。
nud是条目代表连接的状态。下面是状态的完整列表和简单描述:
none 网络邻居的状态为空。
incomplete 这个邻居正在被解析。
reachable 网络邻居有效并且可达。
stale 邻居有效,但是可能不可达。因此,内核将在首次传输时进行检查。
delay 一个数据包已经发到处于stale的网络邻居,内核在等待应答信息。
probe delay计时器过期,还没有收到确认信息。内核开始使用ARP/NDISC消息包
探测这个网络邻居。
failed 解析失败。
noarp 网络邻居有效,不必检查。
permanent 这是一个noarp条目,只有系统管理员可以从邻接表中把它删除。
在这些状态中,除了none、faliled和incomplete.
IPVv6网络邻居可以有一个叫做router的标志,它表示这个节点是一个IPv6路
由器。
-statistics
-statistics选项可以显示很多有用的信息。例如:
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $ ip -s n ls 193.233.7.254
193.233.7.254. dev eth0 lladdr 00:00:0c:76:3f:85 ref 5
used 12/13/20 nud reachable
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $
输出信息里面多了ref和用斜缸分开的三个时间。ref表示有多少用户使用这
个条目;三个时间分别是使用时间、确认时间和刷新时间。因此,上面输出中的
时间表示:
条目12秒之前刚刚使用过;
13秒之前被确认;
20秒之前被更新。
6.4.ip neighbour flush--清除邻接条目
缩写:flush、f
简介
这个命令用来清除符合某个条件的邻接表条目。
参数
这个命令的参数和ip neigh sh相同。不同之处是,如果没有参数,它什么也
不会做。而且,默认情况下,被删除的条目不包括处于permanent和noarp状态的
条目。
-statistics
使用了-statistics选项,这个命令的输出将更为详尽。它会输出删除的条目
数和清除邻接表遍历的次数。如果使用了两个-s选项,命令的输出将包括被删除
条目的信息。
示例
[email=netadm@alisa]netadm@alisa[/email]
:~ # ip -s -s n f 193.233.7.254
193.233.7.254 dev eth0 lladdr 00:00:0c:76:3f:85 ref 5
used 12/13/20 nud reachable
*** Round 1,deleting 1 entries ***
*** Flush is complete after 1 round ***
[email=netadm@alisa]netadm@alisa[/email]
:~ #
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协议的路由个数
[email=kuznet@amber]kuznet@amber[/email]
:~ $ ip route ls proto gated/bgp |wc
1413 9891 79010
[email=kuznet@amber]kuznet@amber[/email]
:~ $
计算路由缓存里面的条数,由于被缓存路由的属性可能大于一行,以此需要使用
-o选项
[email=uznet@amber]uznet@amber[/email]
:~ $ ip -o route ls cloned |wc
159 2543 18707
[email=kuznet@amber]kuznet@amber[/email]
:~ $
输出格式
通常,在这个命令输出的信息中,每个路由纪录占一行。不过,有时某些纪
录可能会超过一行,例如被克隆出来的路由或者包含一些额外
的信息。如果在命令中使用了-o选项,在每个纪录中,会使用代替回车作为回行
标记。例如:
[email=kuznet@amber]kuznet@amber[/email]
:~ $ 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
[email=kuznet@amber]kuznet@amber[/email]
:~ $
如果是列出被克隆的条目,输出信息将是另外的形式。例如:
[email=kuznet@amber]kuznet@amber[/email]
:~ $ 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 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
[email=kuznet@amber]kuznet@amber[/email]
:~ $
输出信息的第二行是以关键词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中的所有网关路由(例如:在路由监控程序挂
掉之后):
[email=netadm@amber]netadm@amber[/email]
:~ # ip -4 ro flush scope global type unicast
第二个例子是清除所有被克隆出来的IPv6路由:
[email=netadm@amber]netadm@amber[/email]
:~ # 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 ***
[email=netadm@amber]netadm@amber[/email]
:~ # ip -6 -s -s ro flush cache
Nothing to flush.
[email=netadm@amber]netadm@amber[/email]
:~ #
第三个例子是在gated程序挂掉之后,清除所有的BGP路由:
[email=netadm@amber]netadm@amber[/email]
:~ # ip ro ls proto gated/bgp |wc
1408 9856 78730
[email=netadm@amber]netadm@amber[/email]
:~ # ip -s ro f proto gated/bgp
*** Round 1, deleting 1408 entries ***
*** Flush is complete after 1 round ***
[email=netadm@amber]netadm@amber[/email]
:~ # ip ro f proto gated/bgp
Nothing to flush.
[email=netadm@amber]netadm@amber[/email]
:~ # ip ro ls proto gated/bgp
[email=netadm@amber]netadm@amber[/email]
:~ #
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的路由
[email=kuznet@amber]kuznet@amber[/email]
:~ $ 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
[email=kuznet@amber]kuznet@amber[/email]
:~ $
搜索目的地址是193.233.7.82,来自193.233.7.82,从eth0设备到达的路由(这
条命令会产生一条非常有意思的路由,这是一条到193.233.7.82的回环路由)
[email=kuznet@amber]kuznet@amber[/email]
:~ $ 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 mtu 1500 rtt 300 iif eth0
[email=kuznet@amber]kuznet@amber[/email]
:~ $
获得一个多播路由,数据包来自主机193.233.7.82,从eth0设备进入,目的地址
是多播组地址224.2.127.254(需要运行多播路由监控程序pimd)。这个命令产生
的路由与上面的不大相同,它包含常规部分和多播部分。常规部分用于把数据包
投递到本地ip监控程序。这里,本地地址不是多播组的成员,因此这个路由没有
local标记,只用于转发数据包。这个路由的输出设备是回环设备。多播部分包含
额外的输出接口。
[email=kuznet@amber]kuznet@amber[/email]
:~ $ 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 iif eth0 Oifs: eth1 pimreg
[email=kuznet@amber]kuznet@amber[/email]
:~ $
下面我们举一个复杂一些的例子。我们首先为一个目标地址添加一个无效的
网关路由,而实际上和这个地址是直连的。
[email=netadm@alisa]netadm@alisa[/email]
:~ # ip route add 193.233.7.98 via 193.233.7.254
[email=netadm@alisa]netadm@alisa[/email]
:~ # 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
[email=netadm@alisa]netadm@alisa[/email]
:~ #
然后,我们ping一下193.233.7.98:
[email=netadm@alisa]netadm@alisa[/email]
:~ # 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
[email=netadm@alisa]netadm@alisa[/email]
:~ #
输出结果可以看出,路由器193.233.7.254知道有更好的路由,因此送回一个
ICMP重定向信息。然后,我们再看看路由表的情况:
[email=netadm@alisa]netadm@alisa[/email]
:~ # ip route get 193.233.7.98
193.233.7.98 dev eth0 src 193.233.7.90
cache mtu 1500 rtt 3072
[email=netadm@alisa]netadm@alisa[/email]
:~ #
有关路由策略管理和多播地址管理的部分
8.ip route -- 路由策略数据库管理命令
8.1.缩写
rule、ru
8.2.对象
路由策略数据库的规则用于控制选择路由的算法。
Internet上采用的路由算法一般是基于数据包目的地址的。理论上,也可以
由TOS域决定,不过这没有实际应用。要了解经典路由算法的详细情况请参考RFC
-1812。
而在某些情况下,我们不只是需要通过数据包的目的地址决定路由,可能还
需要通过其他一些域:源地址、IP协议、传输层端口甚至数据包的负载。这就叫
做:策略路由(policy routing)。
注意:策略路由(policy routing)不等于路由策略(rouing policy)。
在这种情况下,传统的基于目的地址的路由表就无法满足要求了,需要使用
路由策略数据库(routing policy database,RPDB)代替,通过它选择执行某些路
由。这些规则可以由很多不同的状态,而且它们没有天生的次序,要由系统管理
员决定。RPDB可以匹配以下的域:
数据包的源地址;
数据包的目的地址;
服务类型(Type of Service);
进入的网络接口;
匹配IP协议和传输层端口也是可能的,不过这要依靠iptables或者ipchains
通过fwmark为某些数据包做标记,并重定向。
每个路由策略由一个选择符(selector)和一个操作(action)组成。系统按照
顺序搜索路由策略数据库,把选择符和{源地址、目的地址、进入接口、tos、
fwmark}等关键词进行匹配,如果匹配成功,就执行action定义的操作。操作或者
成功返回,或者失败并且中止对路由策略。否则,系统继续查询路由策略数据库
。
操作如何定义?最原始的操作是选择下一跳(nexthop)和输出设备(output
device)。Cisco iOS使用这种方式,我们姑且把这叫做匹配并设置(match & set)
。而Linux的方式则更为灵活,Linux允许的操作包括:基于目的地址的路由表查
询以及按照最长匹配的原则从路由表中选择路由。因此,匹配并设置(match &
set)的方式只是一个最简单的特例而已。
再系统启动时,内核会为路由策略数据库配置三条缺省的规则:
优先级 选择符 操作 解释
0 匹配任何条件 查询路由表local(ID 255) 路由表local是一个特殊的路由表,
包含对于本地和广播地址的高优先级控制路由。rule 0非常特殊,不能被删除或
者覆盖。
32766 匹配任何条件 查询路由表main(ID 254) 路由表main(ID 254)是一个通常
的表,包含所有的无策略路由。系统管理员可以删除或者使用
另外的规则覆盖这条规则。
32767 匹配任何条件 查询路由表default(ID 253) 路由表default(ID 253)是一
个空表,它是为一些后续处理保留的。对于前面的缺省策略没有匹配到的数据包
,系统使用这个策略进行处理。这个规则也可以删除。
不要混淆路由表和策略:规则指向路由表,多个规则可以引用一个路由表,
而且某些路由表可以没有策略指向它。如果系统管理员删除了指向某个路由表的
所有规则,这个表就没有用了,但是仍然存在,直到里面的所有路由都被删除,
它才会消失。
8.3.规则类型
路由策略规则数据库可以包括如下类型的规则:
unicast 返回从被引用的路由表中发现的路由。
blackhole 丢弃数据包,不做任何反应。
unreachable 产生网络不可达(Network is unreachable)的ICMP错误信息 。
prohibit 产生通讯被禁止(Communication is administratively prohibited)的
ICMP错误信息。
nat 把数据报的源地址转换为其它的值。详情请参考附录C。
8.4.命令
add、delete、show(或者list)
8.5.ip rule add -- 插入新的规则。
ip rule delete -- 删除规则。
缩写:add、a;delete、del、d
参数
type TYPE(default): 这个规则的类型。有效的类型上一节已经介绍过了。
from PREFIX: 匹配的源地址
iif NAME: 选择数据包进入的设备。如果接口是回环设备,这个规则就只匹配源
于本机的数据包。这意味着,你可以为本机发出的数据包和要转发的数据包分别
建立路由表,使两者完全隔离。
tos TOS或者dsfield TOS: 选择匹配的TOS值
fwmark MARK: 选择要匹配的fwmark值
priority PREFERENCE: 设置这个规则的优先级。每个规则的优先级都应该明确
设置为一个唯一的数值。实际上,由于历史的原因,ip roule add命令无需任何
优先级的值,也不必是唯一的。如果用户没有在命令中提供优先级的值,内核会
自动选择。如果用户提供的优先级值已经存在,内核也不会拒绝这次请求,而是
在相同优先级的规则前面插入新的规则。
table TABLEID: 如果规则选择符匹配,就被查询的路由表识别符。
realms FROM/TO: 如果规则匹配和路由表查询成功,选择的realms值。
nat ADDRESS: 设置要进行网络地址转换的IP地址段。ADDRESS或者是进行网络地
址转换ip地址段,或者是一个本机地址,甚至可以是0。
警告:使用上面两个命令对路由策略数据库进行的任何修改都不会马上生效。只
有使用ip route flush cach命令刷新路由缓存之后才会生效。
示例
通过路由表inr.ruhep路由来自源地址为192.203.80/24的数据包
ip ru add from 192.203.80/24 table inr.ruhep prio 220
把源地址为193.233.7.83的数据报的源地址转换为192.203.80.144,并通过表1进
行路由
ip ru add from 193.233.7.83 nat 192.203.80.144 table 1 prio 320
删除无用的缺省规则
ip ru del prio 32767
注:32767和32766都可以删除,而0是不可以删除的。
8.7.ip rule show -- 列出路由规则
缩写:show、list、sh、ls、l
参数
好消息,这个命令没有参数。
输出格式
[email=kuznet@amber]kuznet@amber[/email]
:~ $ ip ru ls
0: from all lookup local
200: from 192.203.80.0/24 to 193.233.7.0/24 lookup main
210: from 192.203.80.0/24 to 192.203.80.0/24 lookup main
220: from 192.203.80.0/24 lookup inr.ruhep realms
inr.ruhep/radio-msu
300: from 193.233.7.83 to 193.233.7.0/24 lookup main
310: from 193.233.7.83 to 192.203.80.0/24 lookup main
320: from 193.233.7.83 lookup inr.ruhep map-to 192.203.80.144
32766: from all lookup main
[email=kuznet@amber]kuznet@amber[/email]
:~ $
每行第一部分的数字是规则的优先级,接着是选择符。
关键词lookup后面接着路由表识别符。
如果规则要进行网络地址转换,还需要一个关键词map-to设置转换以后的地
址。
上面的示例非常简单,192.203.80.0/24和193.233.7.0/24组成内部网络,但
是它们向外发送数据包要通过不同的路由。主机193.233.7.83和外界会话时,地
址需要转换为192.203.80.144。
9.ip maddress -- 多播地址管理
9.1.对象
这个命令管理的对象是多播地址。
9.2.命令
add、delete、show(或者list)
9.3.ip maddress show -- 列出多播地址
缩写:show、list、sh、ls、l
参数
dev NAME(defautl) 设备名
输出格式
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $ ip maddr ls dummy
2: dummy
link 33:33:00:00:00:01
link 01:00:5e:00:00:01
inet 224.0.0.1 users 2
inet6 ff02::1
[email=kuznet@alisa]kuznet@alisa[/email]
:~ $
输出的第一行是设备的索引和设备名。后面几行是多播地址,每行由协议识
别符开头。关键词link表示这是链路层多播地址。
如果一个多播地址有几个用户,那么用户数就在users关键词之后列出。上面
的例子没有出现关键词static,它表示这个地址是由ip maddr add命令加入的。
9.4.ip maddress add -- 加入多播地址
ip maddress delete -- 删除多播地址
缩写:add、a;delete、del、d
简介
使用这两个命令,我们可以添加/删除在网络接口上监听的链路层多播地址
。这个命令只能管理链路层地址。
参数
address LLADDRESS(default) 链路层多播地址。
dev NAME 加入/脱离这个多播地址的设备。
示例
让我们继续上一小节的例子
[email=netadm@alisa]netadm@alisa[/email]
:~ # ip maddr add 33:33:00:00:00:01 dev dummy
[email=netadm@alisa]netadm@alisa[/email]
:~ # ip -O maddr ls dummy
2: dummy
link 33:33:00:00:00:01 users 2 static
link 01:00:5e:00:00:01
[email=netadm@alisa]netadm@alisa[/email]
:~ # ip maddr del 33:33:00:00:00:01 dev dummy
注意:ip命令和内核都不会检查多播地址的有效性。这意味着你可以使用
unicast地址代替多播地址。大多数驱动都会忽略unicast地址,但是有些驱动(例
如:tulip)会把这个unicast地址加入其过滤器。这样作的效果有些奇怪,如果你
使用了别的主机或者路由器的地址作为多播地址,你就可以收到发送到它们的数
据包。不过,这并非一个bug,而是内核的一个功能。它可以用于网络监视。
这一部分是关于多播路由和通道的内容,以及策略路由的一些相关内容。
10.ip mroute -- 多播路由缓存管理
10.1.缩写
mroute、mr
10.2.对象
这个命令的操作对象是多播路由缓存条目,这个缓存是由一个用户空间的多
播路由监控进程(例如pimd或者mrouted)建立的。
目前,由于受和多播路由引擎接口的限制,还不能通过ip命令修改多播路由对
象,因此我们只能查看。
10.3.命令
show或者list
10.4.ip mroute show -- 列出多播路由缓存条目
缩写:show、list、sh、ls、l
参数
to PREFIX(default): 选择到目的多播地址是PREFIX。
iif NAME: 接收多播数据包的网络接口。
from PREFIX PREFIX:选择多播路由的IP源地址。
输出格式
[email=kuznet@amber]kuznet@amber[/email]
:~ $ ip mroute ls
(193.232.127.6, 224.0.1.39) Iif: unresolved
(193.232.244.34, 224.0.1.40) Iif: unresolved
(193.233.7.65, 224.66.66.66) Iif: eth0 Oifs: pimreg
[email=kuznet@amber]kuznet@amber[/email]
:~ $
多播路由缓存条目是(S,G)形式的,S是源地址,G是多播组。iif是接收多播
数据包的网络接口,如果设备名是关键词unresolved,就表示路由监控进程不能
解析这个条目;接下来的关键词是oif,它后面跟着一些输出网络接口,接口之间
用空格分开。
统计信息
使用-statistics选项,我们可以得到更为详细的输出信息,包括:数据包的
数量,通过这条路由转发的字节数以及到达错误接口的数据包数量(如果有)。
[email=kuznet@amber]kuznet@amber[/email]
:~ $ ip -s mr ls 224.66/16
(193.233.7.65, 224.66.66.66) Iif: eth0 Oifs: pimreg
9383 packets, 300256 bytes
[email=kuznet@amber]kuznet@amber[/email]
:~ $
11.ip tunnel -- 通道配置
11.1.缩写
tunnel、tunl
11.2.对象
ip tunnel命令的操作对象是网络通道(tunnel)。所谓通道(tunnel)是指把数
据包封装到IPv4数据包中,使用IP协议发出。有关通道的更多信息,请参考
iproute的文档Tunnels over IP in Linux-2.2。
11.3.命令
add、delete、change、show或者list
11.4.ip tunnel add -- 添加新的通道
ip tunnel change -- 修改现有的通道
ip tunnel delete -- 删除一个通道
缩写:add、a;change、chg;delete、del、d
参数
name NAME(default) :选择通道设备名。
mode MODE: 设置通道模式。有效的模式包括:ipip、sit和gre。
remote ADDRESS: 设置通道远端地址。
local ADDRESS: 设置进入通道数据包的固定本地地址,必须是在本机另外一个
接口上的地址。
ttl N: 设置进入通道数据包的TTL为N。N是一个1—255之间的数字。0是一个特
殊的值,表示这个数据包的TTL值是继承(inherit)的。ttl参数的缺省值是:
inherit。
tos T:或者dsfield T 设置进入通道数据包的TOS域,缺省是inherit。
dev NAME: 把通道绑定到设备NAME,以便进入通道的数据包只能通过NAME设备路
由,并且当对端发生变化时,不能够在另外的设备解开封装。
nopmtudisc:在这个通道上禁止路径最大传输单元发现( Path MTU Discovery)。
默认情况下,这个功能是打开的。注意:这个选项和固定的ttl是不兼容的,如果
使用了固定的ttl参数,系统会打开路径最大传输单元发现( Path MTU
Discovery)功能。
key k,ikey k,okey k: 只适用于GRE通道,设置keyed GRE通道的key。K或者是
一个数字或者是IP地址形式的数字序列。参数key在通道的双向使用,ikey和okey
为输入和输出设置不同的key。
csum,icsum,ocsum: 只用于GRE通道,计算进入通道数据包的校验和。ocsum表示
只计算出去的数据包的校验和;icsum表示只计算进入的数据包的校验和;而csum
等于icsum ocsum。
seq,iseq,oseq: 只适用于GRE通道,顺序发送/接收数据包。oseq使向外的数据
包顺序发送;iseq要求所有进入的数据包都是按照顺序的;而seq等于iseq oseq
。
示例
建立一个点对点通道,最大TTL是32
[email=netadm@amber]netadm@amber[/email]
:~ # ip tunnel add Cisco mode sit remote 192.31.7.104
local 192.203.80.1 ttl 32
11.4.ip tunnel show -- 列出现有的通道
缩写:show、list、sh、ls、l
参数
无
输出格式
[email=kuznet@amber]kuznet@amber[/email]
:~ $ ip tunnel ls Cisco
Cisco: ipv6/ip remote 192.31.7.104 local 192.203.80.142 ttl 32
[email=kuznet@amber]kuznet@amber[/email]
:~ $
输出的第一部分是通道的设备名,接着是通道模式。下面就是设置通道时的
各个参数。
统计信息
[email=kuznet@amber]kuznet@amber[/email]
:~ $ ip -s tunl ls Cisco
Cisco: ipv6/ip remote 192.31.7.104 local 192.203.80.142 ttl 32
RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts
12566 1707516 0 0 0 0
TX: Packets Bytes Errors DeadLoop NoRoute NoBufs
13445 1879677 0 0 0 0
[email=kuznet@amber]kuznet@amber[/email]
:~ $
以上输出结果里面的数字和使用ip -s link show的输出是一样的,但是每个
标志都是特定于通道的。
CsumErrs: 对于打开校验和检验的GRE通道,这个数字是由于校验和错误而丢弃
的数据包数量。
OutOfSeg: 在打开顺序功能的GRE通道内,由于顺序错误而丢弃的数据包数量。
Mcasts: 在GRE通道上接收到的多播数据包的数量。
DeadLoop: 由于通道是回环到自己而没有传输的数据包数目。
NoRoute: 由于到对端没有路由而没有被传输的数据包数目。
NoBufs: 由于内核不能分配缓冲区而没有被传输的数据包数目。
12.ip monitor和rtmon -- 状态监视
ip命令可以用于连续地监视设备、地址和路由的状态。这个命令选项的格式
有点不同,命令选项的名字叫做monitor,接着是操作对象:
ip monitor [ file FILE ] [ all | OBJECT-LIST ]
OBJECT-LIST是一些被监控的对象,它可以包括link、address和route。如果
没有给出file参数,ip命令就打开RTNETLINK,在上面监听,
并把状态的变化输出到标准输出设备。
如果使用了file参数,ip命令就不是在RTNETLINK上监听,而是打开由file参
数指定的包含RTNETLINK信息的二进制文件,把解析的结果显示出来。这种历史文
件可以有工具产生。这个工具具有和ip monitor命令的语法类似的命令行。理想
的情况是,在网络配置命令起动之前运行rtmon命令(当然,你可以在任意的时间
起动rtmon,它会记录从起动开始的状态变化)。你可以在起动脚本中插入以下命
令行:
rtmon file /var/log/rtmon.log
如果我们执行如下命令:
[root@nixe0n root]ip route add dev eth0 to 61.133.4.7 via 211.99.114.65
[root@nixe0n root]ip route del dev eth0 to 61.133.4.7
然后,我们使用ip monitor命令分析/var/log/rtmon.log会得到如下输出结
果:
[root@nixe0n root]ip monitor file /var/log/rtmon.log r
Timestamp: Wed Nov 6 20:25:54 2002 733331 us
1: lo: mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: mtu 1500 qdisc pfifo_fast
link/ether 00:01:4f:00:15:f1 brd ff:ff:ff:ff:ff:ff
Timestamp: Wed Nov 6 20:25:58 2002 33700 us
61.133.4.7 via 211.99.114.65 dev eth0
Timestamp: Wed Nov 6 20:25:59 2002 924124 us
Deleted 61.133.4.7 via 211.99.114.65 dev eth0
[root@nixe0n root]
13.rtacct -- 路由范围和策略传播
在使用OSPF或者BGP协议的路由器上,其路由表可能会很大。如果我们需要对
其进行归类或者计算通过每条路由的数据包,就需要保留很多信息。更糟糕的是
,如果我们需要区别的不止是数据包的目的地址,还要包括它们的源地址,这个
任务就更为复杂了,几乎无法解决。
对于这个问题,Cisco IOS Release 12.0 Quality of Service Solutions
Configuration Guide: Configuring QoS Policy Propagation
via Border Gateway Protocol提出了一个解决方案,就是把策略从路由协议迁移
到转发引擎。基本上,通过BGP的Cisco策略迁移(Cisco Policy Propagation via
BGP)就是基于此种方式,它使路由器保留所有和转发引擎关系紧密的RIB(Routing
Information Base,路由信息库),以便策略路由规则能够监查所有的路由属性,
包括ASPATH的信息和团体(community)字符串。
而Linux把这分为由用户空间监控维护的路由信息库(Routing Infomation
Base,RIB),和内核层的转发信息库(Forwarding Infomation Base,FIB)。
这是我们的幸运,因为还有另外的解决方案,而这个方案允许更为灵活的策
略和更为丰富的语义。
换句话说,可以在用户空间根据路由的属性把它们归类,例如:BGP路由的
ASPATH、团体(community);OSPF路由的标记和它们的范围。而管理员手工添加路
由时,也知道它们的属性。按照这个标准划分的集合(我们把它们叫做realm)数量
就很少了,因此按照路由的源地址和目的地址进行完全的分类就可以管理了。
因此,每个路由都可以被分配到一个范围(realm)中。一般这是有路由监控进
程作的,不过对于静态路由,也可以使用ip route命令手工处理。
在某些情况下(例如路由监控进程不理解realm)为了方便,漏掉的realm可
以由路由策略规则补齐。
内核使用如下算法计算每个数据包的源范围(realm)和目的范围(realm):
If route has a realm, destination realm of the packet is set to it.
If rule has a source realm, source realm of the packet is set to it. If
destination realm was not get from route and rule has
destination realm, it is also set.
If at least one of realms is still unknown, kernel finds reversed route
to the source of the packet.
If source realm is still unknown, get it from reversed route.
If one of realms is still unknown, swap realms of reversed routes and
apply step 2 again.
这个过程完成后,我们就知道了数据包的源范围和目的范围。如果某些还是
未知,它就会被设置为0(realm unknown) 范围(realm)主要还是由TC(Traffic
Control)的路由类别(route classifier)使用,我们可以使用路由类别把数据包
分配到给不同的流量类(trafffic class),为数据包计数,以及为它们制定调度
策略。
相对于TC,使用realm为进入的数据包计数就简单多了,但这是一个非常有用
的应用。内核可以根据realm收集总结数据包统计信息。在用户空间,我们可以使
用工具rtacct查看这些信息。例如:
[email=kuznet@amber]kuznet@amber[/email]
:~ $ rtacct russia
Realm BytesTo PktsTo BytesFrom PktsFrom
russia 20576778 169176 47080168 153805
[email=kuznet@amber]kuznet@amber[/email]
:~ $
结果表示,这个路由器收到153805个来自russia地区的数据包,并且向
russia转发了169176个数据包。russia范围由ASPATH(路径自治系统)在俄罗斯的
路由组成。
14:netns
ip netns 管理网络,添加不同的网络,到达网络隔离的效果