net/ipv4/route.c文件分析

原创 2005年04月24日 16:31:00

net/ipv4/route.c

author: elvis


目錄
介紹 route.c 的背景
routing 流程
相關資料結構
route.c 相關函數詳解

介紹 route.c 的背景

linux 在設定 route 有兩個機制,一個是 fib,一個是 dynamic 產生的 routing
fib 是利用 route(man 8 route) 指定來靜態 route table
而 net/ipv4/route.c 所做的則是動能產生 routing hash,以加快 route decision 的速度
範例:
  • 靜態 route table
    # route -F
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    192.168.1.3     *               255.255.255.255 UH    0      0        0 eth0
    140.123.103.156 *               255.255.255.255 UH    0      0        0 eth1
    192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
    140.123.0.0     *               255.255.0.0     U     0      0        0 eth1
    127.0.0.0       *               255.0.0.0       U     0      0        0 lo
    default         CSIE-C5505      0.0.0.0         UG    0      0        0 eth1	
    			
  • 動態 route table
    # route -C
    Kernel IP routing cache
    Source          Destination     Gateway         Flags Metric Ref    Use Iface
    infomedia.cs.cc 140.123.103.255 140.123.103.255 ri    0      6        0 eth1
    CSIE-C5505      not-a-legal-add not-a-legal-add ibl   0      796989       0 lo
    fish.cs.ccu.edu 140.123.103.255 140.123.103.255 ri    0      2        0 eth1
    didi.cs.ccu.edu 140.123.103.255 140.123.103.255 ri    0      31       0 eth1
    lena.cs.ccu.edu 140.123.103.255 140.123.103.255 ri    0      2438       0 eth1
    filter.cs.ccu.e 140.123.103.255 140.123.103.255 ri    0      265       0 eth1
    CSIE-C5505      ALL-SYSTEMS.MCA ALL-SYSTEMS.MCA ml    0      7273       0 lo
    vivi.cs.ccu.edu 140.123.103.255 140.123.103.255 ri    0      7        0 eth1
    gigi.cs.ccu.edu 140.123.103.255 140.123.103.255 ri    0      3        0 eth1
    scoap.cs.ccu.ed 140.123.103.255 140.123.103.255 ri    0      12       0 eth1
    bist.cs.ccu.edu 140.123.103.255 140.123.103.255 ri    0      86       0 eth1
    macgyver.cs.ccu 140.123.103.255 140.123.103.255 ri    0      11       0 eth1		
    			
參考資料:
  • RFC 1122 有關 IP 層 routing 的說明 這裡
table

routing 流程

	一個 skb 要決定行走的路徑(input) 時
	會呼叫如 ip_route_input(skb,...); 來決定他的 rtable
	流程大概是
		1.ip_route_input 查看是否有存在的 rtable
		2.呼叫 ip_route_input_slow 產生 rtable
		3.ip_route_input_slow 呼叫 fib_lookup
		4.fib_lookup 從 fib_rules 找出 fib_rule
		5.fib_lookup 呼叫 fib_get_table 來取得 fib_table
		6.fib_lookup 使用 fib_table 呼叫 tb->tb_lookup 取得 fib_result
		7.fib_lookup 將 fib_rule 設定給 fib_result
		8.ip_route_input_slow 利用 rt_intern_hash 設定 rtable
		9.返回 ip_route_input 此時 skb 已有設定好的 rtable還有 input/output 方法
		10.返回原呼叫者
		11.原呼叫者呼叫 dst->input() 處理
	
table

相關資料結構

/* IPv4 routing cache flags */

#define RTCF_DEAD	RTNH_F_DEAD
#define RTCF_ONLINK	RTNH_F_ONLINK
/* Obsolete flag. About to be deleted */
#define RTCF_NOPMTUDISC RTM_F_NOPMTUDISC

#define RTCF_NOTIFY	0x00010000
#define RTCF_DIRECTDST	0x00020000
#define RTCF_REDIRECTED	0x00040000
#define RTCF_TPROXY	0x00080000
#define RTCF_FAST	0x00200000
#define RTCF_MASQ	0x00400000
#define RTCF_SNAT	0x00800000
#define RTCF_DOREDIRECT 0x01000000
#define RTCF_DIRECTSRC	0x04000000
#define RTCF_DNAT	0x08000000
#define RTCF_BROADCAST	0x10000000
#define RTCF_MULTICAST	0x20000000
#define RTCF_REJECT	0x40000000
#define RTCF_LOCAL	0x80000000
#define RTCF_NAT	(RTCF_DNAT|RTCF_SNAT)
routing type
enum
{
	RTN_UNSPEC,
	RTN_UNICAST,		/* Gateway or direct route	*/
	RTN_LOCAL,		/* Accept locally		*/
	RTN_BROADCAST,		/* Accept locally as broadcast,
				   send as broadcast */
	RTN_ANYCAST,		/* Accept locally as broadcast,
				   but send as unicast */
	RTN_MULTICAST,		/* Multicast route		*/
	RTN_BLACKHOLE,		/* Drop				*/
	RTN_UNREACHABLE,		/* Destination is unreachable   */
	RTN_PROHIBIT,		/* Administratively prohibited	*/
	RTN_THROW,		/* Not in this table		*/
	RTN_NAT,			/* Translate this address	*/
	RTN_XRESOLVE,		/* Use external resolver	*/
};
scope 的值
enum rt_scope_t
{
	RT_SCOPE_UNIVERSE=0,
/* User defined values  */
	RT_SCOPE_SITE=200,
	RT_SCOPE_LINK=253,
	RT_SCOPE_HOST=254,
	RT_SCOPE_NOWHERE=255
	};
用來查詢 fib table 的鍵值
struct rt_key @include/net/route.h
{
	__u32	dst; 目的 ip 位址
	__u32	src; 來源 ip 位址
	int	iif; input interface
	int	oif; output interface
	__u8	tos; type of service
	__u8	scope; Unknown
};
●route table 最主要的結構
一些判斷位址的 macro
#define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000))
	127.0.0.0/255.0.0.0 loopback
#define MULTICAST(x)    (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
	class D
	1110 開頭
#define BADCLASS(x) (((x) & htonl(0xf0000000)) == htonl(0xf0000000))
	class E 保留的區段,不應該有人用到
	11110 開頭
#define ZERONET(x)  (((x) & htonl(0xff000000)) == htonl(0x00000000))
	class A 且 netid 為 0000000 (七個 0)
#define LOCAL_MCAST(x)  (((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
	class D multicast ip
	且 只有最小的 8bit

struct rtable @include/net/route.h
{
	union
	{
		struct dst_entry	dst;
		struct rtable	*rt_next;
	} u;
	unsigned	rt_flags;  RTCF_MULTICAST 之類的 flag
	unsigned	rt_type;  RTN_UNICAST 之類的型態,用來表示此 route rule 是哪種型態
	__u32	rt_dst;	/* Path destination	*/
	__u32	rt_src;	/* Path source		*/
	int	rt_iif;  incoming interface
	/* Info on neighbour */
	__u32	rt_gateway;
	/* Cache lookup keys */
	struct rt_key	key;
	/* Miscellaneous cached information */
	__u32	rt_spec_dst; /* RFC1122 specific destination */
	inet_peer 的結構是個 avl tree 用來紀錄各個 peer 的資訊
	詳細 implement 在 inetpeer.hinetpeer.c
	struct inet_peer	*peer; /* long-living peer info */
};
	
●rt_hash_table 使用的結構
struct rt_hash_bucket { @net/ipv4/route.c
	struct rtable	*chain;
	rwlock_t	lock;	鎖定狀態
	} __attribute__((__aligned__(8)))
