環回介面(loopback interface)的新認識

YY哥發表於2014-08-19

背景

前些日子在IDC實驗docker的時候,為了避免與公司網路衝突,將bridge設定為127.x網段的IP,原以為這樣就OK,後來發現在訪問container內部的服務的時候無法訪問。開始以為iptables的問題,搞了半天,後來,才發現系統對127.x.x.x的包根本不會經過bridge。這兩天補習了一下linux的路由實現,才徹底明白其中緣由。

其實,關於環回介面,TCP/IP詳解中已經描述得很清楚,只是自己沒有去仔細閱讀而已。

TCP/IP關於環回介面的描述

Linu支援環回介面( Loopback Interface),以允許執行在同一臺主機上的客戶程式和伺服器程式通TCP/IP進行通訊。 A 類網路127就是為環回介面預留的 。根據慣例,大多數系統把IP地址127.0.0.1分配給這個介面,並命名為localhost。一個傳給環回介面的IP資料包不能在任何網路上出現。實際上,訪問127.x.x.x的所有IP都是訪問環回介面(lo)。

 

按理來說,一旦傳輸層檢測到目的端地址是環回地址時,應該可以省略部分傳輸層和所有網路層的邏輯操作。但是大多數的產品還是照樣完成傳輸層和網路層的所有過程,只是當
I P 資料包離開網路層時把它返回給自己。Linux的核心實現就是這樣。

 

幾個關鍵點:

(1)傳給環回地址(一般是127.0.0.1 )的任何資料均作為IP輸入。

(2)傳給廣播地址或多播地址的資料包復制一份傳給環回介面,然後送到乙太網上。這是因為廣播傳送和多播傳送的定包含主機本身。

(3)任何傳給該主機I P地址的資料均送到環回介面 。

 

從上面的描述可以明白,訪問127.0.0.1和本機IP(比如192.168.1.10)都是通過lo來完成的。

 

考慮如下路由表:

 

儘管我們為172.16.213.0/24和129.0.0.0/8指定了出口裝置(eth0/docker0),但實際上,資料仍然是通過lo來完成的。

 

Linux的實現

核心預設有兩個路由表(不考慮策略路由):

struct fib_table *ip_fib_local_table;

struct fib_table *ip_fib_main_table;

前者用於本地路由,後都可以由管理員配置。

NewImage

 

從上面的可以看到,172.16.213.129,127.0.0.0/8都被認為是本機IP。

 

linux在進行路由查詢時,先查詢local,再查詢main:

static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)

{

       if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&

           ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))

              return -ENETUNREACH;

       return 0;

}

 

實際上,如果核心認為目標地址是本機IP,就會將包的出口裝置設定為loopback_dev(不管路由表將出口裝置設定成什麼)。

static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)

{

...

       if (res.type == RTN_LOCAL) {

              if (!fl.fl4_src)

                     fl.fl4_src = fl.fl4_dst;

              if (dev_out)

                     dev_put(dev_out);

              dev_out = &loopback_dev;

              dev_hold(dev_out);

              fl.oif = dev_out->ifindex;

              if (res.fi)

                     fib_info_put(res.fi);

              res.fi = NULL;

              flags |= RTCF_LOCAL;

              goto make_route;

       }

整個資料流過程:

 NewImage

 

 主要參考

[1]TCP/IP詳解

[2]深入理解linux網路技術內幕


作者:YY哥 
出處:http://www.cnblogs.com/hustcat/ 
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。

相關文章