Tuesday, December 31, 2013

OpenWrt plus AirPort Extreme Guest network

The Apple AirPort Extreme comes with a great feature, which is Guest networking. If all you want is an AirPort, you can easily click a few check boxes and have a Wifi network that you can share with guests.

But what if you want to do more? What if you want to have an Ethernet port for that guest network? What if you've reached the limits of the AirPort and you want to run something where you can see what's going on in your network? Or control and shape traffic? Or prove that your ISP is dropping packets all the time?

You probably want to run a variant of DD-WRT. Nowadays it seems that the best supported variant with the best features is OpenWrt. Also, you want to run it on inexpensive hardware that can Do More.

AirPort Guest Network Details

The AirPort Guest network is pretty straightforward:
  • A separate wireless SSID (that you choose).
  • A separate IP subnet and gateway (172.16.0.xxx) with DHCP service.
  • A VLAN (1003) that each guest network packet is tagged with (I got this info from this Apple Support Communities thread from user Dennypage, but you should be able to figure it out via tcpdump on your OpenWrt router.).
The first two are obvious in the AirPort UI. But what's not obvious is how this guest network is communicated between multiple AirPorts when one is the router and the other(s) are in bridge mode. What happens is that the guest VLAN is tagged with 802.1Q VLAN tags on VLAN 1003. In this way, the nodes on your internal network doesn't see (unless it really wants to) the guest network traffic. And the nodes on the guest network cannot ever see the internal network traffic.

Now why are these details important? If you want to have a router that replaces your AirPort Extreme(s), but still use its Guest network feature, that router is going to have to serve a Guest network on VLAN 1003.

Hardware Selection

You have to have hardware to run OpenWrt, and the selection of supported hardware is quite extensive. However, you can narrow down what you're looking for, because it sure would be nice if you could have different VLANs (tagged and untagged) on different switch ports. This is possible if you select hardware that supports Port-based VLANs. These seem to all be Broadcom based hardware in the consumer router world. I chose an Asus RT-N16 at Fry's; it seemed reasonably priced, Gigabit Ethernet, and supported Port-based VLANs. It doesn't do 802.11ac, but I'm not concerned about that. Up to you what you want to do, of course.

OpenWrt Installation

I managed to install the latest trunk snapshot of OpenWrt on my Asus RT-N16. It had to be somewhat recent to support the new hardware in it. But you should follow the installation guide for OpenWrt appropriate to your hardware. In addition to the core OpenWrt software, I installed LuCi, to make things easier.

Guest Network Configuration

For the most part your should follow the OpenWrt guide to configure a guest WLAN. That will get you almost all of what you want. But you will have to do things a little differently...

Create a Switch configuration with Guest network VLAN

Before following the instructions on creating an Interface, you'll need to have a Guest VLAN. Do that by accessing the Network -> Switch menu in LuCi.

There you will see that VLAN ID 1 is used for your "internal" or NAT'd network. VLAN ID 2 is used for the WAN network.

You are now going to create VLAN ID 1003, which is going to be your Guest network VLAN. Once it's done, your switch configuration should look something like this:

In this diagram, Port 0 is the WAN port. That's why VLAN ID 2 is "untagged" on that port, and it's the only VLAN on that port.

Port 4 (which happens to be labelled Port 1 on the Asus RT-N16) is the switch port that I am using to connect my AirPort Extreme(s). Therefore I've configured it to carry VLAN ID 1 "untagged," and VLAN ID 1003 "tagged."

Port 3 and Port 2 are "Guest network" ethernet ports that visitors can use at any time to get on the Guest network, not my internal network. You can see that they are "untagged" so that they "just work" as a regular untrunked Ethernet port. At this point, physical security is your main concern, and I leave it up to you to label your ports and control who plugs into what.

Create a Guest network bridge

The recipe above has you create a WLAN, which is all that's needed to create an interface. But when you follow the recipe, you'll want to select "Create a bridge over multiple interfaces":

Then select both the WLAN network you created in the recipe, as well as the VLAN interface you created above:

Now proceed with the rest of the recipe.


Once you've completed the recipe, connect a machine to the AirPort guest network (not the OpenWrt guest WLAN) and see if you get an address in the 192.168.3.xxx range (or whatever range you configured for your guest network).


Obviously you don't have to stop here; you can create a separate Game network or other type of network on your router, and support a mix of Ethernet and Wifi nodes on the network. Up to you. But if you use AirPort Extreme for your Wifi, you will be limited to two networks (untagged and tagged 1003) .

Monday, April 8, 2013

Emacs keyboard delay when switching frame focus

I recently ran into an annoying issue with Emacs; I'm not sure what initiated this problem, but it might be that the default value of focus-follows-mouse changed. Or Ubuntu changed.

Here's the issue that I was seeing:

  • I have multiple Emacs frames, and I like to switch between them often.
  • Switching between them by using Alt-Tab, or clicking, would result in no problems.
  • However, using the interactive function other-frame (via a keybinding) results in a problem that there's an approximately 2 second delay from switching focus to when the keyboard would accept input again. Even worse, Emacs seems to have forgotten what modifier keys I had down, so when it did accept keyboard input, it wouldn't know that I still had the control key held down.
I tried various ways of debugging this to see if anything was going on (xev, strace) but ultimately I figured it out by reading M-x describe-function other-frame. That reveals the following text:

To make this command work properly, you must tell Emacs
how the system (or the window manager) generally handles
focus-switching between windows.  If moving the mouse onto a window
selects it (gives it focus), set `focus-follows-mouse' to t.
Otherwise, that variable should be nil.

When I M-x describe focus-follows-mouse, it shows t, which is wrong. So I instead added the following to my .emacs:

(setq focus-follows-mouse nil)

and now everything is back to normal. Why did that setting break things? Not sure. Maybe Emacs didn't call something it should have called assuming X would take care of it. Or the other way around. Anyhow, it's much better now.

Some details on my setup:
  • Ubuntu 12.04 Precise Pangolin
  • Emacs 23.3.