●route table 最主要操作的結構, 在 ip_rt_init 中配置空間且初始化
  route rules 依 hash 串起來,其中 rt_hash_table[hash] 為一串
static struct rt_hash_bucket 	*rt_hash_table;
table

route.c 相關函數詳解


rt_hash_code rt_cache_get_info rt_cache_stat_get_info rt_free rt_drop
rt_fast_clean rt_valuable rt_may_expire rt_check_expire rt_run_flush
rt_cache_flush rt_garbage_collect rt_intern_hash rt_bind_peer ip_select_fb_ident
__ip_select_ident rt_del ip_rt_redirect ipv4_negative_advice ip_rt_send_redirect
ip_error guess_mtu ip_rt_frag_needed ip_rt_update_pmtu ipv4_dst_check
ipv4_dst_reroute ipv4_dst_destroy ipv4_link_failure ip_rt_bug ip_rt_get_source
rt_set_nexthop ip_route_input_mc ip_route_input_slow ip_route_input ip_route_output_slow
ip_route_output_key ip_rt_multicast_event ip_rt_init

static __inline__ unsigned rt_hash_code(u32 daddr, u32 saddr, u8 tos)
  • 功能:產生 hash 的值
  • 參數:位址和服務類型
  • 回傳:hash 值
  • 說明:rt_hash_table[hash]
static int rt_cache_get_info(char *buffer, char **start, off_t offset,int length)
  • 功能:給 proc fs 用的函式
static int rt_cache_stat_get_info(char *buffer, char **start, off_t offset, int length)
  • 功能:給 proc fs 用的函式
