linux 路由表

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



===============================================================================


 


Linux路由表的結構與算法分析

黃一文

 

路由是網絡棧的核心部分。路由表本身的設計很大情度上影響着路由的性能,並且好的設計能減少系統資源的消耗,這兩方面尤其體現在路由表的查找上。目前的內核路由存在兩種查找算法,一種爲HASH算法,另一種爲LC-trie算法,前者是目前內核使用的缺省算法,而後者更適用在超大路由表的情況,它在這種情況提高查找效率的同時,大大地增加了算法本身的複雜性和內存的消耗。綜上,這兩種算法各有其適用的場合,本文分析了基於2.6.18內核路由部分的代碼在HASH算法上路由表結構的實現,並且在文章最後給出了一個簡單的策略路由的應用。

 

一、路由表的結構

       爲了支持策略路由,Linux使用了多個路由表而不是一個,即使不使用策略路由,Linux也使用了兩個路由表,一個用於上傳給本地上層協議,另一個則用於轉發。Linux使用多個路由表而不是一個,使不同策略的路由存放在不同的表中,有效地被免了查找龐大的路由表,在一定情度上提高了查找了效率。

 

       路由表本身不是由一個結構表示,而是由多個結構組合而成。路由表可以說是一個分層的結構組合。在第一層,它先將所有的路由根據子網掩碼(netmask)的長度(0~32)分成33個部分(structfn_zone),然後在同一子網掩碼(同一層)中,再根據子網的不同(如10.1.1.0/24和10.1.2.0/24),劃分爲第二層(struct fib_node),在同一子網中,有可能由於TOS等屬性的不同而使用不同的路由,這就是第三層(structfib_alias),第三層結構表示一個路由表項,而每個路由表項又包括一個相應的參數,如協議,下一跳路由地址等等,這就是第四層(structfib_info)。分層的好處是顯而易見的,它使路由表的更加優化,邏輯上也更加清淅,並且使數據可以共享(如structfib_info),從而減少了數據的冗餘。

 

 


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結構在內核中表示一個路由表:


       +

圖1(引自[1])

這個結構中包括這個表的ID,以及主要的一些用於操作路由表的函數指針,這裏我們只關心最後一個域――tb_data[0],這是一個零長的數組,它在內核中也較爲常見,它表示

 


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結構中:


 

這個結構中有兩個域比較重要,一個爲fz_hash域,它指向一個HASH表的表頭,這個HASH的長度是fz_divisor。並且這個HASH表的長度是可變的,當表長達到一個限定值時,將重建這個HASH表,被免出現HASH衝突表過長造成查找效率降低。

 

爲了提高查找的效率,內核使用了大量的HASH表,而路由表就是一個例子。在圖1中可以看到,等長子網掩碼的路由存放在同一個fn_zone中,而根據到不同子網(fib_node)的路由鍵值(fn_key),將它HASH到相應的鏈表中。

 


struct fib_node {

       struct hlist_node     fn_hash;

       struct list_head       fn_alias;

       u32                fn_key;

};

 

這個鍵值其實就是這個子網值了(如10.1.1.0/24,則子網值爲10.1.1),得到這個鍵值通過n =fn_hash()函數HASH之後就是這個子網對應的HASH值,然後就可以插入到相應的fz_hash[n]鏈表中了。衝突的fib_node由fn_hash域相鏈,而fn_alias則是指向到達這個子網的路由了。

 


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;

};

當到達這個子網的路由由於TOS等屬性的不同可存在着多個路由時,它們就通過fib_alias中fa_list域將這些路由表項鍊成一個鏈表。這個結構中的另一個域fa_info指向一個fib_info結構,這個纔是存放真正重要路由信息的結構。

 


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

};

 

