NB: The following is only of interest if you want to share the host network with your virtual machine. The most common way this gets implemented is by setting up a bridge which includes the physical interface. Using a MACVTAP inerface is suposed to be more efficient, since it avoids the additional bridge in the network setup.
In this gist, we extend the information provided in the documenation on linux virtual interfaces.
In the following, we assume you host interface is eth0
. IP addresses used:
- host: 198.51.100.50/24
- virtual machine: 198.51.100.198/24
- default gateway: 198.51.100.254
In the normal setup, the host will use eth0
to comunicate with the outside and will have the IP addresses assigned to that interface.
ip addr add dev eth0 198.51.100.50/24
ip route add default via 198.51.100.254
When you look at the docummentation of linux virtual interfaces you notice that, normally, you cannot communicate between the host and a virtual machine using MACVTAP (or direct attachment) instead of a bridged network to connect to the host network. Unless you have support by external hardware, you should use bridge mode.
Here is a snippet used to set up a domain in libvirt with direct attachment to the physical interface:
<interface type='direct' trustGuestRxFilters='yes'>
<source dev='eth0' mode='bridge'/>
<target dev='macvtap0'/>
<model type='virtio'/>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</interface>
This will create a MACVTAP interface connected to eth0
. If you have several virtual machines set up this way, they will be able to communicate. It is not possible, though, for packages to get bridged from eth0
to one of the MACVTAP interfaces.
On-host MACVLAN
To work around this, you can add an additional, virtual, interface for the host and use that for outgoing connections. This will be a MACVLAN interface, which is more often used for containers. Here, we will create the MACVLAN inerface in the host's main network namespace and not in the namespace of a container, so it is accessible as an additional interface on the host. Briding works also between MACVTAP and MACVLAN interfaces, so the host can communicate from veth0
to the VMs and to the outside.
We will create the interface veth0
in the main network namespace and assign the IP addresses to that interface.
ip link set eth0 up
ip link add veth0 link eth0 type macvlan mode bridge
ip addr add dev veth0 198.51.100.50/24
ip route add default via 198.51.100.254
Note that eth0
is activated, but does not have any IP address assigned. The host can now communicate to both to external host and to internal VMs on the 198.51.100.0/24 network.
debian-style interfaces example
In the setup for a debian system, this translates to the /etc/network/interfaces
file as:
auto veth0
iface veth0 inet static
pre-up ifup eth0 || true
pre-up ip link add veth0 link eth0 type macvlan mode bridge
post-down ip link del veth0
address 198.51.100.50
netmask 255.255.255.0
network 198.51.100.0
broadcast 198.51.100.255
gateway 198.51.100.254
# dns-* options are implemented by the resolvconf package, if installed
dns-nameservers 8.8.8.8 1.1.1.1
iface eth0 inet manual