I am putting this here for those that follow - and especially me for when I forget how I finally got it working:
I continued on pressing AI for answers and troubleshooting. Today leaning on Gemini AI. I finally got it working. My layman’s commentary along with Gemini’s work follows:
So - the expansion card NIC you want inside the VM and owned by it completely. The second issue was OpenWRT was grabbing the expansion card by default as the WAN NIC.
So first – to hand over the expansion card nic to the VM
In Ubuntu you start in Grub
sudo nano /etc/default/grub
Modify the GRUB_CMDLINE_LINUX_DEFAULT Line:
for Intel: Add intel_iommu=on
for AMD: Add amd_iommu=on
For me I changed my line to:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"
Then update the changes
sudo update-grub
And reboot
Verify IOMMU is Active: After rebooting, check for IOMMU groups:
dmesg | grep -i iommu
and reading through there – it says “iommu enabled” = Success!
Next build a netplan.yaml file -
sudo /etc/netplan/netplan_config.yaml
for me with my motherboard nic named enp0s25 and my current default gateway and desired static ip my file became:
network:
version: 2
ethernets:
enp0s25:
dhcp4: false
addresses: [192.168.1.190/24]
routes:
- to: default
via: 192.168.1.1 # Gateway (Main Router)
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
Save changes
Correct the permissions of the file
sudo chmod 600 /etc/netplan/netplan_config.yaml
Try the new netplan
sudo netplan try
If you get no errors you are safe to accept the changes or if you time out you can
Apply the new netplan:
sudo netplan apply
Revised virt-install Command
The VM now needs two network connections:
WAN Connection (Virtual): Use the existing network=default (NAT-based) provided by libvirt. This allows the VM to access the host's internet connection (enp0s25) and therefore reach the internet for its WAN duties (like pinging 8.8.8.8).
LAN Connection (Physical Passthrough): Use the --host-device flag to pass enp16s0 directly to the VM. This will be the VM's LAN port, managing your physical LAN traffic.
To passthrough the device you will need to find the PCI address. Replace enp16s0 with the device id of your adapter you want to passthrough. So in the host run:
realpath /sys/class/net/enp16s0/device
For me it returned:
/sys/devices/pci0000:00/0000:00:1c.4/0000:10:00.0
The last piece of the results from this command – is my pci address of my expansion card or ‘10:00.0’
Put your results in the “—host-device….” declaration below.
Revised virt-install Command:
virt-install \
--name OpenWRT \
--os-variant ubuntu24.04 \
--ram 1024 \
--vcpus 1 \
--disk path=/var/lib/libvirt/images/OpenWRT/openwrt.qcow2,format=qcow2,bus=virtio \
--import \
--network network=default,model=virtio \
--host-device=10:00.0 \
--graphics none \
--noautoconsole
But again I got errors when trying to virsh-install:
ERROR internal error: process exited while connecting to monitor: 2025-12-04T18:56:19.348605Z qemu-system-x86_64: -device {"driver":"vfio-pci","host":"0000:10:00.0","id":"hostdev0","bus":"pci.16","addr":"0x1"}: vfio 0000:10:00.0: failed to setup container for group 7: Failed to set iommu for container: Operation not permitted
So – Gemini AI says:
Your hardware/BIOS does not support Interrupt Remapping, which is a crucial security feature required by the VFIO (Virtual Function I/O) driver for safe device assignment. Without it, the kernel prevents the operation because allowing the device access could potentially allow the VM to interfere with other devices or the host system (hence, "unsafe interrupts").
The Solution: Allow Unsafe Interrupts
You need to create a configuration file that loads the vfio_iommu_type1 kernel module with the required parameter.
-Create a new configuration file for the VFIO modules
sudo nano /etc/modprobe.d/vfio.conf
Add the following line to the file:
options vfio_iommu_type1 allow_unsafe_interrupts=1
That is the only line in the file.
Save and close the file.
Reload the Initial Ramdisk and Reboot
sudo update-initramfs -u -k all
Reboot the system for the changes to take effect:
Re-run virt-install
At this point the VM is up and running and I can reach the OpenWRT console but still can not ping 8.8.8.8 from the console or update opkg.
Gemini says - Your current OpenWrt network configuration has the roles of your two NICs completely swapped. The solution is to edit the /etc/config/network file inside the OpenWRT console
sudo virsh console OpenWRT
First thing to do is set a password for OpenWRT
passwd
After that edit the /etc/config/network file with vi.
vi /etc/config/network
- Just a couple of reminders if you don't use vi often:*
i = insert
esc = to accept changes and get to command
:q! = quit without saving
:wq = save and quit
Find the config device 'lan_dev' section and modify the config interface 'lan' and config interface 'wan' sections to match the desired mapping:
So my new file became:
config interface 'loopback'
option device 'lo'
option proto 'static'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'
config globals 'globals'
option ula_prefix 'fd79:a557:f5sd::/48'
config device
option name 'br-lan'
option type 'bridge'
list ports 'eth1' #<--- I changed per note below
config interface 'lan'
# Change 'br-lan' to use 'eth1' as the physical LAN device.
# Note: If your OpenWrt image uses a 'config device' section for br-lan,
# make sure it lists 'eth1' (or whatever eth# is the passthrough)
option device 'eth1' # <--- Set the physical Passthrough NIC as LAN
option proto 'static'
option ipaddr '192.168.10.1'
option netmask '255.255.255.0'
config interface 'wan'
# Set the virtual NAT NIC (eth0) as the WAN device.
option device 'eth0' # <--- Set the Virtual NIC as WAN
option proto 'dhcp' # <--- Essential for getting IP from libvirt NAT
option defaultroute '1'
option peerdns '1'
config interface 'wan6'
option device 'eth1'
option proto 'dhcpv6'
save changes (esc : wq )
Then restart the network
/etc/init.d/network restart
I Tested Internet Connectivity:
ping 8.8.8.8
opkg update
All worked fine!! I hope this helps!!