這個結構裏面是一個用於路由的標誌和屬性,其中最重要的一個域是fib_nh[0],在這裏,我們再次看到了零長數組的應用,它是通過零長來實現變長結構的功能的。因爲,我們需要一個定長的fib_info結構,但是在這個結構末尾,我們需要的fib_nh結構的個數是不確定的,它在運行時確定。這樣,我們就可以通過這種結構組成,在運行時爲fib_info分配空間的時候,同時在其末尾分配所需的若干個fib_nh結構數組,並且這個結構數組可以通過fib_info->fib_nh[n]來訪問,在完成fib_info的分配後將fib_nhs域置爲這個數組的長度。

 

另一方面,fib_info也是HASH表的一個應用,結構中存在着兩個域,分別是fib_hash和fib_lhash,它們都用於HASH鏈表。這個結構在完成分配後,將被用fib_hash域鏈入fib_info_hash表中,如果這個路由存在首選源地址,這個fib_info將同時被用fib_lhash鏈入fib_info_laddrhash表中。這樣,就可以根據不同目的實現快速查找了。

 

Structfib_nh也是一個重要的結構。它存放着下一跳路由的地址(nh_gw)。剛剛已經提到,一個路由(fib_alias)可能有多個fib_nh結構,它表示這個路由有多個下一跳地址,即它是多路徑(multipath)的。下一跳地址的選擇也有多種算法,這些算法都是基於nh_weight,nh_power域的。nh_hash域則是用於將nh_hash鏈入HASH表的。

 


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層將要發送或接收到一個IP數據包時,它就要調用路由子系統完成路由的查找工作。路由表查找就是根據給定的參數,在某一個路由表中找到合適的下一跳路由的地址。

 

       上面已提到過,當一個主機不支持策略路由時,它只使用了兩個路由表,一個是ip_fib_local_table,用於本地,另一個是ip_fib_main_table,用於接發。只有在查找ip_fib_local_table表時沒有找到匹配的路由(不是發給本地的)它纔會去查找ip_fib_main_table。當一個主機支持策略路由時,它就有可能存在着多個路由表,因而路由表的選擇也就是查找的一部分。路由表的選擇是由策略來確定的,而策略則是由應用(用戶)來指定的,如能過iprule命令:

 


ip rule add from 10.1.1.0/24 table TR1

ip rule add iff eth0 table RT2

       如上,第一條命令創建了基於源地址路由的一條策略,這個策略使用了RT1這個路由表,第二條命令創建了基於數據包入口的一個策略,這個策略使用了RT2這個路由表。當被指定的路由表不存在時,相應的路由表將被創建。

 

       第二步就是遍歷這個路由表的fn_zone,遍歷是從最長前綴(子網掩碼最長)的fn_zone開始的,直到找到或出錯爲止。因爲最長前綴纔是最匹配的。假設有如下一個路由表:

 


dst                 nexthop               dev

        10.1.0.0/16       10.1.1.1                     eth0

        10.1.0.0/24          10.1.0.1               eth1

 

它會先找到第二條路由,然後選擇10.1.0.1作爲下一跳地址。但是,如果由第二步定位到的子網(fib_node)有多個路由,如下:

 


dst                 nexthop               dev

        10.1.0.0/24       10.1.0.1                     eth1

        10.1.0.0/24          10.1.0.2               eth1

 

到達同一個子網有兩個可選的路由,僅憑目的子網無法確定,這時,它就需要更多的信息來確定路由的選擇了,這就是用於查找路由的鍵值(structflowi)還包括其它信息(如TOS)的原因。這樣,它才能定位到對應一個路由的一個fib_alias實例。而它指向的fib_info就是路由所需的信息了。

最後一步,如果內核被編譯成支持多路徑(multipath)路由,則fib_info中有多個fin_nh,這樣,它還要從這個fib_nh數組中選出最合適的一個fib_nh,作爲下一跳路由。

 

 

