Linux 虚拟网络设备之 bridge

2021-09-23 18:00 PHP开源社区
点击进入“PHP开源社区”    
免费获取进阶面试、文档、视频资源
PHP开源社区
PHP开源社区
免费提供10GPHP进阶架构师学习教程,关注即可免费领取。每天推送PHP最新资讯技术文章。
84篇原创内容
公众号

本文将通过实际的例子来一步一步解释bridge是如何工作的。

什么是bridge?

首先,bridge是一个虚拟网络设备,所以具有网络设备的特征,可以配置IP、MAC地址等;其次,bridge是一个虚拟交换机,和物理交换机有类似的功能。

对于普通的网络设备来说,只有两端,从一端进来的数据会从另一端出去,如物理网卡从外面网络中收到的数据会转发给内核协议栈,而从协议栈过来的数据会转发到外面的物理网络中。

而bridge不同,bridge有多个端口,数据可以从任何端口进来,进来之后从哪个口出去和物理交换机的原理差不多,要看mac地址。

创建bridge

我们先用iproute2创建一个bridge:

dev@debian:~$ sudo ip link add name br0 type bridge
dev@debian:~$ sudo ip link set br0 up

当刚创建一个bridge时,它是一个独立的网络设备,只有一个端口连着协议栈,其它的端口啥都没连,这样的bridge没有任何实际功能,如下图所示:

+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|              ↑                                ↑                |
|..............|................................|................|
|              ↓                                ↓                |
|        +----------+                     +------------+         |
|        |   eth0   |                     |     br0    |         |
|        +----------+                     +------------+         |
| 192.168.3.21 ↑                                                 |
|              |                                                 |
|
              |                                                 |
+--------------|-------------------------------------------------+
               ↓
         Physical Network

这里假设eth0是我们的物理网卡,IP地址是192.168.3.21,网关是192.168.3.1

将bridge和veth设备相连

创建一对veth设备,并配置上IP

dev@debian:~$ sudo ip link add veth0 type veth peer name veth1
dev@debian:~$ sudo ip addr add 192.168.3.101/24 dev veth0
dev@debian:~$ sudo ip addr add 192.168.3.102/24 dev veth1
dev@debian:~$ sudo ip link set veth0 up
dev@debian:~$ sudo ip link set veth1 up

将veth0连上br0

dev@debian:~$ sudo ip link set dev veth0 master br0
#通过bridge link命令可以看到br0上连接了哪些设备
dev@debian:~$ sudo bridge link
6: veth0 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 2

这时候,网络就变成了这个样子:

+----------------------------------------------------------------+
|                                                                |
|       +------------------------------------------------+       |
|       |             Newwork Protocol Stack             |       |
|       +------------------------------------------------+       |
|            ↑            ↑              |            ↑          |
|
............|............|..............|............|..........|
|
            ↓            ↓              ↓            ↓          |
|
        +------+     +--------+     +-------+    +-------+      |
|
        | .3.21|     |        |     | .3.101|    | .3.102|      |
|
        +------+     +--------+     +-------+    +-------+      |
|
        | eth0 |     |   br0  |<--->| veth0 |    | veth1 |      |
|
        +------+     +--------+     +-------+    +-------+      |
|
            ↑                           ↑            ↑          |
|
            |                           |            |          |
|            |                           +------------+          |
|
            |                                                   |
+------------|---------------------------------------------------+
             ↓
     Physical Network

这里为了画图方便,省略了IP地址前面的192.168,比如.3.21就表示192.168.3.21

br0和veth0相连之后,发生了几个变化:

  • br0和veth0之间连接起来了,并且是双向的通道

  • 协议栈和veth0之间变成了单通道,协议栈能发数据给veth0,但veth0从外面收到的数据不会转发给协议栈

  • br0的mac地址变成了veth0的mac地址

相当于bridge在veth0和协议栈之间插了一脚,在veth0上面做了点小动作,将veth0本来要转发给协议栈的数据给拦截了,全部转发给bridge了,同时bridge也可以向veth0发数据。

下面来检验一下是不是这样的:

通过veth0 ping veth1失败:

dev@debian:~$ ping -c 1 -I veth0 192.168.3.102
PING 192.168.2.1 (192.168.2.1from 192.168.2.11 veth0: 56(84) bytes of data.
From 192.168.2.11 icmp_seq=1 Destination Host Unreachable

--- 192.168.2.1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

为什么veth0加入了bridge之后,就ping不通veth2了呢?先抓包看看:

#由于veth0的arp缓存里面没有veth1的mac地址,所以ping之前先发arp请求
#从veth1上抓包来看,veth1收到了arp请求,并且返回了应答
dev@debian:~$ sudo tcpdump -n -i veth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
21:43:48.353509 ARP, Request who-has 192.168.3.102 tell 192.168.3.101length 28
21:43:48.353518 ARP, Reply 192.168.3.102 is-at 26:58:a2:
本文章转载自公众号:phpopensource

首页 - PHP 相关的更多文章: