Tuesday, March 25, 2008

Enabling Quality of Service for the HDHomeRun

A few times recently, I've had problems where I was generating a large amount of bandwidth at the same time mythtv was recording a few HD programs from my HDHomeRun. The HDHomeRun transmits its data over the network via UDP instead of TCP, so when it ends up on the losing end of an oversaturated network, it's packets just get dropped and the data is never retransmitted. The end result is a lot of packet loss, and the recording will be full of skips and other corruption. Having damaged recordings is an unacceptable situation, and was something that I needed to resolve. Simply scheduling any heavy network activity around the recording schedule was not acceptable, either. I needed a better solution.

Upgrading the network

As it just so happens, I also had another problem at the same time. My home network had grown considerably, and I was now out of ports on my router and switch. I needed to add another switch to the network. In looking around, I found the D-Link DGS-2208 and it seemed to be both inexpensive and had very good reviews. It also had something else I found interesting...support for 802.1p Quality of Service delivery.

QoS on the HDHomeRun

When I saw 802.1p support in the feature list, something clicked in my mind. I remember reading once that the HDHomeRun could enable Quality of Service flagging on its packets. I figured that would be a great feature to enable, to ensure that the HDHomeRun got priority over other devices when the network starts getting saturated.

I figured it would be as simple as changing a setting in the HDHomeRun, and all data would be streamed with a QoS flag. Do that once, and it would be transparent to everything else. I promptly opened up a support ticket with Silicon Dust to find out how to do it. I got a prompt response back indicating how it could be done.

As I expected, the solution was quite simple. Simply pass an extra flag to hdhomerun_config when you tell it where to stream the data to. Instead of

hdhomerun_config FFFFFFFF set /tuner0/target "udp://"

it would be

hdhomerun_config FFFFFFFF set /tuner0/target "udp:// qos"

(note...the quotes in the parameter list are important so that the qos string doesn't get treated as a separate parmaeter).

I gave it a try and it worked. That was a very easy solution. However, there was a slight problem here. The way this was enabled meant that a patch would need to be applied to mythtv to enable this to happen each time it opened up the stream.

Patching MythTV

The patch to make this happen wasn't very difficult. There were only a few tiny changes that needed to take place. A single line of code could be used to accomplish this, except for the fact that 802.1p tagging is applied as part of the 802.1q standard for virtual LANs. This meant in order to QoS tag the packet, the packet had to be destined for a VLAN (the HDHomeRun uses VLAN 0).

By default, linux will ignore packets that are received for a VLAN unless it has been explicitly configured to do otherwise. This means that a quick and dirty patch to mythtv would break HDHomeRun functionality for anyone who doesn't have VLANs configured, as the packets from the HDHomeRun would never be handled. Obviously, this needed to be a feature that could be toggled on/off in the capture card setup of mythtv-setup. This made the patch just a tiny bit more complex, because it requires a schema change to the database so you have somewhere to store this flag. Regardless, I was quickly able to code up the patch. I'll release it soon, but I first need to run a few things by the mythtv-dev mailing list.

Enabling VLAN support under Debian

As I mentioned, linux ignores packets destined for VLANs unless explicitly configured to do otherwise. It turns out that configuring Debian to handle a VLAN wasn't all that difficult.

The first step was to install the vlan package ( apt-get install vlan ). Once that was done, you needed load the 8021q module ( modprobe 8021q ). Finally, you just needed to tell linux to accept packets for VLAN 0 on your adapter ( vconfig add eth0 0 ). Your network is now accepting VLAN 0 packets. This created an entry for eth0.0 under /proc/net/vlan/. If you view its contents ( cat /proc/net/vlan/eth0.0 ), it will give you network usage statistics for that VLAN.

That last thing you need to do is make sure your VLAN configuration survives a reboot. Simply create a script called /etc/init.d/vlan that runs your modprobe and vconfig commands. This script can then be run automatically when your eth0 interface comes up by adding the line "up /etc/init.d/vlan" to your /etc/network/interfaces file in the section for "iface eth0".

1 comment:

Tom said...

Can you provide me some info on where I can find a tutorial on the command line interface? I'm trying to do something similar with a Mac over 802.11n so I might need the QoS. Thanks for the great post.