日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux .forward,linux forward的实现

發布時間:2024/7/23 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux .forward,linux forward的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于linux的數據包流向,大家應該是比較了解,如果還不是很了解,可以參考《OReilly.Understanding.Linux.Network.Internals.Dec.2005》,其中有一個圖非常清楚的描述了數據包的流向。

ip的數據包接收函數是ip_rcv()==>ip_rcv_finish()

在ip_rcv_finish()中:

if (skb->dst == NULL) {

int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,

skb->dev);

剛接收到的數據包,skb->dst項是空的,因此會調用ip_route_input()函數,我們來追蹤ip_route_input函數:

ip_route_input()==>ip_route_input_slow()

在ip_route_input_slow()中:

if ((err = fib_lookup(&fl, &res)) != 0) {

if (!IN_DEV_FORWARD(in_dev))

goto e_hostunreach;

goto no_route;

}

調用fib_lookup()函數用來在fib中查詢路由信息,將路由查詢結果保存在fib_result結構的res中。

接下來:

if (res.type == RTN_LOCAL) {

int result;

result = fib_validate_source(saddr, daddr, tos,

loopback_dev.ifindex,

dev, &spec_dst, &itag);

if (result < 0)

goto martian_source;

if (result)

flags |= RTCF_DIRECTSRC;

spec_dst = daddr;

/*設置skb->dst->input=ip_local_deliver*/

goto local_input;

}

如果查詢的結果顯示,路由類型RTN_LOCAL的話,跳轉到local_input段,設置skb->dst->input = ip_local_deliver

接下來,路由類型是RTN_LOCAL的已經跳轉到下面去了,剩下的就是非LCOAL的,也就是Forward的:

if (!IN_DEV_FORWARD(in_dev))

goto e_hostunreach;

if (res.type != RTN_UNICAST)

goto martian_destination;

/*設置skb->dst->input=ip_forward*/

err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);

調用IN_DEV_FORWARD宏來判斷網絡設備是否處于FORWARD狀態;調用ip_mkroute_input()函數來設置skb->dst->input=ip_forward

我們來分析一下IN_DEV_FORWARD這個宏:

#define IN_DEV_FORWARD(in_dev)??? ((in_dev)->cnf.forwarding)

在ipv4_sysctl_forward()函數中調用inet_forward_change()函數:

在inet_forward_change()函數中:

int on = ipv4_devconf.forwarding;

in_dev->cnf.forwarding = on;

在sysctl_net_ipv4.c中

{

.ctl_name??? = NET_IPV4_FORWARD,

.procname??? = "ip_forward",

.data??? ??? = &ipv4_devconf.forwarding,

.maxlen??? ??? = sizeof(int),

.mode??? ??? = 0644,

.proc_handler??? = &ipv4_sysctl_forward,

.strategy??? = &ipv4_sysctl_forward_strategy

},

這樣,我們通過

echo 1 > /proc/sys/net/ipv4/ip_forward

來打開forward功能,實際上就調用了

ipv4_sysctl_forward()==>inet_forward_change()

設置了in_dev->cnf.forwarding = 1;

這樣IN_DEV_FORWARD(in_dev)返回為1,當forward的數據包到來的時候,能夠調用ip_mkroute_input()函數,設置skb->dst->input=ip_forward。

==========

再回到ip_rcv_finish()中,最后函數調用了dst_input函數,我們來追蹤一下dst_input()函數:

dst_input()==>skb->dst->input

對于LOCAL的數據包來說調用的是:ip_local_deliver()函數

對于FORWARD的數據包來說調用的是:ip_forward()函數

對于fib_lookup的細節,可以參考:

http://blog.chinaunix.net/u/28366/showart_215922.html

閱讀(4638) | 評論(0) | 轉發(0) |

總結

以上是生活随笔為你收集整理的linux .forward,linux forward的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。