網絡子係統85_inet協議族-l3向上
// ip數據報向本地傳遞 // 調用路徑:ip_rcv->dst_input->...->ip_local_deliver 1.1 int ip_local_deliver(struct sk_buff *skb) { //如果ip數據報被分片,則重組 if (ip_is_fragment(ip_hdr(skb))) { if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER)) return 0; } //通過hook點,向上傳遞 return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, skb, skb->dev, NULL, ip_local_deliver_finish); } // ip數據報向本地傳遞 // 步驟: // 1.向raw套接字傳遞一份skb // 2.根據ip報頭的協議號在inet_protos中找到l4協議 // 3.調用l4協議處理函數 1.2 static int ip_local_deliver_finish(struct sk_buff *skb) { struct net *net = dev_net(skb->dev); //使skb有足夠的ip報頭 __skb_pull(skb, ip_hdrlen(skb)); //使指針指向ip報文內容 skb_reset_transport_header(skb); rcu_read_lock(); { int protocol = ip_hdr(skb)->protocol; const struct net_protocol *ipprot; int raw; resubmit: //向raw套接字傳遞 raw = raw_local_deliver(skb, protocol); //通過l4協議號查找上層協議 //在inet_init中,通過inet_add_protocol注冊l4協議到inet_protos數組 ipprot = rcu_dereference(inet_protos[protocol]); if (ipprot != NULL) { int ret; //l4協議處理函數 ret = ipprot->handler(skb); if (ret < 0) { protocol = -ret; goto resubmit; } //snmp統計 IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS); } ... } out: rcu_read_unlock(); return 0; }
最後更新:2017-04-03 12:55:18