TCP IP關於環迴介面的描述

2021-09-18 06:10:09 字數 4221 閱讀 9695

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

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

linu支援環迴介面( loopback inte***ce),以允許執行在同一臺主機上的客戶程式和伺服器程式通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來完成的。

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

struct fib_table *ip_fib_local_table;

struct fib_table *ip_fib_main_table;

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

從上面的可以看到,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;

整個資料流過程:

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

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

linu支援環迴介面( loopback inte***ce),以允許執行在同一臺主機上的客戶程式和伺服器程式通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來完成的。

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

struct fib_table *ip_fib_local_table;

struct fib_table *ip_fib_main_table;

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

從上面的可以看到,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;

整個資料流過程:

TCP IP 環迴介面

我們經常在linux的host下面看到 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 實際上這個就是環迴介面,下面是w.richard stevens 在tcp ip 卷1中關於環迴介面的描述...

關於127 0 0 1環迴位址

有網路知識基礎的人,肯定不會對127.0.0.1這個ip位址感到陌生,如果本機搭建了 web伺服器 只要在瀏覽器中輸入這個127.0.0.1或localhost就能訪問。很多人因此把它叫做本機位址,實際上這種叫法是不準確的,127.0.0.1真正的名稱是環迴位址 loopback address 1...

關於介面的問答

問題一 為乙個子系統定義介面,然後其它子系統通過介面來進行訪問該子系統。這時其它子系統就要 呼叫 該系統的介面 怎麼個呼叫法,通過實現介面中的方法?問題二 比如 後台維護子系統 它其中有很多 用例類 類是根據用例抽象來的 每個類都有 增 刪 改 查 這些 增 刪 改 查 可不可以抽象出來,抽象成介面...