static __inline__ void rt_free(struct rtable *rt)
  • 功能:釋放 rtable->dst
  • 參數:rtable
  • 回傳:無
  • 說明:dst_free((&rt->u.dst)
static __inline__ void rt_drop(struct rtable *rt)
  • 功能:丟棄 rtable
  • 參數:rtable
  • 回傳:無
  • 說明:
    • ip_rt_put(); //dst_release(rt) 減少 rt->u.dst.__refcnt dst 使用的次數
    • dst_free((&rt->u.dst)
static __inline__ int rt_fast_clean(struct rtable *rth)
  • 功能:檢查是不是 broadcast/multicast
  • 說明:broadcast/multicast 的 rtable 應該優先被捨棄
static __inline__ int rt_valuable(struct rtable *rth)
  • 功能:檢查是不是 redirect/notify rtable
static __inline__ int rt_may_expire(struct rtable *rth, int tmo1, int tmo2)
  • 功能:檢查 rtable 是否過期應該廢棄
  • 參數:tmo1,tmo2 (tmo2 > tmo1,tmo2 harder than tmo1)
  • 回傳:是否過期
  • 說明:
    • 349:還有在使用(__refcnt不會0) 則回傳否
    • 353:已達這個 rtable 的 expire time,回傳是
    • 359:age = 距最後一次使用的時間
      假如 age <= tmo1 且不是屬於 broadcast 或 multicast rtable 則回傳否
      都優先清除 broadcast/multicast 的 rtable
      (使用 rt_fast_clean)
      假如 age <= tmo2 且 rtable 是屬於 redirected 或 notify
      雖已經超過 tmo1 也回傳否(比較重要)
      (使用 rt_valuable)
    • 362:預設是 expire
static void SMP_TIMER_NAME(rt_check_expire)(unsigned long dummy)
  • 功能:強制 rt_free 掉 rt_hash_table[] chain 中的 expire entries
  • 說明:此函數為 timer 的 timer function
    每 ip_rt_gc_interval 呼叫一次
static void SMP_TIMER_NAME(rt_run_flush)(unsigned long dummy)
  • 功能:
    • 清除所有的 rtable
    • rt_flush_timer 的 timer function
    • also called by rt_cache_flush()
  • 說明:依序將 rt_hash_table[] 中的 rtable rt_free
void rt_cache_flush(int delay)
  • 功能:delay 幾個 jiffies 後,call rt_flush_timer()
  • 說明:
    • 449:移除 rt_flush_timer,重算 delay
    • 472:重設 rt_deadline
    • 475:加上 rt_flush_timer
      第一次的 rt_flush_timer 在這裡被掛上
  • Note:delay 一開始不為 0,怎麼才會呼叫 rt_run_flush()
    不過似乎只會用 0,-1 來呼叫
static int rt_garbage_collect(void)
  • 功能:maintain routing cache
    動態調整routing cache 的有效時間,使其產生/過期的 rtable 速率相同
  • 說明:
    • 506:檢查上次的執行時間,garbage collection 不需要太常做(很費資源)
      (時間間格太小或要清掉的東西不夠多,不做)
    • 511-527:計算現在要清除過期 rtable的個數
    • 529:記錄這次 garbage collection 的時間
    • 537-585:開始做 garbage collection
      • 540-559:從上次做完的 hash chain 開始(rover)
        541:用 rt_may_expire檢查是否 expire
        把 tmo 減半增加來找 expire 的 entries的機率
        (因為有可能是因為 traffic 太高,需要做快速的 expire
      • 583:要清的 entries 小於 rtable 的最大值就不需要做了
      • 577:expire >>=1
        要是 traffic 過高,很可能一個 hash chain 做不完
        減小 expire 來限制 routing cache 的大小
    • 585:從 interrupt 呼叫這個 function 則只跑過一次
      就強制返回
    • 589:net_ratelimit()
      限制 garbage collection 的速率
    • 594:重設 expire
static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
  • 功能:將 rtable 加入 chain 中
  • 說明:
    • 616:從 rt_hash_table[hash] 中找相同 key 的 rtable
      使用次數 +1 並將傳入的 rt rt_drop
    • 638:找不到現存的 rtable,若 rtable type 為 unicast forwarding path 或為 output route
      則產生一個 dst - arp_bind_neighbour()
      output route 或 unicast forward 時要 bind arp,因為是出去
    • 653: arp_bind_neighbour 失敗, 做 rt_garbage_collect 來縮小 route table
      然後重新再行執行一次
    • 670:將新產生的 rtable 掛上 rt_hash_table[hash].chain
void rt_bind_peer(struct rtable *rt, int create)
  • 功能:建立 rt->peer
  • 說明:
    • 692:inet_getpeer(); 定義在 net/ipv4/inetpeer.c
    • 700:假如已經存在 rt->peer,則把產生的 peer 拿掉(inet_putpeer())
  • Note:peer 是各點(每個ipv4 addess)資訊
static void ip_select_fb_ident(struct iphdr *iph)
  • 功能:強制產生 ip id
  • 說明:只有在 __ip_select_identrt_bind_peer 失敗才會執行這個函數來強生 random 的 ip id
  • 原註解:
    /*
    * Peer allocation may fail only in serious out-of-memory conditions. However
    * we still can generate some output.
    * Random ID selection looks a bit dangerous because we have no chances to
    * select ID being unique in a reasonable period of time.
    * But broken packet identifier may be better than no packet at all.
    */
void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst)
  • 功能:
  • 說明:
static void rt_del(unsigned hash, struct rtable *rt)
  • 功能:移除指定hash中的 rtable
  • 參數:hash,rtable
  • 回傳:
  • 說明:從 rt_hash_table[hash] 中找出 rt,rt_free() 掉它
void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,u32 saddr, u8 tos, struct net_device *dev)
  • 功能:redirect,設定新的 rtable
  • 說明:找到原來的 rtable,將原來的資訊複制後
    修改 gateway,flags 等轉送要改的資訊,移除原來的 rtable
  • 使用:net/ipv4/icmp.c icmp_redirect()
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
  • 功能:處理毀損的 dst
  • 說明:
    • 891:obsolete,ip_rt_put() it
    • 894:redirect 的 dst 或 expire 掉的 rt_del
void ip_rt_send_redirect(struct sk_buff *skb)
  • 功能:轉送 skb
  • 說明: called by ip_forward()
    • 942:經過 ip_rt_redirect_silence 長的時間沒轉送過 skb 則 reset 狀態
    • 948:太多 redirect 封包,忽略(假定 host 不理我們的 redirect 封包,ip_forward() 就得幫他送 -_-")
      上次 rate_last設為現在時間
    • 956:check load
    • 958:傳送 icmp 封包
static int ip_error(struct sk_buff *skb)
  • 功能:檢查 rt->u.dst.error
    然後利用icmp_send() 送出對應的錯誤訊息
  • 說明:1001:上一個發生 ip_error() 的 時間太短也不送
static __inline__ unsigned short guess_mtu(unsigned short old_mtu)
  • 從 mtu_plateau[] 中找出小於且最接近 old_mut 的 mtu 值
    預設是 68
unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
  • 功能:拆開封包,需要重新計算 mtu
  • 說明:
    • 1045:找到這個 ip header 所用的 rtable
    • 1056-1079:計算新的 mtu
void ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu)
  • 功能:設定新的 mtu
  • 說明:
    • 1096:設定 dst 的有效時間
      dst_set_expires() 定義在 include/net/dst.h
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
  • 功能:用法 unknown
  • 說明:ipv4_dst_ops 的 check funtion
    release 傳進的 dst //dst_release();
static struct dst_entry *ipv4_dst_reroute(struct dst_entry *dst,struct sk_buff *skb)
  • 功能:用法 unknown
  • 說明:ipv4_dst_ops 的 reroute function
  • Note:Linux 在 2.2/2.4 kernel 皆未實作它
static void ipv4_dst_destroy(struct dst_entry *dst)
  • 功能:回收 dst peer
  • 說明:
    • 1118:rt->peer = NULL;
    • 1119:inet_putpeer(peer); 定義在 include/net/inetpeer.h 將 rt->peer 放到 unused list
static void ipv4_link_failure(struct sk_buff *skb)
  • 功能:利用 icmp 告知目的位址無法連結
  • 參數:skb
  • 說明:
    • 1127:送出 icmp 告知目的位址無法連結
    • 1130:設定此路徑立即失效(expire time == 0)
static int ip_rt_bug(struct sk_buff *skb)
  • 功能:輸出 skb 資訊,並 kfree_skb()
    ip_route_input_mc() 指定為 dst 的 output function (rth->u.dst.output= ip_rt_bug;)
void ip_rt_get_source(u8 *addr, struct rtable *rt)
  • 功能:取得 source address,從哪個 interface 出去的,ip address 就設為它
  • 說明:因為沒有 cache outgoing route 的 source address
    所以利用這個函數取得
    • 1157:iif==0,直接指定 rt->rt_src 給他
    • 1159:從 fib 找
    • 1169:用 inet_select_addr() 找
static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
  • 功能:依據 fib_result 的資訊來設定下一個 hop 的資訊
int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,u8 tos, struct net_device *dev)
  • 功能:利用 rt_key 找出 input 的 rtable
  • 說明:
    • 1633-1655:從 rt_hash_table[] 中找出相符 rt_key 的 rtable(且oif==0)
    • 1505:實際產生 rt_intern_hash() 不檢查 tos(因為 tos 不同..rt_hash_code() 出來的也不會一樣)
    • 1668-1686:假如是 multicast address,且在 dev 的 multicast list 中
      呼叫 ip_route_input_mc() 來產生 entry
    • 1687:不是 multicast 也沒找到已經產生的 entry
      利用 ip_route_input_slow() 新增 entry
  • Note:called by
    net/ipv4/arp.carp_rcv()
    net/ipv4/ipip.cipip_err()
    net/ipv4/ip_gre.cipgre_err()
    net/ipv4/ip_input.cip_rcv_finish()
    net/ipv4/ip_options.cip_options_rcv_srr()
    net/ipv4/netfilter/ip_fw_compat.cfw_in()
