Stupid OpenWRT ipv6 tricks

So, if you’re like me you find yourself wondering why your broadband provider has a /32 IPv6 prefix assigned, and yet chooses not to use it, forcing one to either be IPv4-only (how 20’th century) or use an IPv6-over-IPv4 tunnel solution.

Fortunately there is a simple and free solution out there, courtesy of Hurricane Electric’s rather fabulous tunnelbroker service. Obtaining an IPv6 prefix and setting up the tunnel is covered, extensively, so I won’t go into it. It’s also rather easy to set the tunnel up on an OpenWRT based router, like mine. The default setup is rather nice, but there are some changes you can make to your router configuration that will make it even nicer.

Remove the “ULA Prefix”

OpenWRT creates, by default, a ULA prefix — a deprecated “site-local” prefix. While these are perfectly valid, I’ve found that non-globally routable IPv6 addresses tends to confuse the heck out of Android-based phones, resulting in certain operations taking forever while various network operations time out, and are then retried with globally routable addresses. They’re also pointless, as we don’t do IPv6 NAT (don’t even think it), so just remove it. Your phone will thank you.

A note about firewalls

It’s worth repeating: we don’t do IPv6 NAT. Assuming you’ve removed the ULA prefix, every non-link-local IPv6 address assigned will be globally routable, meaning, among other things, that you can’t just rely on NAT to be your firewall, you’ll actually have to use your router as a firewall as well.

This is also well documented, and left as an exercise for the reader. …one I rather suspect you’ve already completed, as, well, you’re using OpenWRT, aren’t you?

More than one network? Get a /48!

By default, HE will give you a /64 routed prefix: this is the pool of addresses your LAN-connected devices will draw from. If you ask — that is, hit the “assign /48” button on your tunnel’s configuration page — HE will also give you a /48. Why would you do this? Well, while you can subdivide your /64 up and route it however you want, most IPv6 tech presumes the smallest network it will ever encounter is a /64. If you choose to, say, make your wired and wireless networks distinct and route rather than bridge between the two the canonical approach is to use one /64 for the wired network, and a second, different /64 for your wireless. (The same logic applies if you wish to also delegate prefixes to hosts on your network — say a /64 to some box you have running a bunch of VM’s or docker containers on.)

But how to set this up easily? Remember that “ULA prefix” option, above? Just put the /48 prefix HE assigned you in there, and everything will Just Work. Delegating specific /64’s to interfaces can be done with “hints” in the interface configuration, and each internal interface will receive a /64 from your /48 automatically.

Yes, this means at least one of your internal networks will have two /64 prefixes addresses can be assigned/chosen from. Don’t sweat it: your device should pick up an address from each /64, and things will Just Work.


OpenWRT uses dnsmasq to provide DNS, and because of this we can do some neat things. If you edit your /etc/dnsmasq.conf appropriately, you can get:

Hostnames for the ips assigned to our interfaces, automatically

# hostnames for our interface ips!


$ host lan.router
lan.router has address
lan.router has IPv6 address 2001:470:XXXX:1::1
lan.router has IPv6 address 2001:470:1f11:XXXX::1

“Synthetic” hostnames

That is, a deterministic hostname for every ip on a given subnet that dnsmasq doesn’t already know a hostname for.

# Apparently /48 breaks dnsmasq more than a bit


$ host 2001:470:1f11:XXX::2 domain name pointer 2001-470-1f11-XXXX--2.ip.lan.

Note this “synthetic hostname” will only be returned if dnsmasq lacks a better name, e.g.:

$ host 2001:470:1f11:XXX::1 domain name pointer lan.router.

AAAA records

While OpenWRT does not use dnsmasq for router advertisements, we can still use it’s rather nifty “match info from DHCPv4 requests against the DID/MAC the device would use for SLAAC” functionality to enable it to return both A (IPv4) and AAAA (IPv6) records when asked for an internal hostname:

$ host mfc.lan
mfc.lan has address
mfc.lan has IPv6 address 2001:470:...
$ ping6 mfc.lan
PING mfc.lan(mfc.lan) 56 data bytes
64 bytes from mfc.lan: icmp_seq=1 ttl=64 time=0.490 ms
64 bytes from mfc.lan: icmp_seq=2 ttl=64 time=46.5 ms

Enable with the somewhat cryptic:

# serve AAAA records based off DID/MAC and DHCPv4 requests

…or some permutation thereof, if you’ve altered the topology of your internal network.

Strip AAAA records for Netflix

Sigh. Yes, apparently we need to do this. Lame. Basically, Netflix thinks it doesn’t know where you are located, so will refuse to serve content to any address that HE has delegated to you via tunnelbroker (e.g. your /64, /48). Fortunately, this is a problem others have already elegantly resolved: OpenWRT workaround against Netflix blocking IPv6 requests from tunnel brokers.

Basically, the solution is to build and install a bind package that supports the strip-aaaa option, then have dnsmasq delegate any lookups for * to the bind server. Clean, simple, and easily extensible to any other service that may choose to do the same thing in the future.

With this hack in place, without impacting any other domain your lookups will go from this:

$ host
Using domain server:
Aliases: has address has address has address has address has address has address has address has address has IPv6 address 2406:da00:ff00::34cf:6f90 has IPv6 address 2406:da00:ff00::34ca:21dd has IPv6 address 2406:da00:ff00::34c8:ef2b has IPv6 address 2406:da00:ff00::36a4:da76 has IPv6 address 2406:da00:ff00::34ce:44b0 has IPv6 address 2406:da00:ff00::3655:55f6 has IPv6 address 2406:da00:ff00::34cb:53f8 has IPv6 address 2406:da00:ff00::34cd:591a

