一、macvlan或macvtap 命令格式

添加 macvlan或macvtap 命令如下

ip link add link {DEVICE} name {NAME} type { macvlan | macvtap } 
    mode { private | vepa | bridge | passthru  [ nopromisc ] | source }


# 举例:现有网卡名称为ens33,创建macvlan类型的,名为ens33.1的 网卡
ip link add link ens33 name ens33.1 type macvlan mode bridge

type {macvlan | macvtap}

指定即将创建link的类型。macvlan仅创建虚拟网卡,macvtap除了创建虚拟网卡,还创建字符设备(character device)  /dev/tapX,该字符设备就和tuntap设备类似。

假设

  1. 物理网卡为p
  2. 在这一张物理网卡上,创建了两个macvlan网卡,分别为m1和m2。

定好以上前提,我们描述下面5种模式

1. mode private

m1和m2直接无法通信,即使外部交换机支持hairpin模式,m1和m2也无法通信。

为什么提到外部交换机呢?因为:macvlan是二层,都连在同一个交换机上。这里的意思是说即使p所连接到的交换机支持hairpin,m1和m2也无法通信。

2. mode vepa(虚拟以太网端口聚合模式)。默认

m1和m2之间的数据传输,总是走p。p连接的交换机必须要能支持hairpin模式,或p连接到路由器(路由器都支持包转发的)。

3. mode bridge

所有终端都两两相连。通信无需p转发。

4. mode passthru [nopromisc]

该模式赋予单个终端更多能力,经常用在macvtap下。在此模式下,同一张物理网卡只允许单一一个终端。全部流量都被转发到该终端,允许virtio guest更改MAC地址,或设置promiscuous 模式,以支持对网卡进行桥接或在网卡上创建vlan接口。

默认情况下,该模式强制网卡进入promiscuous模式。传入nopromisc 标志可以禁止进入promiscuous模式。

5. mode source

该模式允许设置所允许的MAC地址列表,从底层的网卡收到frame时,对比frame中的source字段。这使得可以创建基于MAC地址的VLAN,而不是基于标准端口(port)或标记(tag)的VLAN。在部署基于 802.1x MAC的行为时,由于底层网卡的驱动不支持基于MAC的VLAN,此时mode source就很有用啦。

二、我们来试试

我们通过创建network namespace来试验下。

macvlan网卡的IP和物理网卡的IP必须位于同一个网段,在我们的例子中:

物理网卡为ens33,其IP为 192.168.86.205

两个macvlan的IP分别为:192.168.86.101 和 192.168.86.102

# 创建 macvlan网卡

sudo ip link del dev ens33.1

sudo ip link add link ens33 name ens33.1 type macvlan mode bridge

# 创建 namespace

sudo ip netns del ns1

sudo ip netns add ns1

# 将子接口挂到 namespace

sudo ip link set ens33.1 netns ns1

# 配置 IP 并启用

sudo ip netns exec ns1 ip addr add 192.168.86.101/24 dev ens33.1

sudo ip netns exec ns1 ip link set ens33.1 up

配置完成后,ns1中的配置如下

marvin@vm205:~$ sudo ip netns exec ns1 ip -c addr 
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
43: ens33.1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether c2:bf:47:28:89:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.86.101/24 scope global ens33.1
       valid_lft forever preferred_lft forever
    inet6 fe80::c0bf:47ff:fe28:89f1/64 scope link 
       valid_lft forever preferred_lft forever
marvin@vm205:~$ sudo ip netns exec ns1 ip -c route
192.168.86.0/24 dev ens33.1 proto kernel scope link src 192.168.86.101 
marvin@vm205:~$

#同样的,配置起来第二个macvlan网卡

# ens33.2
sudo ip link del dev ens33.2
sudo ip link add link ens33 name ens33.2 type macvlan mode bridge

sudo ip netns del ns2
sudo ip netns add ns2
sudo ip link set ens33.2 netns ns2
sudo ip netns exec ns2 ip addr add 192.168.86.102/24 dev ens33.2
sudo ip netns exec ns2 ip link set ens33.2 up

看下效果:

marvin@vm205:~$ sudo ip netns exec ns2 ping 192.168.86.101
PING 192.168.86.101 (192.168.86.101) 56(84) bytes of data.
64 bytes from 192.168.86.101: icmp_seq=1 ttl=64 time=0.124 ms
....
^C
--- 192.168.86.101 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4092ms
rtt min/avg/max/mdev = 0.028/0.049/0.124/0.037 ms
marvin@vm205:~$ sudo ip netns exec ns1 ping 192.168.86.102
PING 192.168.86.102 (192.168.86.102) 56(84) bytes of data.
64 bytes from 192.168.86.102: icmp_seq=1 ttl=64 time=0.021 ms
....
^C
--- 192.168.86.102 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2056ms
rtt min/avg/max/mdev = 0.021/0.026/0.030/0.004 ms
marvin@vm205:~$

mode bridge,通

mode private,不通

mode vepa,不通

(可能是由于我的物理网卡所连接到的交换机192.168.86.2,不支持hairpin模式)

完