int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,u8 tos, struct net_device *dev)
  • 功能:判斷從外面收進的 skb 的去處
  • 說明:
    • 前置工作
      • 1336-1346:初始化 key,跟算出 hash
        key.dstdaddr
        key.srcsaddr
        key.tostos
        key.iifdev->ifindex
        key.oif0沒有 output dev
        key.scopeRT_SCOPE_UNIVERSE
      • 1352:檢查 saddr,不可為 multicast(class D address), badclass(class E address),loopback address
      • 1355-1365:除了 0xffffffff 外的 zeronet saddr 皆為 bad source
        1355:若為 broadcast(daddr 為 0xffffffff 或 saddr/daddr 都為 0x0), 跳到 brd_input 處理,這些都是 broadcast
      • 1364:檢查 daddr,不可為 badclass(class E address), zeronet,loopback
      • 1370:fib_lookup 依據 key 值找出 res (result)
      • 1404:為 broadcast type brd_input
      • 1407:為 local type
    • 真正進行 route 產生
      • Ⅰ‧ip_forward()
        一般的 route table(需轉送)
          • 1437:fib_validate_source 檢查來源是否正確,not broadcast or our local address 確定 spec_dst
          • 1445:flags 加上 RTCF_DOREDIRECT
            表示並不是最佳的路徑,redirect host
          • 1458:dst_alloc() 一個新的 route table
            1462-1491:填入 route table 資料
            out_devin_dev_get(FIB_RES_DEV(res))
            spec_dstfib_validate_source()
            flags|= RTCF_DIRECTSRCif fib_validate_source err
            flags|= RTCF_DOREDIRECTSRCif 該通知轉送
            rth->u.dst.__refcnt1
            rth->key.dstdaddr
            rth->rt_dstdaddr
            rth->key.tostos
            rth->key.srcsaddr
            rth->rt_srcsaddr
            rth->rt_gatewaydaddr
            rth->rt_iifdev->ifindex
            rth->key.iifdev->ifindex
            rth->u.dst.devout_dev->dev
            rth->u.dst.dev.refcnt++
            rth->key.oif0
            rth->rt_spec_dstspec_dst
            rth->u.dst.inputip_forward
            rth->u.dst.outputip_output
            rth->rt_flagsflags
          • 1485:dst.input = ip_forward
          • 1505:實際產生 rt_intern_hash()
      • Ⅱ‧ip_local_deliver()
        broadcast route table
        • 設定 type/flags 檢查 saddr,因為不需要 forward 出去
          spec_dstinet_select_addr(dev, 0, RT_SCOPE_LINK)if ZERONET
          spec_dstfib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,&itag)if not ZERONET
          flags|= RTCF_DIRECTSRCif fib_validate_source err
          flags|= RTCF_BROADCAST
          res.typeRTN_BROADCAST
          利用 local input route table部份 code 來產生 route table 資料
        local input route table
        • 1409:fib_valid_source()
        • 1414:if (result) flags 加上 RTCF_DIRECTSRC
        • 配置 route table 並填入資料
          rth->u.dst.outputip_rt_bugip_rt_bug()
          rth->u.dst.__refcnt1
          rth->key.dstdaddr
          rth->rt_dstdaddr
          rth->key.tostos
          rth->key.srcsaddr
          rth->rt_srcsaddr
          rth->rt_iifdev->ifindex
          rth->key.iifdev->ifindex
          rth->u.dst.dev&loopback_dev
          rth->u.dst.dev->refcnf++
          rth->key.oif0
          rth->rt_gatewaydaddr
          rth->rt_spec_dstspec_dst = daddr
          rth->u.dst.inputip_local_deliverip_local_deliver()
          rth->rt_flags|= RTCF_LOCAL
          rth->rt_ryperes.type
          如果 res.type == RTN_UNREACHABLE
          rth->u.dst.inputip_errorip_error
          rth->u.dst.error-err
          rth->rt_flags&= ~RTCF_LOCAL把剛設的拿掉
        • 1563:input 正常的話為 ip_local_deliver() 往上層丟
        • 1566:unreachable 則為 ip_error() 來處理
        • 1505:實際產生 rt_intern_hash()
      • Ⅲ‧no route
        • route type = unreachable then do Ⅲ‧local_input
