How can I create VLANs faster or in a batch?

I have a project that sometimes requires configuring a lot of vlans, but when I try to, for example, configure 100 vlans, it takes about 2 minutes, and when creating more vlans, that grows linearly, so it takes about 20 minutes for creating 1000 vlans, and over an hour for 4000 vlans. Is there a way to create them in a batch. A little birdy told me that iflib may be taking the parent interface and disabling/enabling it for each vlan, but all my vlans are on the same parent physical interface, so ideally I feel like they could be created and then the interface can then be toggled.

Any thoughts on how to speed this up?

Here is my create vlans script:

Bash:
#!/bin/sh -ex

for i in `seq 100 199`; do
    ifconfig "vlan$i" create vlan $i vlandev em0
done

And the destroy script:

Bash:
#!/bin/sh -ex

for i in `seq 100 199`; do
    ifconfig "vlan$i" destroy
done
 
I tested your script with 4000 vlan's inside a virtual machine and with a vtnet0 interface. Creating the vlan's took ~ 32 seconds and destroying them ~10-12 minutes.
Of course, the performance probably is heavily dependent on the system configuration, but there's an idea:

If creating a vlan indeed disables and enables the parent interface and doing so with a physical interface takes more time than a virtual one, try creating a tap interface and create all vlan's with the tap interface. Then bridge the tap with your physical device. The result should be the same but creating the vlan's could be faster.

Something like this:
Bash:
ifconfig tap0 create up

for i in `seq 100 199`; do
    ifconfig "vlan$i" create vlan $i vlandev tap0
done

ifconfig bridge0 create up
ifconfig bridge0 addm em0 addm tap0

Also, experiment and try to create the tap0 down first, then after creating the vlan's bring it up. Maybe it will skip disabling it each time with the vlan's.
 
I think it does speed things up. See, the following script ran on the same VM in about 1 minute:
Bash:
EXTERNAL=$(netstat -rn4 | grep default | awk '{print $4}')
echo $EXTERNAL
TAP=$(ifconfig tap create)
echo $TAP

date
for i in `seq 100 1099`; do
    ifconfig "vlan$i" create vlan $i vlandev $TAP
done
date

ifconfig $TAP up
BRIDGE=$(ifconfig bridge create up)
echo $BRIDGE
ifconfig $BRIDGE addm $EXTERNAL addm $TAP

# Delete them all

ifconfig $BRIDGE deletem $EXTERNAL deletem $TAP
ifconfig $BRIDGE destroy
ifconfig $TAP down

date
for i in `seq 100 1099`; do
    ifconfig "vlan$i" destroy
done
date

ifconfig $TAP destroy
 
You might want to read one of the PRs about that "down/up for each vlan" issue:
(there were several others back when this behaviour was introduced ~2018ish)

A patch (https://reviews.freebsd.org/D24659) has been merged (https://svnweb.freebsd.org/base?view=revision&revision=361053, https://svnweb.freebsd.org/base?view=revision&revision=360902), but at least on 13-RELEASE on my desktop with em and igb interfaces setting up a VLAN still always resets the interface as well as on several other machines (12.2 & 13.0) with em, igb and even ixgbe interfaces.

I also encountered that (mis)behaviour and had to work around this issue: on our storage hosts we only change the vlan config during maintenance windows. for our routers and gateways this behaviour was just completely inacceptable and we switched them all to OpenBSD (which brought some other benefits like rdomains and latest OpenBGPd).
So even if this might not be the preferred answer in this forum, you might want to try OpenBSD for that project, even if 'just' running on bhyve (which works great - we have ~10 OBSD VMs running on bhyve in our infrastructure).
 
Back
Top