網絡子係統18_arp對代理的處理
// 代理使用的特性: // medium-id 當ARP請求的目的地址非本機地址時,處理ip子網橫跨不同的lan,且該子網中提供arp請求的主機有多快nic,設置這些nic是否在同一lan // arp代理處理的特點: // 1.本機arp請求的優先級高於對代理主機的arp請求 // 延遲處理的實現: // 1.通過tbl->proxy_queue入隊對代理地址的arp,通過param->proxy_delay指定封包在代理隊列中應該待的時間 // arp代理處理 // 函數主要功能: // 1. 設備需要開啟轉發功能 // 2. 目的ip地址應該為單播類型 // 3. 發送arp請求的主機與被代理的主機使用不同的接口設備連接 // 4. 已經開啟全局代理或設備代理,並且入口lan與出口lan不同 // 5. 如果arp沒有被延遲處理,則延遲處理,否則應答 1.1 static int arp_process(struct sk_buff *skb) { ... //請求地址非本機ip,存在到目的地的路由 } else if (IN_DEV_FORWARD(in_dev)) {//輸入接口具有轉發功能 if ((rt->rt_flags&RTCF_DNAT) ||//此路由項執行目的地網絡地址轉換 (addr_type == RTN_UNICAST && rt->u.dst.dev != dev &&//或目的ip地址為單播類型,並且出口設備不是入口設備 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {//設備可以處理代理,或者代理過的地址數據庫中有目的地址 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);//創建發送ip對應的neighbour結構,被動學習 if (n) neigh_release(n); if (skb->stamp.tv_sec == LOCALLY_ENQUEUED || //檢測此skb是從延時隊列中出隊的 skb->pkt_type == PACKET_HOST ||//或者配置了延時處理,目標主機為本機 in_dev->arp_parms->proxy_delay == 0) {//入口設備配置不適用延時 arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);//應答arp } else { pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb);//否則將此arp入隊,延時處理 in_dev_put(in_dev); return 0; } goto out; } } } ... //此skb為鄰居可達的證據,更新鄰居狀態 ... out: if (in_dev) in_dev_put(in_dev); kfree_skb(skb); return 0; } // 判斷是否可以對此主機進行代理 // 1.開啟全局代理或設備代理 // 2.被代理主機與請求主機應該在不同的lan 2.1 static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt) { struct in_device *out_dev; int imi, omi = -1; //是否開啟設備代理,或者全局代理 if (!IN_DEV_PROXY_ARP(in_dev)) return 0; //一台主機,給連接在同一個lan的多個nic設置相同的medium-id,告訴協議這些nic是否在同一的lan上 if ((imi = IN_DEV_MEDIUM_ID(in_dev)) == 0)//medium-id特性被關閉 return 1; if (imi == -1)//arp代理已關閉 return 0; if ((out_dev = in_dev_get(rt->u.dst.dev)) != NULL) { omi = IN_DEV_MEDIUM_ID(out_dev); in_dev_put(out_dev); } return (omi != imi && omi != -1);//出口設備的medium-id不等於出口設備的medium-id時,才可以代理此請求,表示兩塊nic在不用的lan }
最後更新:2017-04-03 15:22:11