static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,u8 tos, struct net_device *dev, int our)
  • 功能:產生 multicast address 的 input rtable
  • 說明:
    • 1238-1248:檢查 saddr/daddr 的正確性
    • 1250-1285:填入資訊, 如果在 device 的 multicast list,則 input function 為 ip_local_deliver()
    • 1294:rt_intern_hash()
int ip_route_output_key(struct rtable **rp, const struct rt_key *key)
(struct rtable **rp, const struct rt_key *key)
  • 功能:利用 rt_key 找出 output 的 rtable
  • 參數:rtable
  • 說明:
    • 1993-2017:在 rt_hash_table[] 中找相符的 rtable
    • 2019:找不到,則利用 ip_route_output_slow() 產生 entry
  • Note:2.2 版的相對應函數為 ip_route_output()
int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey)
  • 功能:產生 output routing cache/rtable
  • 說明:
    • 1722:if (oldkey-gtsrc)
      • 1724:檢查 oldkey->src 的位址型態(multicast/badclass/zeronet return error)
      • 1730:利用 src 找出去的第一個 device ip_dev_find() net/ipv4/fib_frontend.c
      • 1742-1761:oldkey->oif ==0 且 oldkey->dst 是 multicast 或 0xffffffff
        key.oif = dev_out->ifindex,直接 make route
      • 1762-1764:檢查完後 dev_out 不需要了
    • 1766-1790:if (oldkey->oif)
      依 oldkey->dst 型態找出 key.src
    • 1792-1804:沒有 key.dst,設成 loopback,make route
    • 1806:if (fib_lookup()) if(找得到 fib entry)
      • 存在 oldkey->oif,則 type = unicast ,不經 gateway make_route
        否則 error
    • 1843-1856:loopback, 設定 dev,oif make route
    • 1863-1873:以上皆不符合,預設資料設定
      • 1864:fib_select_default()
      • 1867:FIB_RES_PREFSRC()
        include/net/ip_fib.h
        #define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
      • 1869:取消先前找出的 dev_out
        dev_out = FIB_RES_DEV
        inlcude/net/ip_fib.h
        #define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
      • 1872:dev_hold() dev_out->refcnt++
    • 1875:make_route:
      • 1876:no loopback src address error
      • 1879-1884:依 dst 位址型態設定 res.type
        no badclass/zeronet dst address error
      • 1889-1894:處理 broadcast
        fib_info_put() include/net/ip_fib.h fi 不使用了
        不知道為啥要 broadcast 就 dec fi
      • 1912-1965:配置 dst 並填 rth/rth->dst 資料
      • 1967:rt_set_nexthop
      • 1972:rt_intern_hash
