網絡子係統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