…to this:

$ host has address has address has address has address has address has address has address has address

These are little things, yes (hence the “stupid … tricks” appellation), but every little bit helps when trying to figure out a problem.

…or, you know, appease Netflix 🙂


Currying patterns

One of the most dangerous books I’ve ever even partially read is MJD’s Higher Order Perl. In particular, its description of subroutine currying — that is, building more specific functions out of more general purpose ones — is a pattern I find incredibly useful.

The other day I found myself writing a number of routines that were surprisingly similar… kinda. They all implemented a common pattern, but across routines that were rather… different. I found myself wistfully longing for the familiar pattern of currying, and then realized — I’m working in PERL, DAMNIT.

This is part of recent work of mine, extending Test::Moose::More to use subtests where they make sense. Here I was able to curry one function — _validate_subtest_wrapper() — by passing it a reference to another function, that it then invokes.

Excellent. Life is easier, as it should be.

easy command-line compiz settings import and export

One thing I dislike about setting up any new machine is how many places I have to poke compiz to get it to behave in the manner to which I am accustomed (e.g. widget layer enabled; sloppy focus (the One True Focus); viewport grid with names and quick-jump hotkeys; etc, etc). One can use compiz-settings-manager to do a manual import of settings (that one has hopefully exported — also manually — from another machine setup the way one likes it), but that gets… tedious.

Enter this nifty little question and answer! Note that there are two scripts: one for export and one for import.

Using these scripts to set up a cron-driven auto backup is left as an exercise for the reader. 🙂

Intel 7260AC Bluetooth [8087:07dc], Ubuntu, and the Thinkpad T440p

This requires a little magic, unfortunately; either the driver, system, hardware itself, or some combination thereof do not operate well with autosuspend enabled. Disabling autosuspend for this device does appear to resolve dropped / corrupted / weird bluetooth issues.

Based on my googling, I do not believe this to be Thinkpad-specific, rather something the Intel 7260AC firmware isn’t handling properly at the moment. FWIW, I’m running Ubuntu 13.10 (saucy) on the thinkpad in question, and 12.04LTS (precise) on my destop, with the same card sold by Intel in a PCI-e mount.

Based on one posting in particular, the following solution presents itself:

This isn’t ideal — as it should Just Work — but it works, and is certainly less drastic than turning off USB autosuspend globally. In retrospect, having the bluetooth device drop out shortly after boot/resume, but always be available after resuming, was a big clue.

docker without password prompting

Just a little snippet.  This should be pretty obvious to those familiar with how sudo functions, but it’s easy to run docker commands with sudo without being prompted for your password by configuring sudo to not ask for it.

Note that the normal warnings and red flags apply here.

If you install the above as /etc/sudoers.d/docker, then the user rsrchboy (line 1) and any user in the docker group (line 2) will not be asked for a password when running “sudo docker …”.

Again, the normal warnings and red flags apply here.

Useful git defaults — systemwide

Sometimes it’s necessary to — for one’s sanity, if nothing else — to establish a set of generally non-controversial, sane, system-wide git configuration defaults. This is largely helpful when multiple people are using the same system who may not have a standard ~/.gitconfig they carry around with them.

To do this, we can leverage the little-used system-wide git config file at /etc/gitconfig. Remember that by default git looks at three files to determine its configuration: /etc/gitconfig (system), ~/.gitconfig (user aka global), and .git/config (configuration for the current repository); settings closer to the user win. This allows us to set defaults in the system configuration file without interfering with people who prefer different settings: their global config at ~/.gitconfig will win.

This config sets a couple safer defaults for pushing, makes git merge/diff/rebase a little more DWIM, causes the committer, as well as the author, information to be displayed by default, as well as allowing for an easy way to override the system config on a per-system basis. (In case, say, you’re using puppet or the like to distribute this configuration across multiple hosts.)

And… As with all things “generally non-controversial”, remember that these are the sorts of things likely to touch off religious wars. The goal here is for a sane set of defaults for all users, not The One True Way To Do GIT. That’s what user global configs are for 🙂

screen, vim, tabs, and C-PgUp/C-PgDn mappings

I use screen with vim. One of the things I like about vim is that, much like unix itself, I’m always discovering useful new features, even after years of use.

Recently, I’ve been using tabs in vim to complement window regions. I’ve found it pretty useful, as there are times I’d want to keep certain tasks on one tab but not another. e.g. different source files open in windows on one tab; a test file + vim-pipe buffer showing the rest.

While I’m not using screen to change between multiple vim sessions in the same project anymore, I still use it pretty much everywhere: it’s there, and sometimes a wireless network isn’t. (Or you’re working one place and need to pack up and move to another place.) screen preserves your working sessions, so you don’t have to get everything “just right” again.

Unfortunately, screen seems to mangle the C-PgUp and C-PgDn commands vim gives as default (right?) shortcuts to switch between tabs. Leaving out that these key sequences are also used at the windowing level to switch tabs, it turns out that screen was mangling them on the way through to vim, so vim didn’t see C-PgUp, for instance, it saw some other sequence.

Adding this to your ~/.vimrc will cause vim to recognize the sequence it sees when running under screen:

My first YAPC::NA!

I’m in lovely Madison, WI right now, and will be headed over to my first YAPC::NA tomorrow. The first couple days are the hackathon, at which I think I’m going to work on a Dist::Zilla stash to hold repository related information. There are a bunch of Git related plugins for Dist::Zilla, a couple that I maintain, and a lot of code is duplicated between them; a stash should resolve that.

I hope to meet you all there! 🙂