void ip_rt_multicast_event(struct in_device *in_dev)
  • 功能:在 multicast 狀態改變時要清掉 cache
    called by net/ipv4/igmp.c#451 ip_mc_inc_group() #471 ip_mc_dec_group(0
    called by net/ipv4/ipmr.c#232 vif_delete() #775 ip_mroute_setsockopt()
  • 參數:in_device
  • 回傳:
  • 說明:
void __init ip_rt_init(void)
  • 功能:kernel 一開始初始 route table 的初始函數
  • 參數:
  • 回傳:
  • 說明:初始化流程
    • 2474:kmem_cache_create() 建立 kernel cache for ip dst cache
    • 2482-2497:配置 rt_hash_table 的記憶體
    • 2506:rt_hash_table initial
    • 2512,2513:初始化 ipv4_dst_ops.gc_thresh ip_rt_max_size
    • 2515:devinet_init();
    • 2516:ip_fib_init();
    • 2517:rt_flush_timer 雖然被宣告,也指定 timer function
      但是從未被初始化過,只有在第一次呼叫完了 rt_cache_flush()
      才會真正被啟動
    • 2519-2526:add_timer(&rt_periodic_timer); timer function 為 rt_check_expire
    • 2528,2529:proc fs 相關的資訊
table 問題
  • RTCF_DIRECTSRC 不知道幹嘛的 唯一用到的地方 icmp.c icmp_address_reply() if (skb->len < 4 || !(rt->rt_flags&RTCF_DIRECTSRC)) return;

