4.2 FIB資料的讀取
第一部份:使用 proc 檔案系統讀取 FIB 的資料。輸出所有存在 FIB 中的資料。
第二部份:使用 route 系統讀取 FIB 的資料。輸出一個符合搜尋條件的資料。
4.2.1 proc 檔案系統讀取 FIB 資料
一般情況下使用者想要知道 FIB 的內容時,用文字編譯器檢視檔案 /proc/net/route 的內容是最快速的方法。/proc/net/route 檔案內容是由函數根據 FIB 內的資料(main routing table)所動態產生。/*上層的部份屬於 proc 檔案系統負責,有興趣者可以參考 fs/proc/ 目錄下相關檔案。舊版核心函數為 rt_get_info() */
4.2.1.1
- 在 net/ipv4/fib_frontend.c 的部份,由函數 fib_get_procinfo() 負責。
- 在這裡會把標頭依照格式印出到緩衝區中;由要求取得資料個數和實際抓到資料個數,計算出剩餘的資料個數;回傳共寫入了多少個 byte 到緩衝區裡面。
- 所謂的標頭,就是每行資料最前面資料名稱,如 Iface, Destination .. 等等。而格式是使用 tab 來分開每一個資料名稱。
- 呼叫了 main_table->tb_get_info() 將繼續下一步,此函數實際上就是 fn_hash_get_info()。
4.2.1.2
- 在 net/ipv4/fib_hash.c 的部份,由函數 fn_hash_get_info() 負責。
- 在這裡使用三個迴圈掃描過 main_table 所有的資料。第一層掃描所有的 fn_zone,第二層掃描 fn_zone 的 hash table 內所有的 slot,第三層掃描每一個 slot 裡面所有的 fib_node。結束迴圈的狀況有兩種:迴圈執行完畢,或者已經讀取的資料個數大於等於要求讀取數目。
- 呼叫了 fib_node_get_info() 將資料輸出到緩衝區。
4.2.1.3
- 在 net/ipv4/fib_semantics.c 的部份,由函數 fib_node_get_info() 負責。
- 在這裡負責把資料寫入緩衝區。寫入的狀況有兩種:一種是當 fib_info 不存在時,只輸出部份資料( Destination, Flags, Masks ),其他輸出預設值 0 ;另外一種是當 fib_info 存在時,輸出完整資料。
Iface | fi->fib_nh[0].nh_dev->name |
Destination | prefix(為傳入參數) |
Gateway | fi->fib_nh->nh_gw |
Flags | flags(運算所得) |
RefCnt | 0 |
Use | 0 |
Metric | fi->fib_priority |
Mask | mask(為傳入參數 fz->fz_mask) |
MTU | fi->fib_advmss + 40 |
Window | fi->fib_window |
IRRT | fi->fib_rtt >>3(往右 shift 3 bit) |
呼叫了函數 fib_flag_trans() 做 flags 運算。此函數也在 net/ipv4/fib_semantics.c 中。
4.2.2 route 系統讀取 FIB 資料
route 系統讀取資料與 proc 檔案系統之間最明顯的不同點有二:- proc 檔案系統在讀取的過程中,將讀取的資料存成字串放在緩衝區。而 route 系統讀取過程則將資料存到 fib_result 資料結構裡,使個別欄位仍具備原來的意義。
- proc 檔案系統讀取資料沒有限制條件。找到資料就放到緩衝區裡,直到讀取個數滿足。route 系統需檢查找到的資料是否符合條件,若不符合則繼續找,直到找完整個 FIB 為止。
4.2.2.1
- 在 net/ipv4/fib_rules.c 的部份,由函數 fib_lookup() 負責。
- 一開始先根據傳入的條件,找到合適的 fib_rule 使用。主要的比對條件有三個:目的地位置,來源位置,使用的網路介面。預設的 fib_rule 比對順序為 local_rule , main_rule , default_rule ,也可以說是 fib_rule 的優先順序。
- 找到合適的 fib_rule 之後,根據 fib_rule->r_action 決定繼續往下執行( RTN_UNICAST, RTN_NAT ),或者跳出並回傳錯誤值。
- 繼續往下執行。根據 fib_rule->r_table 決定所要尋找的 fib_table之後,呼叫 tb->tb_lookup() 找尋資料。tb->tb_lookup() 實際上就是 fn_hash_lookup(),回傳的資料大部分是由這個函數所設定,除了 fib_result->r 設定為剛剛所找到的 fib_rule(即合適的 fib_rule) 。
4.2.2.2
- 在 net/ipv4/fib_hash.c 的部份,由函數 fn_hash_lookup() 負責。
- 在這裡用了兩個迴圈,外層迴圈用來搜尋所有屬於此 fib_table 的 fn_zone,內層迴圈搜尋 hash table 其中一個 slot。
- 為什麼可以直接搜尋 hash table 其中一個 slot ?因為可以用函數 fz_key() 加上兩個參數:目的地位置和所找的 fz_zone,算出 hash key。然後用函數 fz_chain() 把 slot 抓出來。這就是使用 hash table 的好處,可以加快資料找尋的速度。
- 找到符合位置(IP位置)的 fib_node 之後,做狀態檢查和回傳值設定。其中呼叫 fib_semantic_match() 做狀態檢查和回傳值設定, fib_semantic_match() 在檔案 net/ipv4/fib_semantics.c 中。
以下為回傳值設定表:
fib_result 成員 | 設定值 | 設定函數 |
r (struct fib_rule) | policy | fib_lookup() |
type | f->fn_type | fn_hash_lookup() |
scope | f->fn_scope | fn_hash_lookup() |
prefixlen (mask length) | fz->fz_order | fn_hash_lookup() |
fi (struct fib_info) | fi (傳入的參數) | fib_semantic_match() |
nh_sel | nhsel(全域變數?) | fib_semantic_match() |
prefix | 無,prefix = dst AND operation with it's mask | 無 |
4.3 FIB 資料的修改
由 inet_ioctl()(net/ipv4/AF_INET.C #856)中下指令,呼叫 ip_rt_ioctl()(net/ipv4/fib_frontend.c #247)實作新增和刪除routing information的動作。
4.3.1 資料修改的前置作業:函數 ip_rt_ioctl()
此函數位在 net/ipv4/fib_frontend.c 。在這裡所收到的資料為最原始的使用者輸入資料:命令(cmd)和參數(arg)。接受的命令只有兩個:SIOCADDRT(socket IO control add routing,加入資料),SIOCDELRT(socket IO control delete routing,刪除資料),若為其他命令則回傳錯誤(-EINVAL)。參數 arg 為一指標,指向存在 user space 的原始資料,必須將內容複製到kernel space 中(arg 到 rtentry)。由於收到的資料格式不符合使用,所以呼叫函數 fib_convert_rtentry()(檔案 net/ipv4/fib_semantics.c)做資料格式的轉換:將 rtentry 轉換為 kern_rta, rtmsg, nlmsghdr 。資料轉換完成後,依照傳入的命令執行資料加入或者資料刪除。資料轉換對照表:
TO struct rtmsg | 條件 | 設定值 |
rtm_family | 無 | 0 |
rtm_dst_len | 預設值 | 32 |
if(!(rt->flags & RTF_HOST)) | inet_mask_len(mask) | |
rtm_src_len | 無 | 0 |
rtm_tos | 無 | 0 |
rtm_table | 無 | 0 |
rtm_protocol | 預設值 | 0 |
cmd != SIOCDELRT | RTPROT_BOOT | |
rtm_scope | 預設值 | RT_SCOPE_NOWHERE |
r->rt_flags&RTF_REJECT | RT_SCOPE_HOST | |
cmd != SIOCDELRT 並且 rtm->rtm_scope == RT_SCOPE_NOWHERE | RT_SCOPE_LINK | |
r->rt_flags&RTF_GATEWAY 並且 inet_addr_type( rta->rta_gw )==RTN_UNICAST | RT_SCOPE_UNIVERSE | |
rtm_type | 預設值 | RTN_UNICAST |
r->rt_flags&RTF_REJECT | RTN_UNREACHABLE | |
rtm_flags | 無 | 0 |
TO struct nlmsghdr | 條件 | 設定值 |
nlmsg_len | 預設值 | NLMSG_LENGTH(sizeof(*rtm)) |
nlmsg_type | cmd == SIOCDELRT | RTM_DELROUTE |
cmd == SIOCADDRT | RTM_ADDROUTE | |
nlmsg_flags | 預設值 | NLM_F_REQUEST |
cmd == SIOCDELRT | 0 | |
cmd == SIOCADDRT | NLM_F_REQUEST | NLM_F_CREATE | |
nlmsg_seq | 預設值 | 0 |
nlmsg_pid | 預設值 | 0 |
TO struct kern_rta | 條件 | 設定值 |
rta_dst | 預設值 | &((struct sockaddr_in*)&r->rt_dst)->sin_addr.s_addr |
rta_src | 無 | 0 |
rta_iif | 無 | 0 |
rta_oif | 預設值 | 0 |
r->rt_dev | &dev->ifindex | |
rta_gw | 預設值 | 0 |
r->rt_gateway.sa_family == AF_INET && (&((struct sockaddr_in*)&r->rt_gateway)->sin_addr.s_addr) | &((struct sockaddr_in*)&r->rt_gateway)->sin_addr.s_addr | |
rta_priority | 預設值 | 0 |
r->rt_metric | (u32*)&r->rt_pad3 = r->rt_metric-1 | |
rta_prefsrc | 預設值 | 0 |
r->rt_dev , colon , ifa!=NULL | &ifa->ifa_local | |
rta_mx | 預設值 | 0 |
r->rt_flags&( RTF_MTU | RTF_WINDOW | RTF_IRRT ) | 詳情見程式碼 net/ipv4/fib_semantics.c, #812~#841 | |
rta_mp | 無 | 0 |
rta_protoinfo | 無 | 0 |
rta_flow | 無 | 0 |
rta_ci | 無 | 0 |
函數流程圖如下:
![函數流程圖](http://www.cs.ccu.edu.tw/%7Ecwr87u/Project_undergraduate/linux_firewall/www/net/ipv4/ip_rt_ioctl_flow.gif)
4.3.2 資料的刪除
執行資料修改之前,必須決定要修改哪一個fib_table,由於 req.rtm.rtm_table 值為0,所以回傳的fib_table為main_table。在 ip_rt_ioctl() 中,呼叫 tb->tb_delete() 執行資料刪除的工作,此函數實際上是 fn_hash_delete() ,在檔案 net/ipv4/fib_hash.c 中。使用傳入的資訊可以輕易的找到要刪除的 fib_node 所存在的 fn_zone(用 r->rtm_dst_len 選出)和在 hash table 中的那個 slot(用 fz_key(dst, fz)選出)。掃描所選出的 slot,找到符合條件的第一個 fib_node。如果有多個符合條件的 fib_node 存在,其位置必定緊接著第一個之後。所以藉著比對條件可以知道有幾個 fib_node 符合搜尋條件,把個數記下來(matched)。呼叫 rtmsg_fib() 做必要的系統更改或系統通知。呼叫 fn_free_node() 釋放資料。
4.3.3 資料的新增
fib_new_table()並不是每次都建立新的fib_table,而是會依情況取出舊的table或者建立新的table。 req.rtm.rtm_table目前為0,所以回傳main_table,類似前面提到的資料刪除。在 ip_rt_ioctl() 中,呼叫 tb->tb_insert() 執行資料新增的工作,此函數實際上是 fn_hash_insert() ,在檔案 net/ipv4/fib_hash.c 中。往同一個目的地可以有兩個以上的規則存在,只要規則具有不同的優先權即可。原因可能是需要有『臨時規則』存在的必要,需要暫時更改路徑,但是不要刪除 掉原有的路徑。所以在插入新的fib_node時需要有額外的命令,即 NLM_F_xxx,這些名稱常數定義在netlink.h中。找尋放置新增資料的方法和刪除時類似,利用 r->rtm_des_len 選出 fn_zone,以及用 fz_key(dst, fz) 選出 hash table slot。插入的位置在前一個 key 大於插入的key 時找到。建立新的 fib_node 和其所屬 fib_info(若已存在相同資料,使用此舊資料)。資料轉換對照表:
TO struct fib_node | 條件 | 設定值 |
fn_next | ||
fn_info | 預設值 | fib_create_info(r, rta, n, &err) |
fn_key | 預設值 | fz_key(dst, fz) |
fn_tos | 預設值 | r->rtm_tos |
fn_type | 預設值 | r->trm_type |
fn_scope | 預設值 | r->rtm_scope |
fn_state | 無 | 0 |
TO struct fib_info | 條件 | 設定值 |
fib_next | ||
fib_prev | ||
fib_refcnt | ||
fib_flags | 預設值 | r->rtm_flags |
fib_protocol | 預設值 | r->rtm_protocol |
fib_prefsrc | 預設值 | 0 |
rta->rta_prefsrc | rta->rta_prefsrc | |
fib_priority | 預設值 | 0 |
rta->rta_priority | *rta->rta_priority | |
fib_metrics[] | 預設值 | 0 |
RTA_OK(attr, attrlen) && flavor | fib_metrics[flavor-1] = *(unsigned*)RTA_DATA(attr) | |
fib_nhs | 預設值 | 1 |
rta->rta_mp | fib_count_nexthops( rta->rta_mp ) | |
fib_power | 無 | 0 |
fib_nh[0] |
TO struct fib_nh | 條件 | 設定值 |
nh_dev | 預設值 | 0 |
r->rtm_scope == RT_SCOPE_HOST 並且 !(nhs !=1 || nh->nh_gw) | dev_get_by_index(fi->fib_nh->nh_oif) | |
nh_flags | 預設值 | 0 |
!(rta->rta_mp) | r->rtm_flags | |
nh_scope | 預設值 | 0 |
r->rtm_scope == RT_SCOPE_HOST 並且 !(nhs !=1 || nh->nh_gw) | RT_SCOPE_NOWHERE | |
nh_weight | 預設值 | 0 |
!(rta->rta_mp) | 1 | |
nh_power | 無 | 0 |
nh_tclassid | 預設值 | 0 |
!(rta->rta_mp) 並且 rta->rta_flow | rta->rta_flow | |
nh_oif | 預設值 | 0 |
!(rta->rta_mp) 並且 rta->rta_oif | rta->rta_oif | |
nh_gw | 預設值 | 0 |
!(rta->rta_mp) 並且 rta->rta_gw | rta->rta_gw |
Forward Information Base (FIB) table簡介
struct fib_table 為一個包含 operation 和 data 的結構,類似c++中的類別。data 的部份由 struct fib_zone 所構成,其中每個結構負責管理一個區域(zone),而一個區域是由具有相同路徑遮罩(或稱為子網路遮罩,netmask)的路徑所組成。
每個 fib_zone 使用 hash table 資料結構來管理所有屬於它的路徑。hash table 中記錄多個 struct fib_node 結構的串列。這些結構內含指標指向類型為struct fib_info 的結構,其中存有路徑的所有資訊。在此我們把資訊分成兩個部份(fib_node, fib_info),存在不同的結構中,是因為 不同的路徑間也有許多資訊是相同的。 詳細資料結構
![fib_table內含所有資料結構關係](http://www.cs.ccu.edu.tw/%7Ecwr87u/Project_undergraduate/linux_firewall/www/net/ipv4/fib_table_struct_relation.gif)
FIB table內容的存取
讀取:proc 檔案系統(/proc/net/route)是取得路徑表內容的唯一方法,在ioctl()中並沒有可用的命令。路徑快取區在/proc/net/rt_cache。
修改:由 inet_ioctl()(net/ipv4/AF_INET.C #856)中下指令,呼叫 ip_rt_ioctl()(net/ipv4/fib_frontend.c #247)實作新增和刪除routing information的動作。
![ip_rt_ioctl()修改fib_table的流程](http://www.cs.ccu.edu.tw/%7Ecwr87u/Project_undergraduate/linux_firewall/www/net/ipv4/ip_rt_ioctl_flow.gif)
sock.ops->inet_ioctl() 呼叫 ip_rt_ioctl()
- SIOCADDRT
- SIOCDELRT
- SIOCRTMSG
ip_rt_ioctl()
- DELETE: ip_rt_ioctl() call tb->tb_delete()==fn_hash_delete():此時必須決定要修改哪一個fib_table。由於 req.rtm.rtm_table 值為0,所以回傳的fib_table為main_table。一般而言,route指令所見到的資訊即為main_table的資訊。
- INSERT: ip_rt_ioctl() call tb->tb_insert()==fn_hash_insert():fib_new_table()並不是每次都建立新的fib_table, 而是會依情況取出舊的table或者建立新的table。req.rtm.rtm_table目前為0,所以回傳main_table。
fib_convert_rtentry()
- 傳入:struct rtentry,回傳:struct rtmsg、struct kern_rta、struct nlmsghdr。
- 以下為fib_convert_rtentry()中資料轉換的情形:
![rtentry轉換成kern_rta和rtmsg](http://www.cs.ccu.edu.tw/%7Ecwr87u/Project_undergraduate/linux_firewall/www/net/ipv4/rtentry_to_kern_rta_and_rtmsg.gif)
fn_hash_delete()中的流程
- DELETE: ip_rt_ioctl() call tb->tb_delete()==fn_hash_delete():此時必須決定要修改哪一個fib_table。由於 req.rtm.rtm_table 值為0,所以回傳的fib_table為main_table。一般而言,route指令所見到的資訊即為main_table的資訊。
1.netmask的表示法:有三種不同表示法,意思是相同的。
128.0.0.0 == 1000...0 == 1
192.0.0.0 == 1100...0 == 2
...
255.255.255.254 == 111...10 == 31
255.255.255.255 == 111...11 == 32
幾這些例子,應該瞭解了吧!
2.fib_node的狀態:fib_node->fn_state,狀態有二:
- FN_S_ACCESSED:表示可使用。
- FN_S_ZOMBIE:表示不可使用。
- 找到多個:若此資訊為可使用(FN_S_ACCESSED),則可能存在快取區中,必須更新快取區。呼叫 fn_free_node() 釋放此 fib_node 的記憶空間,將所參考到的 fib_info 的被參考值減一(呼叫 fib_release_info() 來處理)。
- 找到一個:若此資訊為可使用(FN_S_ACCESSED),則可能存在快取區中,必須更新快取區。將 fib_node 狀態設為 FN_S_ZOMBIE 後暫時不管。等到 zombie 累積的數目超過 128 個再一起釋放記憶空間。
#606,596:z 實際上就是netmask,所以值不可以超過32。
#608:無資料可刪除,錯誤。
#611:設定key=0。
#615:檢查destination IP address 的網域部份是否為0。0為錯誤。
#620:利用key (hash key) 找出在 fz 中的位置。也就是在fz這個zone的hash table 中的位置。此位置為串列的開頭。
#622-627:在串列中找到想要的 fib_node。
#637:見#398,找出 fn_tos == tos 的 fib_node。
#638:取得 fib_node 中的 fib_info。
#645:del_fp == NULL,只的是 del_fp 只記錄符合條件且為第一個找到的fib_node(如果有多個符合條件)。註:為何找到多個,因為同一個 fib_info 可以被多個 fib_node 參考到。
#646-649:條件檢查。
#657-664:找到多個符合條件的 fib_node。
#658:因為有多個,所以下一個必定為條件符合者。如果matched配合回圈即可全部刪除(目前無實作)。
#661-662:在 rt_cache中存在此 routing message ,必須清掉。
#664:此 zone 的 fib_node 數目減一。
#665-673:FN_S_ACCESSED指的是快取區可取用此一資料。
#667-669:清除快取區中的過期資料,藉此除去快取區中的此資料。
#671-672:累積夠多無用資訊後一起刪除。釋放佔用的記憶體。
rtmsg_fib()
- #define CONFIG_RTNETLINK,可以呼叫此函數實作(#834)。
- 否則不實作,函數呼叫以空白取代。
?? 實作部份看不懂,尤其是 fib_dump_info()。是不是在通知系統fib_table有改變?還是更新/proc/net/route的內容?
fn_hash_delete() to fn_free_node()
#213-215:釋放 fib_info 和 fib_node 的memory。call fib_release_info()。
fib_release_info(), /net/ipv4/fib_semantics.c #103
把 fib_info 的被參考數量減一,檢查是否為零。若為零則將此 fib_info 從 fib_info_list 中將此 fib_info 移除。
fn_hash_insert()中的流程
- INSERT: ip_rt_ioctl() call tb->tb_insert()==fn_hash_insert():fib_new_table()並不是每次都建立新的fib_table, 而是會依情況取出舊的table或者建立新的table。req.rtm.rtm_table目前為0,所以回傳main_table。
往同一個目的地可以有兩個以上的規則存在,只要規則具有不同的優先權即可。原因可能是需要有『臨時規則』存在的必要,需要暫時更改路徑。但是不要刪除掉原有的路徑。所以在插入新的fib_node時需要有額外的命令,即 NLM_F_xxx,這些名稱常數定義在netlink.h中。
/* Modifiers to NEW request */
#define NLM_F_REPLACE 0x100 /* Override existing */
#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */
#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
#define NLM_F_APPEND 0x800 /* Add to end of list */
#422:取得netmask(使用0~32)的表示法。
??#430-432:做啥?
#435-437:取出zone。zone不存在就建立一個新的。
#455:找出應放在hash table中的位置。
#464:此位置中,串列由小到大串連。所以找到大於或等於的點就把資料串在前面。
#468:什麼是Type of Service?
#480-488:找到的node,key value相同且狀態為ZOMBIE,用新建立的資料取代就資料,並刪除就資料。
#501-518:
#510:命令為使用舊版。
#513:命令為使用新版。
#527:用舊的。
#537-582:建立fib_node並插入正確位置。
fn_hash_insert() to fib_create_info()
![kern_rta和rtmsg轉換成fib_info](http://www.cs.ccu.edu.tw/%7Ecwr87u/Project_undergraduate/linux_firewall/www/net/ipv4/kern_rta_and_rtmsg_to_fib_info.gif)
附錄
結構關係為由大到小,外部到內部。連貫結構有以下六個:
struct fib_table # , ip_fib.h
{
unsigned char tb_id;
unsigned tb_stamp;
int (*tb_lookup)(); ==fn_hash_lookup() //on #262, fib_hash.c
int (*tb_insert)(); ==fn_hash_insert() //on #414, fib_hash.c
int (*tb_delete)(); ==fn_hash_delete() //on #591, fib_hash.c
int (*tb_dump)(); ==fn_hash_dump() //on #814, fib_hash.c
int (*tb_flush)(); ==fn_hash_flush() //on #702, fib_hash.c
int (*tb_get_info)(); ==fn_hash_get_info() //on #723, fib_hash.c
void (*tb_select_default)(); ==fn_hash_select_default() //on #331, fib_hash.c
unsigned char tb_data[0]; ==struct fn_hash
};
說明: 初始化於 fib_hash_init() #864, fib_hash.c
struct fn_hash #102, fib_hash.c
{
struct fn_zone * fn_zones[33];//分別存位置長度為 1, 2, ..., 32 的資料。
struct fn_zone * fn_zone_list;//所有 fn_zone 的串列。便於搜尋。
};
說明: 說兩個fn_zone* 內容相同,都指向全部的fn_zone,差異只在使用的時機。若要依照類別存取fn_zone,則使用fn_zones[]。fn_zone_list通常用在存取全部fn_zone的時候。
struct fn_zone #83, fib_hash.c
{
struct fn_zone *fz_next; /* Next not empty zone */ 把fn_zone串成串列。
struct fib_node ** fz_hash; /* Hash table pointer */ 指標陣列,存數個串列。hash 常用的結構。可用此雙重指標做出二維陣列的效果。
int fz_nent; /* Number of entries */ slot 總數。fib_node總數(此fn_zone裡面)。
int fz_divisor; /* Hash divisor */ 除數。有三個值:16,256,1024。做hash運算使用。
u32 fz_hashmask; /* (1<<fz_divisor) - 1 */ 檢查錯誤用。 做hash運算使用。
#define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
int fz_order; /* Zone order */ 位置長度。
u32 fz_mask; 檢查錯誤用。
#define FZ_MASK(fz) ((fz)->fz_mask)
};
/* NOTE. On fast computers evaluation of fz_hashmask and fz_mask can be cheaper than memory lookup, so that FZ_* macros are used. */
struct fib_node #66, fib_hash.c
{
struct fib_node *fn_next; 形成串列。
struct fib_info * fn_info ; 實際資料所在。 記錄routing內容。
#define FIB_INFO(f) ((f)->fn_info)
fn_key_t fn_key; //hash 識別碼。 ,在hash中尋找fib_node用。
u8 fn_tos;
u8 fn_type;
u8 fn_scope;
u8 fn_state;
};
說明: 為hash table的儲存格。
struct fib_info # , ip_fib.h
{
struct fib_info *fib_next; 雙向串列。
struct fib_info *fib_prev;
int fib_refcnt;
unsigned fib_flags;
int fib_protocol; 通訊協定。
u32 fib_prefsrc; 來源?
u32 fib_priority; 優先權。
#define FIB_MAX_METRICS RTAX_RTT
unsigned fib_metrics[FIB_MAX_METRICS];
#define fib_mtu fib_metrics[RTAX_MTU-1]
#define fib_window fib_metrics[RTAX_WINDOW-1]
#define fib_rtt fib_metrics[RTAX_RTT-1]
int fib_nhs;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_power;
#endif
struct fib_nh fib_nh[0] ;
#define fib_dev fib_nh[0].nh_dev
};
說明: This structure contains data shared by many of routes.
struct fib_nh # , ip_fib.h
{
struct device *nh_dev;
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;
};