在日常的工作环境中,我们习惯使用ping来测试网络的连通性。如果ping不通,我们往往会怀疑路由配置有误。我们知道路由是什么,IP地址就是网络世界的门牌号。你可以通过IP地址访问天上很远的网站,那么数据是如何到达网站的呢?它依赖于路径上每个节点的路由。路由,简单的说,就是指导IP数据包应该去哪里的标志。一般来说,主机会在以下两次进行路由查询。当收到消息时,查询路由决定是将消息发送到本机(LOCALIN),还是通过本机发送消息的出接口(FORWARD)转发消息。注意报文的出接口,需要开启net/ipv4/ip_forward路由表进行转发。以一个典型的主机为例。Tristan有外网卡eth0和内回网卡lo[root@tristan]#ifconfigeth0Linkencap:EthernetHWaddr00:80:C8:F8:4A:51inetaddr:192.168.99.35Bcast:192.168.99.255Mask:255.255.255.0UPBROADCASTRUNNINGMULTICASTMTU:1500Metric:1RXpackets:27849718runerrors:1:0frame:0TXpackets:29968044errors:5dropped:0overruns:2carrier:3collisions:0txqueuelen:100RX字节:943447653(899.7Mb)TX字节:2599122310(2478.7Mb)中断:9Basex10000:0loLinkencap:LocalLoopbackinetaddr:127.0.0.1Mask:255.0.0.0UPLOOPBACKRUNNINGMTU:16436Metric:1RXpackets:7028982错误:0丢弃:0溢出:0帧:0TX数据包:7028982错误:0丢弃:0溢出:0运营商:0冲突:0txqueuelen:0RXbytes:1206918001(1151.0Mb)TXbytes:1206918001(1151.0Mb)[root@tristan]#route-nKernelIProutingtableDestinationGatewayGenmaskFlagsMetricRefUseIface192.168.95.500.0.0.0U2500eth0127.0.0.00.0.0.0255.0.0.0U000lo0.0.0.0192.168.99.2540.0.0.0UG000eth0通过route-n我们可以看到主机上的简要路由表信息(当然也可以要使用iproute),那么上面路由信息中的每一项是什么意思呢?如果报文的目的IP地址在192.168.99.0/24网段,那么应该从eth0转发;如果报文的目的IP地址在127.0.0.1/8网段,则应该从lo转发。其他情况(0.0.0.0/0),报文从eth0转发,下一跳IP地址为192.168.99.254。第1项和第2项应该易于理解。比较难理解的是第3项,为什么它的Gateway不是全0.0.0.0,这个需要从网络拓扑结构说起。网关的左侧是一个典型的网络拓扑结构。主机通过交换机组成一个小型局域网,再通过路由器连接到一个更大的网络。图中的路由器可以称为局域网中主机的网关,一般翻译为网关。它的地位就像一个国家的风俗习惯。出关后,IP报文在另一个网络中。回到前面路由表的第3项,当主机发现数据包的目的IP地址不满足其他表项时,就说明这个数据包需要发往局域网外,所以会发送或将数据包转发到网关。即192.168.99.254。在这种情况下,192.168.99.254称为默认网关,此条目也称为默认路由。对应于这个名字,第一和第二路由表项也称为网段路由局域网内部通信。当我们为网卡配置IP地址或者通过DHCP服务器分配IP地址时,Linux内核会自动生成对应的网段路由。这相当于告诉系统这个网段的主机在同一个局域网中。例如,假设我们在tristan主机上ping局域网内的susan主机。然后这个ICMP请求报文按如下方式组装就OK了。如果tristan不知道主机susan上eth0的MAC地址,就必须先发送ARP广播报文获取。局域网外与局域网外主机的通信需要经过(via)网关。类似的例子,假设我们在tristan主机上ping局域网外的Paul主机的eth0,查询路由后,内核选择了默认网关,那么组装好的ICMP请求的header会是这样的:Setstaticrouting网段路由有时候,系统生成的默认路由不能满足我们的要求,需要我们手动设置路由[root@tristan]#route-nKernelIProutingtableDestinationGatewayGenmaskFlagsMetricRefUseIface192.168.99.00.0.0.0255.255.255.0U000eth0127.0.0.00.0.0.0255.0.0.0U000lo0.0.0.0192.168.99.2540.0.0.0UG0例如0在刚才的拓扑中,主机tristan要与主机jerry所在的网络通信,显然根据现有的路由表,显然是不可能的。因此,我们需要在tristan主机上配置额外的路由表条目:[root@tristan]#routeadd-net192.168.98.0netmask255.255.255.0gw1??92.168.99.1[root@tristan]#route-nKernelIProutingtableDestinationGatewayGenmask标志公制参考使用Iface192.168.99.00.0.0.0255.255.255.0U000eth0192.168。0.0.0192.168.99.2540.0.0.0UG000eth0新增加的路由表项表示本机与192.168.98.0/24范围内的主机通信,需要网关192.168.99.1才能使用iproute命令实现同样通过via设置下一跳网关的效果本质上是一样的[root@tristan]#iprouteadd192.168.98.0/24via192.168.99.1我们甚至可以添加或删除默认路由[root@tristan]#routedeldefaultgw1??92.168.99.254[root@tristan]#routeadddefaultgw1??92.168.99.1除了设置整个网段外,我们还可以为某个目的IP设置路由,即主机路由。其实主机路由的掩码是255.255.255.255[root@tristan]#routeadd-host192.168.98.42gw1??92.168.99.1or[root@tristan]网段路由的特殊形式an]#routeadd-net192.168.98.42netmask255.255.255.255gw1??92.168.99.1可以为特定主机生成路由,Flags字段中的H表示Host[root@tristan]#route-nKernelIProutingtableDestinationGatewayGenmaskFlagsMetricRefUseIface192.168.99.00.0.0.0255.255.255.0U000eth0192.168.98.42192.168.99.1255.255.255.255UGH000eth0127.0.0.00.0.0.00.0255U..0192.168.99.2540.0.0.0UG000eth0Equal-costrouting等价路由(ECMP)是指有多条链路通向同一目的地,链路可以起到负载均衡和链路备份的作用,例如下面的拓扑结构:主机melo上设置的路由如下[root@melo]#routeshowscopeglobaldefaultvia203.0.113.5deveth0192.0.2.0/25nexthopvia203.0.113.7deveth1weight1nexthopvia203.0.113.9deveth2weight1means即如果报文的目的地址是192.0.2.0/25,那么同样会选择out1或者out2作为出接口policyroutingmultipleroutingtables以上所有的路由选择都是根据目的IP寻找对应的路由表项进行。此外,Linux还提供了一种更高级、更灵活的方式来完成更复杂的路由策略,这就是策略路由。它使用户能够根据源IP和其他信息配置路由。策略路由的基本原理是系统根据IP数据包的特点使用不同的路由表。编译内核时需要检查CONFIG_IP_MULTIPLE_TABLES。Linux内核最多支持256个路由表,其中4个是系统默认保留的。用户可以创建252个表。从/etc/iproute2/rt_tables可以看到内核保留的4张表。有用的是本地表和主表root@ubuntu-1:/home/user1#cat/etc/iproute2/rt_tables##reservedvalues#255local254main253default0unspeclocaltable存放本地自动生成的路由和广播通过内核路由。当我们在没有指定路由表的情况下使用route命令或者iproute时,要操作的表就是主表,所以我们需要使用额外的参数来操作查看本地表[root@real-server]#ipaddressshowdeveth16:eth1:
