Skip to content

Linux

Latency simulation over long fat network

World Network

One of our clients asked us how we handle latency, and not just a few ms across racks but 2 and even 3 digit ms latency that indicates geographically separate locations across continents, not just a country. Not only that, the "pipes" involved are 10Gbps and we had to fill them. We have the theories and made models of how it would work. We perhaps might not be able to fill a 10Gbps fully with one stream, we could fill it with multiple streams but we had to validate this conclusion. The question now becomes, how do we test this. We've done our research and there are only a few commercial solutions available like the Netropy 10G2 which is a 4 port, 2 lane hardware latency simulator for $30,000 new. Not only is that outside my budget, it is still limited to simulating 2 10Gbps pipes while we need at least 3 lanes (6 ports) and possibility to expand to more as necessary. We decided it was cheaper in terms of total cost to put the research into creating our own Latency Simulator. We studied what we could from google, specifically the work done by NASA on a "Channel Emulator". They used traffic control (tc) to handle delay on the egress of an interface. This means that if a packet travels through, it is delayed but the return packet is not and goes right through. Our setup means that we have one 10Gbps card with 2 ports. We then link the two interfaces with bridge control (brctl) to create a layer2 bridge. We then split the "round trip time" or RTT delay and apply that to each 10Gbps interface. All packets going to and returning from a network then have the full simulated RTT delay. This type of machine does not need much in the way of RAM as the buffers necessary are not large, 4GiB is sufficient. What is important is the CPU operating frequency, all other aspects of the CPU is not important except that there should be 1 core per 10Gbps interface. This is required because part of the network stack is being simulated with the bridge then processed. For a 3 lane setup, that is 6 ports so we need at least a 6 core CPU @ >= 2.2 Ghz to handle the load.

Latency Simulator

You may be asking why just 3 and not 4 latency lanes, this is because for us there will always be a 'local' data center and the other 3 connect to it in a star like network layout like in the above diagram. Since this is a 'flat' network in the same subnet, any ping from one of the data centers to another data center will go through the 'local' data center. In reality, these 'data center' switches are connected to the Latency Simulator which then connects to the local data center switch. Realistic latency from the 'local' data center in New York: California: 32ms England: 80ms Japan: 346ms Source: Verizon's latency table Going from California to Ireland would involve first a hop through New York, so the compound delay would be 112ms. With that in mind you can then compute your bandwidth delay product (BDP) Once the machine is up and running with whatever Linux distribution you like, make sure that tc and brctl are installed. Here are the scripts that can be used to bring the bridges up and down, and apply latencies and remove the latencies for the four geographically seperate datacenters. Files:

Once in place, we could ping from one side to the other and see the latency being applied. It is now time for baseline testing. First we turned off the latency and used iperf to test end to end that we can fill the 10Gbps pipes and that the Latency Simulator isn't the bottleneck. We could get around 9.50Gbps point to point. Then we turn on the latency and see the impact directly. The first thing we noticed is that when running iperf for the default 10s that the slow start and initial TCP window size has an impact how much data we can send over the wire. Because of the slow start, if you want better performance in your stream then you need to test for longer than 10s. We could not fill a pipe with 120ms latency until after 25s of running iperf which time we had transferred something like 15GiB of data. So trying to send a 1GiB file will not fill pipe.

RTT in ms   MiB/s default   MiB/s MAX
0       1162        1157
2       1053        1136
4       513     1076
8       248     1075
16      103     691
22      91      366
32      47      358
44      31      208
64      8.2     64
128     0.8     26
130     0.7     26

The MAX settings I used is the MAX TCP Window Size of 1GiB. If you try to go above that, you will find that Linux gets mad and some networking services will just not work. The sweet spot for us to set the initial window size to 8MiB which gave the algorithm enough time to shrink to either 4096 bytes or to grow in the other direction. Below are two 'key' tunables where rmem is the read buffer and wmem is the write buffer of the TCP buffer. sysctl -w net.ipv4.tcp_rmem='4096 8388608 33554432' sysctl -w net.ipv4.tcp_wmem='4096 8388608 33554432' However even with an initial 8MiB TCP Window Size, you'll never reach this potential because the Initial Congestion Window (initcwnd) is set to 10 as of 2011 per this git diff. This "slow start" is a congestion avoidance mechanism with exponential growth, a feature not a bug. Below is the 'slow start' in action when downloading a linux source tarball from kernel.org. slow star congestion control slow star congestion control What you are seeing is the an exponential growth of the congestion window that eventually grows to allow the TCP Window Size to kick in which then scales up linearly. You can however changed this per route which makes sense because congestion control works on a per network/host level. Examples of setting the initial congestion and receive windows: ip route change default via x.x.x.x initcwnd 20 initrwnd 20 # update your default gateway ip route change dev eth0 192.168.1.0/24 proto kernel src 192.168.0.1 initcwnd 20 initrwnd 20 # if you want to apply it just to one network Do not think of this as just updating the values and expecting fantastic results, because if you enter packet loss into the equation or real network congestion, then you are in for a painful experience with values that are too large. You'll not be as agile to respond to the pitfalls of the Internet, but if you are on a long fat network then adjusting these values can be a real boon for your throughput. You should now the tools necessary to implement your own "Long Fat Network" simulator and various things you can look at and adjust to get the most out of your network and applications.

Wireless BCM4312 with the 3.6, 3.7 and 3.8 kernel

Broadcom Chipset BCM4312

As a follow up to , I've also tested the Broadcom hybrid driver with the 3.6, 3.7 and the soon to be released 3.8 kernels with success. There have been no major changes that should effect the operation of this driver.

To verify that everything is working as expected on the software side, when modprobe or insmod wl, you should get a similar dmesg output:

[ 307.560347] lib80211: common routines for IEEE802.11 drivers [ 307.560353] lib80211_crypt: registered algorithm 'NULL' [ 307.564524] wl: module license 'unspecified' taints kernel. [ 307.564529] Disabling lock debugging due to kernel taint

The only real issue at this point is this:

WARNING: modpost: missing MODULE_LICENSE() in /home/bcurtis/workspace/wl/wl.o see include/linux/module.h for more information WARNING: modpost: Found 1 section mismatch(es). To see full details build your kernel with: 'make CONFIG_DEBUG_SECTION_MISMATCH=y' CC /home/bcurtis/workspace/wl/wl.mod.o LD /home/bcurtis/workspace/wl/wl.ko

While these aren't errors, they are problems to be addressed upstream by Broadcom if they wish to see their driver to be used in the future. They will also need to incorporate my patch sets from my previous post. They haven't updated their driver in about two years now.

Upgrade Samsung Galaxy Gio to CyanogenMod 7.2

Android

Going from 2.3.x (Gingerbread) to CyanogenMod 7.2 (Gingerbread) is surprisingly simple unlike upgrading from Froyo. I'll go into more detail below, but there are two necessary bits: an updated recovery rom and a custom (non-official) CyanogenMod rom. This version of CyanogenMod is specific to the Samsung Gio.

Before upgrading your Samsung Gio, you must first be running at least 2.3.x (Gingerbread) before continuing because of the use of ext4 instead of rfs. Please follow my upgrade guide "Upgrade Samsung Galaxy Gio from 2.2.x Froyo to 2.3.x Gingerbread" first.

Warning: Caveat emptor - While I used to this process to update my phone, I take no responsibility if you brick your phone. Be sure to back up anything you wish to save, this procedure works best when your Gio is fully wiped of data.

Installation of the ClockworkMod (CWM)

  1. Download the custom CWM "px-cwm-v2.zip" and copy it to your sdcard.
  2. Reboot into the default recovery in your stock Gingerbread or with your Gio turned off, hold down the Home/OK (middle) button and press the Power button.
  3. In recovery mode, use the Volume buttons for navigation and the Home/OK button for selecting.
  4. Select “Update from SD card” from the recovery menu.
  5. Look for "px-cwm-v2.zip" which should be on your sdcard and press OK to flash.
  6. Reboot again like above into recovery mode and you should now have the new CWM recovery screen.

You can read more about CWM here.

Here is a video that shows the process: http://www.youtube.com/watch?feature=player_embedded&v=hxjxB8P9rSU

Installation of CyanogenMod 7.2 for Samsung Gio

  1. Download update-cm-7.2.0-20120710-NIGHTLY-gio-AROMA.zip from either here or here.
  2. Copy to sdcard
  3. Reboot to Recovery Mode (CWM)
  4. Select install zip from sd card
  5. Select "update-cm-7.2.0-20120710-NIGHTLY-gio-AROMA.zip" ROM
  6. Select Yes - Install update
  7. Wait till the Installation is finish
  8. Select wipe data/factory reset
  9. Select reboot mobile and enjoy

Cyanogen Mod 7.2.0 For Galaxy Gio based on Gingerbread (2.3.7) Working:

  • RIL
  • proximity sensor
  • touchscreen with multi touch
  • keychar
  • storage mode
  • gps
  • compass
  • accelerometer sensor
  • microphone (both phone & headset)
  • headset button
  • Root & Busybox
  • call,sms,mms
  • auto rotate
  • packet data with automatically apn detect
  • GPRS, EDGE, 3G, HSDPA
  • wifi
  • hardware video acceleration
  • secret code
  • bluetooth
  • camera
  • static wifi mac address
  • audio & FM Radio
  • wired & hotspot tether
  • Backlight Notification

Not Working:

  • Sim Toolkit (maybe)

Known issues:

  • some option are not working on setting (like: mute camera sound, etc)
  • slow loading png image on gallery
  • after use camera, governor force back to "ondemand"

Sources:

All thanks should go to CyanogenMod team, phiexz and all those that have put effort into ever aspect of this ROM.

This is part 2 of a 3 part series about the Galaxy Gio. Part1: Upgrade Samsung Galaxy Gio from 2.2.x Froyo to 2.3.x Gingerbread Part2: Upgrade Samsung Galaxy Gio to CyanogenMod 7.2 Part3: Upgrade Samsung Galaxy Gio to CyanogenMod 10.1

The case of the non-booting USB thumb-drive and the Dell R620

dell_poweredge_r620

Awhile back I wrote about 'Doing battle with a Dell R620 and Ubuntu' where I touched on the fact that booting from USB thumb-drive was a painful problem. In short, the same USB thumb-drive that would work in the R610 would not work in the R620.

It comes down BIOS support for USB and how it is handled. On the R610 there are 3 options: 'auto-detect', 'floppy emulation' and 'hard drive'. Auto was hit-or-miss, floppy would not work but 'hard drive' worked every time. On the R620 there are no options so I can only suppose that it supports 'floppy emulation' upon detection of a USB thumb-drive.

To try to find the cause of this problem we tried using the 'standard' method of taking Precise 12.04 ISO from Ubuntu's website and using UNetbootin to create a USB thumb-drive that did boot on the R620. It turns out there was something wrong with our process that prevented it from booting. In comparing the partition table (with parted) of our USB thumb-drive and the Precise thumb-drive we noticed that the starting position of the first (and only) partition were different!

Non-booting USB:

Model: TDKMedia Trans-It Drive (scsi) Disk /dev/sdc: 3999MB Sector size (logical/physical): 512B/512B Partition Table: msdos

Number Start End Size Type File system Flags 1 1049kB 3998MB 3997MB primary ext4 boot

Booting USB:

Model: TDKMedia Trans-It Drive (scsi) Disk /dev/sdc: 3999MB Sector size (logical/physical): 512B/512B Partition Table: msdos

Number Start End Size Type File system Flags 1 32.9kB 3998MB 3997MB primary ext4 boot

The choice to do 1MiB was to increase the lifespan of the thumb-drive by aligning the partition to the erase-block size of the thumb-drive. Doing this however renders 'floppy emulation' a non-option on both the Dell R620 and R610. Setting it to 32.9KiB also means that the drive is not properly aligned and you will get bad performance when writing, reading and health of the thumb-drive itself.

In the interest of getting bootable thumbdrive we ended up doing this: parted -a none /dev/sdb 'mkpart primary 0 -1 set 1 boot on' What this does is create a primary partition at the start of the thumb-drive that goes all the way to the end. We ignore the alignment problems and set the partition to bootable. After that, it was easy enough to through our ext4 filesystem on top and syslinux/casper to get our custom installer working.

The end result is that we now have a USB thumb-drive that boots on a R620 every time.

Wireless BCM4312 with the 3.4 and 3.5 kernel

Broadcom Chipset BCM4312

The hybrid driver from Broadcom is still a bit behind in terms of support for the latest kernels but there are workarounds. This particular issue also effects other kernel modules such as the out of tree Nvidia and ATI blobs that require the asm/system.h file in their includes.

I've had success with replacing it with asm/switch_to.h which seems to have fixed things for now. The cause for this can be found on the LKML.

Chipsets supported by "Broadcom’s IEEE 802.11a/b/g/n hybrid Linux® device driver" are: BCM4311, BCM4312, BCM4313, BCM4321, BCM4322, BCM43224, and BCM43225, BCM43227 and BCM43228.

Errors:

bcurtis@ronin:~/workspace/wl$ make KBUILD_NOPEDANTIC=1 make -C /lib/modules/uname -r/build M=pwd make[1]: Entering directory /usr/src/linux-headers-3.5.0-030500rc3-generic' Wireless Extension is the only possible API for this kernel version Using Wireless Extension API LD /home/bcurtis/workspace/wl/built-in.o CC /home/bcurtis/workspace/wl/src/shared/linux\_osl.o CC /home/bcurtis/workspace/wl/src/wl/sys/wl\_linux.o /home/bcurtis/workspace/wl/src/wl/sys/wl\_linux.c:43:24: fatal error: asm/system.h: No such file or directory compilation terminated. make[2]: \*\*\* Error 1 make[1]: \*\*\* Error 2 make[1]: Leaving directory/usr/src/linux-headers-3.5.0-030500rc3-generic' make: *** Error 2

The rundown:

  1. Download the 32 or 64-bit version: http://www.broadcom.com/support/802.11/linux_sta.php
  2. Download my patches: bc_wl_abiupdate.patch and switch_to.patch
  3. Extract the sources: cd ~/Downloads; mkdir -p wl; cd wl; tar xf ../hybrid-portsrc*.tar.gz
  4. Patch and compile the sources: patch -p0 src/wl/sys/wl_linux.c < ~/Downloads/switch_to.patch; patch -p0 src/wl/sys/wl_linux.c < ~/Downloads/bc_wl_abiupdate.patch; make; sudo make install; sudo depmod; sudo modprobe wl

Give Ubuntu a few seconds after loading the "wl" kernel module, then eventually the Network Manager will start looking for wireless networks.

TL;DR: These patches are required for a working wl kernel module for the 3.4 and 3.5 kernel series.

Update: Also verified to work with Linux 3.6 series.

Doing battle with a Dell R620 and Ubuntu

dell_poweredge_r620

We recently got sent a Dell R620 to evaluate and while its technical specification is amazing there are a few things that need to be handled first.

As far as Ubuntu and the Dell R620 go, Precise (12.04) is the only way to go here. Every release before Precise has issues with this hardware in one way or another. This is new hardware of after all.

For our "use case" we downgraded the PERC H710P controller to a H310 controller so we can have direct access to the drives via pass-through. The H310 allows TRIM support for SSDs and SMART data via smartctl to be used without any problems. If you are interested in SMART information and PERC H700 series RAID controller, I posted about possible workarounds at Dell's customer support site.

Let's begin: USB Booting: try as we might, we could not get any usb stick to boot on the R620. We've gone through the iDRAC to do virtual drives and looked at BIOS/UEFI methods. The usb stick is recognized, but the R620 just shows us a blank screen. The same stick works in the R610, VM and other machines. We have a ticket with Dell support and they have yet to resolve the problem. Booting over PXE or CD/DVD are our only options at this point.

Bad MAC Addresses

Intel® Ethernet Server Adapter I350-T4: The igb kernel module for 2.6.35 and 2.6.38 will detect this card and it will get you connectivity, but it will behave funny. For example, 3 to 4 ports will have the same MAC address. You need download, compile, and install the latest sources for the igb from Intel before you get full functionality out of your I350-T4. The other option is to install Ubuntu Precise (12.04) as the 3.2 kernel has the updated drivers from Intel.

