Matt's Musings

October 9, 2006

Per Client VLANs with Madwifi

Filed under: Linux — matt @ 11:18 am NZST

I’ve written a patch for the madwifi-ng driver to separate each associated client into a unique VLAN. The patch only makes sense for use when the driver is in master mode being controlled by hostapd. Using this patch with WPA2/RSN you can acheive complete layer 2 isolation between associated clients. The patch does not support placing multiple clients in the same VLAN.

Full layer 2 isolation requires that there is no broadcast or multicast traffic transmitted from the access point. To enforce this the patch mangles outgoing broadcast / multicast packets to be directed only to the node associated with the VLAN that the packet was received from. Clients can still send/recieve broadcast and multicast traffic without problems if you bridge them onto another layer 2 network. You must fully understand the consequences of this before using the patch.

In the worst case scenario if you bridged the VLANs for each client together onto a common L2 network you will cause every broadcast/multicast packet sent onto that L2 network to be transmitted by the access point as a unicast packet to each associated client. If you have a lot of broadcast/multicast packets this is going to significantly reduce the performance of your network. This is a somewhat contrived situation as there is no point creating the VLANs in the first place if you’re just planning to bridge them back together, but I use it to illustrate the risks this patch can introduce if you don’t understand it properly.

At this stage I’m not convinced that the patch is actually useful, and I’m not going to be proposing it for inclusion in the driver. You’re welcome to use it if you find it useful. Please let me know how you are using it and any problems that you run into. I don’t guarantee that I can provide support or assistance though :P

The Patch

How the patch works
One of the primary constraints I had in writing this patch was that the clients using the access point are not required to do anything special. From their point of view they are simply associated to a standard AP running 802.1x with WPA2. There are no 802.1q packets “on the air”. All of the VLAN functionality is handled within the driver itself.

Inside the driver there is a node table listing every node that is associated. The patch adds an entry to each node record specifying a VLAN id for that client. By default this id is automatically assigned when a node associates, but it can be modified by wriiting to the /proc/net/madwifi/<iface>/sta_vlan file.

As packets are moved between the kernel and the actual physical card by the driver 802.1q tags are added and removed as appropriate to ensure that the kernel sees every node in it’s own VLAN.

The VLAN tagging code in the driver ignores EAPOL frames so that they are always sent to the base device where hostapd is listening.

Userspace Setup
By default per node VLANs are disabled and have to be explicitly enabled

echo 1 > /proc/sys/net/<iface>/per_node_vlan

And you almost certainly want to stop the driver from bridging packets between clients

iwpriv <iface> ap_bridge 0

Then it’s simply a matter of creating the appropriate VLANs on the base interface using the standard Linux VLAN tools, eg:

vconfig add <iface> 4

Final Comments
I’ve tested the code fairly extensive and it works fine for me. It’s not particularly clean and the mangling of broadcast/multicast packets is a messy hack. You can achieve a very similar situation using PPPoE from the client to the Access Point without having to patch the driver to support per node VLANs.

Powered by WordPress