System-Engineering | 7 min read
TRex meets SRX
You may have read my recent article on TRex the open-source traffic generator. I was keen to test it with a real device and not only with looped back cables. Lucky me, ngworx had one of the new Juniper SRX380 firewalls available and I could use it for my purpose. It promised to be more fund than the small SRX300 I already have access to since it has 4 10Gig Ethernet interfaces.
Thanks to the Corona crisis, I’m currently working from home which makes the logistics for the project slightly more involving than it would have been otherwise. Thanks to my SRX380-express-bicycle I could get the device from ngworx’s office safely and integrate it into my home lab.
I could think of many interesting configurations and scenarios to test. But since time is limited and I’m still new to TRex I decided to start simple. The datasheet for the SRX 300 series lists some performance numbers and I picked the first few entries in the list:
- forwarding of 64 byte packets
- forwarding of 1518 byte packets
- forwarding of IMIX packets
Since these SRX firewalls have two basic modes to operate in (flow mode and packet mode), I have six tests.
The datasheet mentions that these numbers were evaluated using UDP traffic and following RFC 2544. To test this type of traffic the stateful features of TRex are not needed. So I looked in the folder with the stateless example test profiles in the TRex installation. I started with udp_1pkt_simple_bdir.py. It generates UDP packets for both TRex network interfaces and uses different source and destination IP addresses, depending on the interface the packets are transmitted. Unfortunately, the packet size was not exactly what I wanted (64 byte). So I copied that file and changed it slightly.
--- udp_1pkt_simple_bdir.py 2020-04-23 15:48:17.000000000 +0200 +++ udp_1pkt_64_simple_bdir.py 2020-05-07 14:14:30.115299144 +0200 @@ -14,7 +14,7 @@ pkt = STLPktBuilder( pkt = Ether()/IP(src=src_ip,dst=dst_ip)/ - UDP(dport=12,sport=1025)/(10*'x') ) + UDP(dport=12,sport=1025)/(18*'x') ) return [ STLStream( packet = pkt,mode = STLTXCont()) ]
For the 1518 byte profile I applied the same logic:
--- udp_1pkt_simple_bdir.py 2020-04-23 15:48:17.000000000 +0200 +++ udp_1pkt_1518_simple_bdir.py 2020-05-07 14:01:43.732334756 +0200 @@ -14,7 +14,7 @@ pkt = STLPktBuilder( pkt = Ether()/IP(src=src_ip,dst=dst_ip)/ - UDP(dport=12,sport=1025)/(10*'x') ) + UDP(dport=12,sport=1025)/(1472*'x') ) return [ STLStream( packet = pkt,mode = STLTXCont()) ]
For the IMIX test I just started with the profile I found in the same folder as the previous test: stl/imix.py. I started testing in packet mode and the tests delivered performance numbers in the expected range. After I changed to flow mode the situation changed drastically. While the 64 byte and 1518 byte test looked still good, the numbers for the IMIX tests were extremely low. Initially, I could not make sense out of it and started asking my colleagues for ideas on how to debug this on the SRX side. After much reading and testing with different packet sizes and different numbers of concurrent flows, I found the important difference between the IMIX test and the other two: UDP port numbers! The IMIX profile from TRex does not fill in the port numbers in the UDP header. Once I figured this out I quickly adapted the test and then got the throughput in the expected range. Of course with proper firewall rules (security policy) such UDP packets would have been filtered.
--- imix.py 2020-05-07 22:26:41.596174753 +0200 +++ imix_ports.py 2020-05-07 22:28:25.349425029 +0200 @@ -19,7 +19,7 @@ def create_stream (self, size, pps, isg, vm ): # Create base packet and pad it to size - base_pkt = Ether()/IP()/UDP() + base_pkt = Ether()/IP()/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' pkt = STLPktBuilder(pkt = base_pkt/pad,
Before starting with the tests I checked what Junos version JTAC recommends for the two devices and installed the suggested versions. At the time of my testing, this was 18.4R3-S2 for SRX300 and 20.1R1-S1.1 for SRX380.
Below are the configurations I used for SRX380 (packet and flow mode). For SRX300 I used the exact same minimal configs except I used ge-0/0/6 and ge-0/0/7 instead of the xe interfaces.
The two static routes are important since the TRex tests I’m using generate traffic with source or destination IP addresses form these subnets.
When changing the configuration from packet mode to flow mode it is very important to reboot the device in order to activate the new mode.
Packet Mode Configuration
Flow Mode ConfigurationResults
While running the tests I was connected to the serial console of the SRX device and compared the stats from TRex with the output from “monitor interface traffic”. The numbers displayed were the same as the TRex numbers. I also noticed that there was no impact on the responsiveness of the console during the tests. Maybe this is taken for granted but I think it is noteworthy.
The measurement that stands out here is the 1518 bytes test on SRX300: 1.5 Gbps from the datasheet vs. 1 Gbps measured. Since the numbers are almost the same as in flow mode I suspected that the configured state on the SRX300 was wrong. This was not the case. I checked and repeated this test several times but could not figure out what the cause for this could be. Maybe the limitation is how the interfaces are connected internally and more throughput can be reached by involving more than two interfaces.
There are two surprises with the tests in flow mode. First the bad results with the first IMIX test run (UDP ports not set). And second the IMIX result for SRX380 that is 2 Gbps better than specified by Juniper (with UDP ports set).
For most test cases I could push more packets through the SRX compared to the datasheet. This shows that Juniper is conservative while creating the datasheets. This makes them a reliable source when searching a device that fits when we plan and build networks.
The IMIX test case with empty UDP headers showed several things:
- The importance of understanding how the test exactly works.
- Checking if the results look reasonable.
- How easy it is to adapt TRex tests or write new tests.
I enjoyed it very much to learn how to work TRex while testing these Juniper firewalls. In case you are interested in getting a head start with your TRex setup or you need a specific performance characteristic of your network tested, feel free to contact ngworx (https://ngworx.ag/en/contact/).