DRHD: handling fault status reg: at some point during booting of a freshly installed Ubuntu with the 2.6.35 kernel, we ran into this error that would effectively loop endlessly and cause the R620 to become unresponsive. We got this:

DRHD INTR-REMAP problems

DRHD: handling fault status reg 502 INTR-REMAP: Request device[[42:00.1] fault index b0 INTR-REMAP:[] Present field in the IRTE entry is clear

and it would endlessly print that to the console. This apparently has something to do with the IO-MMU part of the kernel dealing with interrupt remapping. Whatever the problem was, it was fixed in the 2.6.38 kernel and caused no more problems.

Dell SSD: the SSDs are rebranded Samsung drives which do not support TRIM but are at least over provisioned. These drives have a problem with smartctl in that while there is SMART information, the drive itself doesn't (yet) exist in the drivedb.h file. You have to use the latest smartctl version (5.42) to get anything usefull out of the drive. Older versions give you things like this:

Log Sense failed, IE page

hdparm: and other tools like smartctl, lshw and others have issues when getting the required data from over the PERC H310, even if it is pass-through. You have to use the latest versions of each to even read the serial number off a HDD or SSD. Hdparm versions >= 9.37 work, otherwise you get this:

root@node:~# hdparm -I /dev/sda

/dev/sda: HDIO_DRIVE_CMD(identify) failed: Invalid exchange

Once we got all the little inconveniences out of the way, we got down to benchmarking and performance testing. In comparison to the Dell R610's 2x Xeon(R) E5606, the R620's 2x Xeon(R) CPU E5-2643 has double the CPU performance in our testing. The obvious bottleneck here are the 2x 2port 10Gbps NICs in that even at a theoretical max of 40Gbps, for our purposes, we would be network bound. Thankfully there is another PCI-Express available, just in case.

A poor man's https, using ssh to secure web traffic

HTTPS_Everywhere_new_logo

Sometimes you get a web-hosting environment that only serves non-ssl (http) content. If you need to do any type of management through tools like phpMyAdmin, then you can see the problem with this. All it would take is someone on your network or on the Internet to sniff the traffic and retrieve your username and password, then they too can do a bit of "management" on your site.

If you also have secure shell (SSH) access, then there is a way to manage your site securely by using SSH's venerable port forwarding (SOCKS). The trick is to tell your management tools to only listen or respond to connections coming in over SSH instead of normal traffic. First you need to set up your SSH connection and configure your browser to use your newly made SOCKS proxy. Please refer to my post about SSH Proxies for more information.

The second part is to secure your application to only accept connections from itself, which is where your browser requests travels through your secure tunnel. We can mask it a bit so that you will have to look hard to see that there is something of interest going on there. It will also be ignored by Google and other search engines.

You can add this to your php code: /* custom code to deny access to world */ if ($_SERVER["SERVER_ADDR"] != $_SERVER["REMOTE_ADDR"]){ header('HTTP/1.1 404 Not Found'); exit();

If the remote IP (your request) is not he same as the server IP, then we give the 404 error message in return, otherwise you get to your application.

SSH as a socks proxy

passwords

Recently there was a need to visit a US based website to verify some personal information. Apparently there are 'rules' about who is geographical allowed to get access to the site which means that a citizen of said country cannot access the site from outside of the US.

I will not get into the absurdity of such security mandates, instead we will go around the problem and get our information that bureaucracy tried to prevent.

The general idea is to use a proxy inside the US that will allow us to hop over the geographical firewall. I do not trust open proxies by default because of their ability to sniff traffic. I do however have access to a secure shell (SSH) in the US that I can use. Using this command: ssh -D 8080 [email protected]

will create a port 8080 on localhost (your computer). You can then use a web-browser like chrome from anywhere in the world and through an encrypted tunnel come out the other side on a network based in the US. You need to configure your web-browser to use a 'SOCKS Proxy' in order for this to work.

For chrome, it is easy as doing this: chrome --proxy-server="socks5://127.0.0.1:8080" or you can follow this guide to setting up chrome with socks.

To check that it is working, go to google and ask "What is my IP".

For more detailed information, here is the ssh man page:

Specifies a local “dynamic” application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server.

Asymmetric networking using Linux

asymmetric_network_icon

The idea is simple, two subnets (separate networks) and then route packets from one to the other. The environment, however, is not symmetric. We wanted to contact a node on the other subnet and we could see the packets travelling over the switch to the router back through another switch to the node, but the node itself refused to reply. Each node has two NICs and each NIC is connected to a separate network. If you try to connect or ping one node from another, Linux is smart enough to go directly over the NIC with the right network. If a NIC should ever fail, the failover is that the packets are then routed up one network to the router then over to the other network. The network looks something like this:

        ----(router)----
        |               |
        |               |
   | switch |__  __| switch |
        |      \/       |
        |      /\       |
        |     /  \      |
        |    x    \     |
   | node1 |/      \| node2 |

note: The x is the broken link.

Apparently when going from node1 to node2 is not the problem, node2 just does not respond. This has to do Reverse Path Filtering and per default is enabled in the Linux kernel. From the manual:

By default, routers route everything, even packets which 'obviously' don't belong on your network. A common example is private IP space escaping onto the internet. If you have an interface with a route of 195.96.96.0/24 to it, you do not expect packets from 212.64.94.1 to arrive there. ... Basically, if the reply to this packet wouldn't go out the interface this packet came in, then this is a bogus packet and should be ignored.

Armed with this new knowledge and acknowledging that this system will not be on an Internet route-able environment, we decided to turn off the filtering. for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 0 > $i; done This solved the problem and node2 could reply back over it's NIC to the other network without having to go back through the router.

Wireless BCM4312 3.0 kernel

Broadcom Chipset BCM4312

With the latest 3.0 kernel there is still no "out of the box" support for my BCM4312 wireless chipset. Nor is there any help from Ubuntu 11.04 leaving me to use Broadcoms hybrid driver with patch.

Chipsets supported by "Broadcom's IEEE 802.11a/b/g/n hybrid Linux® device driver" are: BCM4311, BCM4312, BCM4313, BCM4321, BCM4322, BCM43224, and BCM43225, BCM43227 and BCM43228.

My specific chipset from lspci command:

Broadcom Corporation BCM4312 802.11b/g LP-PHY (rev 01)

Below is the error I get with v5_100_82_38 from Broadcom when compiling against Linux kernel 3.0:

bcurtis@zwartevogel:~/Downloads/wl.org$ make KBUILD_NOPEDANTIC=1 make -C /lib/modules/uname -r/build M=pwd make[1]: Entering directory /usr/src/linux-headers-2.6.38-020638-generic' LD /home/bcurtis/Downloads/wl.org/built-in.o CC /home/bcurtis/Downloads/wl.org/src/shared/linux\_osl.o CC /home/bcurtis/Downloads/wl.org/src/wl/sys/wl\_linux.o /home/bcurtis/Downloads/wl.org/src/wl/sys/wl\_linux.c: In function ‘wl\_attach’: /home/bcurtis/Downloads/wl.org/src/wl/sys/wl\_linux.c:485:3: error: implicit declaration of function ‘init\_MUTEX’ make[2]: \*\*\* Error 1 make[1]: \*\*\* Error 2 make[1]: Leaving directory/usr/src/linux-headers-3.0.0-0300rc1-generic' make: *** Error 2

To get your wireless adapter working again:

  1. Download the 32 or 64-bit version: http://www.broadcom.com/support/802.11/linux_sta.php
  2. Download my patch for > 2.6.37 support: broadcom-sta_4_kernel-2.6.38.patch
  3. Extract the sources: cd ~/Downloads; mkdir -p wl; cd wl; tar xf ../hybrid-portsrc*-v5_100_82_38.tar.gz
  4. Patch the sources, compile and install: patch -p1 < ../broadcom-sta_4_kernel-2.6.38.patch make; sudo make install; sudo depmod; sudo modprobe wl

Give Ubuntu a few seconds after loading the "wl" kernel module, then eventually the Network Manager will start looking for wireless networks.