FiberStore is a staple provider of optics and network gear in Europe. Although I’ve been buying opfics like SFP+ and QSFP+ from them for years, I rarely looked at the switch hardware they have on sale, until my buddy Arend suggested one of their switches as a good alternative for an Internet Exchange Point, one with Frysian roots no less!
The FS.com S5860 switch is pretty great: 20x 10G SFP+ ports, 4x 25G SPF28 ports and 2x 40G QSFP ports, which can also be reconfigued to be 4x10G each. The switch has a Cisco-like CLI, and great performance. I loadtested a pair of them in L2, QinQ, and in L3 mode, and they handled all the packets I sent to and through them, with all of 10G, 25G and 40G ports in use. Considering the redundant power supply with relatively low power usage, silicon based switching of L2 and L3, I definitely appreciate the price/performance. The switch would be a better match if it allowed for MPLS based L2VPN services, but it doesn’t support that.
The switch is based on Broadcom’s BCM56170, codename Hurricane with 28x10GbE + 4x25GbE ports internally, for a total switching bandwidth of 380Gbps. I noticed that the FS website shows 760Gbps of nonblocking capacity, which I can explain: Broadcom has taken the per port ingress capacity, while FS.com is taking the ingress/egress port capacity and summing them up. Further, the sales pitch claims 565Mpps which I found curious: if we divide the available bandwidth of 380Gbps (the number from the Broadcom dataspec) by smallest possible frame of 84 bytes (672 bits), we’ll see 565Mpps. Why FS.com decided to seemingly arbitrarily double the switching capacity while reporting the nominal fowarding rate, is beyond me.
You can see more (hires) pictures in this Photo Album.
This Broadcom chip is an SOC (System-on-a-Chip) which comes with an Arm A9 and modest amount of TCAM on board and packs into a 31x31mm ball grid array formfactor. The switch chip is able to store 16k routes and ACLs - it did not become immediately obvious to me what the partitioning is (between IPv4 entries, IPv6 entries, L2/L3/L4 ACL entries). One can only assume that the total sum of TCAM based objects must not exceed 4K entries. This means that as a campus switch, the L3 functionalty will be great, including with routing protocols such as OSPF and ISIS. However, BGP with any amount of routing table activity will not be a good fit for this chip, so my dreams of porting DANOS to it are shot out of the box :-)
This Broadcom chip alone retails for €798,- apiece at Digikey, with a manufacturer lead time of 50 weeks as of Aug’21, which may be related to the ongoing foundry and supply chain crisis, I don’t know. But at that price point, the retail price of €1150,- per switch is really attractive.
The switch comes with two modular and field-replaceble power supplies (rated at 150W each, delivering 12V at 12.5A, one fan installed), and with two modular and equally field replaceble fan trays installed with one fan each. Idle, without any optics installed and with all interfaces down, the switch draws about 18W of power, which is nice. The fans spin up only when needed, and by default the switch is quiet, but certainly not silent. I measured it after a tip from Michael, certainly nothing scientific, but in a silent room that measures a floor of ~30 dBA, the switch booted up and briefly burst the fans at 60dBA after which it stabilized at 54dBA or thereabouts. This is with both power supplies on, and with my cell phone microphone pointed directly towards the rear of the device, at 1 meter distance. Or something, IDK, I’m a network engineer, Jim, not an audio specialist!
Besides the 20x 1G/10G SFP+ ports, 4x 25G ports and 2x 40G ports (which, incidentally, can be
broken out into 4x 10G as well, bringing the Tengig port count to the datasheet specified 28),
the switch also comes with a USB port (which mounts a filesystem on a USB stick, handy to do
firmware upgrades and to copy files such as SSH keys back and forth), an RJ45 1G management
port, which does not participate in the switch at all, and an RJ45 serial port that uses a
standard Cisco cable for access and presents itself as
9600,8n1 to a console server, although
flow control must be disabled on the serial port.
FS did not attempt any vendor locking or crippleware with the ports and optics, yaay for that. I successfully inserted Cisco optics, Arista optics, FS.com ‘Generic’ optics, and several DACs for 10G, 25G and 40G that I had lying around. The switch is happy to take all of them. The switch, as one would expect, supports diagnostics, which looks like this:
fsw0#show interfaces TFGigabitEthernet0/24 transceiver Transceiver Type : 25GBASE-LR-SFP28 Connector Type : LC Wavelength(nm) : 1310 Transfer Distance : SMF fiber -- 10km Digital Diagnostic Monitoring : YES Vendor Serial Number : G2006362849 Current diagnostic parameters[AP:Average Power]: Temp(Celsius) Voltage(V) Bias(mA) RX power(dBm) TX power(dBm) 33(OK) 3.29(OK) 38.31(OK) -0.10(OK)[AP] -0.07(OK) Transceiver current alarm information: None
.. with a helpful shorthand
show interfaces ... trans diag that only shows the optical budget.
I bought a pair of switches, and they came delivered with a current firmware version. The devices
idenfity themselves as
FS Campus Switch (S5860-20SQ) By FS.COM Inc with a hardware version of
and a software version of
S5860_FSOS 12.4(1)B0101P1. Firmware updates can be downloaded from the
FS.com website directly. I’m not certain if there’s a viable ONIE firmware for this chip, although the
N8050 certainly can run ONIE, Cumulus and its own ICOS which is backed by Broadcom. Maybe
in the future I could take a better look at the open networking firmware aspects of this type of
hardware, but considering the CAM is tiny and the switch will do L2 in hardware, but L3 only up to
a certain amount of routes (I think 4K or 16K in the FIB, and only 1GB of ram on the SOC), this is
not the right platform to pour energy into trying to get DANOS to run on.
Taking a look at the CLI, it’s very Cisco IOS-esque; there’s a few small differences, but the look and feel is definitely familiar. Base configuration kind of looks like this:
fsw0#show running-config hostname fsw0 ! sntp server oob 22.214.171.124 sntp enable ! username pim privilege 15 secret 5 $1$<redacted> ! ip name-server oob 126.96.36.199 ! service password-encryption ! enable service ssh-server no enable service telnet-server ! interface Mgmt 0 ip address 192.168.1.10 255.255.255.0 gateway 192.168.1.1 ! snmp-server location Zurich, Switzerland snmp-server contact firstname.lastname@example.org snmp-server community 7 <redacted> ro !
Configuration as well follows the familiar
conf t (configure terminal) that many of us grew up
show command allow for
exclude modifiers, of course with all the
shortest-next abbriviations such as
sh int | i Forty and the likes. VLANs are to be declared
up front, with one notable cool feature of
supervlans, which are the equivalent of aggregating
VLANs together in the switch - a useful example might be an internet exchange platform which has
trunk ports towards resellers, who might resell VLAN 101, 102, 103 each to an individual customer,
but then all end up in the same peering lan VLAN 100.
A few of the services (SSH, SNMP, DNS, SNTP) can be bound to the management network, but for this
to work, the
oob keyword has to be used. This likely because the mgmt port is a network interface
that is attached to the SOC, not to the switch fabric itself, and thus its route is not added to
the routing table. I like this, because it avoids the mgmt network to be picked up in OSPF, and
accidentally routed to/from. But it does show a bit more of an awkward config:
fsw1#show running-config | inc oob sntp server oob 188.8.131.52 ip name-server oob 184.108.40.206 ip name-server oob 220.127.116.11 ip name-server oob 18.104.22.168 fsw1#copy ? WORD Copy origin file from native flash: Copy origin file from flash: file system ftp: Copy origin file from ftp: file system http: Copy origin file from http: file system oob_ftp: Copy origin file from oob_ftp: file system oob_http: Copy origin file from oob_http: file system oob_tftp: Copy origin file from oob_tftp: file system running-config Copy origin file from running config startup-config Copy origin file from startup config tftp: Copy origin file from tftp: file system tmp: Copy origin file from tmp: file system usb0: Copy origin file from usb0: file system
Note here the hack
oob_ftp: and such; this would allow the switch to copy things from the
OOB (management) network by overriding the scheme. But that’s OK, I guess, not beautiful,
but it gets the job done and these types of commands will rarely be used.
A few configuration examples, notably QinQ, in which I configure a port to take usual dot1q traffic, say from a customer, and add it into our local VLAN 200. Therefore, untagged traffic on that port will turn into our VLAN 200, and tagged traffic will turn into our dot1ad stack of outer VLAN 200 and inner VLAN whatever the customer provided – in our case allowing only VLANs 1000-2000 and untagged traffic into VLAN 200:
fsw0#confifgure fsw0(config)#vlan 200 fsw0(config-vlan)#name v-qinq-outer fsw0(config-vlan)#exit fsw0(config)#interface TenGigabitEthernet 0/3 fsw0(config-if-TenGigabitEthernet 0/3)#switchport mode dot1q-tunnel fsw0(config-if-TenGigabitEthernet 0/3)#switchport dot1q-tunnel native vlan 200 fsw0(config-if-TenGigabitEthernet 0/3)#switchport dot1q-tunnel allowed vlan add untagged 200 fsw0(config-if-TenGigabitEthernet 0/3)#switchport dot1q-tunnel allowed vlan add tagged 1000-2000
The industry remains conflicted about the outer ethernet frame’s type – originally a tag
protocol identifier (TPID) of 0x9100 was suggested, and that’s what this switch uses. But
the first specification of Q-in-Q called 802.1ad specified that the TPID should be 0x88a8
instead of the VLAN tag that was 0x8100. This ugly reality can be reflected directly in the
switchport configuration by adding a
frame-tag tpid 0xXXXX value to let the switch know
which TPID needs to be used for the outer tag.
For my loadtests, I used Cisco’s T-Rex (ref) in stateless mode,
with a custom Python controller that ramps up and down traffic from the loadtester to the device
under test (DUT) by sending traffic out
port0 to the DUT, and expecting that traffic to be
presented back out from the DUT to its
port1, and vice versa (out from
port1 -> DUT -> back
port0). You can read a bit more about my setup in my Loadtesting at Coloclue
To stress test the switch, several pairs at 10G and 25G were used, and since the specs boast line rate forwarding, I immediately ran T-Rex at maximum load with small frames. I found out, once again, that Intel’s X710 network cards aren’t line rate, something I’ll dive into in a bit more detail another day, for now, take a look at the T-Rex docs.
First let’s test a straight forward configuration. I connect a DAC between a 40G port on each
switch, and connect a loadtester to port
TenGigabitEthernet 0/1 and
on either switch, and leave everything simply in the default VLAN. This means packets from
Te0/1 and Te0/2 go out on Fo0/26, then through the DAC into Fo0/26 on the second switch, and
out on Te0/1 and Te0/2 there, to return to the loadtester. Configuration wise, rather boring:
fsw0#configure fsw0(config)#vlan 1 fsw0(config-vlan)#name v-default fsw0#show run int te0/1 interface TenGigabitEthernet 0/1 fsw0#show run int te0/2 interface TenGigabitEthernet 0/2 fsw0#show run int fo0/26 interface FortyGigabitEthernet 0/26 switchport mode trunk switchport trunk allowed vlan only 1 fsw0#show vlan id 1 VLAN Name Status Ports ---------- -------------------------------- --------- ----------------------------------- 1 v-default STATIC Te0/1, Te0/2, Te0/3, Te0/4 Te0/5, Te0/6, Te0/7, Te0/8 Te0/9, Te0/10, Te0/11, Te0/12 Te0/13, Te0/14, Te0/15, Te0/16 Te0/17, Te0/18, Te0/19, Te0/20 TF0/21, TF0/22, TF0/23, Fo0/25 Fo0/26
I set up T-Rex with unique MAC addresses for each of its ports, I find it useful to codify a few bits of information into the MAC, such as loadtester machine, PCI bus, port, so that when I try to find them on the switches in the forwarding table, and I have many loadtesters running at the same time, it’s easier to find what I’m looking for. My trex configuration for this loadtest:
pim@hippo:~$ cat /etc/trex_cfg.yaml - version : 2 interfaces : ["42:00.0","42:00.1", "42:00.2", "42:00.3"] port_limit : 4 port_info : - dest_mac : [0x0,0x2,0x1,0x1,0x0,0x00] # port 0 src_mac : [0x0,0x2,0x1,0x2,0x0,0x00] - dest_mac : [0x0,0x2,0x1,0x2,0x0,0x00] # port 1 src_mac : [0x0,0x2,0x1,0x1,0x0,0x00] - dest_mac : [0x0,0x2,0x1,0x3,0x0,0x00] # port 2 src_mac : [0x0,0x2,0x1,0x4,0x0,0x00] - dest_mac : [0x0,0x2,0x1,0x4,0x0,0x00] # port 3 src_mac : [0x0,0x2,0x1,0x3,0x0,0x00]
Here’s where I notice something I’ve noticed before: the Intel X710 network cards cannot actually fill 4x10G at line rate. They’re fine at larger frames, but they max out at about 32Mpps throughput – and we know that each 10G connection filled with small ethernet frames in one direction will consume 14.88Mpps. The same is true for the XXV710 cards, the chip used will really only source 30Mpps across all ports, which is sad but true.
So I have a choice to make: either I run small packets at a rate that’s acceptable for the
NIC (~7.5Mpps per port thus 30Mpps across the X710-DA4), or I run
imix at line rate
but with slightly less packets/sec. I chose the latter for these tests, and will be reporting
the usage based on
imix profile, which saturates 10G at 3.28Mpps in one direction, or
13.12Mpps per network card.
Of course, I can run two of these at the same time, pourquois pas, which looks like this:
fsw0#show mac Vlan MAC Address Type Interface Live Time ---------- -------------------- -------- ------------------------------ ------------- 1 0001.0101.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 00:16:11 1 0001.0102.0000 DYNAMIC TenGigabitEthernet 0/1 0d 00:16:11 1 0001.0103.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 00:16:11 1 0001.0104.0000 DYNAMIC TenGigabitEthernet 0/2 0d 00:16:10 1 0002.0101.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 00:15:51 1 0002.0102.0000 DYNAMIC TenGigabitEthernet 0/3 0d 00:15:51 1 0002.0103.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 00:15:51 1 0002.0104.0000 DYNAMIC TenGigabitEthernet 0/4 0d 00:15:50 fsw0#show int usage | exclude 0.00 Interface Bandwidth Average Usage Output Usage Input Usage ------------------------------------ ----------- ---------------- ---------------- ---------------- TenGigabitEthernet 0/1 10000 Mbit 94.66% 94.66% 94.66% TenGigabitEthernet 0/2 10000 Mbit 94.66% 94.66% 94.66% TenGigabitEthernet 0/3 10000 Mbit 94.65% 94.66% 94.66% TenGigabitEthernet 0/4 10000 Mbit 94.66% 94.66% 94.66% FortyGigabitEthernet 0/26 40000 Mbit 94.66% 94.66% 94.66% fsw0#show cpu core [Slot 0 : S5860-20SQ] Core 5Sec 1Min 5Min 0 16.40% 12.00% 12.80%
This is the first time that I noticed that the switch usage (94.66%) somewhat confusingly lines up with the observed T-Rex statistics: what the switch reports, T-Rex considers L2 (ethernet) use, not L1 use. For an in-depth explanation of this, see below in the L3 section. But for now, let’s just say that when T-Rex says it’s sending 37.9Gbps of ethernet traffic (which is 40.00Gbps of bits on the line), that corresponds to the 94.75% we see the switch reporting.
So suffice to say, at 80Gbit actual throughput (40G from Te0/1-3 ingress and 40G to Te0/1-3 egress), the switch performs at line rate, with no noticable lag or jitter. The CLI is responsive and the fans aren’t spinning harder than at idle, even after 60min of packets. Good!
Then, I reconfigured the switch to let each pair of ports (Te0/1-2 and Te0/3-4) each drop into a Q-in-Q VLAN, with tag 20 and tag 21 respectively. The configuration:
interface TenGigabitEthernet 0/1 switchport mode dot1q-tunnel switchport dot1q-tunnel allowed vlan add untagged 20 switchport dot1q-tunnel native vlan 20 ! interface TenGigabitEthernet 0/3 switchport mode dot1q-tunnel switchport dot1q-tunnel allowed vlan add untagged 21 switchport dot1q-tunnel native vlan 21 spanning-tree bpdufilter enable ! interface FortyGigabitEthernet 0/26 switchport mode trunk switchport trunk allowed vlan only 1,20-21 fsw0#show mac Vlan MAC Address Type Interface Live Time ---------- -------------------- -------- ------------------------------ ------------- 20 0001.0101.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 01:15:02 20 0001.0102.0000 DYNAMIC TenGigabitEthernet 0/1 0d 01:15:01 20 0001.0103.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 01:15:02 20 0001.0104.0000 DYNAMIC TenGigabitEthernet 0/2 0d 01:15:03 21 0002.0101.0000 DYNAMIC TenGigabitEthernet 0/4 0d 00:01:50 21 0002.0102.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 00:01:03 21 0002.0103.0000 DYNAMIC TenGigabitEthernet 0/3 0d 00:01:59 21 0002.0104.0000 DYNAMIC FortyGigabitEthernet 0/26 0d 00:01:02
Two things happen that require a bit of explanation. First of all, despite both loadtesters use the exact samve configuration (in fact, I didn’t even stop them from emitting packets while reconfiguring the switch), I now have packetloss, the throughput per 10G port has reduced from 94.67% to 93.63% and at the same time, I observe that the 40G ports raised their usage from 94.66% to 94.81%.
fsw1#show int usage | e 0.00 Interface Bandwidth Average Usage Output Usage Input Usage ------------------------------------ ----------- ---------------- ---------------- ---------------- TenGigabitEthernet 0/1 10000 Mbit 94.20% 93.63% 94.67% TenGigabitEthernet 0/2 10000 Mbit 94.21% 93.65% 94.67% TenGigabitEthernet 0/3 10000 Mbit 91.05% 94.66% 94.66% TenGigabitEthernet 0/4 10000 Mbit 90.80% 94.66% 94.66% FortyGigabitEthernet 0/26 40000 Mbit 94.81% 94.81% 94.81%
The switches, however, are perfectly fine. The reason for this loss is that when I created
dot1q-tunnel, the switch sticks another VLAN tag (4 bytes, or 32 bits) on each packet
before sending it out the 40G port between the switches, and at these packet rates, it adds
up. Each 10G switchport is receiving 3.28Mpps (for a total of 13.12Mpps) which, when the
switch needs to send it to its peer on the 40G trunk, adds 13.12Mpps * 32 bits = 419.8Mbps
on top of the 40G line rate, implying we’re going to be losing roughly 1.045% of our packets.
And indeed, the difference between 94.67 (inbound) and 93.63 (outbound) is 1.04% which lines
Global Statistics connection : localhost, Port 4501 total_tx_L2 : 37.92 Gbps version : STL @ v2.91 total_tx_L1 : 40.02 Gbps cpu_util. : 43.52% @ 8 cores (4 per dual port) total_rx : 37.92 Gbps rx_cpu_util. : 0.0% / 0 pps total_pps : 13.12 Mpps async_util. : 0% / 198.64 bps drop_rate : 0 bps total_cps. : 0 cps queue_full : 0 pkts Port Statistics port | 0 | 1 | 2 | 3 -----------+-------------------+-------------------+-------------------+------------------ owner | pim | pim | pim | pim link | UP | UP | UP | UP state | TRANSMITTING | TRANSMITTING | TRANSMITTING | TRANSMITTING speed | 10 Gb/s | 10 Gb/s | 10 Gb/s | 10 Gb/s CPU util. | 46.29% | 46.29% | 40.76% | 40.76% -- | | | | Tx bps L2 | 9.48 Gbps | 9.48 Gbps | 9.48 Gbps | 9.48 Gbps Tx bps L1 | 10 Gbps | 10 Gbps | 10 Gbps | 10 Gbps Tx pps | 3.28 Mpps | 3.27 Mpps | 3.27 Mpps | 3.28 Mpps Line Util. | 100.04 % | 100.04 % | 100.04 % | 100.04 % --- | | | | Rx bps | 9.48 Gbps | 9.48 Gbps | 9.48 Gbps | 9.48 Gbps Rx pps | 3.24 Mpps | 3.24 Mpps | 3.23 Mpps | 3.24 Mpps ---- | | | | opackets | 1891576526 | 1891577716 | 1891547042 | 1891548090 ipackets | 1891576643 | 1891577837 | 1891547158 | 1891548214 obytes | 684435443496 | 684435873418 | 684424773684 | 684425153614 ibytes | 684435484082 | 684435916902 | 684424817178 | 684425197948 tx-pkts | 1.89 Gpkts | 1.89 Gpkts | 1.89 Gpkts | 1.89 Gpkts rx-pkts | 1.89 Gpkts | 1.89 Gpkts | 1.89 Gpkts | 1.89 Gpkts tx-bytes | 684.44 GB | 684.44 GB | 684.42 GB | 684.43 GB rx-bytes | 684.44 GB | 684.44 GB | 684.42 GB | 684.43 GB ----- | | | | oerrors | 0 | 0 | 0 | 0 ierrors | 0 | 0 | 0 | 0
For this test, I reconfigured the 25G ports to become routed rather than switched, and I put them under 80% load with T-Rex (where 80% here is of L1), thus the ports are emitting 20Gbps of traffic at a rate of 13.12Mpps. I left two of the 10G ports just continuing their ethernet loadtest at 100%, which is also 20Gbps of traffic and 13.12Mpps. In total, I observed 79.95Gbps of traffic between the two switches: an entirely saturated 40G port in both directions.
I then created a simple topology with OSPF, both switches configured a
Loopback0 interface with
a /32 IPv4 and /128 IPv6 address, and a transit network between them in a
OSPF and OSPFv3 both distribute connected and static routes, to keep things simple.
Finally, I added an IP address on the
Tf0/24 interface, set a static IPv4 route for 22.214.171.124/8
and 126.96.36.199/8 towards that interface on each switch, and added VLAN 100 to the
It looks like this for switch
interface Loopback 0 ip address 100.64.0.0 255.255.255.255 ipv6 address 2001:DB8::/128 ipv6 enable interface VLAN 100 ip address 100.65.2.1 255.255.255.252 ipv6 enable ip ospf network point-to-point ipv6 ospf network point-to-point ipv6 ospf 1 area 0 interface TFGigabitEthernet 0/24 no switchport ip address 100.65.1.1 255.255.255.0 ipv6 address 2001:DB8:1:1::1/64 interface FortyGigabitEthernet 0/26 switchport mode trunk switchport trunk allowed vlan only 1,20,21,100 router ospf 1 graceful-restart redistribute connected subnets redistribute static subnets area 0 network 100.65.2.0 0.0.0.3 area 0 ! ipv6 router ospf 1 graceful-restart redistribute connected redistribute static area 0 ! ip route 188.8.131.52 255.0.0.0 100.65.1.2 ipv6 route 2001:db8:100::/40 2001:db8:1:1::2
With this topology, an L3 routing domain emerges between
Tf0/24 on switch
fsw1, and we can inspect this, taking a look at
fsw1, I can see that both IPv4 and
IPv6 adjacencies have formed, and that the switches, néé routers, have learned
routes from one another:
fsw1#show ip ospf neighbor OSPF process 1, 1 Neighbors, 1 is Full: Neighbor ID Pri State BFD State Dead Time Address Interface 100.65.2.1 1 Full/ - - 00:00:31 100.65.2.1 VLAN 100 fsw1#show ipv6 ospf neighbor OSPFv3 Process (1), 1 Neighbors, 1 is Full: Neighbor ID Pri State BFD State Dead Time Instance ID Interface 100.65.2.1 1 Full/ - - 00:00:31 0 VLAN 100 fsw1#show ip route Codes: C - Connected, L - Local, S - Static R - RIP, O - OSPF, B - BGP, I - IS-IS, V - Overflow route N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 SU - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 IA - Inter area, EV - BGP EVPN, A - Arp to host * - candidate default Gateway of last resort is no set O E2 184.108.40.206/8 [110/20] via 100.65.2.1, 12:42:13, VLAN 100 S 220.127.116.11/8 [1/0] via 100.65.0.2 O E2 100.64.0.0/32 [110/20] via 100.65.2.1, 00:05:23, VLAN 100 C 100.64.0.1/32 is local host. C 100.65.0.0/24 is directly connected, TFGigabitEthernet 0/24 C 100.65.0.1/32 is local host. O E2 100.65.1.0/24 [110/20] via 100.65.2.1, 12:44:57, VLAN 100 C 100.65.2.0/30 is directly connected, VLAN 100 C 100.65.2.2/32 is local host. fsw1#show ipv6 route IPv6 routing table name - Default - 12 entries Codes: C - Connected, L - Local, S - Static R - RIP, O - OSPF, B - BGP, I - IS-IS, V - Overflow route N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 SU - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 IA - Inter area, EV - BGP EVPN, N - Nd to host O E2 2001:DB8::/128 [110/20] via FE80::669D:99FF:FED0:A054, VLAN 100 LC 2001:DB8::1/128 via Loopback 0, local host C 2001:DB8:1::/64 via TFGigabitEthernet 0/24, directly connected L 2001:DB8:1::1/128 via TFGigabitEthernet 0/24, local host O E2 2001:DB8:1:1::/64 [110/20] via FE80::669D:99FF:FED0:A054, VLAN 100 O E2 2001:DB8:100::/40 [110/20] via FE80::669D:99FF:FED0:A054, VLAN 100 C FE80::/10 via ::1, Null0 C FE80::/64 via Loopback 0, directly connected L FE80::669D:99FF:FED0:A076/128 via Loopback 0, local host C FE80::/64 via TFGigabitEthernet 0/24, directly connected L FE80::669D:99FF:FED0:A076/128 via TFGigabitEthernet 0/24, local host C FE80::/64 via VLAN 100, directly connected L FE80::669D:99FF:FED0:A076/128 via VLAN 100, local host
Great success! I can see from the
fsw1 output above, its OSPF process has learned
routes for the IPv4 and IPv6 loopbacks (100.64.0.0/32 and 2001:DB8::1/128 respectively),
the connected routes (100.65.1.0/24 and 2001:DB8:1:1::/64 respectively), and the
static routes (18.104.22.168/8 and 2001:db8:100::/40).
So let’s make use of this topology and change one of the two loadtesters to switch to L3 mode instead:
pim@hippo:~$ cat /etc/trex_cfg.yaml - version : 2 interfaces : ["0e:00.0", "0e:00.1" ] port_bandwidth_gb: 25 port_limit : 2 port_info : - ip : 100.65.0.2 default_gw : 100.65.0.1 - ip : 100.65.1.2 default_gw : 100.65.1.1
I left the loadtest running for 12hrs or so, and observed the results to be squeaky clean. The loadtester machine was generating ~96Gb/core at 20% utilization, so lazily generating 40.00Gbit of traffic at 25.98Mpps (remember, this was setting the load to 80% on the 25G port, and 99% on the 10G ports). Looking at the switch and again being surprised about the discrepancy, I decided to fully explore the curiosity in this switch’s utilization reporting.
fsw1#show interfaces usage | exclude 0.00 Interface Bandwidth Average Usage Output Usage Input Usage ------------------------------------ ----------- -------------- -------------- ----------- TenGigabitEthernet 0/1 10000 Mbit 93.80% 93.79% 93.81% TenGigabitEthernet 0/2 10000 Mbit 93.80% 93.79% 93.81% TFGigabitEthernet 0/24 25000 Mbit 75.80% 75.79% 75.81% FortyGigabitEthernet 0/26 40000 Mbit 94.79% 94.79% 94.79% fsw1#show int te0/1 | inc packets/sec 10 seconds input rate 9381044793 bits/sec, 3240802 packets/sec 10 seconds output rate 9378930906 bits/sec, 3240123 packets/sec fsw1#show int tf0/24 | inc packets/sec 10 seconds input rate 18952369793 bits/sec, 6547299 packets/sec 10 seconds output rate 18948317049 bits/sec, 6545915 packets/sec fsw1#show int fo0/26 | inc packets/sec 10 seconds input rate 37915517884 bits/sec, 13032078 packets/sec 10 seconds output rate 37915335102 bits/sec, 13026051 packets/sec
Looking at that number, 75.80% was not the 80% that I had asked for, and actually the usage of the 10G ports (which I put at 99% load) and 40G port are also lower than I had anticipated. What’s going on there? It’s quite simple after doing some math: the switch is reporting L2 bits/sec, not L1 bits/sec!
On the L3 loadtest and using the
imix profile, T-Rex is sending 13.02Mpps of load, which,
according to its own observation is 37.8Gbit of L2 and 40.00Gbps of L1 bandwidth. On the L2
loadtest, again using
imix profile, T-Rex is sending 4x 3.24Mpps as well, which it claims
is 37.6Gbps of L2 and 39.66Gbps of L1 bandwidth (note: I put the loadtester here at 99% of
line rate, this is to ensure I would not end up losing packets due to congestion on the 40G
So according to T-Rex, I am sending 75.4Gbps of traffic (37.8Gbps in the L2 test and 37.6Gbps in the simultenous L3 loadtest), yet I’m seeing 37.9Gbps on the switchport. Oh my!
Here’s how all of these numbers relate to one another:
- First off, we are sending 99% linerate at 3.24Mpps into Te0/1 and Te0/2 on each switch.
- Then, we are sending 80% linerate at 6.55Mpps into Tf0/24 on each switch.
- The Te0/1 and Te0/2 are both in the default VLAN on either side.
- But, the Tf0/24 is sending its IP traffic through VLAN 100 interconnect, which means all of that traffic gets a dot1q VLAN tag added. That’s 4 bytes for each packet.
- Sending 6.55Mpps * 32bits extra, equals 209600000 bits/sec (0.21Gbps)
- Loadtester claims 37.70Gbps, but the switch sees 37.91Gbps which is exactly the difference we calculated above (0.21Gbps), and equals the overhead created by adding the VLAN tag on the 25G stream that is in VLAN tag 100.
Now we are ready to explain the difference between the switch reported port usage and the loadtester reported port usage:
- The loadtester is sending an
imixtraffic mix, which consts of a ratio of 28:16:4 of packets that are 64:590:1514 bytes.
- We already know that to create a packet on the wire, we have to add a 7 byte preamble a 1 byte start frame delimiter, and end with a 12 byte interpacket gap, so each ethernet frame is 20 bytes longer, making 84 bytes the on-the-wire smallest possible frame.
- We know we’re sending 3.24Mpps on a 10G port at 99% T-Rex (L1) usage:
- Each packet needs 20 bytes or 160 bits of overhead, which is 518400000 bits/sec
- We are seeing 9381044793 bits/sec on a 10G port (corresponding switch 93.80% usage)
- Adding these two numbers up gives us 9899444793 bits/sec (corresponding T-Rex 98.99% usage)
- Conversely, the whole system is sending 37.9Gbps on the 40G port (corresponding switch 37.9/40 == 94.79% usage)
- We know this is 2x 10G streams at 99% utilization and 1x25G stream at 80% utilization
- This is 13.03Mpps, which generate 2084800000 bits/sec of overhead
- Adding these two numbers up gives us 40.00 Gbps of usage (which is the expected L1 line rate)
I find it very fulfilling to see these numbers meaningfully add up! Oh, and by the way, the switches that are now switching and routing all of this with with 0.00% packet loss, and the chassis doesn’t even get warm :-)
Global Statistics connection : localhost, Port 4501 total_tx_L2 : 38.02 Gbps version : STL @ v2.91 total_tx_L1 : 40.02 Gbps cpu_util. : 21.88% @ 4 cores (4 per dual port) total_rx : 38.02 Gbps rx_cpu_util. : 0.0% / 0 pps total_pps : 13.13 Mpps async_util. : 0% / 39.16 bps drop_rate : 0 bps total_cps. : 0 cps queue_full : 0 pkts Port Statistics port | 0 | 1 | total -----------+-------------------+-------------------+------------------ owner | pim | pim | link | UP | UP | state | TRANSMITTING | TRANSMITTING | speed | 25 Gb/s | 25 Gb/s | CPU util. | 21.88% | 21.88% | -- | | | Tx bps L2 | 19.01 Gbps | 19.01 Gbps | 38.02 Gbps Tx bps L1 | 20.06 Gbps | 20.06 Gbps | 40.12 Gbps Tx pps | 6.57 Mpps | 6.57 Mpps | 13.13 Mpps Line Util. | 80.23 % | 80.23 % | --- | | | Rx bps | 19 Gbps | 19 Gbps | 38.01 Gbps Rx pps | 6.56 Mpps | 6.56 Mpps | 13.13 Mpps ---- | | | opackets | 292215661081 | 292215652102 | 584431313183 ipackets | 292152912155 | 292153677482 | 584306589637 obytes | 105733412810506 | 105733412001676 | 211466824812182 ibytes | 105710857873526 | 105711223651650 | 211422081525176 tx-pkts | 292.22 Gpkts | 292.22 Gpkts | 584.43 Gpkts rx-pkts | 292.15 Gpkts | 292.15 Gpkts | 584.31 Gpkts tx-bytes | 105.73 TB | 105.73 TB | 211.47 TB rx-bytes | 105.71 TB | 105.71 TB | 211.42 TB ----- | | | oerrors | 0 | 0 | 0 ierrors | 0 | 0 | 0
It’s just super cool to see a switch like this work as expected. I did not manage to overload it at all, neither with IPv4 loadtest at 20Mpps and 50Gbit of traffic, nor with L2 loadtest at 26Mpps and 80Gbit of traffic, with QinQ demonstrably done in hardware as well as IPv4 route lookups. I will be putting these switches into production soon on the IPng Networks links between Glattbrugg and Rümlang in Zurich, thereby upgrading our backbone from 10G to 25G CWDM. It seems to me, that using these switches as L3 devices given a smaller OSPF routing domain (currently, we have ~300 prefixes in our OSPF at AS50869), would definitely work well, as would pushing and popping QinQ trunks for our customers (for example on Solnet or Init7 or Openfactory).
Approved. A+, will buy again.