Jaguar Portrait
Valid HTML 4.01 Transitional

Sony Vaio
Wireless Network

Jim Carter, 2014-04-09

I have several issues I had to deal with involving the wireless network.

No IPv6 Address

The first presenting symptom is that upon boot the laptop never gets an IPv6 address or default route. Strangely, this doesn't happen on the machines with wired Ethernet. The per machine firewall tosses packets in a weird conntrack state (invalid or untracked); it positively accepts only new, related and established. Apparently ICMP router advertisements and multicast listener queries were getting tossed. I speculate that incoming packets from 802.11 wireless are treated differently than from 802.3 wired Ethernet.

I put in a special case to accept packets (from anywhere) to the All Nodes multicast address ff02::1, and to the host specific multicast address, ff02:0:0:0:0:1:ff00::/104, which is to be followed by the last 24 bits of the host's IPv6 unicast address. (So the intended host will accept the packet, but very few others will be bothered, avoiding one of the bad features of ARP over IPv4 broadcast.) Now the laptop gets its RFC 2464 autoconfigured address and default route.

Wireless NIC Excluded From Bridge

The second major symptom is that the wireless NIC will not join the bridge device.

This laptop normally connects to the outside world via 802.11 WiFi (wireless networking in the 2.4GHz ISM band). 802.3 wired Ethernet is used when the maximum reliability is required or when higher speed is needed, but this is rare. On the old Xena with kernel 2.6.37, I had a network bridge whose members were the wired Ethernet (eth0), wireless (wlan0), and the virtual interface (virt0) of any virtual machine I was running. The virtual machine was directly on the host network and managed its IP address independent of Xena. This worked out well. However, with the current kernel 3.11.10 the bridge driver refuses to accept the wireless NIC, or the wireless driver refuses to be added to the bridge.

brctl addbr br0
brctl addif br0 wlan0
It says: can't add wlan0 to bridge br0: Operation not supported

I did strace; it opens a PF_LOCAL SOCK_STREAM socket, then does

ioctl(3, SIOCBRADDIF, 0x7fffa9427800) = -1 EOPNOTSUPP
ioctl(3, SIOCDEVPRIVATE, 0x7fffa9427800) = -1 EOPNOTSUPP

This error is thrown in /usr/src/linux/./net/bridge/br_ioctl.c . The SIOCDEVPRIVATE thing is deprecated and feeds into the same code for adding an interface. br_if_add() is defined in br_if.c and tests for dev->priv_flags & IFF_DONT_BRIDGE; the comment says "No bridging devices that dislike that (e.g. wireless)". So the problem is to be found in the wireless driver.

Looking in /usr/src/linux/net/wireless , I'm pretty sure it's building cfg80211.ko. In the function core.c cfg80211_netdev_notifier_call(), when the device is registered it tests wdev->iftype (mode of operation) for NL80211_IFTYPE_STATION, P2P_CLIENT, or ADHOC, and not wdev->use_4addr. In this case it turns on IFF_DONT_BRIDGE. In util.c cfg80211_change_iface() it turns on IFF_DONT_BRIDGE for the same types, but not for P2P_GO, AP, AP_VLAN, WDS or MESH_POINT. P2P_GO means the Group Owner in a WiFi Direct (peer to peer) network. We definitely aren't going to be in any of these modes. Conclusion: it isn't going to let the NIC join the bridge without some hacking that actually breaks a clearly intentional design decision.

I've seen one explanation, not too clear, that the 802.11 spec states that the client should only send to the AP's MAC address, not to the MAC address of some object that it has not personally authenticated to. Of course this makes bridging impossible.

This calls for a tunnel, which can be bridged. But from where and to where? I was not able to figure that out; see below for the progress I made, such as it is.

Instead I sabotaged the places where cfg80211.ko turns on IFF_DONT_BRIDGE. This was effective and the wireless NIC is now able to join the bridge.

NetworkManager Restarts Network Every 10 Minutes

Very annoying: about every 10 minutes the wireless disconnects and takes about 30 seconds to re-establish the connection.

In syslog the kernel reports: wlan0: deauthenticated from 90:f6:52:ea:18:da (Reason: 2). Here is a link to a list of reason codes: Reason 2 means Previous auth no longer valid. Searches on Google reveal that a number of people report this symptom of wireless disconnection at various regular repeating intervals. Interventions on the client always fail, except for (only) one person who avoided failures while a media playback node originated traffic to his wireless box that had media storage. In the successful fixes, the finger of blame points to the access point.

I am running hostapd on my gateway. Simultaneous with the disconnects, other stations finish a group re-key (without needing full reauthentication). So I put this Band-Aid on the problem, successfully. In /etc/hostapd.conf I added:

wpa_group_rekey=86400
wpa_strict_rekey=0

The group key is the one used for broadcast and multicast packets sent to the whole group (BSS). The first parameter is the interval in seconds between group rekey events; the default is 600 secs, which is my former disconnect interval. The second one, if set to 1 (the default), tells it to re-key whenever a station leaves the BSS, whereupon it could reveal the group key to hostile hackers. (Of course, a station with jiggered firmware could also reveal the group key before leaving the BSS.) These changes weaken security, but I use encrypted protocols on the wire, and an aggressive firewall on each host, so I judge that in my situation, when balancing security versus useability, security should not win this one.

All the Android, Windows and IOS (Apple) wireless stations manage to replace the group key without doing a full reauth, and I think the problem probably resides in NetworkManager, or possibly in the wireless driver stack. In any event, I'm calling it a bug.

Tunneling for Fun and Profit

I had the idea to put one end of a tunnel in the bridge, and to somehow connect the other end to or through the wireless NIC. But I was unable to figure out any working combination. The following discussion is kept for historical interest, and in case in the future I can make progress on it.

Let's be clear on the goals for the tunnel:

Now let's try to design the networking.

Can we cheat? Create a tap device. Add to the bridge. A daemon reads/writes raw packets on wlan0 and copies them to/from tap0. Will this work? See Net::RawIP and/or Net::Write. Net::Pcap or Net::PcapUtils is for capturing (reading) raw packets. Probably better to write actual code rather than messing with Perl.

Is it possible to create a tunnel to ourself? The local tunnel endpoint can then be in the bridge. The idea is that the remote endpoint is going to be routed through the wireless NIC. But making that happen sounds kind of weird and likely impossible.

(As of 2014-04-20 the bridge network is turning into a time sink and I'm going to defer it. Actually the best strategy is going to be to sabotage cfg80211.ko to not turn on IFF_DONT_BRIDGE. )

Jaguar Portrait