Present Location: News >> Blog >> LTE Adventures: Part Two

Blog

> LTE Adventures: Part Two
Posted by prox, from Charlotte, on August 22, 2011 at 15:33 local (server) time

This is the second part of my LTE adventures blog series.  Don't worry, this is the last part.  Read part one here.

LG VL-600 (yes, again)

After playing with the Pantech UML290 until I was blue in the face, I decided that I wasn't going to get anywhere with IPv6.  I needed to backtrack.

Rather than getting rid of the UML290 (and probably paying some restocking fee among other things), I managed to snag a used LG VL600 from eBay for essentially peanuts, and threw in my SIM card.  Surprisingly, moving the SIM card actually worked.  Shocker, since this is Verizon we're talking about.  Just for the heck of it I checked my account, and it showed a picture of the VL600:

Verizon Device

I suspect the presence of a different ESN or IMEI automatically updated the device on my account.  Anyway, no hassle.

As expected, IPv6 worked again on OS X and Windows with the VZAM software.  So, giving up on IPv6 for a little bit, I turned my focus back to integrating the VL600 into my home network.

I picked up an ALIX.2D13 board and case to be used exclusively for the LTE connection in my condo.  After installing Debian (ok, not really installing, I cheated and dd'ed an existing install from one of my Soekris boxes onto the new CF card), I turned up routing and terminated a VPN on the LTE interface, providing a [fast] backup to my existing cable modem connection.  With a few tweaks, I was able to seamlessly move Internet and VPN traffic between my cable modem and the LTE connections.

Since I'm using Quagga and run BGP on my network, swinging VPN traffic is as easy as just swapping out a route map with a more appropriate one.  Moving IPv4 Internet traffic is more bumpy, since the source IP will change (double NAT, woot!), but is as simple as reloading the iptables script on my core router to policy route all traffic toward the ALIX box.  I still routinely hit the spoofing bug, since iptables will "leak" sometimes and spill a packet with an untranslated source out the LTE interface.  This is probably something I'll have to look into eventually, but for now I was happy.

I also put together a wrapper script to graph the signal strength from the VL600.  Other than the breaks, which are caused by me taking the modem on adventures to Panera Bread and other places, it seems to remain fairly constant:

Signal Strength

View the live graph here.

Fixing IPv6

Recently, I was getting annoyed with the lack of IPv6 on Linux with the VL600, and a bug cropped up in kernel 2.6.39 that nuked the VL600's functionality.  I sent an e-mail to Andrew Zaborowski, the original author of the VL600 Linux driver, and asked what he thought of the two problems.  Unfortunately, as his blog indicated, he was only in the United States on a trip, and wasn't able to continue development of the driver in Europe, where the VL600 serves only as a nice paperweight.

I managed to resolve the 2.6.39 problem fairly easily, as it was a one-line fix.

The lack of IPv6 support took some more thought, and lots of debugging, but I managed to figure it out.  The key ended up being a problem with the ethertype of the Ethernet frames containing IPv6 packets.  From Andrew's comments in the driver, I was well aware that the VL600 didn't follow the 3GPP specifications very well, but apparently this was just the tip of the iceberg.

I first changed the initial interface flags to enable multicast (IFF_MULTICAST), which can also be done at runtime:

ip link set dev wwan0 multicast on

After doing this, I immediately started seeing more packets in the tcpdump output:

22:31:50.840001 IP6 , wrong link-layer encapsulationbad-hlen 0
	0x0000:  6000 0000 0030 3aff fe80 0000 0000 0000  `....0:.........
	0x0010:  0000 0034 9471 d840 ff02 0000 0000 0000  ...4.q.@........
	0x0020:  0000 0000 0000 0001 8600 ed45 ff40 ffff  ...........E.@..
	0x0030:  0000 0000 0000 0000 0304 4040 ffff ffff  ..........@@....
	0x0040:  ffff ffff 0000 0000 2600 1004 b008 f951  ........&......Q
	0x0050:  0000 0000 0000 0000                      ........

However, they were broken.  The ethertype is 0x800 (IPv4) but the frame contains an IPv6 packet.  The ethertype should obviously have been 0x86dd, but it wasn't.  Wireshark was nice enough to ignore the ethertype, and provide a clean decode of the ICMPv6 router advertisement from Verizon:

Internet Control Message Protocol v6
    Type: Router Advertisement (134)
    Code: 0
    Checksum: 0xed45 [correct]
    Cur hop limit: 255
    Flags: 0x40
        0... .... = Managed address configuration: Not set
        .1.. .... = Other configuration: Set
        ..0. .... = Home Agent: Not set
        ...0 0... = Prf (Default Router Preference): Medium (0)
        .... .0.. = Proxy: Not set
        .... ..0. = Reserved: 0
    Router lifetime (s): 65535
    Reachable time (ms): 0
    Retrans timer (ms): 0
    ICMPv6 Option (Prefix information : 2600:1004:b008:f951::/64)
        Type: Prefix information (3)
        Length: 4 (32 bytes)
        Prefix Length: 64
        Flag: 0x40
            0... .... = On-link flag(L): Not set
            .1.. .... = Autonomous address-configuration flag(A): Set
            ..00 0000 = Reserved: 0
        Valid Lifetime: 4294967295 (Infinity)
        Preferred Lifetime: 4294967295 (Infinity)
        Reserved
        Prefix: 2600:1004:b008:f951:: (2600:1004:b008:f951::)

I was curious.  How could this work?  I ran a tcpdump on the VL600 when plugged into OS X, and it showed valid ethertypes for IPv6.  So, I connected the VL600 to a VM I have running Windows Vista, installed the VZAM software, and captured the USB traffic from the host OS (Linux):

21:23:05.494245 BULK SUBMIT to 1:29:2
        0x0000:  7800 0000 5d00 0000 0100 0000 0000 0000  x...]...........
        0x0010:  0000 0000 0000 0000 0000 0000 0000 0000  ................
        0x0020:  5000 0000 0800 6000 0000 0028 3a80 2600  P.....`....(:.&.
        0x0030:  1004 b005 726c 6699 5dff fef7 c054 2001  ....rlf.]....T..
        0x0040:  1998 2001 0301 0000 0000 0000 1002 8000  ................
        0x0050:  8bfe 0001 0001 6162 6364 6566 6768 696a  ......abcdefghij
        0x0060:  6b6c 6d6e 6f70 7172 7374 7576 7761 6263  klmnopqrstuvwabc
        0x0070:  6465 6667 6869 0000                      defghi..
21:23:05.494345 BULK COMPLETE from 1:29:2
21:23:05.563225 BULK COMPLETE from 1:29:3
        0x0000:  7800 0000 1b00 0000 0100 0000 0000 0000  x...............
        0x0010:  0000 0000 5354 4448 0000 0000 0000 0000  ....STDH........
        0x0020:  5000 0000 0800 6000 0000 0028 3a2f 2001  P.....`....(:/..
        0x0030:  1998 2001 0301 0000 0000 0000 1002 2600  ..............&.
        0x0040:  1004 b005 726c 6699 5dff fef7 c054 8100  ....rlf.]....T..
        0x0050:  8afe 0001 0001 6162 6364 6566 6768 696a  ......abcdefghij
        0x0060:  6b6c 6d6e 6f70 7172 7374 7576 7761 6263  klmnopqrstuvwabc
        0x0070:  6465 6667 6869 7333                      defghis3

(BTW, the Linux usbmon module and libpcap 1.1.x make it easy as pie to capture USB traffic - I just used tcpdump -i usbmon1)

Anyway, the above output was the result of me running a PING to an IPv6 host on the Internet from the VM.  Bytes 37 and 38 clearly show 0x800 as the ethertype.  Looks invalid to me, but the OS itself sees the right ethertypes.  I figured the driver must be peeking in the L3 header and changing frames containing IPv6 packets to have an ethertype of 0x86dd.  Why the heck is LG doing this?  It seems retarded, but after some trial & error, I got lg-vl600.c to perform the necessary conversions, as well, and it only took a few lines of code.

Things now seem to work properly, although I can't seem to get autoconfiguration to work on the wwan0 interface, but I can just statically assign the host ID for now:

(evolution:21:06)% sudo rdisc6 wwan0
Soliciting ff02::2 (ff02::2) on wwan0...

Hop limit                 :          255 (      0xff)
Stateful address conf.    :           No
Stateful other conf.      :          Yes
Router preference         :       medium
Router lifetime           :        65535 (0x0000ffff) seconds
Reachable time            :  unspecified (0x00000000)
Retransmit time           :  unspecified (0x00000000)
 Prefix                   : 2600:1004:b005:6a25::/64
  Valid time              :     infinite (0xffffffff)
  Pref. time              :     infinite (0xffffffff)
 from fe80::2f:82cc:ed40
(evolution:21:07)% sudo ip -6 addr add 2600:1004:b005:6a25::1000/64 dev wwan0
(evolution:21:07)% sudo ip -6 route add default dev wwan0
(evolution:21:08)% ping6 -c4 ipv6.google.com.
PING ipv6.google.com.(qy-in-x6a.1e100.net) 56 data bytes
64 bytes from qy-in-x6a.1e100.net: icmp_seq=1 ttl=50 time=88.1 ms
64 bytes from qy-in-x6a.1e100.net: icmp_seq=2 ttl=50 time=88.5 ms
64 bytes from qy-in-x6a.1e100.net: icmp_seq=3 ttl=50 time=83.8 ms
64 bytes from qy-in-x6a.1e100.net: icmp_seq=4 ttl=50 time=83.4 ms

--- ipv6.google.com. ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 83.480/86.024/88.579/2.375 ms

So, success!  I'll probably try to fix the autoconfiguration problem a little later, but I have a feeling it's something Linux sysctl-related rather than driver or network-related.

You can grab the patch here, for now.  I'll be opening up another kernel bugzilla ticket to get this into mainline in the next day or so, too.

Comment by Tommy on August 12, 2011 at 02:11 local (server) time

Hey Mark, i'm glad it finally came together, you never seem to give up, true hacker soul! :)


> Add Comment

New comments are currently disabled for this entry.