策略性路由
策略性是指對於IP包的路由是以網絡管理員根據需要定下的一些策略為主要依據進行路由的。例如我們可以有這樣的策略:“所有來直自網A的包,選擇X路徑;其他選擇Y路徑”,或者是“所有TOS為A的包選擇路徑F;其他選者路徑K”。
Cisco 的網絡操作系統 (Cisco IOS) 從11.0開始就采用新的策略性路由機制。而Linux是在內核2.1開始采用策略性路由機制的。策略性路由機制與傳統的路由算法相比主要是引入了多路由表以及規則的概念。
多路由表(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)進行操作。而在單表體系裡,路由的操作是不用指明路由表的。
規則的配置IP Rule
在Linux裡,總共可以定義 個優先級的規則,一個優先級別只能有一條規則,即理論上總共可以有 條規則。其中有3個規則是默認的。命令用法如下:
Usage: ip rule [ list | add | del ] SELECTOR ACTION SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ dev STRING ] [ pref NUMBER ] ACTION := [ table TABLE_ID ] [ nat ADDRESS ] [ prohibit | reject | unreachable ] [ flowid CLASSID ] TABLE_ID := [ local | main | default | new | NUMBER
首先我們可以看看路由表默認的所有規則:
root@netmonster# ip rule list 0: from all lookup local 32766: from all lookup main 32767: from all lookup default
規則0,它是優先級別最高的規則,規則規定,所有的包,都必須首先使用local表(254)進行路由。本規則不能被更改和刪除。
規則32766,規定所有的包,使用表main進行路由。本規則可以被更改和刪除。
規則32767,規定所有的包,使用表default進行路由。本規則可以被更改和刪除。
在默認情況下進行路由時,首先會根據規則0在本地路由表裡尋找路由,如果目的地址是本網絡,或是廣播地址的話,在這裡就可以找到合適的路由;如果路由失敗,就會匹配下一個不空的規則,在這裡只有32766規則,在這裡將會在主路由表裡尋找路由;如果失敗,就會匹配32767規則,即尋找默認路由表。如果失敗,路由將失敗。重這裡可以看出,策略性路由是往前兼容的。
還可以添加規則:
router># ip rule add [from 0/0] table 1 pref 32800 router >#ip rule add from 192.168.3.112/32 [tos 0x10] table 2 pref 1500 prohibit
第一條命令將向規則鏈增加一條規則,規則匹配的對象是所有的數據包,動作是選用路由表1的路由,這條規則的優先級是32800。
第二條命令將向規則鏈增加一條規則,規則匹配的對象是IP為192.168.3.112,tos等於0x10的包,使用路由表2,這條規則的優先級是1500,動作是。添加以後,我們可以看看系統規則的變化。
router># ip rule 0: from all lookup local 1500 from 192.168.3.112/32 [tos 0x10] lookup 2 32766: from all lookup main 32767: from all lookup default 32800: from all lookup 1
上面的規則是以源地址為關鍵字,作為是否匹配的依據的。除了源地址外,還可以用以下的信息:
From -- 源地址
To -- 目的地址(這裡是選擇規則時使用,查找路由表時也使用)
Tos -- IP包頭的TOS(type of sevice)域
Dev -- 物理接口
Fwmark -- 防火牆參數
采取的動作除了指定表,還可以指定下面的動作:
Table 指明所使用的表
Nat 透明網關
Action prohibit 丟棄該包,並發送 COMM.ADM.PROHIITED的ICMP信息
Reject 單純丟棄該包
Unreachable丟棄該包, 並發送 NET UNREACHABLE的ICMP信息
策略性路由的應用
基於源地址選路( Source-Sensitive Routing)
如果一個網絡通過兩條線路接入互聯網,一條是比較快的ADSL,另外一條是比較慢的普通的調制解調器。這樣的話,網絡管理員既可以提供無差別的路由服務,也可以根據源地址的不同,使一些特定的地址使用較快的線路,而普通用戶則使用較慢的線路,即基於源址的選路。
根據服務級別選路(Quality of Service)
網絡管理員可以根據IP報頭的服務級別域,對於不同的服務要求可以分別對待對於傳送速率、吞吐量以及可靠性的有不同要求的數據報根據網絡的狀況進行不同的路由。
節省費用的應用
網絡管理員可以根據通信的狀況,讓一些比較大的陣發性通信使用一些帶寬比較高但是比較貴的路徑一段短的時間,然後讓基本的通信繼續使用原來比較便宜的基本線路。例如,管理員知道,某一台主機與一個特定的地址通信通常是伴隨著大量的陣發性通信的,那麼網絡管理員可以安排一些策略,使得這些主機使用特別的路由,這些路由是按需撥號,帶寬比較高的線路,通信完成以後就停止使用,而普通的通信則不受影響。這樣既提高網絡的性能,又能節省費用。
負載平衡(Load Sharing)
根據網絡交通的特征,網絡管理員可以在不同的路徑之間分配負荷實現負載平衡。
Linux下策略性路由的實現--RPDB(Routing Policy DataBase)
在Linux下,策略性路由是由RPDB實現的。對於RPDB的內部機制的理解,可以加深對於策略性路由使用的理解。這裡分析的是linux 2.4.18的RPDB實現的細節。主要的實現文件包括:
fib_hash.c fib_rules.c fib_sematic fib_frontend.c route.c
RDPB主要由多路由表和規則組成。路由表以及對其的操作和其對外的接口是整個RPDB的核心部分。路由表主要由table,zone,node這些主要的數據結構構成。對路由表的操作主要包含物理的操作以及語義的操作。路由表除了向IP層提供路由尋找的接口以外還必須與幾個元素提供接口:與用戶的接口(即更改路由)、proc的接口、IP層控制接口、以及和硬件的接口(網絡接口的改變會導致路由表內容的改變)。處在RDPB的中心的規則,由規則選取表。IP層並不直接使用路由表,而是通過一個路由適配層,路由適配層提供為IP層提供高性能的路由服務。
路由表(Fib Table)
數據結構:
在整個策略性路由的框架裡,路由表是最重要的的數據結構,我們在上面以及對路由表的概念和結構進行了清楚的說明。Linux裡通過下面這些主要的數據結構進行實現的。
主要的數據結構 作用 位置 struct fib_table 路由表 ip_fib.h 116 struct fn_hash 路由表的哈希數據 fib_hash.c 104 struct fn_zone zone域 fib_hash.c 85 struct fib_node 路由節點 fib_hash.c 68 struct fib_info 路由信息 ip_fib.h 57 struct fib_result 路由結果 ip_fib.h 86數據結構之間的主要關系如下。路由表由路由表號以及路由表的操作函數指針還有表數據組成。這裡需要注意的是,路由表結構裡並不直接定義zone域,而是通過一個數據指針指向fn_hash。只有當zone裡有數據才會連接到fn_zone_list裡。
系統的所有的路由表由數組變量*fib_tables[RT_TABLE_MAX+1]維護,其中系統定義RT_TABLE_MAX為254,也就是說系統最大的路由表為255張,所有的路由表的操作都是對這個數組進行的。。同時系統還定義了三長路由表*local_table; *main_table。
路由表的操作:
Linux策略路由代碼的主要部分是對路由表的操作。對於路由表的操作,物理操作是直觀的和易於理解的。對於表的操作不外乎就是添加、刪除、更新等的操作。還有一種操作,是所謂的語義操作,語義操作主要是指諸如計算下一條的地址,把節點轉換為路由項,尋找指定信息的路由等。
1、物理操作(operation):
路由表的物理操作主要包括如下這些函數:
路由標操作 實現函數 位置 新建路由表 刪除路由表 搜索路由 fn_hash_lookup fib_hash.c 269 插入路由到路由表 fn_hash_insert fib_hash.c 341 刪除路由表的路由 fn_hash_delete fn_hash_dump fib_hash.c 433 fib_hash.c 614 更新路由表的路由 fn_hash_flush fib_hash.c 729 顯示路由表的路由信息 fn_hash_get_info fib_hash.c 750 選擇默認路由 fn_hash_select_default fib_hash.c 8422、語義操作(semantics operation):