linux 路由表及路由设置
linux 路由表维护
使用下面的 route 命令可以查看 Linux 内核路由表。
# route
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
route 命令的输出项说明
输出项 | 说明 |
---|---|
Destination | 目标网段或者主机 |
Gateway | 网关地址,”*” 表示目标是本主机所属的网络,不需要路由 |
Genmask | 网络掩码 |
Flags | 标记。一些可能的标记如下: |
U — 路由是活动的 | |
H — 目标是一个主机 | |
G — 路由指向网关 | |
R — 恢复动态路由产生的表项 | |
D — 由路由的后台程序动态地安装 | |
M — 由路由的后台程序修改 | |
! — 拒绝路由 | |
Metric | 路由距离,到达指定网络所需的中转数(linux 内核中没有使用) |
Ref | 路由项引用次数(linux 内核中没有使用) |
Use | 此路由项被路由软件查找的次数 |
Iface | 该路由表项对应的输出接口 |
3 种路由类型
主机路由
主机路由是路由选择表中指向单个IP地址或主机名的路由记录。主机路由的Flags字段为H。例如,在下面的示例中,本地主机通过IP地址192.168.1.1的路由器到达IP地址为10.0.0.10的主机。
Destination Gateway Genmask Flags Metric Ref Use Iface
----------- ------- ------- ----- ------ --- --- -----
10.0.0.10 192.168.1.1 255.255.255.255 UH 0 0 0 eth0
网络路由
网络路由是代表主机可以到达的网络。网络路由的Flags字段为N。例如,在下面的示例中,本地主机将发送到网络192.19.12的数据包转发到IP地址为192.168.1.1的路由器。
Destination Gateway Genmask Flags Metric Ref Use Iface
----------- ------- ------- ----- ----- --- --- -----
192.19.12 192.168.1.1 255.255.255.0 UN 0 0 0 eth0
默认路由
当主机不能在路由表中查找到目标主机的IP地址或网络路由时,数据包就被发送到默认路由(默认网关)上。默认路由的Flags字段为G。例如,在下面的示例中,默认路由是IP地址为192.168.1.1的路由器。
Destination Gateway Genmask Flags Metric Ref Use Iface
----------- ------- ------- ----- ------ --- --- -----
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
配置静态路由
route 命令
设置和查看路由表都可以用 route 命令,设置内核路由表的命令格式是:
# route [add|del] [-net|-host] target [netmask Nm] [gw Gw] [[dev] If]
其中:
- add : 添加一条路由规则
- del : 删除一条路由规则
- -net : 目的地址是一个网络
- -host : 目的地址是一个主机
- target : 目的网络或主机
- netmask : 目的地址的网络掩码
- gw : 路由数据包通过的网关
- dev : 为路由指定的网络接口
route 命令使用举例
添加到主机的路由
# route add -host 192.168.1.2 dev eth0:0
# route add -host 10.20.30.148 gw 10.20.30.40
添加到网络的路由
# route add -net 10.20.30.40 netmask 255.255.255.248 eth0
# route add -net 10.20.30.48 netmask 255.255.255.248 gw 10.20.30.41
# route add -net 192.168.1.0/24 eth1
添加默认路由
# route add default gw 192.168.1.1
删除路由
# route del -host 192.168.1.2 dev eth0:0
# route del -host 10.20.30.148 gw 10.20.30.40
# route del -net 10.20.30.40 netmask 255.255.255.248 eth0
# route del -net 10.20.30.48 netmask 255.255.255.248 gw 10.20.30.41
# route del -net 192.168.1.0/24 eth1
# route del default gw 192.168.1.1
设置包转发
在 CentOS 中默认的内核配置已经包含了路由功能,但默认并没有在系统启动时启用此功能。开启 Linux的路由功能可以通过调整内核的网络参数来实现。要配置和调整内核参数可以使用 sysctl 命令。例如:要开启 Linux内核的数据包转发功能可以使用如下的命令。
# sysctl -w net.ipv4.ip_forward=1
这样设置之后,当前系统就能实现包转发,但下次启动计算机时将失效。为了使在下次启动计算机时仍然有效,需要将下面的行写入配置文件/etc/sysctl.conf。
# vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
用户还可以使用如下的命令查看当前系统是否支持包转发。
# sysctl net.ipv4.ip_forward
==================================------------- eliu --------------=============================================
struct fib_table *fib_tables[RT_TABLE_MAX+1]; // RT_TABLE_MAX 为255 |
图1为一个路由表的总体结构。自上而下由左向右看,它首先为一个fib_table结构指针的数组,它被定义为:
struct fib_table {
unsigned char tb_id;
unsigned tb_stamp;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
int (*tb_insert)(struct fib_table *table, struct rtmsg *r,
……
void (*tb_select_default)(struct fib_table *table,
const struct flowi *flp, struct fib_result *res);
unsigned char tb_data[0];
};
|
每个fib_table结构在内核中表示一个路由表:
struct fn_hash {
struct fn_zone *fn_zones[33];
struct fn_zone *fn_zone_list;
};
|
指向这个结构的末尾。由图1可以看到,这个结构的末尾接着便是一个struct fn_hash结构,这个结构是随着fib_table结构一起分配的,所以fib_table->tb_data就是fn_hash。
struct fn_zone {
struct fn_zone *fz_next; /* Next not empty zone */
struct hlist_head *fz_hash; /* Hash table pointer */
int fz_nent; /* Number of entries */
int fz_divisor; /* Hash divisor */
u32 fz_hashmask; /* (fz_divisor - 1) */
#define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
int fz_order; /* Zone order */
u32 fz_mask;
#define FZ_MASK(fz) ((fz)->fz_mask)
};
|
这个fn_zone域就是我们上面提前的结构,用于将路由根据子网掩码的长度分开成33个部分,其中fn_zones[0]用于默认网关。而fn_zone_list域就是将正在使用的fn_zone链成一个链表。接着再深入到struct fn_zone结构中:
struct fib_node {
struct hlist_node fn_hash;
struct list_head fn_alias;
u32 fn_key;
};
|
struct fib_alias {
struct list_head fa_list;
struct rcu_head rcu;
struct fib_info *fa_info;
u8 fa_tos;
u8 fa_type;
u8 fa_scope;
u8 fa_state;
};
|
struct fib_info {
struct hlist_node fib_hash;
struct hlist_node fib_lhash;
……
int fib_dead;
unsigned fib_flags;
int fib_protocol;
u32 fib_prefsrc;
u32 fib_priority;
……
int fib_nhs;
struct fib_nh fib_nh[0];
#define fib_dev fib_nh[0].nh_dev
};
|
struct fib_nh {
struct net_device *nh_dev;
struct hlist_node nh_hash;
struct fib_info *nh_parent;
unsigned nh_flags;
unsigned char nh_scope;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int nh_weight;
int nh_power;
#endif
#ifdef CONFIG_NET_CLS_ROUTE
__u32 nh_tclassid;
#endif
int nh_oif;
u32 nh_gw;
};
|
ip rule add from 10.1.1.0/24 table TR1
ip rule add iff eth0 table RT2
|
dst nexthop dev
10.1.0.0/16 10.1.1.1 eth0
10.1.0.0/24 10.1.0.1 eth1
|
dst nexthop dev
10.1.0.0/24 10.1.0.1 eth1
10.1.0.0/24 10.1.0.2 eth1
|
ip route add 10.0.1.0/24 nexthop via 10.0.1.1 weight 1
nexthop via 10.0.1.2 weight 2
table RT3
|
ip addr add 172.16.100.1/24 dev eth1
ip route add default via a.b.c.d dev eth1
|
ip route add 172.16.10.0/24 via e.f.g.h dev eth2 |
echo “250 HS_RT” >> /etc/iproute2/rt_tables |
ip rule add from 192.168.1.0/24 dev eth0 table HS_RT pref 32765
ip route add default via e.f.g.h dev eth2
iptables –t nat –A POSTROUTING –s 192.168.1.0/24 –j MASQUERADE
|
ip route flush cache
|
====================================------------- eliu --------------===========================================
linux双网卡怎么设置我就不说了,我这里说的是linux双网卡的流量问题...
可能这个问题很偏们..你们也许用不上..我还是要说..
问题描述,一个linux主机,上面两个网卡..:)
route -n的输出是这样的.
Destination Gateway Genmask Flags Metric Ref Use Iface
61.132.43.128 0.0.0.0 255.255.255.192 U 0 0 0 eth1
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
0.0.0.0 61.132.43.134 0.0.0.0 UG 0 0 0 eth0
这里解释一下...第一行是说,你要访问61.132.43.128这个网段,掩码是255.255.255.192的话..从e
th1这个网卡出去..
第二行是关于本机的,访问自己从lo这个虚拟的本地网卡走..
第三行是说你要去任何地方的话..从网关61.132.43.134出去.并且网卡是eth0
到这里我们看到了..我们除了去61.132.43.128这个网络是从eth1走以外..去其他地方都是从eth0�
�...
这样是不是很浪费了双网卡??没错..是很浪费..因为不论你用那种监测工具查看流量..都是eth0有
..而其他网卡没有...天哪...为此我是煞费苦心..甚至怀疑网卡是不是坏了..因为在win2k上这种�
虑槭遣豢赡芊⑸�..:)
那我们怎么解决这个问题呢?有人也许会说给个不同网关让另一块网卡用其他网关不就可以..是这�
鍪强梢�..但是问题是我的ip都是在同一个网段..那来的不同网关.?网关就一个61.132.43.134...
还好linux系统给我们提供了一个很好的路由套件---iproute2
我们来熟悉一下..iproute2由几个常见的命令..
ip ro ls ip就是ip命令啦,ro就是route的所写,ls是list的缩写...
整个命令就是列出系统的路由表..这个可和route
-n的效果差不多..但是更为清楚系统的route是如何的..
我们来看看吧:
[root@localhost root]# ip ro ls
61.132.43.128/26 dev eth1 proto kernel scope link src 61.132.43.136
127.0.0.0/8 dev lo scope link
default via 61.132.43.134 dev eth0
是不是一样呢?由几个地方不同..第一条多了一个src,增加了对源数据包的选择,而且子网掩码也变
成/26的形式..(参考ip地址的书籍)
最后一个仍然是网关...
现在我们只要稍稍动手把从61.132.43.136出来的流量让他不要从eth0出去..然他走eth1
我们加一条自定义的路由表
ip ro add default via 61.132.43.134 table 200
这里只是加了一条默认路由到一个自定义的路由表200中,最大数值是255,但是你不要用255,因为那
是系统默认用了..你用200以下就可以.
具体的路由表在/etc/iproute2/rt_tables中
查看刚才建立的路由表可以用ip ro ls table 200
[root@localhost root]# ip ro ls table 200
default via 61.132.43.134 dev eth1
看到了吗?虽然我没有指定dev是什么.但是系统自动分配了一个eth1给这个路由表,因为eth0已经用
在主路由表中了..
这也说明了,的确不能在同一个路由表中由相同的网关..虽然可以设置,但是具体没什么作用.
然后我们要用一个规则把,匹配的数据包引导到刚刚建立的路由表中..:)
ip ru add from 61.132.43.136 table 200
这里ru是rule的缩写.from是一个匹配的动作.就是所源地址是61.132.43.136的包..请走自定义路�
杀�的设置..:)
查看一下
[root@localhost root]# ip ru ls
0: from all lookup local
32765: from 61.132.43.136 lookup 200
32766: from all lookup main
32767: from all lookup 253
ip ro flush cache
linux 下 双网卡 同网段,可以把IP_FORWARD 打开,这样一个网卡down掉数据会从另外一个网卡出去
==================================------------- eliu --------------=============================================
linux路由表
宏CONFIG_IP_MULTIPLE_TABLES表示路由策略,当定义了该宏,也即意味着内核配置了“路由策略”。产生的最大的不同就是内核可以使用多达256张FIB。其实,这256张FIB在内核中的表示是一个全局数组:
struct fib_table *myfib_tables[RT_TABLE_MAX+1];
而宏RT_TABLE_MAX定义如下:
enum rt_class_t
{
RT_TABLE_UNSPEC=0,
RT_TABLE_DEFAULT=253,
RT_TABLE_MAIN=254,
RT_TABLE_LOCAL=255,
__RT_TABLE_MAX
};
#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
我们可以看到,虽然这张表多达256项,但枚举类型rt_class_t给出的表示最常用的也就三项,在系统初始化时,由内核配置生成的路由表只有RT_TABLE_MAIN,RT_TABLE_LOCAL两张。
main表中存放的是路由类型为RTN_UNICAST的所有路由项,即网关或直接连接的路由。在myfib_add_ifaddr函数中是这样添加main表项的:对于某个网络设备接口的一个IP地址,如果目的地址的网络号不是零网络(网络号与子网号全为零),并且它是primary地址,同时,它不是D类地址(网络号与子网号占32位)。最后一个条件是:它不是一个环回地址(device上有flagIFF_LOOPBACK)。那么,就添加为main表项,如果是环回地址,则添加为local表的一个表项。
在我们的系统中,有两个已开启的网络设备接口eth0和lo,eth0上配置的primaryIP地址是172.16.48.2,所以,相应的,main表中就只有一项。为main表添加路由项的时候,该路由项的目的地址是子网内的所有主机(把主机号部分字节清零),而对应于lo,在local表中也有一项,其类型为RTN_LOCAL(注:前一篇文章中的local表的hash8中的路由项表述有误,类型应该是RTN_LOCAL,而不是RTN_BORADCAST)。
而其它的路由项全部归入local表,主要是广播路由项和本地路由项。在我们的系统环境下,local表共有7项,每个网络设备接口占三项。分别是本地地址(源跟目的地址一致),子网广播地址(主机号全为1),子网广播地址(主机号为零)。再加上一个lo的RTN_LOCAL项。
现在我们再来看myfib_add_ifaddr函数的路由添加策略。对于一个传入的ip地址(结构structin_ifaddr表示),如果它是secondary地址,首先要确保同一个网络设备接口上存在一个跟其同类型的primary地址(网络号与子网号完全一致),因为,路由项的信息中的源地址全是primary的,secondary地址其实没有实际使用,它不会在路由表中产生路由项。然后,向local表添加一项目的地址是它本身的,类型为RTN_LOCAL的路由项;如果该ip地址结构中存在广播地址,并且不是受限广播地址(255.255.255.255),那么向local表添加一个广播路由项;然后,对符合加入main表的条件进行判断,如果符合,除了加入main表,最后,如果不是D类地址,还要加入两个广播地址(其实,已经跟前面有重叠,很多情况下不会实际触发加入的动作,只要记住,一个ip地址项对应最多有两个广播地址就可以了)。
多路由表(multiple Routing Tables)
传统的路由算法是仅使用一张路由表的。但是在有些情形底下,我们是需要使用多路由表的。例如一个子网通过一个路由器与外界相连,路由器与外界有两条线路相连,其中一条的速度比较快,一条的速度比较慢。对于子网内的大多数用户来说对速度并没有特殊的要求,所以可以让他们用比较慢的路由;但是子网内有一些特殊的用户却是对速度的要求比较苛刻,所以他们需要使用速度比较快的路由。如果使用一张路由表上述要求是无法实现的,而如果根据源地址或其它参数,对不同的用户使用不同的路由表,这样就可以大大提高路由器的性能。
规则(rule)
规则是策略性的关键性的新的概念。我们可以用自然语言这样描述规则,例如我门可以指定这样的规则:
规则一:“所有来自192.16.152.24的IP包,使用路由表10, 本规则的优先级别是1500”
规则二:“所有的包,使用路由表253,本规则的优先级别是32767”
我们可以看到,规则包含3个要素:
什么样的包,将应用本规则(所谓的SELECTOR,可能是filter更能反映其作用);
符合本规则的包将对其采取什么动作(ACTION),例如用那个表;
本规则的优先级别。优先级别越高的规则越先匹配(数值越小优先级别越高)。
策略性路由的配置方法
传统的linux下配置路由的工具是route,而实现策略性路由配置的工具是iproute2工具包。这个软件包是由Alexey Kuznetsov开发的,软件包所在的主要网址为ftp://ftp.inr.ac.ru/ip-routing/。
这里简单介绍策略性路由的配置方法,以便能更好理解第二部分的内容。详细的使用方法请参考Alexey Kuznetsov写的 ip-cfref文档。策略性路由的配置主要包括接口地址的配置、路由的配置、规则的配置。
接口地址的配置IP Addr
对于接口的配置可以用下面的命令进行:
Usage: ip addr [ add | del ] IFADDR dev STRING
例如:
router># ip addr add 192.168.0.1/24 broadcast 192.168.0.255 label eth0 dev eth0
上面表示,给接口eth0赋予地址192.168.0.1 掩码是255.255.255.0(24代表掩码中1的个数),广播地址是192.168.0.255
路由的配置IP Route
Linux最多可以支持255张路由表,其中有3张表是内置的:
表255 本地路由表(Local table) 本地接口地址,广播地址,已及NAT地址都放在这个表。该路由表由系统自动维护,管理员不能直接修改。
表254 主路由表(Main table) 如果没有指明路由所属的表,所有的路由都默认都放在这个表里,一般来说,旧的路由工具(如route)所添加的路由都会加到这个表。一般是普通的路由。
表253 默认路由表 (Default table) 一般来说默认的路由都放在这张表,但是如果特别指明放的也可以是所有的网关路由。
表 0 保留
路由配置命令的格式如下:
Usage: ip route list SELECTOR
|
如果想查看路由表的内容,可以通过命令:
ip route list table table_number
对于路由的操作包括change、del、add 、append 、replace 、 monitor这些。例如添加路由可以用:
router># ip route add 0/0 via 192.168.0.4 table main
|
第二条命令代表向路由表1添加一条路由,子网192.168.3.0(子网掩码是255.255.255.0)的网关是192.168.0.3。
在多路由表的路由体系里,所有的路由的操作,例如网路由表添加路由,或者在路由表里寻找特定的路由,需要指明要操作的路由表,所有没有指明路由表,默认是对主路由表(表254)进行操作。而在单表体系里,路由的操作是不用指明路由表的。
===============================================================================
===============================================================================