net/ipv4/route.c文件分析

2910阅读 0评论2015-11-03 猪也有春天
分类:LINUX

net/ipv4/route.c

author: elvis


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

linux 在設定 route 有兩個機制,一個是 fib,一個是 dynamic 產生的 routing
fib 是利用 route(man 8 route) 指定來靜態 route table
而 net/ipv4/route.c 所做的則是動能產生 routing hash,以加快 route decision 的速度
範例:
參考資料: table

	一個 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 	*;
table


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 (u32 daddr, u32 saddr, u8 tos)
static int (char *buffer, char **start, off_t offset,int length)
static int (char *buffer, char **start, off_t offset, int length)
static __inline__ void (struct rtable *rt)
static __inline__ void (struct rtable *rt)
static __inline__ int (struct rtable *rth)
static __inline__ int (struct rtable *rth)
static __inline__ int (struct rtable *rth, int tmo1, int tmo2)
static void SMP_TIMER_NAME()(unsigned long dummy)
static void SMP_TIMER_NAME((unsigned long dummy)
void (int delay)
static int (void)
static int (unsigned hash, struct rtable *rt, struct rtable **rp)
void (struct rtable *rt, int create)
static void (struct iphdr *iph)
void (struct iphdr *iph, struct dst_entry *dst)
static void (unsigned hash, struct rtable *rt)
void (u32 old_gw, u32 daddr, u32 new_gw,u32 saddr, u8 tos, struct net_device *dev)
static struct dst_entry *(struct dst_entry *dst)
void (struct sk_buff *skb)
static int (struct sk_buff *skb)
static __inline__ unsigned short (unsigned short old_mtu)
unsigned short (struct iphdr *iph, unsigned short new_mtu)
void (struct dst_entry *dst, unsigned mtu)
static struct dst_entry *(struct dst_entry *dst, u32 cookie)
static struct dst_entry *(struct dst_entry *dst,struct sk_buff *skb)
static void (struct dst_entry *dst)
static void (struct sk_buff *skb)
static int (struct sk_buff *skb)
void (u8 *addr, struct rtable *rt)
static void (struct rtable *rt, struct fib_result *res, u32 itag)
int (struct sk_buff *skb, u32 daddr, u32 saddr,u8 tos, struct net_device *dev)
int (struct sk_buff *skb, u32 daddr, u32 saddr,u8 tos, struct net_device *dev)
static int (struct sk_buff *skb, u32 daddr, u32 saddr,u8 tos, struct net_device *dev, int our)
int (struct rtable **rp, const struct rt_key *key)
(struct rtable **rp, const struct rt_key *key)
int struct rtable **rp, const struct rt_key *oldkey)
void (struct in_device *in_dev)
void __init (void)
table 問題
  • RTCF_DIRECTSRC 不知道幹嘛的 唯一用到的地方 icmp.c icm
上一篇:snmp 之Row Status
下一篇:Linux原始套接字实现分析