userland traffic shaping
For more flexibility, we can pass all our network traffic through userland using tun and have an arbitrary program analyze and shape it. This setup requires a whole mess of virtual interfaces to be configured with ifconfig, but it’s really not so bad. We want to pass ethernet frames, so we use the link0 flag.
ifconfig tun0 create link0 ifconfig bridge0 create add em0 add tun0 ifconfig tun1 create link0 ifconfig vether0 create ifconfig bridge1 create add vether0 add tun1
Now we have a vether interface connected, via bridges and tuns, to the network. We configure this interface with our IP (run dhclient if you like), and it effectively replaces em0 as the primary interface. This is an endpoint configuration; vether can be replaced by a physical interface for a router. All that’s missing is a program to pass traffic between the two tun interfaces.
Here’s a short Lua (luajit) program. It reads from the two tun interfaces and passes packets between them as they arrive. As the amount of traffic passed approaches our five minute quota, it starts probabilistically dropping packets. As written it lets you use 75% of your quota at full speed before rather sharply curtailing it. (As a bonus, it will occasionally print a frequency count of each byte to demonstrate other uses.)
See also trickle.