三、路由的插入與刪除

       路由表的插入與刪除可以看看是路由查找的一個應用,插入與刪除的過程本身也包含一個查找的過程,這兩個操作都需要檢查被插入或被刪除的路由表項是否存在,插入一個已經存在的路由表項要做特殊的處理,而刪除一個不存在的路由表項當然會出錯。

       下面看一個路由表插入的例子:

 


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

 

 

 

 

這個命令在內核中建立一條新的路由。它首先查找路由表RT3中的子網掩碼長爲24的fn_zone,如果找不到,則創建一個fn_zone。接着,繼續查找子網爲10.0.1的fib_node,同樣,如果不存在,創建一個fib_node。然後它會在新建一個fib_info結構,這個結構包含2個fib_nh結構的數組(因爲有兩個nexthop),並根據用戶空間傳遞過來的信息初始化這個結構,最後內核再創建一個fib_alias結構(如果先前已經存在,則出錯),並用fib_nh來創始化相應的域,最後將自己鏈入fib_node的鏈中,這樣就完成了路由的插入操作。

 

路由的刪除操作是插入操作的逆過程,它包含一系列的查找與內存的釋放操作,過程比較簡單,這裏就不再贅述了。

 

 

四、策略路由的一個簡單應用

       Linux系統在策略路由開啓的時候將使用多個路由表,它不同於其它某些系統,在所有情況下都只使用單個路由表。雖然使用單個路由表也可以實現策略路由,但是如本文之前所提到的,使用多個路由表可以得到更好的性能,特別在一個大型的路由系統中。下面只通過簡單的情況說明Linux下策略路由的應用。

如圖2,有如下一個應用需求,其中網關服務器上有三個網絡接口。接口1的IP爲172.16.100.1,子網掩碼爲255.255.255.0,網關gw1爲a.b.c.d,172.16.100.0/24這個網段的主機可以通過這個網關上網;接口2的IP是172.16.10.1,子網掩碼同接口一,網關gw2爲e.f.g.h,172.16.10.0/24這個網段的主機可以通過這個網關上網;接口0的IP爲192.168.1.1,這個網段的主機由於網絡帶寬的需求需要通過e.f.g.h這個更快的網關路由出去。

 


圖 2

 

步驟一:設置各個網絡接口的IP,和默認網關:

 


ip addr add 172.16.100.1/24 dev eth1

ip route add default via a.b.c.d dev eth1

       其它接口IP的設置和第一個接口一樣,這時,如果沒有其它設置,則所有的數據通過這個默認網關路由出去。

 

步驟二:使子網172.16.10.0/24可以通過gw2路由出去

 


       ip route add 172.16.10.0/24 via e.f.g.h dev eth2

      


 

 

步驟三:添加一個路由表 

 


       echo   “250 HS_RT” >> /etc/iproute2/rt_tables

 

 

步驟四:使用策略路由使192.168.1.0/24網段的主機可以通過e.f.g.h這個網關上網

 

 


       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

      

步驟五:刷新路由cache,使新的路由表生效

 

 


ip route flush cache 

這樣就可以實現了以上要求的策略路由了,並且可以通過traceroute工具來檢測上面的設置是否能正常工作。

 

===============================================================================


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掉數據會從另外一個網卡出去

===============================================================================

linux路由表

2010年08月18日 星期三 17:44

宏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 { change | del | add | append | replace | monitor } ROUTE


 


  如果想查看路由表的內容,可以通過命令:


  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

router># ip route add 192.168.3.0/24 via 192.168.0.3 table 1


 


第一條命令是向主路由表(main table)即表254添加一條路由,路由的內容是設置192.168.0.4成爲網關。

 


  第二條命令代表向路由表1添加一條路由,子網192.168.3.0(子網掩碼是255.255.255.0)的網關是192.168.0.3。


  在多路由表的路由體系裏,所有的路由的操作,例如網路由表添加路由,或者在路由表裏尋找特定的路由,需要指明要操作的路由表,所有沒有指明路由表,默認是對主路由表(表254)進行操作。而在單表體系裏,路由的操作是不用指明路由表的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章