There are multiple ways to achieve your setup, but I am going to add one of the recommended ones. Use openvswitch
Openvswitch is a multilayer virtual switch, its designed to enable network automation (from its source site)
http://openvswitch.org/download/ (thats where you download the package)
I had referred below tutorials for installing and setting up openvswitch
http://blog.scottlowe.org/2012/08/17/installing-kvm-and-open-vswitch-on-ubuntu/
or
https://n40lab.wordpress.com/2015/06/28/centos-7-installing-openvswitch-2-3-2-lts/
If the VM Host has its interfaces on trunk mode, then you can do the following.
You can setup a single OV bridge (of course this would have an IP, and of the untagged/native vlan).
Then you might want to setup VIRSH Network. Something like this
<network>
<name>ovs-network2</name>
<forward mode='bridge'/>
<bridge name='br0'/>
<virtualport type='openvswitch'/>
<portgroup name='vlan-a'>
<vlan>
<tag id='1'/>
</vlan>
</portgroup>
<portgroup name='vlan-b' default='yes'>
</portgroup>
</network>
In my above example, vlan-a is for tagged traffic, and vlan-b is untagged
Once you define/start virsh network, you might want to change XML settings for your VM, in the following order
<interface type='network'>
<mac address='blah blah'/>
<source network='ovs-network2' portgroup='vlan-a'/>
</inteface>
You might have other settings in it too like virtio, addresstype
The above example might help you in avoiding multiple IP addresses for each tagged vlan bridge. Here are some great references to look at.
http://blog.scottlowe.org/2012/11/07/using-vlans-with-ovs-and-libvirt/
And here is another article that does a similar setup
https://www.netflask.net/transparent-vlan-tagging-libvirt-ovs/
I hope this helps! :)
Maybe you can use libvirt's hook script. You script a shell script that libvirt will execute as soon as your VM is started.
Create the file /etc/libvirt/hooks/qemu
with this inside:
#!/bin/bash
if [ "${1}" = "<the name of your vm>" ] ; then
VM_NAME=${1}
VM_IP=172.16.20.10
if [ "${2}" = "prepare" ] ; then
iptables -t nat -I POSTROUTING -s ${VM_IP} -o eth0 \
-m comment --comment "${VM_NAME} nat" -j MASQUERADE
elif [ "%{2}" = release" ] ; then
iptables -t nat -D POSTROUTING -s ${VM_IP} -o eth0 \
-m comment --comment "${VM_NAME} nat" -j MASQUERADE
fi
Make sure you substitute the <the name of yout vm>
and the value of VM_IP appropriately.
Make the file executable too: chmod +x /etc/libvirt/hooks/qemu
.
Now, every time libvirt start your VM, it will prepare the NAT configuration and after VM stop, will deconfigure the NAT.
For more information, you can look at here and here
Best Answer
This is very simple to do. Normally, you would use bridging on the host, the bridge acting as a virtual switch for the VMs and the physical NICs to plug into:
network -> Host NIC -> BRIDGE <- VM
With VLANs this gets a bit more complicated:
network (trunk port) -> Host NIC -> Tagged IF -> BRIDGE <- VM
All of this is managed in
ifcfg
scripts on a RHEL host, e.g. ifcfg-eth0 (host NIC); ifcfg-eth0.100 (Tagged IF); ifcfg-br100 (bridge interface working on top of the tagged interface, transmitting tagged traffic).If you need multiple VLANs, simply add more ifcfg-eth0.tagNumber interfaces, and build a bridge on top of each, for VMs who need to be on the tagged network to plug into.
Hope it makes sense, it's really quite simple.
EDIT: