FIB

 

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 存在時,輸出完整資料。
以下是標題和 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 檔案系統之間最明顯的不同點有二:
  1. proc 檔案系統在讀取的過程中,將讀取的資料存成字串放在緩衝區。而 route 系統讀取過程則將資料存到 fib_result 資料結構裡,使個別欄位仍具備原來的意義。
  2. proc 檔案系統讀取資料沒有限制條件。找到資料就放到緩衝區裡,直到讀取個數滿足。route 系統需檢查找到的資料是否符合條件,若不符合則繼續找,直到找完整個 FIB 為止。
/*上層部份屬於 route 系統負責,有興趣者可以參考 net/ipv4/route.c ,函數 ip_route_input_slow(), ip_route_output_slow() 。*/

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

函數流程圖如下:
函數流程圖


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簡介

(參考 Linux 核心研究篇,第319頁)
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內含所有資料結構關係


FIB table內容的存取

(參考 Linux 核心研究篇,第321頁)
讀取: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的流程


sock.ops->inet_ioctl() 呼叫 ip_rt_ioctl()

此情況發生在 inet_ioctl() 接到以下三個指令時發生:
  1. SIOCADDRT
  2. SIOCDELRT
  3. SIOCRTMSG
根據之前的解釋,程式碼對於命令 SIOCRTMSG(取得資訊)並不實作。由此可知 ip_rt_ioctl()所作的動作為『增加』或『刪除』fib_table 內的 routing information。

ip_rt_ioctl()

在 ip_rt_ioctl() 中所作的動作有兩個:
  1. 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的資訊。
  2. 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。
註:在 ip_rt_ioctl() 中(net/ipv4/fib_frontend.c #277-278),因為kern_rta為local variable,在ip_rt_ioctl()結束後會自動釋放佔用的記憶體,但rat.rat_mx是在fib_convert_rtentry()中呼叫malloc()分配記憶體,所以需要手動釋放。


fib_convert_rtentry()

?不知道是不是為了相容性,所有才有這一個資料轉換函數的存在?
  1. 傳入:struct rtentry,回傳:struct rtmsg、struct kern_rta、struct nlmsghdr。
  2. 以下為fib_convert_rtentry()中資料轉換的情形:
rtentry轉換成kern_rta和rtmsg


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,狀態有二:
  1. FN_S_ACCESSED:表示可使用。
  2. FN_S_ZOMBIE:表示不可使用。
在尋找符合條件的 fib_node 時,是以其所參考到的 fib_info 為依據。所以找到的 fib_node 有兩種情形:找到一個或者找到多個。
  1. 找到多個:若此資訊為可使用(FN_S_ACCESSED),則可能存在快取區中,必須更新快取區。呼叫 fn_free_node() 釋放此 fib_node 的記憶空間,將所參考到的 fib_info 的被參考值減一(呼叫 fib_release_info() 來處理)。
  2. 找到一個:若此資訊為可使用(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()

宣告在fib_hash.c, #404。有兩中 宣告情況:
  1. #define CONFIG_RTNETLINK,可以呼叫此函數實作(#834)。
  2. 否則不實作,函數呼叫以空白取代。

?? 實作部份看不懂,尤其是 fib_dump_info()。是不是在通知系統fib_table有改變?還是更新/proc/net/route的內容?

fn_hash_delete() to fn_free_node()

在找到多個符合刪除條件的 fib_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()

利用參數 struct rtmsg, struct kern_rat, struct nlmsghdr 建立fib_info。 fib_create_info() trace

kern_rta和rtmsg轉換成fib_info



附錄

結構關係為由大到小,外部到內部。
連貫結構有以下六個:

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;
};
































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值