tapip的网络拓扑

网络拓扑一:替换内核网络协议栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+----------+
| internet | (10.20.133.20)
+----|-----+ |
+----|-----+ |
| eth0 | (0.0.0.0)
+----|-----+ |
+----|-----+ |
| bridge | (0.0.0.0)
+----|-----+ |
+----|---------+ |
| tap0 | (0.0.0.0)
|--------------|
| /dev/net/tun | /dev/net/tun
+--|----|---|--+ |
poll | | |
| read | |
| | write |
+--|----|---|--+ |
| my netstack | (10.20.133.21)
+--------------+

通过网桥连通本地网络eth0和虚拟网络tap0

区别

  1. 本地网络作为网关
  2. 不支持重定向
  3. 路由初始化,下一跳为TAP的IP
  4. 如果下一跳不可达,需要返回Code 0 (Network Unreachable) ICMP报文(RFC 1812)
  5. 虚拟网络设备额外初始化过程
  6. ifconfig 命令特殊提示

脚本

  1. 创建网络设备tap0 简要输出接口名到垃圾桶
  2. 创建网桥设备br0
  3. 配置网桥通过 br0 连通 eth0 tap0
  4. eth0 tap0 br0加入本地网络并启动

WARNING

谨慎使用该模式,内核协议栈会被挂起,网络由用户态接管。
如果是远程登录使用TOP1可能会导致断连,无法继续使用。
建议直接使用串口同真实机器交互,以方便恢复原网络拓扑。

网络拓扑二:虚拟设备与核心交互

1
2
3
4
5
6
7
8
localhost                     outside network
kernel stack usermode stack [ ./tapip ]
| (10.0.0.1)
| (write) | .
| \|/ /|\
| ' | (read)
tap0 <------ netif_rx() -----/dev/net/tun
(10.0.0.2) `-- tun_net_xmit() -----------^

local -> tap0(10.0.0.2) -> veth0(10.0.0.1)

交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
                  +-------------------[Linux kernel TCP/IP stack]---------------------+
| |
arping 10.0.0.1 -----> socket send --> route --> tap0 --> tap0::dev_hard_xmit |
| ( arp packet: | |
| 10.0.0.2 request | |
| hwaddr of 10.0.0.1) | _tap0 (10.0.0.2)_ |
| | |
arping received <----- socket recv <-- tap0(netif_rx) <----. | |
| | | |
+-----------------------------------------|--|----------------------+
| |
/dev/net/tun
| |
(write) | | (read)
| |
.--------> reply --> netdev_tx-' | _veth (10.0.0.1)_
| \|/
| '
'- arp_in <-- netif_in <----- process
update arp cache <------' { usermode network stack }
  1. arping 命令进程向内核发起寻址请求
  2. 内核将请求包路由至tap0设备
  3. 经虚拟网络设备交换至用户态协议栈tapip处理
  4. 寻址结果返回设备tap0,经内核返回arping命令进程显示

Linux虚拟网络设备之tun/tap
user-mode TCP/IP stack based on linux tap device