published: 1st of September 2019
In this post I will cover how to create a Juniper vQFX Vagrant box 18.4R1.8 for use with the vagrant-libvirt provider. This is an update to a previous post post . Thankfully Juniper has released newer versions of the vQFX vagrant boxes for the Virtual box provider that can be utilized to create Libvirt boxes in a much simpler fashion that before.
With other Juniper VM's such as the vSRX and vMX there are some required steps to get the KVM host prepped, these may be required for the vQFX also. I did not find any documentation directly stating this but if you have issues this could be a good place to look.
This post assumes a working installation of Vagrant with the vagrant-libvirt plugin already installed. You can follow this post to get the vagrant-libvirt plugin installed.
For reference the following software will be used in this post.
The vQFX is made up of two VMs, one for the routing engine (RE) that runs Junos and one for the packet forwarding engine (PFE) that runs wind river linux. Although there are two separate VMs, logically they act as a single device. Conceptually a vQFX looks like the below diagram.
The first two interfaces from each VM are reserved. The first is for management and the second is used as a communication channel between the two VMs. Additionally the third interface on the RE is unusable. The PFE only requires two interfaces. The RE supports an additional 12 interfaces for data plane traffic.
Juniper provides ready built Vagrant boxes for use with the Virtualbox provider. We will use these images to create libvirt Vagrant boxes
Navigate to the Juniper software download page and under the Application Package section download both the PFE: Vagrant Package for Virtualbox (VQFX10K PFE) and RE: Vagrant Package for Virtualbox (VQFX10K Routing Engine) boxes.
Create and change into a directory for vQFX files. I like to keep my custom vagrant boxes under ~/vagrant/boxes/ .
mkdir -p ~/vagrant/boxes/juniper/vqfx
cd ~/vagrant/boxes/juniper/vqfx
Copy the PFE and RE files downloaded earlier to the ~/vagrant/boxes/juniper/vqfx/ directory.
cp ~/Downloads/vqfx-18.4R1.8-* .
Create directories to extract both the PFE and RE images.
mkdir {pfe,re}
Extract the HDD from the PFE Vagrant box.
tar -xvf vqfx-18.4R1.8-pfe-virtualbox.gz -C pfe
The PFE is already prepared as a Vagrant box so the only thing required to get it working with libvirt is convert the disk to a qcow2 image and package it up as a libvirt box.
qemu-img convert -f vmdk -O qcow2 pfe/packer-virtualbox-ovf-1520878605-disk001.vmdk pfe.qcow2
The good folks who maintain the vagrant-libvirt plugin have a script can be used to convert qcow2 images to a vagrant box. Download the libvirt conversion script.
curl -O https://raw.githubusercontent.com/vagrant-libvirt/vagrant-libvirt/master/tools/create_box.sh
Create a file called metadata.json with the following contents for the PFE box.
echo '{"provider":"libvirt","format":"qcow2","virtual_size":6}' > metadata.json
Create a PFE vagrant box with the create_box.sh script.
bash create_box.sh pfe.qcow2
# output
{6}
==> Creating box, tarring and gzipping
./metadata.json
./Vagrantfile
./box.img
Total bytes written: 1356738560 (1.3GiB, 21MiB/s)
==> pfe.box created
==> You can now add the box:
==> 'vagrant box add pfe.box --name pfe'
Create a metadata file called pfe.json so that the box is added with the correct version number.
cat << EOF > pfe.json
{
"name": "juniper/vqfx-pfe",
"description": "Juniper vQFX Packet Forwarding Engine",
"versions": [
{
"version": "18.4R1.8",
"providers": [
{
"name": "libvirt",
"url": "file:///home/bradmin/vagrant/boxes/juniper/vqfx/pfe.box"
}
]
}
]
}
EOF
Add the PFE box to Vagrant.
vagrant box add pfe.json
# output
==> box: Loading metadata for box 'pfe.json'
box: URL: file:///home/bradmin/vagrant/boxes/juniper/vqfx/pfe.json
==> box: Adding box 'juniper/vqfx-pfe' (v18.4R1.8) for provider: libvirt
box: Unpacking necessary files from: file:///home/bradmin/vagrant/boxes/juniper/vqfx/pfe.box
==> box: Successfully added box 'juniper/vqfx-pfe' (v18.4R1.8) for 'libvirt'!
Confirm the PFE box was added successfully
vagrant box list
# output
CumulusCommunity/cumulus-vx (libvirt, 3.4.2)
arista/veos (libvirt, 4.20.1F)
extreme/xos (libvirt, 22.4.1.4)
juniper/vmx-vcp (libvirt, 19.1R1.6)
juniper/vmx-vfp (libvirt, 19.1R1.6)
juniper/vqfx-pfe (libvirt, 18.4R1.8)
As with the PFE the RE is already prepared as a Vagrant box. The only thing required to get it working with libvirt is convert the disk to a qcow2 image and package it up as a libvirt box.
qemu-img convert -f vmdk -O qcow2 re/packer-virtualbox-ovf-1547241286-disk001.vmdk re.qcow2
Create a file called metadata.json with the following contents for the RE box.
echo '{"provider":"libvirt","format":"qcow2","virtual_size":4}' > metadata.json
Create an RE vagrant box with the create_box.sh script.
bash create_box.sh vqfx-re.qcow2
# output
{4}
==> Creating box, tarring and gzipping
./metadata.json
./Vagrantfile
./box.img
Total bytes written: 1356738560 (1.3GiB, 21MiB/s)
==> vqfx-re.box created
==> You can now add the box:
==> 'vagrant box add vqfx-re.box --name vqfx-re'
Create a metadata file called re.json so that the box is added with the correct version number.
cat << EOF > re.json
{
"name": "juniper/vqfx-re",
"description": "Juniper vQFX Routing Engine",
"versions": [
{
"version": "18.4R1.8",
"providers": [
{
"name": "libvirt",
"url": "file:///home/bradmin/vagrant/boxes/juniper/vqfx/re.box"
}
]
}
]
}
EOF
Add the RE box to Vagrant.
vagrant box add re.json
# output
==> box: Loading metadata for box 're.json'
box: URL: file:///home/bradmin/vagrant/boxes/juniper/vqfx/re.json
==> box: Adding box 'juniper/vqfx-re' (v18.4R1.8) for provider: libvirt
box: Unpacking necessary files from: file:///home/bradmin/vagrant/boxes/juniper/vqfx/re.box
==> box: Successfully added box 'juniper/vqfx-re' (v18.4R1.8) for 'libvirt'!
Confirm the RE box was added successfully
vagrant box list
# output
CumulusCommunity/cumulus-vx (libvirt, 3.4.2)
arista/veos (libvirt, 4.20.1F)
extreme/xos (libvirt, 22.4.1.4)
juniper/vmx-vcp (libvirt, 19.1R1.6)
juniper/vmx-vfp (libvirt, 19.1R1.6)
juniper/vqfx-pfe (libvirt, 18.4R1.8)
juniper/vqfx-re (libvirt, 18.4R1.8)
Now that the boxes are installed create a Vagrantfile and confirm you can build VMs with Vagrant.
Create a test directory.
mkdir ~/vqfx-test && cd ~/vqfx-test
Add a Vagrantfile to the test directory with the following contents.
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Created: 2019-09-01--07-54-13
def get_mac(oui="28:b7:ad")
"Generate a MAC address"
nic = (1..3).map{"%0.2x"%rand(256)}.join(":")
return "#{oui}:#{nic}"
end
cwd = Dir.pwd.split("/").last
username = ENV['USER']
domain_prefix = "#{username}_#{cwd}"
domain_uuid = "9e7c5277-f332-5311-a344-20dc47a99a5b"
Vagrant.require_version ">= 2.1.0"
Vagrant.configure("2") do |config|
config.vm.define "sw1" do |node|
guest_name = "sw1"
node.vm.box = "juniper/vqfx-re"
node.vm.box_version = "18.4R1.8"
node.vm.guest = :tinycore
node.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
node.ssh.insert_key = false
node.vm.provider :libvirt do |domain|
domain.default_prefix = "#{domain_prefix}"
domain.cpus = 1
domain.memory = 1024
domain.disk_bus = "ide"
domain.nic_adapter_count = 14
domain.nic_model_type = "e1000"
end
node.vm.network :private_network,
# sw1-internal-1 <--> sw1-pfe-internal-1
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.1",
:libvirt__tunnel_local_port => 11001,
:libvirt__tunnel_ip => "127.197.249.2",
:libvirt__tunnel_port => 11001,
:libvirt__iface_name => "sw1-internal-1-#{domain_uuid}",
auto_config: false
node.vm.network :private_network,
# sw1-reserved-1 <--> blackhole-666
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.1",
:libvirt__tunnel_local_port => 12001,
:libvirt__tunnel_ip => "127.6.6.6",
:libvirt__tunnel_port => 12666,
:libvirt__iface_name => "sw1-reserved-1-#{domain_uuid}",
auto_config: false
node.vm.network :private_network,
# sw1-xe-0/0/0 <--> sw2-xe-0/0/0
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.1",
:libvirt__tunnel_local_port => 10000,
:libvirt__tunnel_ip => "127.197.249.3",
:libvirt__tunnel_port => 10000,
:libvirt__iface_name => "sw1-xe-0/0/0-#{domain_uuid}",
auto_config: false
node.vm.network :private_network,
# sw1-xe-0/0/1 <--> sw2-xe-0/0/1
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.1",
:libvirt__tunnel_local_port => 10001,
:libvirt__tunnel_ip => "127.197.249.3",
:libvirt__tunnel_port => 10001,
:libvirt__iface_name => "sw1-xe-0/0/1-#{domain_uuid}",
auto_config: false
end
config.vm.define "sw1-pfe" do |node|
guest_name = "sw1-pfe"
node.vm.box = "juniper/vqfx-pfe"
node.vm.box_version = "18.4R1.8"
node.vm.guest = :tinycore
node.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
node.ssh.insert_key = false
node.vm.provider :libvirt do |domain|
domain.default_prefix = "#{domain_prefix}"
domain.cpus = 1
domain.memory = 2048
domain.disk_bus = "ide"
domain.nic_adapter_count = 1
domain.nic_model_type = "e1000"
end
node.vm.network :private_network,
# sw1-pfe-internal-1 <--> sw1-internal-1
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.2",
:libvirt__tunnel_local_port => 11001,
:libvirt__tunnel_ip => "127.197.249.1",
:libvirt__tunnel_port => 11001,
:libvirt__iface_name => "sw1-pfe-internal-1-#{domain_uuid}",
auto_config: false
end
config.vm.define "sw2" do |node|
guest_name = "sw2"
node.vm.box = "juniper/vqfx-re"
node.vm.box_version = "18.4R1.8"
node.vm.guest = :tinycore
node.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
node.ssh.insert_key = false
node.vm.provider :libvirt do |domain|
domain.default_prefix = "#{domain_prefix}"
domain.cpus = 1
domain.memory = 1024
domain.disk_bus = "ide"
domain.nic_adapter_count = 14
domain.nic_model_type = "e1000"
end
node.vm.network :private_network,
# sw2-internal-1 <--> sw2-pfe-internal-1
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.3",
:libvirt__tunnel_local_port => 11001,
:libvirt__tunnel_ip => "127.197.249.4",
:libvirt__tunnel_port => 11001,
:libvirt__iface_name => "sw2-internal-1-#{domain_uuid}",
auto_config: false
node.vm.network :private_network,
# sw2-reserved-1 <--> blackhole-666
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.3",
:libvirt__tunnel_local_port => 12001,
:libvirt__tunnel_ip => "127.6.6.6",
:libvirt__tunnel_port => 12666,
:libvirt__iface_name => "sw2-reserved-1-#{domain_uuid}",
auto_config: false
node.vm.network :private_network,
# sw2-xe-0/0/0 <--> sw1-xe-0/0/0
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.3",
:libvirt__tunnel_local_port => 10000,
:libvirt__tunnel_ip => "127.197.249.1",
:libvirt__tunnel_port => 10000,
:libvirt__iface_name => "sw2-xe-0/0/0-#{domain_uuid}",
auto_config: false
node.vm.network :private_network,
# sw2-xe-0/0/1 <--> sw1-xe-0/0/1
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.3",
:libvirt__tunnel_local_port => 10001,
:libvirt__tunnel_ip => "127.197.249.1",
:libvirt__tunnel_port => 10001,
:libvirt__iface_name => "sw2-xe-0/0/1-#{domain_uuid}",
auto_config: false
end
config.vm.define "sw2-pfe" do |node|
guest_name = "sw2-pfe"
node.vm.box = "juniper/vqfx-pfe"
node.vm.box_version = "18.4R1.8"
node.vm.guest = :tinycore
node.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true
node.ssh.insert_key = false
node.vm.provider :libvirt do |domain|
domain.default_prefix = "#{domain_prefix}"
domain.cpus = 1
domain.memory = 2048
domain.disk_bus = "ide"
domain.nic_adapter_count = 1
domain.nic_model_type = "e1000"
end
node.vm.network :private_network,
# sw2-pfe-internal-1 <--> sw2-internal-1
:mac => "#{get_mac()}",
:libvirt__tunnel_type => "udp",
:libvirt__tunnel_local_ip => "127.197.249.4",
:libvirt__tunnel_local_port => 11001,
:libvirt__tunnel_ip => "127.197.249.3",
:libvirt__tunnel_port => 11001,
:libvirt__iface_name => "sw2-pfe-internal-1-#{domain_uuid}",
auto_config: false
end
end
Now vagrant up and confirm you can login to the RE.
vagrant up
# output
Bringing machine 'sw1' up with 'libvirt' provider...
Bringing machine 'sw1-pfe' up with 'libvirt' provider...
Bringing machine 'sw2' up with 'libvirt' provider...
Bringing machine 'sw2-pfe' up with 'libvirt' provider...
==> sw1-pfe: Checking if box 'juniper/vqfx-pfe' version '18.4R1.8' is up to date...
==> sw1: Checking if box 'juniper/vqfx-re' version '18.4R1.8' is up to date...
==> sw2-pfe: Checking if box 'juniper/vqfx-pfe' version '18.4R1.8' is up to date...
==> sw2: Checking if box 'juniper/vqfx-re' version '18.4R1.8' is up to date...
==> sw2-pfe: Creating image (snapshot of base box volume).
==> sw2-pfe: Creating domain with the following settings...
==> sw2-pfe: -- Name: bradmin_vqfx-test_sw2-pfe
==> sw2-pfe: -- Domain type: kvm
==> sw2-pfe: -- Cpus: 1
==> sw2-pfe: -- Feature: acpi
==> sw2-pfe: -- Feature: apic
==> sw2-pfe: -- Feature: pae
==> sw2-pfe: -- Memory: 2048M
==> sw2-pfe: -- Management MAC:
==> sw2-pfe: -- Loader:
==> sw2-pfe: -- Nvram:
==> sw2-pfe: -- Base box: juniper/vqfx-pfe
==> sw2-pfe: -- Storage pool: default
==> sw2-pfe: -- Image: /var/lib/libvirt/images/bradmin_vqfx-test_sw2-pfe.img (6G)
==> sw2-pfe: -- Volume Cache: default
==> sw2-pfe: -- Kernel:
==> sw2-pfe: -- Initrd:
==> sw2-pfe: -- Graphics Type: vnc
==> sw2-pfe: -- Graphics Port: -1
==> sw2-pfe: -- Graphics IP: 127.0.0.1
==> sw2-pfe: -- Graphics Password: Not defined
==> sw2-pfe: -- Video Type: cirrus
==> sw2-pfe: -- Video VRAM: 9216
==> sw2-pfe: -- Sound Type:
==> sw2-pfe: -- Keymap: en-us
==> sw2-pfe: -- TPM Path:
==> sw2-pfe: -- INPUT: type=mouse, bus=ps2
==> sw2-pfe: Creating shared folders metadata...
==> sw2-pfe: Starting domain.
==> sw2-pfe: Waiting for domain to get an IP address...
==> sw1-pfe: Creating image (snapshot of base box volume).
==> sw1-pfe: Creating domain with the following settings...
==> sw1-pfe: -- Name: bradmin_vqfx-test_sw1-pfe
==> sw2: Creating image (snapshot of base box volume).
==> sw1: Creating image (snapshot of base box volume).
==> sw1-pfe: -- Domain type: kvm
==> sw2: Creating domain with the following settings...
==> sw1-pfe: -- Cpus: 1
==> sw2: -- Name: bradmin_vqfx-test_sw2
==> sw1-pfe: -- Feature: acpi
==> sw2: -- Domain type: kvm
==> sw1-pfe: -- Feature: apic
==> sw1: Creating domain with the following settings...
==> sw1-pfe: -- Feature: pae
==> sw1: -- Name: bradmin_vqfx-test_sw1
==> sw2: -- Cpus: 1
==> sw1-pfe: -- Memory: 2048M
==> sw1: -- Domain type: kvm
==> sw2: -- Feature: acpi
==> sw2: -- Feature: apic
==> sw1-pfe: -- Management MAC:
==> sw1: -- Cpus: 1
==> sw1-pfe: -- Loader:
==> sw1-pfe: -- Nvram:
==> sw1: -- Feature: acpi
==> sw1-pfe: -- Base box: juniper/vqfx-pfe
==> sw2: -- Feature: pae
==> sw1: -- Feature: apic
==> sw1-pfe: -- Storage pool: default
==> sw1-pfe: -- Image: /var/lib/libvirt/images/bradmin_vqfx-test_sw1-pfe.img (6G)
==> sw1: -- Feature: pae
==> sw2: -- Memory: 1024M
==> sw1-pfe: -- Volume Cache: default
==> sw1: -- Memory: 1024M
==> sw2: -- Management MAC:
==> sw1-pfe: -- Kernel:
==> sw2: -- Loader:
==> sw1: -- Management MAC:
==> sw1-pfe: -- Initrd:
==> sw1-pfe: -- Graphics Type: vnc
==> sw1: -- Loader:
==> sw1-pfe: -- Graphics Port: -1
==> sw2: -- Nvram:
==> sw2: -- Base box: juniper/vqfx-re
==> sw1-pfe: -- Graphics IP: 127.0.0.1
==> sw1-pfe: -- Graphics Password: Not defined
==> sw1: -- Nvram:
==> sw2: -- Storage pool: default
==> sw1-pfe: -- Video Type: cirrus
==> sw1: -- Base box: juniper/vqfx-re
==> sw2: -- Image: /var/lib/libvirt/images/bradmin_vqfx-test_sw2.img (4G)
==> sw1: -- Storage pool: default
==> sw1-pfe: -- Video VRAM: 9216
==> sw2: -- Volume Cache: default
==> sw1: -- Image: /var/lib/libvirt/images/bradmin_vqfx-test_sw1.img (4G)
==> sw2: -- Kernel:
==> sw1-pfe: -- Sound Type:
==> sw1: -- Volume Cache: default
==> sw2: -- Initrd:
==> sw1-pfe: -- Keymap: en-us
==> sw2: -- Graphics Type: vnc
==> sw1: -- Kernel:
==> sw2: -- Graphics Port: -1
==> sw1-pfe: -- TPM Path:
==> sw1-pfe: -- INPUT: type=mouse, bus=ps2
==> sw2: -- Graphics IP: 127.0.0.1
==> sw1: -- Initrd:
==> sw2: -- Graphics Password: Not defined
==> sw1: -- Graphics Type: vnc
==> sw2: -- Video Type: cirrus
==> sw1: -- Graphics Port: -1
==> sw1-pfe: Creating shared folders metadata...
==> sw2: -- Video VRAM: 9216
==> sw1-pfe: Starting domain.
==> sw1: -- Graphics IP: 127.0.0.1
==> sw2: -- Sound Type:
==> sw1: -- Graphics Password: Not defined
==> sw2: -- Keymap: en-us
==> sw1: -- Video Type: cirrus
==> sw2: -- TPM Path:
==> sw1: -- Video VRAM: 9216
==> sw1-pfe: Waiting for domain to get an IP address...
==> sw1: -- Sound Type:
==> sw2: -- INPUT: type=mouse, bus=ps2
==> sw1: -- Keymap: en-us
==> sw1: -- TPM Path:
==> sw1: -- INPUT: type=mouse, bus=ps2
==> sw2: Creating shared folders metadata...
==> sw2: Starting domain.
==> sw1: Creating shared folders metadata...
==> sw1: Starting domain.
==> sw2: Waiting for domain to get an IP address...
==> sw1: Waiting for domain to get an IP address...
==> sw2-pfe: Waiting for SSH to become available...
==> sw1-pfe: Waiting for SSH to become available...
==> sw1-pfe: Configuring and enabling network interfaces...
==> sw2-pfe: Configuring and enabling network interfaces...
==> sw1: Waiting for SSH to become available...
==> sw2: Waiting for SSH to become available...
==> sw1: Configuring and enabling network interfaces...
==> sw2: Configuring and enabling network interfaces...
Confirm you can login to the sw1 RE box.
# Host terminal
vagrant ssh sw1
--- JUNOS 18.4R1.8 built 2018-12-17 03:30:15 UTC
{master:0}
vagrant@vqfx>
# Now in vagrant box terminal
vagrant@vqfx> show version
fpc0:
--------------------------------------------------------------------------
Hostname: vqfx-re
Model: vqfx-10000
Junos: 18.4R1.8 limited
JUNOS Base OS boot [18.4R1.8]
JUNOS Base OS Software Suite [18.4R1.8]
JUNOS Crypto Software Suite [18.4R1.8]
JUNOS Online Documentation [18.4R1.8]
JUNOS Kernel Software Suite [18.4R1.8]
JUNOS Packet Forwarding Engine Support (qfx-10-f) [18.4R1.8]
JUNOS Routing Software Suite [18.4R1.8]
JUNOS jsd [i386-18.4R1.8-jet-1]
JUNOS SDN Software Suite [18.4R1.8]
JUNOS Enterprise Software Suite [18.4R1.8]
JUNOS Web Management [18.4R1.8]
JUNOS py-base-i386 [18.4R1.8]
JUNOS py-extensions-i386 [18.4R1.8]
Confirm that the RE is connected to the PFE.
vagrant@vqfx> show chassis fpc
Temp CPU Utilization (%) CPU Utilization (%) Memory Utilization (%)
Slot State (C) Total Interrupt 1min 5min 15min DRAM (MB) Heap Buffer
0 Online Testing 1 0 0 0 0 1024 0 85
1 Empty
2 Empty
3 Empty
4 Empty
5 Empty
6 Empty
7 Empty
8 Empty
9 Empty
{master:0}
We have confirmed we can build and login to the box with Vagrant. Lastly, let clean up a bit.
Destroy to running lab.
vagrant destroy -f
# output
==> sw2-pfe: Removing domain...
==> sw2: Removing domain...
==> sw1-pfe: Removing domain...
==> sw1: Removing domain...
Remove the original downloaded images.
rm -rf ~/vagrant/boxes/juniper/vqfx/{pfe,re}
rm -f ~/vagrant/boxes/juniper/vqfx/*.qcow2
rm -f ~/vagrant/boxes/juniper/vqfx/*.gz
As a final note, the vQFX has a bunch of interface config (et/xe-0/0/0 - 71) defined. The below config can be used to delete all the interface config after boot. In practice you would use a provisioner to apply this config automatically.
wildcard range delete interfaces et-0/0/[0-71]
wildcard range delete interfaces xe-0/0/[0-71]
wildcard range delete interfaces xe-0/0/[0-71]:[0-3]
The Juniper vQFX is a community driven project, its great that Juniper is offering virtual flavors of their devices for testing and training purposes. As with the vMX the vQFX requires two VMs but I think its worth the effort to be able to test the Juniper switching features.