讀大學時,宿舍每一個人都買了電腦,爲了節約網費,整個宿舍又從二手市場淘了臺TP-LINK路由器。這樣每一個人的電腦就經過路由器鏈接到學校網管中心,再鏈接到外網。從路由器後臺界面能夠看到,路由器爲每一個人的電腦分配了一個IP
地址。這看上去IP
是屬於主機的.網絡
進入職場之後,公司的電腦都安裝了兩個物理網卡,經過兩根網線分別接入了兩個網絡(10.X.X.X/8 和 192.X.X.X/24).tcp
從適配器管理界面能夠看到,兩個網卡都有各自的IP地址.這樣看上去,IP
地址是屬於網卡的。spa
那麼,究竟哪一種說法正確呢 ?3d
先上結論:IP地址屬於主機,即便咱們配置都是在網卡上配置IP地址。code
在Linux
中, 咱們能夠經過ifconfig -a
或者ip addr
看到主機上的全部網絡接口
,它有兩種來源,一種是物理網卡的驅動程序建立的,另外一種是內核本身或者用戶主動建立的虛擬接口。blog
舉個栗子:接口
ip addr
命令一共輸出了4
項,其中ens33
是物理網卡驅動程序建立的,而lo
是內核啓動時本身建立的環回網絡接口,veth0
和veth1
則是咱們本身建立的veth peer
虛擬網絡接口。ip
咱們能夠將每一個網絡接口都視做一條管道,管道的一端鏈接到本機內核路由子系統,而另外一端根據類型各有不一樣。物理網卡對應的網絡接口另外一端通向設備驅動程序;veth peer
類型的接口另外一端通向對方;tun
類型設備的另外一端通向用戶應用程序。路由
另外,從上面的輸出內容中還能夠注意到的是:網絡接口上並非必定都有IP
地址(本文提到的IP地址專指IPv4地址),好比veth0
和veth1
後面都沒有IP
地址。rem
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
地址仍是屬於主機的,而不是某個網絡接口。