/proc/sys/net/ipv4/ 下参数理解,方便服务器优化

/proc/sys/net/ipv4/下文件: 1)  /proc/sys/net/ipv4/ip_forward 该文件表示是否打开IP转发。 0,禁止 1,转发 基本用途...
  • pangyemeng
  • pangyemeng
  • 2017年06月02日 16:52
  • 463

sysctl命令及改变net.ipv4.ip_forward = 1方法

sysctl命令及改变net.ipv4.ip_forward = 1方法
  • zmycoco2
  • zmycoco2
  • 2013年11月27日 09:04
  • 14973

IP地址格式输入文本框

IP地址格式输入文本框。 话不多说,直接贴图: 这里写了三个类: //监听类 KeyBoardListener.java /**  * 数值输入文本框。  * 该数值输入文本框具有:  * 设置...
  • wqjsir
  • wqjsir
  • 2011年08月04日 21:59
  • 6550

不要在linux上启用net.ipv4.tcp_tw_recycle参数

本文为翻译英文BLOG《 Coping with the TCP TIME-WAIT state on busy Linux servers 》,但并非完整的翻译,译者CFC4N对原文理解后,进行...
  • achejq
  • achejq
  • 2016年06月29日 16:49
  • 3123

net/ipv4/route.c文件分析

net/ipv4/route.cauthor: elvis目錄 介紹 route.c 的背景 routing 流程 相關資料結構 route.c 相關函數詳解 介紹 route.c 的背景linux ...
  • ryman
  • ryman
  • 2005年04月24日 16:31
  • 5439

时间戳引起的网站访问不了的问题(net.ipv4.tcp_timestamps)

针对有些用户能ping通我们的网站,但是连接时超时服务器没有任何响应,怀疑问题处在了了http的三次握手环节,这是决定通过抓包进行分析: 1、有问题机器的截图: 2、正常机器的截图: ...
  • jueshengtianya
  • jueshengtianya
  • 2015年12月31日 11:42
  • 5206

net/ipv4/route.c

 http://www.cs.ccu.edu.tw/~cwr87u/Project_undergraduate/linux_firewall/www/net/ipv4/route.c.htmlnet/...
  • romandion
  • romandion
  • 2008年12月23日 16:38
  • 1721

Linux内核分析 - 网络[四补]:路由表补充

内核版本:2.6.34       前篇路由表http://blog.csdn.net/qy532846454/article/details/6423496说明了路由表的结构及路由表的创建。下面是...
  • qy532846454
  • qy532846454
  • 2011年08月28日 08:46
  • 10085

网络优化之net.ipv4.tcp_tw_recycle参数

来源:http://mp.weixin.qq.com/s?__biz=MzA3MzYwNjQ3NA==&mid=403232978&idx=1&sn=4ed396ac1999a...
  • cgm88s
  • cgm88s
  • 2016年06月14日 10:36
  • 4494
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:net/ipv4/route.c文件分析
举报原因:
原因补充:

(最多只允许输入30个字)