Network Rate Limiting with OpenWRT and a Single Board Computer

 On 2016-05-02 and filed under: linux openwrt raspberrypi


Notes

  • eth1 should be used for SQM. Using eth0 for SQM will lock up the interface when it applies the settings.
  • Add:

    /usr/lib/sqm/run.sh start

to /etc/init.d/sqm so that sqm is started at boot. Bridge detection doesn’t work with SQM.

Overview

This provides a walk-through of how to install OpenWRT on a Raspberry Pi, and how to configure it to rate limit traffic going through it.

On my own home network, I have a pretty performant network, however

When we’re done, the Device to Internet path will look something like this:

Device to be managed -> Ethernet Cable

-> Ethernet-To-USB Adapter -> Single Board Computer

-> Ethernet Cable -> Internet (Router)

We’ll basically be physically inserting something in-between the network path to manage and shape the network traffic.

And as far as software for doing this sort of thing, OpenWRT offers an amazing footprint-to-power ratio. This article will be using a tiny subset of what it offers, so do check out the packages for some inspiration.

Look here to get the right image: https://wiki.openwrt.org/toh/raspberry_pi_foundation/raspberry_pi

Follow the instructions to dd the image to an SD card, or use the Windows formatter tool (etc). OpenWRT is designed for routers with small amounts of flash space, so a huge SD card isn’t a necessity.

If you’re really lazy and want to cut corners: zcat openwrt-15.05.1-brcm2708-bcm2708-sdcard-vfat-ext4.img.gz > /dev/mmcblk0

When the prompt returns, eject the card and connect your Pi up (HDMI, keyboard, USB ethernet adapter+ethernet cables)

Networking

It’s possible to do everything without an HDMI setup too.

The network on your Pi will be set (by default) to a static address of 192.168.1.1.

It is possible to self­-assign your computer to something like 192.168.1.2 and then telnet to the Pi to complete setup.

telnet 192.168.1.1
passwd
vi /etc/config/network

# Add the option proto ‘dhcp’ line to make your Pi ask for an IP address
config interface 'lan'
option ifname 'eth0'
option type 'bridge'
option proto 'dhcp'
# option proto 'static'
# option ipaddr '192.168.1.1'
# option netmask '255.255.255.0'
# option ip6assign '60'

# Exit with <ESC> :wq

ifup lan
opkg update
opkg install luci­ssl
reboot

Your Pi will now reboot, and telnet should be inaccessible. Use ssh for all future interactions. The console should also spawn a password-less shell by hitting ‘enter’ after boot completes, so don’t count on full security locally.

Installing luci also gave us a web interface at https://192.168.1.1 ­­ The user is root by default, with the password you’ve set earlier.

Add a USB to Ethernet adapter

● There are plenty of USB to Ethernet adapters available.The most common ones are asix­based. Support in OpenWRT isn’t baked in, but provided via an installable kernel module.

opkg update
opkg install kmod-usb-net-asix

If this didn’t work, it might help to install usbutils (opkg install usbutils) and use lsusb to get more information on your Ethernet adapter’s chipset.

To figure out which ethernet interface the adapter has been assigned:

dmesg | grep asix
[ .. snip .. ] asix 1­1.3:1.0 eth1: register ‘asix’ [ .. snip .. ]

Another method is to match up the MAC address (printed on the adapter usually), by abusing grep slightly:

grep : /sys/class/net/*/address

This lists all of the interfaces picked up by Linux. The MAC address for your adapter is typically printed on the rear.

Application: SQM (fighting bufferbloat) Overview: https://wiki.openwrt.org/doc/howto/sqm Build bridges across all the things:

The idea is to bridge things so clients get internet access through the USB­ Ethernet adapter.

● Be sure to do this over a console so that you’re able to safely recover if something goes south (something always does).

vi /etc/config/network

config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config interface 'wan'
    option proto 'dhcp'
    option auto '1'
    option delegate '0'
    option _orig_ifname 'br-lan'
    option _orig_bridge 'false'
    option ifname 'eth0'
    option defaultroute '1'
    option peerdns '1'

config interface 'lan'
    option ifname 'eth0 eth1'
    option type 'bridge'
    option auto '1'

The next step will likely disconnect your SSH session

/etc/init.d/network reload

Installing SQM stuff: By default the standard QoS stuff isn’t installed. The instructions on the wiki recommend removing them if they are (qos­scripts and luci­app­qos).

opkg update && opkg install luci­app­sqm
https://192.168.1.X (where X is the DHCP address your Pi was assigned).

Log in with your username (probably ‘root’) and password.

Go to Network ­> SQM QoS

Check ‘Enable this SQM Instance’

Ensure the interface name is set to your Ethernet adapter

Set the Download and Upload speed as desired

Save & Apply (bottom­right)

Now test using your favourite speed test application. The speed should be limited to whatever you wish, and all things behind the USB-­Ethernet adapter should behave a little bit better.

On my personal connection to the Internet (in the States), things are slow as compared to other, more progressively technological countries, so the shared Ethernet/USB bus doesn’t really seem to get saturated at all.

* Of course, the real answer lies somewhere in the future. OpenWRT already features modern techniques for minimizing network latency (see Smart Queue Management), aka bufferbloat.