乐趣区

IP地址是主机的还是网卡的

读大学时,宿舍每个人都买了电脑,为了节约网费,整个宿舍又从二手市场淘了台 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 是内核启动时自己创建的环回网络接口,veth0veth1 则是我们自己创建的 veth peer 虚拟网络接口。

我们可以将每个网络接口都视作一条管道,管道的一端连接到本机内核路由子系统,而另一端根据类型各有不同。物理网卡对应的网络接口另一端通向设备驱动程序;
veth peer类型的接口另一端通向对方;tun类型设备的另一端通向用户应用程序。

另外,从上面的输出内容中还可以注意到的是:网络接口上并不是一定都有 IP 地址 (本文提到的 IP 地址专指 IPv4 地址),比如veth0veth1后面都没有 IP 地址。

IP 地址 是网络层的概念,而网卡其实更多的是链路层的概念。

一个简化版的 IP 报文的接收处理流程如下:

IF  报文目标 MAC == 网卡 MAC
    对报文进行路由
    IF 报文目标 IP 匹配本机路由
        上送本机传输层
    ELSE IF 匹配其他路由
        根据路由进行转发
    END
END

在这个过程中,网卡只参加了链路层头部的检查,只要报文通过检查,就会上送给网络层进行路由,至于之后报文去哪,它才不会管。报文去哪儿完全是路由说了算

一般来说就两条路,如果匹配上了 本机路由 ,则表示这个报文就是给自己的,那么就根据报文的protocol 字段,上送给对应协议 (比如TCP UDP ICMP) 处理;如果匹配上 其他路由 , 就表示这个报文只是将本机当作中转站,于是它会根据路由结果找到报文的 出网络接口 ,从该网络接口(管道) 的另一端发送出去.

那么问题来了,这些路由是哪里来的?

答案是:当你为网络接口配置 IP 地址时,内核会生成对应的主机路由、网段路由和广播路由!

还是上面那个栗子,我们为 veth0 上配置 IP 地址

MAIN 表里可以看到新添加的网段路由

LOCAL 表里可以看到新添加的主机路由和广播路由

现在我们做个实验,从 PC2ping刚刚配置 IPveth0

(我们需要先在 PC2 上为 1.2.3.4 配置一条静态路由,让其知道这个地址其实就在局域网上的主机上,而不会走默认网关)

执行 ping, 果然能ping 通!

我们在 PC1 上对网卡的抓包结果如下:

这是是普通的局域网内的 ping 交互过程:PC2先通过 ARP 获得 1.2.3.4 对应的 MAC 地址,再是普通的 ICMP requestICMP reply

稍微有点意思的是 PC2 得到的 1.2.3.400:0c:29:d6:56:46,这不是 veth0MAC地址,而是 ens33MAC地址。这说明上面的交互过程压根没有 veth0 的参与!如果你用 tcpdump 去抓取 veth0 上的报文,得不到任何结果!

之所以会这样,这是因为 Linux 在收到 ARP 请求时,默认行为是只要 ARP 请求报文的目标 IP 地址能匹配 本机路由 ,就会回复收到ARP 请求报文的网络接口的 MAC 地址。

只有主机路由,没有 IP 地址

也就是说,如果没有为 veth0 配置IP,而只是配置了主机路由呢?

上面的操作中,我们删除了之前为 veth0 配置的 IP 地址,而是主动配置了一条 本机路由

还是在 PC2ping 1.2.3.4, 也能 ping 通!

结论

我们在网络接口上配置 IP 地址的本质是配置路由。说到底,IP地址还是属于主机的,而不是某个网络接口。

退出移动版