I've tried to have different (iocage) jails on my TrueNAS machine live in different vlans but I never got it working reliably, and as I didn't want to reboot that machine too often I eventually just setup another FreeBSD machine at home.
So another note to my future self - this is how I made it work as expected. This is my setup:
One machine with one main interface, to which a 'trunk' line with a few, tagged vlans are attached. There is no untagged traffic on this interface, the port vlan id is unique to the port itself.
One vlan is for management of the machine, the rest are for different jails
I'm using VNET due to reasons, and typically I use a bridge per vlan and connect jails to this bridge
/etc/rc.conf looks something like this:
# One interface and one bridge per vlan cloned_interfaces="vlan100 vlan200 bridge200 vlan300 bridge300" # Management interface, no bridge here as it won't be shared with any jail ifconfig_vlan100="inet 192.168.100.2 netmask 255.255.255.0 vlan 100 vlandev re0" # Jail vlans ifconfig_vlan200="vlan 200 vlandev re0 up" ifconfig_vlan300="vlan 300 vlandev re0 up" # Jail bridges ifconfig_bridge200="addm vlan200 up" ifconfig_bridge300="addm vlan300 up" # Main interface, it's enough that it's up ifconfig_re0="up" defaultrouter="192.168.100.1" gateway_enable="YES"
And then, when I create my iocage jails:
iocage create -r 13.0-RELEASE -b --name test200 vnet=1 dhcp=on \ interfaces="vnet0:bridge200" iocage create -r 13.0-RELEASE -b --name test300 vnet=1 dhcp=on \ interfaces="vnet0:bridge300" # this jail will have two interfaces, one in vlan200 and one in # vlan300, with static addresses, and the default route will go # through vlan300s router (plus DNS) iocage create -r 13.0-RELEASE -b --name test230 vnet=1 \ interfaces="vnet0:bridge200,vnet1:bridge300"\ vnet_default_interface="vlan300" \ ip4_addr="vnet0|192.168.200.100/24,vnet1|192.168.300.100/24" \ resolver="nameserver 192.168.300.1" \ defaultrouter="192.168.300.1"