Does the vQFX support port mirroring? It certainly seems so!
I couldn’t find a definitive answer to this in a quick search, so I decided to try it out and see what happens.
The Setup
Eve-NG is built as “bare metal” on a VM.
Juniper vQFX – Junos 21.3R3
3 x Linux images within Eve-NG (Ubuntu 22.04)
Linux-1 connects to xe-0/0/1, access port in VLAN 20.
Linux 2 connects to xe-0/0/2, access port in VLAN 20.
Linux-Capture connects to xe-0/0/11. The interface on the Linux image is an “extra” and not configured with any addressing.

Configuration
The configuration on the vQFX is pretty simple:
– xe-0/0/1 configured as an access port in VLAN 20
– xe-0/0/2 configured as an access port in VLAN 20
– xe-0/0/10 configured with just family ethernet-switching
– VLAN 20 defined
– Port mirroring (Analyzer) configured under forwarding options
interfaces {
xe-0/0/1 {
unit 0 {
family ethernet-switching {
interface-mode access;
vlan {
members 20;
}
}
}
}
xe-0/0/2 {
unit 0 {
family ethernet-switching {
interface-mode access;
vlan {
members 20;
}
}
}
}
xe-0/0/10 {
unit 0 {
family ethernet-switching;
}
}
}
forwarding-options {
analyzer {
testing {
input {
ingress {
vlan 20;
}
}
output {
interface xe-0/0/10.0;
}
}
}
}
vlans {
test {
vlan-id 20;
}
}
Linux-1 and linux-2 were configured with static addresses. This was achieved by editing /etc/netplan/00-installer-config.yaml and running ‘sudo netplan apply’. There is probably a better way of doing this, but as a quick test, this works fine.
The relevant portions of the netplan file are:
network:
ethernets:
ens4:
addresses:
- 192.168.20.5/24
routes:
- to: default
via: 192.168.20.1
version: 2
Testing
The testing is pretty straightforward.
First, let us test the basic connectivity by pinging from Linux-1 to Linux-2.
eve@linux-1:~$ ping -c 1 192.168.20.6
PING 192.168.20.6 (192.168.20.6) 56(84) bytes of data.
64 bytes from 192.168.20.6: icmp_seq=1 ttl=64 time=314 ms
--- 192.168.20.6 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 313.602/313.602/313.602/0.000 ms
Since we’ve got that working, we can now start tcpdump on Linux-Capture and see if we see any traffic. Because the interface we’re using isn’t configured, we need to bring the interface up first. The two parameters set for tcpdump are -i to specify the interface and -s to specify how much of the packet to capture.
eve@linux-capture:~$ ip address show ens4
3: ens4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:50:00:00:06:01 brd ff:ff:ff:ff:ff:ff
altname enp0s4
eve@linux-capture:~$ sudo ip link set ens4 up
eve@linux-capture:~$ ip address show ens4
3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:50:00:00:06:01 brd ff:ff:ff:ff:ff:ff
altname enp0s4
inet6 fe80::250:ff:fe00:601/64 scope link
valid_lft forever preferred_lft forever
eve@linux-capture:~$
eve@linux-capture:~$ sudo tcpdump -i ens4 -s 1500
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens4, link-type EN10MB (Ethernet), snapshot length 1500 bytes
Next, we repeat the ping command from Linux-1 and then use curl to fetch a default webpage from Linux-2. I’ve removed most of the output of the curl command.
eve@linux-1:~$ ping -c 1 192.168.20.6
PING 192.168.20.6 (192.168.20.6) 56(84) bytes of data.
64 bytes from 192.168.20.6: icmp_seq=1 ttl=64 time=112 ms
--- 192.168.20.6 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 112.242/112.242/112.242/0.000 ms
eve@linux-1:~$ curl http://192.168.20.6/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Modified from the Debian original for Ubuntu
Last updated: 2022-03-22
See: https://launchpad.net/bugs/1966004
-->
<head>
*** OUTPUT OMITTED ***
</head>
<body>
*** OUTPUT OMITTED ***
</body>
</html>
eve@linux-1:~$
On the packet capture we see the following:
05:49:54.948183 IP 192.168.20.5 > 192.168.20.6: ICMP echo request, id 2, seq 1, length 64
05:49:55.051305 IP 192.168.20.6 > 192.168.20.5: ICMP echo reply, id 2, seq 1, length 64
05:49:59.943989 ARP, Request who-has 192.168.20.6 tell 192.168.20.5, length 28
05:50:00.079696 ARP, Reply 192.168.20.6 is-at aa:bb:cc:dd:05:01 (oui Unknown), length 28
05:50:00.080255 ARP, Request who-has 192.168.20.5 tell 192.168.20.6, length 28
05:50:00.211603 ARP, Reply 192.168.20.5 is-at aa:bb:cc:dd:03:01 (oui Unknown), length 28
05:50:03.904415 IP6 linux-capture > ip6-allrouters: ICMP6, router solicitation, length 16
05:50:12.246005 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [S], seq 131317445, win 64240, options [mss 1460,sackOK,TS val 3764551206 ecr 0,nop,wscale 7], length 0
05:50:12.339432 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [S.], seq 3300248501, ack 131317446, win 65160, options [mss 1460,sackOK,TS val 283667207 ecr 3764551206,nop,wscale 7], length 0
05:50:12.441913 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 1, win 502, options [nop,nop,TS val 3764551311 ecr 283667207], length 0
05:50:12.442724 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [P.], seq 1:77, ack 1, win 502, options [nop,nop,TS val 3764551311 ecr 283667207], length 76: HTTP: GET / HTTP/1.1
05:50:12.479604 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [.], ack 77, win 509, options [nop,nop,TS val 283667411 ecr 3764551311], length 0
05:50:12.479762 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [P.], seq 1:2897, ack 77, win 509, options [nop,nop,TS val 283667437 ecr 3764551311], length 2896: HTTP: HTTP/1.1 200 OK
05:50:12.480145 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [.], seq 2897:4345, ack 77, win 509, options [nop,nop,TS val 283667437 ecr 3764551311], length 1448: HTTP
05:50:12.480620 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [P.], seq 4345:5793, ack 77, win 509, options [nop,nop,TS val 283667437 ecr 3764551311], length 1448: HTTP
05:50:12.486217 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [.], seq 5793:7241, ack 77, win 509, options [nop,nop,TS val 283667437 ecr 3764551311], length 1448: HTTP
05:50:12.488056 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [P.], seq 7241:8689, ack 77, win 509, options [nop,nop,TS val 283667437 ecr 3764551311], length 1448: HTTP
05:50:12.490531 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [P.], seq 8689:10927, ack 77, win 509, options [nop,nop,TS val 283667437 ecr 3764551311], length 2238: HTTP
05:50:12.491008 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 2897, win 497, options [nop,nop,TS val 3764551451 ecr 283667437], length 0
05:50:12.491893 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 4345, win 491, options [nop,nop,TS val 3764551451 ecr 283667437], length 0
05:50:12.491893 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 5793, win 501, options [nop,nop,TS val 3764551451 ecr 283667437], length 0
05:50:12.497150 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 7241, win 501, options [nop,nop,TS val 3764551457 ecr 283667437], length 0
05:50:12.498014 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 8689, win 501, options [nop,nop,TS val 3764551459 ecr 283667437], length 0
05:50:12.595451 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 10137, win 501, options [nop,nop,TS val 3764551461 ecr 283667437], length 0
05:50:12.595452 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 10927, win 501, options [nop,nop,TS val 3764551462 ecr 283667437], length 0
05:50:12.595452 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [F.], seq 77, ack 10927, win 501, options [nop,nop,TS val 3764551462 ecr 283667437], length 0
05:50:12.696496 IP 192.168.20.6.http > 192.168.20.5.34178: Flags [F.], seq 10927, ack 78, win 509, options [nop,nop,TS val 283667564 ecr 3764551462], length 0
05:50:12.797498 IP 192.168.20.5.34178 > 192.168.20.6.http: Flags [.], ack 10928, win 501, options [nop,nop,TS val 3764551668 ecr 283667564], length 0
Conclusion
The vQFX port mirroring certainly worked in my setup.
Note that I haven’t tested other versions of vQFX or whether it works when deployed on VMWare. It may also depend less on the version of the RE and more on the vQFX-PFE you use.
Really appreciate your great article here.
I’m seriously looking forward to the RE & PFE images ( vQFX 21.3R3) to build up labs for learning.
Could you please share them via google drive or send them to my mailbox ?
Thanks a million in advance.
Hi,
Thanks for the feedback.
Unfortunately, I can’t share Junos images.
Have a look at https://www.juniper.net/try to see what is currently available in terms of Trial software.
Also have a look Juniper’s vLabs and vJunos Labs to see if either of those will meet your needs. I believe that the vQFX is being retired and vJunos will be the path forward.
If you are a Juniper customer or partner, I’d suggest having a chat with your account team or sales engineer as well. They are usually pretty helpful.