linux 的三种硬件设备

linux 的硬件设备分为字符设备,块设备,网络设备。
字符设备提供连续的数据流,应用程序只能顺序读取,常见的有键盘,串口等,发送的指令数据都是顺序进行处理的,这一点比较好理解。
块设备可以允许随机读取,比如磁盘,内存条等,可以寻址到任意的位置去读取数据。
字符设备和块设备都可以在 /dev 下看到,列一部分设备如下,c 表示字符设备,b 表示块设备。

  1. [root@bjht-100G-GPU-001 stat]# ll /dev/
  2. crw------- 1 root root 10, 235 8 22 17:08 autofs
  3. drwxr-xr-x 2 root root 200 8 22 17:08 block
  4. crw------- 1 root root 10, 234 8 22 17:08 btrfs-control
  5. drwxr-xr-x 3 root root 60 8 22 17:08 bus

网络设备是特殊设备的驱动,它负责接收和发送帧数据,可能是物理帧,也可能是ip数据包,这些特性都有网络驱
动决定。它并不存在于/dev下,所以与一般的设备不同。网络设备是一个net_device结构,通过register_netdev
注册到系统里,可以通过 ifconfig -a 看到。

Linux 的虚拟网络设备之 ——tun/tap

tun/tap 的一端连着内核协议栈,一端连着应用程序。从内核协议栈传输到物理网络的包会有一部分被 tun/tap 劫持交给特定的应用程序处理,然后再从的应用程序发到物理网络上去。
这种流量劫持最常用的场景就是VPN,加密,压缩等应用。

  1. +----------------------------------------------------------------+
  2. | |
  3. | +--------------------+ +--------------------+ |
  4. | | User Application A | | User Application B |<-----+ |
  5. | +--------------------+ +--------------------+ | |
  6. | | 1 | 5 | |
  7. |...............|......................|...................|.....|
  8. | | |
  9. | +----------+ +----------+ | |
  10. | | socket A | | socket B | | |
  11. | +----------+ +----------+ | |
  12. | | 2 | 6 | |
  13. |.................|.................|......................|.....|
  14. | | |
  15. | +------------------------+ 4 | |
  16. | | Newwork Protocol Stack | | |
  17. | +------------------------+ | |
  18. | | 7 | 3 | |
  19. |................|...................|.....................|.....|
  20. | | |
  21. | +----------------+ +----------------+ | |
  22. | | eth0 | | tun0 | | |
  23. | +----------------+ +----------------+ | |
  24. | 10.32.0.11 | | 192.168.3.11 | |
  25. | | 8 +---------------------+ |
  26. | | |
  27. +----------------|-----------------------------------------------+
  28. Physical Network

https://segmentfault.com/a/1190000009249039

Linux 的虚拟网络设备之 ——veth

veth 一般是成对出现。

  1. +----------------------------------------------------------------+
  2. | |
  3. | +------------------------------------------------+ |
  4. | | Newwork Protocol Stack | |
  5. | +------------------------------------------------+ |
  6. | |
  7. |..............|...............|...............|.................|
  8. | |
  9. | +----------+ +-----------+ +-----------+ |
  10. | | eth0 | | veth0 | | veth1 | |
  11. | +----------+ +-----------+ +-----------+ |
  12. |192.168.1.11 |
  13. | | +---------------+ |
  14. | | 192.168.2.11 192.168.2.1 |
  15. +--------------|-------------------------------------------------+
  16. Physical Network

https://segmentfault.com/a/1190000009251098

Linux 的虚拟网络设备之 —— Bridge

https://segmentfault.com/a/1190000009491002
物理网络设备有网卡、中继器、网桥、路由器、交换机等,linux 内核为这些物理设备抽象了各个虚拟的网络设备。
linux 内核中的 bridge 可以理解为一个虚拟交换机,有多个端口,数据可以从任何端口进来,进来之后从哪个口出去和物理交换机的原理差不多,要看mac地址。Bridge 内部维护了端口到Mac地址的映射表。
新建一个网桥:

  1. //新增一个网桥
  2. [root@vbj-mlp-zhaomeng-9-4 husong]# ip link add name br0 type bridge
  3. //查看新增网桥的状态
  4. [root@vbj-mlp-zhaomeng-9-4 husong]# ip link show br0 type bridge
  5. 542: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
  6. link/ether fe:f5:fb:5f:b7:d9 brd ff:ff:ff:ff:ff:ff
  7. //UP 网桥
  8. [root@vbj-mlp-zhaomeng-9-4 husong]# ip link set br0 up
  9. //查看网桥的状态
  10. [root@vbj-mlp-zhaomeng-9-4 husong]# ip link show br0 type bridge
  11. 542: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
  12. link/ether fe:f5:fb:5f:b7:d9 brd ff:ff:ff:ff:ff:ff

Bridge 和 veth 连接之后,会劫持veth 和内核协议栈的包,如图 veth0 收到的包不在给协议栈,而是给 bridge。

  1. +----------------------------------------------------------------+
  2. | |
  3. | +------------------------------------------------+ |
  4. | | Newwork Protocol Stack | |
  5. | +------------------------------------------------+ |
  6. | | |
  7. |............|............|..............|............|..........|
  8. | |
  9. | +------+ +--------+ +-------+ +-------+ |
  10. | | .3.21| | | | .3.101| | .3.102| |
  11. | +------+ +--------+ +-------+ +-------+ |
  12. | | eth0 | | br0 |<--->| veth0 | | veth1 | |
  13. | +------+ +--------+ +-------+ +-------+ |
  14. | |
  15. | | | | |
  16. | | +------------+ |
  17. | | |
  18. +------------|---------------------------------------------------+
  19. Physical Network

当一个设备被 attach 到 Bridge 上时,那个设备的 IP 会变的无效,Linux 不再使用那个 IP 在三层接受数据。举例如下:如果 eth0 本来的 IP 是 192.168.1.2,此时如果收到一个目标地址是 192.168.1.2 的数据,Linux 的应用程序能通过 Socket 操作接受到它。而当 eth0 被 attach 到一个 bridge0 时,尽管 eth0 的 IP 还在,但应用程序是无法接受到上述数据的。此时应该把 IP 192.168.1.2 赋予 bridge0。
如果bridge 和 eth0 相连,eth0 发给协议栈的数据也会被劫持,从而退化成一根网线,对 bridge 来说,根本不区分是虚拟网络设备还是物理网络设备,所以 veth 和 eth0 连上bridge 之后的效果是一样的。

Linux 的虚拟网络设备之 —— VLAN device for 802.1.q