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