閱讀220 返回首頁    go 阿裏雲 go 技術社區[雲棲]


網絡子係統49_ip協議報頭id選取

//more = skb_shinfo(skb)->tso_segs,由tcp傳遞
1.1 static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more)
{
	if (iph->frag_off & htons(IP_DF)) {//禁止分片
		if (sk && inet_sk(sk)->daddr) {
			iph->id = htons(inet_sk(sk)->id);//使用sock中指定的id
			inet_sk(sk)->id += 1 + more;//sock中id遞增
		} else
			iph->id = 0;
	} else
		__ip_select_ident(iph, dst, more);//可分片ip報文選擇id
}
//調用路徑ip_select_ident_more->__ip_select_ident
//函數主要任務:
//	1.處理路由項與inet_peer的綁定
//	2.通過inet_peer,或者全局ip_fallback_id獲取id
1.2 void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
{
	struct rtable *rt = (struct rtable *) dst;

	if (rt) {//存在到目的地址的路由
		if (rt->peer == NULL)//inet_peer結構,表示該緩存路由項的目的ip地址對應的主機
			rt_bind_peer(rt, 1);//尋找和該端點相匹配的inet_peer結構,如果不存在,嚐試創建一個新的inet_peer

		if (rt->peer) {//通過inet_peer的計數器,生成與接收方相關的遞增id
			iph->id = htons(inet_getid(rt->peer, more));
			return;
		}
	} else
		printk(KERN_DEBUG "rt_bind_peer(0) @%p\n", NET_CALLER(iph));
	//之前嚐試都失敗,通過一個靜態變量ip_fallback_id,再和端點的目的地ip地址結合,通過secure_ip_id獲取id
	ip_select_fb_ident(iph);
}

//調用路徑ip_select_ident_more->__ip_select_ident->inet_getid
1.3 static inline __u16	inet_getid(struct inet_peer *p, int more)
{
	__u16 id;

	spin_lock_bh(&inet_peer_idlock);//獲取一個全局的鎖
	id = p->ip_id_count;
	p->ip_id_count += 1 + more;//更新inet_peer中的id計數器
	spin_unlock_bh(&inet_peer_idlock);
	return id;
}

最後更新:2017-04-03 14:53:41

  上一篇:go oracle 不是group by表達式
  下一篇:go 麵試之如何回答關於算法設計的問題?