讀大學時,宿舍每個人都買了電腦,爲了節約網費,整個宿舍又從二手市場淘了臺TP-LINK路由器。這樣每個人的電腦就通過路由器連接到學校網管中心,再連接到外網。從路由器後臺界面可以看到,路由器爲每個人的電腦分配了一個IP
地址。這看上去IP
是屬於主機的.
進入職場以後,公司的電腦都安裝了兩個物理網卡,通過兩根網線分別接入了兩個網絡(10.X.X.X/8 和 192.X.X.X/24).
從適配器管理界面可以看到,兩個網卡都有各自的IP地址.這樣看上去,IP
地址是屬於網卡的。
那麼,究竟哪種說法正確呢 ?
先上結論:IP地址屬於主機,即使我們配置都是在網卡上配置IP地址。
IP地址與網絡接口
在Linux
中, 我們可以通過ifconfig -a
或者ip addr
看到主機上的所有網絡接口
,它有兩種來源,一種是物理網卡的驅動程序創建的,另一種是內核自己或者用戶主動創建的虛擬接口。
舉個栗子:
ip addr
命令一共輸出了4
項,其中ens33
是物理網卡驅動程序創建的,而lo
是內核啓動時自己創建的環回網絡接口,veth0
和veth1
則是我們自己創建的veth peer
虛擬網絡接口。
我們可以將每個網絡接口都視作一條管道,管道的一端連接到本機內核路由子系統,而另一端根據類型各有不同。物理網卡對應的網絡接口另一端通向設備驅動程序;veth peer
類型的接口另一端通向對方;tun
類型設備的另一端通向用戶應用程序。
另外,從上面的輸出內容中還可以注意到的是:網絡接口上並不是一定都有IP
地址(本文提到的IP地址專指IPv4地址),比如veth0
和veth1
後面都沒有IP
地址。
IP地址
是網絡層的概念,而網卡其實更多的是鏈路層的概念。
一個簡化版的IP
報文的接收處理流程如下:
IF 報文目標MAC == 網卡MAC
對報文進行路由
IF 報文目標IP匹配本機路由
上送本機傳輸層
ELSE IF 匹配其他路由
根據路由進行轉發
END
END
在這個過程中,網卡只參加了鏈路層頭部的檢查,只要報文通過檢查,就會上送給網絡層進行路由,至於之後報文去哪,它纔不會管。報文去哪兒完全是路由說了算!
一般來說就兩條路,如果匹配上了本機路由
,則表示這個報文就是給自己的,那麼就根據報文的protocol
字段,上送給對應協議(比如TCP
UDP
ICMP
)處理;如果匹配上其他路由
,就表示這個報文只是將本機當作中轉站,於是它會根據路由結果找到報文的出網絡接口,從該網絡接口(管道)的另一端發送出去.
那麼問題來了,這些路由是哪裏來的?
答案是:當你爲網絡接口配置IP
地址時,內核會生成對應的主機路由、網段路由和廣播路由!
還是上面那個栗子,我們爲veth0
上配置IP
地址
在MAIN
表裏可以看到新添加的網段路由
在LOCAL
表裏可以看到新添加的主機路由和廣播路由
現在我們做個實驗,從PC2
上ping
剛剛配置IP
的veth0
(我們需要先在PC2
上爲1.2.3.4
配置一條靜態路由,讓其知道這個地址其實就在局域網上的主機上,而不會走默認網關)
執行ping
,果然能ping
通!
我們在PC1
上對網卡的抓包結果如下:
這是是普通的局域網內的ping
交互過程:PC2
先通過ARP
獲得1.2.3.4
對應的MAC
地址,再是普通的ICMP request
和ICMP reply
。
稍微有點意思的是PC2
得到的1.2.3.4
的00:0c:29:d6:56:46
,這不是veth0
的MAC
地址,而是ens33
的MAC
地址。這說明上面的交互過程壓根沒有veth0
的參與!如果你用tcpdump
去抓取veth0
上的報文,得不到任何結果!
之所以會這樣,這是因爲Linux
在收到ARP
請求時,默認行爲是隻要ARP
請求報文的目標IP
地址能匹配本機路由,就會回覆收到ARP
請求報文的網絡接口的MAC
地址。
只有主機路由,沒有IP
地址
也就是說,如果沒有爲veth0
配置IP
,而只是配置了主機路由呢 ?
上面的操作中,我們刪除了之前爲veth0
配置的IP
地址,而是主動配置了一條本機路由
還是在PC2
上ping
1.2.3.4
,也能ping
通!
結論
我們在網絡接口上配置IP
地址的本質是配置路由。說到底,IP
地址還是屬於主機的,而不是某個網絡接口。