macvlan是linux的一种虚拟网络接口,macvlan 允许你在主机的一个网络接口上配置多个虚拟的网络接口,这些网络 interface 有自己独立的 mac 地址,也可以配置上 ip 地址进行通信。macvlan 下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。
macvlan 和 bridge 比较相似,但因为它省去了 bridge 的存在,所以配置和调试起来比较简单,而且效率也相对高。除此之外,macvlan 自身也完美支持 VLAN。
macvlan 虚拟网卡设备包括5种模式:
private 模式:在这种模式下,macvlan设备不能接受寄生在同一个物理网卡的其他macvlan设备的数据包,即使是其他macvlan设备通过物理网卡发送出去并通过hairpin设备返回的包。
vepa 模式:在这种模式下,macvlan设备不能直接接受寄生在同一个物理网卡的其他macvlan设备的数据包,但是其他macvlan设备可以将数据包通过物理网卡发送出去,然后通过hairpin设备返回的给其他macvlan设备。
passthru 模式:在这种模式下,每一个物理设备只能寄生一个macvlan设备
bridge 模式:在这种模式下,寄生在同一个物理设备的macvlan设备可以直接通讯,不需要外接的hairpin设备帮助。
source 模式: 在这种模式下,寄生在物理设备的这类macvlan设备,只能接受指定的源 mac source的数据包,其他数据包都不接受。
macvlan在协议栈中两个重要的数据结构:
创建macvlan接口的时候,struct macvlan_dev 会作为macvlan接口设备数据结构net_device的私有数据结构创建(netdev_priv(dev)获取)保存单个macvlan接口的信息。
同时会为其宿主接口(如果是在其上创建的第一个macvlan接口)的net_device挂载特殊设备接收处理函数rx_handler=macvlan_handle_frame,以及这个函数需要用到的参数rx_handler_data,就是macvlan_port。保存的是这个宿主接口以及其下的macvlan接口的整体信息,最重要的当然是查找报文dmac锁对应的macvlan接口。
所有相关处理都在macvlan_common_newlink函数中。
struct macvlan_port {
struct net_device *dev;
struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; // macvlan设备macvlan_dev结构hash表,用于查找
struct list_head vlans; // macvlan设备macvlan_