Thursday, December 13, 2012

BGP Redistribution Redo

I've always been weary of redistributing an IGP into BGP rather than using explicit network statements. Sure it automates the process, but if I'm going to be redistributing BGP into the IGP (say for MPLS CPE) - hopefully with a 'route-map' - there is a potential for funky redistribution loops and issues. Better to break the cycle and statically configure BGP with 'network' statements to explicitly advertise only what you want.

Of course, I'll break my own rules in the name of testing or in this case, a lab exercise. I'm in a Cisco IPv6 training class and our BGP routing lab instructed us to:

"Configure IBGP between R1 and R2 using the parameters that are listed in the table."

ParameterR1R2
SourceLoopback 1Loopback 1
Redistribute into BGPIPv6 Connected
Set origin IGP
IPv6 Connected
Set origin IGP

The original configuration was pretty straight forward. EIGRP was used as the IGP to which we were to add BGP. EIGRP was already advertising the connected routes so the EIGRP admin distance was modified so IBGP would be preferred. I was already cringing, but decided to play along.

The relevant parts of the provided R1 configuration follow. You can assume R2 was identical with the appropriate corresponding addresses for interfaces and peers.

interface Loopback1
 ipv6 address 2001:DB9:121:100::1/64
!
interface Loopback2
 ipv6 address 2001:DB9:121:200::1/64
!
interface Serial0/0/0
 no ip address
 encapsulation frame-relay IETF
 frame-relay lmi-type cisco
!
interface Serial0/0/0.1 point-to-point
 description To R2
 ipv6 address 2001:DB9:123:1::1/64
 ipv6 eigrp 1
 frame-relay interface-dlci 122
!
ipv6 router eigrp 1
 eigrp router-id 10.12.1.1
 no shutdown
 passive-interface Loopback1
 passive-interface Loopback2
 distance 250 255

At this point, the BGP configuration was pretty easy. I added the following:

router bgp 65012
 bgp router-id 10.12.1.1
 no bgp default ipv4-unicast
 bgp log-neighbor-changes
 neighbor 2001:DB9:122:100::1 remote-as 65012
 neighbor 2001:DB9:122:100::1 update-source Loopback1
 !
 address-family ipv6
  neighbor 2001:DB9:122:100::1 activate
  redistribute connected route-map BGPCONN
  no synchronization
 exit-address-family
!
route-map BGPCONN permit 10
 match source-protocol connected
 set origin igp

It's no surprise that BGP came up and all was working. From R1:

W1P2R1#show bgp ipv6 unicast summary
BGP router identifier 10.12.1.1, local AS number 65012

Neighbor    V       AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
2001:DB9:122:100::1
            4   65012    1027    1044     47   0    0 00:02:05 4

And I could see my R1 routes on R2:

W1P2R2#show ipv6 route 2001:db9:121:200::/64
Routing entry for 2001:DB9:121:200::/64
  Known via "bgp 65012", distance 200, metric 0, type internal
  Backup from "eigrp 1 [250]"
  Route count is 1/1, share count 0
  Routing paths:
    2001:DB9:121:100::1
      Last updated 00:00:59 ago

But a subsequent 'show' command revealed an issue:

W1P2R2#show ipv6 route 2001:db9:121:200::/64
Routing entry for 2001:DB9:121:200::/64
  Known via "eigrp 1", distance 250, metric 20640000, type internal
  Route count is 1/1, share count 0
  Routing paths:
    FE80::219:55FF:FE35:1B90, Serial0/0/0.1
      Last updated 00:00:00 ago

The route was no longer learned via BGP, but through EIGRP. Weird. The previous command shows the admin distance was correct; iBGP [200] should be preferred over EIGRP [250 - modified]. What was happening?

I did the "up-arrow, enter" troubleshooting technique; that is, I ran the previous 'show ipv6 route ...' command over and over. Of course it worked. I noticed the "Last updated" timer reset every minute as the route flip-flopped between EIGRP and BGP. I started thinking about the BGP walker process and how it runs every 60 seconds.

Since we were in a lab, I had no issues with running 'debug bgp ipv6 unicast updates' on R2 and verified my instinct was correct.

*Dec 13 15:05:50.176: BGP(1): no valid path for 2001:DB9:121:1::/64
*Dec 13 15:05:50.176: BGP(1): no valid path for 2001:DB9:121:100::/64
*Dec 13 15:05:50.176: BGP(1): no valid path for 2001:DB9:121:200::/64
*Dec 13 15:05:50.176: BGP(1): no valid path for 2001:DB9:121:300::/64
*Dec 13 15:05:50.196: BGP(1): nettable_walker 2001:DB9:121:1::/64 no best path
*Dec 13 15:05:50.196: BGP(1): nettable_walker 2001:DB9:121:100::/64 no best path
*Dec 13 15:05:50.196: BGP(1): nettable_walker 2001:DB9:121:200::/64 no best path
*Dec 13 15:05:50.200: BGP(1): nettable_walker 2001:DB9:121:300::/64 no best path

*Dec 13 15:06:50.220: BGP(1): Revise route installing 2001:DB9:121:1::/64 -> 2001:DB9:121:100::1 (::) to main IPv6 table
*Dec 13 15:06:50.220: BGP(1): Revise route installing 2001:DB9:121:100::/64 -> 2001:DB9:121:100::1 (::) to main IPv6 table
*Dec 13 15:06:50.220: BGP(1): Revise route installing 2001:DB9:121:200::/64 -> 2001:DB9:121:100::1 (::) to main IPv6 table
*Dec 13 15:06:50.220: BGP(1): Revise route installing 2001:DB9:121:300::/64 -> 2001:DB9:121:100::1 (::) to main IPv6 table

BGP on R2 put the routes for the advertised R1 connected interfaces - including the network containing the address for the R1 Loopback1 interface it was peering with - into the routing table. The routes had a next hop of the R1 Loopback1 interface. When these routes entered the routing table, they displaced the EIGRP routes for the same networks. A minute later when BGP walker ran again, there was no IGP (EIGRP) path to the next hop for those routes, so BGP removed them (as seen in the first 8 lines of the 'debug'). The routes were quickly replaced with the EIGRP routes as seen in the above "show ipv6 route ..." commands. Sixty seconds later when BGP walker ran again, the BGP routes were learned and now had a valid next hop as the IGP routes were in the routing table and BGP introduced the same routes - as seen in the last 4 lines of the above 'debug'. Every sixty seconds this repeated and flip-flopped the routes between EIGRP and BGP.

Knowing the problem, the fix was easy. Just use the existing 'route-map' to block the Loopback1 network from being advertised as a connected route. On R1, I used:

route-map BGPCONN deny 5
 match ipv6 address PEER
!
ipv6 access-list PEER
 permit ipv6 2001:DB9:121:100::/64 any

The complementary statements on R2 and a 'clear bgp ipv6 unicast *' had everything working perfectly!

The lesson learned just reinforced my original statement regarding redistribution - proceed with caution.

Friday, December 07, 2012

Testing DHCPv6

I've been doing some research into DHCPv6 for a client and beyond the talk and text, I needed some hands on testing. I can create a DHCPv6 server on a Cisco router in GNS3, but who knew creating a DHCPv6 client would be so troublesome.

I suppose I could have just used my Windows 7 x64 host and connected to the GNS3 simulation on a loopback interface. I've done this before, but I was looking for a way to do this in the simulation. I took a look at the Tiny Core 3.8.2 linux Qemu image available on the GNS3 appliances page and gave it a go. Unfortunately, Tiny Core uses 'udhcpc' as the DHCP client and it only supports IPv4. Partial success.

I had a look at Tiny Core and found that you can load packages and one package was the ISC DHCP package version 4.2.1 including client, server and relay. According to their website, 4.2.1 supports IPv6 so I thought I'd pursue.

The first step was to get the ISC DHCP package installed. Tiny Core comes with a package manager; however, you need to be online to use it and I hadn't played with the Qemu emulator (to run Tiny Core) outside of GNS3. To get network access, Qemu needs a TAP interface, which isn't available on Windows. I had to get one.

OpenVPN offers Windows software that comes with - among other things - a TAP interface driver. So simply download the latest Windows intstaller and run it. Luckily, it asks what components you'd like to install. I unchecked everything except for the Tunnel TAP interface driver. Once the install was completed, I had a new interface under Network and Sharing Center - Adapters, which I renamed to "TUN-TAP".

Simply select my physical NIC - in my case my wireless card - and the new TUN-TAP interface, right-click and select "Bridge Connections".

Armed with my new interface, I was able to launch Qemu and get Tiny Core online to add the proper packages:

C:\> qemu -hda linux-tinycore-3.8.2.img -net nic -net tap,ifname=TUN-TAP

Once loaded, I used the AppBrowser, pressed the "Connect" button and the available packages loaded. I used the search to look for "dhcp" and found "isc-dhcp.tcz". I selected "OnBoot" and pressed "Go". It installed the prerequisites and finished.

Next, I had to change Tiny Core to use 'dhclient' instead of 'udhcpc' and make the change permanent over reboots. First, I edited the "/etc/init.d/dhcp.sh" file. I commented out the line with 'udhcpc' and added two new lines after it:

/usr/local/sbin/dhclient    -sf /usr/local/sbin/dhclient-script $DEVICE >/dev/null 2>&1 &
/usr/local/sbin/dhclient -6 -sf /usr/local/sbin/dhclient-script $DEVICE >/dev/null 2>&1 &

That will load 'dhclient' (ISC DHCP client) instead of 'udhcpc' and it will do it for all interfaces and for both IPv4 and IPv6.

Finally, to make the change permanent, I edited the "/opt/.filetool.lst" file. I removed the line with "/sbin/dhclient" and replaced with:

/etc/init.d/dhcp.sh

and then ran 'filetool' and did a "Backup". Curiously, I got an error saying the backup failed, but examining the "/mnt/hda1/tce/mydata.tgz" file, I found the "/etc/init.d/dhcp.sh" file with my edits. So, I shutdown and restarted and hoped for the best.

It worked! I verified 'dhclient' was running instead of 'udhcpc':

tc@box:~$ ps -ef | grep dhc
 1562 root     /usr/local/sbin/dhclient -sf /usr/local/sbin/dhclient-script eth0
 1699 root     /usr/local/sbin/dhclient -6 -sf /usr/local/sbin/dhclient-script eth0
 1762 tc       grep dhc

The final test was to check DHCPv4 and DHCPv6 functionality in the GNS3 simulation. I had a 7200 series router configured as a DHCPv4 and DHCPv6 server and connected a Qemu host with the newly updated Tiny Core image. The host booted in the simulation and got both an IPv4 and IPv6 address. This was verified on the router by looking at:

R1>show ip dhcp binding
Bindings from all pools not associated with VRF:
IP address      Client-ID/          Lease expiration       Type
                Hardware address/
                User name
10.100.104.17   00ab.298c.3e00      Dec 07 2012 03:48 PM   Automatic
R1>show ipv6 dhcp binding
Client: FE80::2AB:29FF:FE8C:3E00
  DUID: 000100011855208300AB298C3E00
  Username : unassigned
  IA NA: IA ID 0x298C3E00, T1 43200, T2 69120
    Address: 2001:DB8:A64:6800:9D60:EF10:536A:28BF
            preferred lifetime 86400, valid lifetime 172800
            expires at Dec 09 2012 11:47 AM (172618 seconds)

The one thing to remember is that Qemu doesn't save any changes to the actual image file when in a GNS3 simulation. All changes are saved to a FLASH disk in the working directory. If that file or directory is removed, the Qemu host is back to defaults. I learned this the hard way the first time through. The answer is to load any packages and make any edits by running Qemu itself - as shown in the first command of this post - and then using the updated image in the GNS3 simulation.

NOTE: You can do the same for Micro Core linux by using the command line AppBroswer 'ab' and using the 'filetool.sh -b' command to commit the changes.

Wednesday, December 05, 2012

Smartphone Snacks

Last night I fed my AT&T Samsung Galaxy S3 some jelly beans - that is, the Android 4.1 Jelly Bean update. AT&T / Samsung announced availability earlier this week. However, they also said there would be no over-the-air update. So this was a manual process - first installing Kies from Samsung.

The Kies install on Windows 7 x64 was kludgy. I started the install and it kept looping at "Installing Hotfix". I pressed "Cancel" and it warned me it hadn't completed the install and asked for a confirmation. I canceled that and allowed the install to continue and that seemed to skip out of the loop as the install proceeded and completed successfully.

The next step was to connect my GS3 to the computer with USB and Kies recognized it. I got a pop-up for the new firmware update and allowed it to go forward. A few confirmations and a very slow loading and update process followed. But again, SUCCESS!

I've only been exploring / using Jelly Bean for a few hours but it seems nice and smooth. I see I have an explicit "Driving Mode" (although I don't know what it does) even though I already side-loaded Google Car Home. I already had loaded Chrome as my default browser so that remained. I didn't like that the Accounts under "Settings" are now all listed in the main Settings menu rather than a sub menu. The previous sub menu had an icon regarding sync status for each account. Now you need to click into each account to see the sync status.

I haven't had a chance to try IPv6 yet. Previously, I would get IPv6 addresses via SLAAC on my home network, but I didn't have access to the IPv6 Internet. I'll do some testing in the next few days when I find the time.

Tuesday, November 27, 2012

IPv6 over IPv4-only MPLS with 6to4

Last year, I researched, created and presented training on 6VPE technology for our internal consultants. Passing IPv6 routes and traffic over an IPv4-only MPLS network is a problem. 6VPE solves that problem from a carrier perspective allowing the MPLS carrier to provide dual-stack IPv4 and IPv6 at the LAN side interface of the customer edge devices.

But what if your MPLS provider has not rolled out IPv6 support?

I knew you could use tunnels to solve this problem from a client perspective. Further, configuring static tunnels in a full mesh over MPLS would be an awful management burden so automatic 6to4 tunnels could address that. However, I never pursued it further.

Recently, a question about this came up again and forced me to reconsider. Some research yielded Dynamic Routing Over 6to4 Automatic Tunnels which describes how to enable dynamic routing over 6to4 tunnels using BGP - specifically external BGP (eBGP). However, the article doesn't consider an MPLS backbone. I did some testing and it turns out it's not that hard to adapt this concept to an IPv4-only MPLS backbone.

Assume the following scenario:

  • MPLS provider offers IPv4-only MPLS VPN access for customers
  • Customer A wants IPv6 access
  • Customer A has many remote sites so solution must be scalable

Since Customer A wants IPv6 access and the provider doesn’t offer it, the first step is for Customer A to configure tunnel endpoints on each of the remote sites. Static tunnels such as 6in4 will require n(n - 1) tunnel endpoints – essentially an n^2 problem or management burden. Each new site almost exponentially increases the management burden.

The solution is to configure 6to4 tunnel endpoints on each remote site. 6to4 tunnels are dynamic so only a single tunnel endpoint is needed per remote site. Adding a new site now only adds 1 new tunnel interface – a linear increase.

To enable dynamic routing, the customer edge routers already use BGP to connect to the MPLS backbone. We can use the existing BGP configuration to enable internal (iBGP) sessions between the 6to4 addresses and advertise the IPv6 networks.

To begin, let's configure the 6to4 endpoints on each remote site:


ACE1
interface Tunnel2002
 ipv6 address 2002:a01:102::/128
 tunnel source Serial1/0
 tunnel mode ipv6ip 6to4

ipv6 unicast-routing

ipv6 route 2002::/16 Tunnel2002

ACE2
interface Tunnel2002
 ipv6 address 2002:a01:106::/128
 tunnel source Serial1/0
 tunnel mode ipv6ip 6to4

ipv6 unicast-routing

ipv6 route 2002::/16 Tunnel2002

ACE3
interface Tunnel2002
 ipv6 address 2002:a01:10a::/128
 tunnel source Serial1/0
 tunnel mode ipv6ip 6to4

ipv6 unicast-routing

ipv6 route 2002::/16 Tunnel2002

At this point, the sites have reachability to the newly configured 6to4 addresses but not the IPv6 addresses on the LAN of each remote site. To enable reachability to those networks we need to enable routing.

The easiest way is to add some static routes pointing to the remote 6to4 address for the remote sites' IPv6 networks. For example, on ACE1, the static IPv6 routes to add for the four (4) IPv6 networks on ACE2 and the four (4) IPv6 networks on ACE3 are:

ipv6 route 2001:DB8:A64:6800::/54 2002:A01:106::
ipv6 route 2001:DB8:A64:6C00::/54 2002:A01:10A::

Of course, with static routing we've simply shifted the n^2 problem of tunnel endpoint management to static route management, which could actually be much worse if routes are not hierarchical like the /54 summaries above. Imagine managing several static routes per site on each remote router.

The best solution is dynamic routing and as the previous linked article described, an internal gateway routing protocol will not work as the 6to4 addresses are not on the same subnet. BGP solves this with explicit peering definitions and since the edge routers are already running BGP to the MPLS provider, we can use that configuration.

BGP peers will be configured to the 6to4 addresses so BGP routing traffic will be passed as over the 6to4 tunnels the same way data traffic is passed. We use iBGP since the customer edge routers are all in the same BGP Autonomous System. Finally, we offloaded the configuration burden of an iBGP full mesh by configuring ACE1 as a route reflector ACE2 and ACE3 as route reflector clients.


ACE1
router bgp 65100
 neighbor 2002:A01:106:: remote-as 65100
 neighbor 2002:A01:10A:: remote-as 65100
 address-family ipv6
  neighbor 2002:A01:106:: activate
  neighbor 2002:A01:106:: route-reflector-client
  neighbor 2002:A01:10A:: activate
  neighbor 2002:A01:10A:: route-reflector-client
  network 2001:DB8:A64:6400::/64
  network 2001:DB8:A64:6500::/64
  network 2001:DB8:A64:6600::/64
  network 2001:DB8:A64:6700::/64

ACE2
router bgp 65100
 neighbor 2002:A01:102:: remote-as 65100
 address-family ipv6
  neighbor 2002:A01:102:: activate
  network 2001:DB8:A64:6800::/64
  network 2001:DB8:A64:6900::/64
  network 2001:DB8:A64:6A00::/64
  network 2001:DB8:A64:6B00::/64

ACE3
router bgp 65100
 neighbor 2002:A01:102:: remote-as 65100
 address-family ipv6
  neighbor 2002:A01:102:: activate
  network 2001:DB8:A64:6C00::/64
  network 2001:DB8:A64:6D00::/64
  network 2001:DB8:A64:6E00::/64
  network 2001:DB8:A64:6F00::/64

Note that we've made no changes to the PE router - meaning the MPLS provider does not need to support IPv6 at all for this configuration to work. You will need to make sure the provider doesn't do any exotic filtering at the edge or in the MPLS backbone such as blocking IP protocol 41 (IPv6 in IPv4 encapsulation).

At this point, we can test the configuration with some BGP show commands and pings to test connectivity. Without the benefit of a live demo here, rest assured these commands produced the provided output:

ACE1#show bgp ipv6 unicast
BGP table version is 17, local router ID is 10.100.103.1

   Network          Next Hop        Metric LocPrf Weight Path
*> 2001:DB8:A64:6400::/64
                    ::                   0         32768 i
[...]
*>i2001:DB8:A64:6800::/64
                    2002:A01:106::       0    100      0 i
*>i2001:DB8:A64:6900::/64
                    2002:A01:106::       0    100      0 i
[...]
*>i2001:DB8:A64:6C00::/64
                    2002:A01:10A::       0    100      0 i
*>i2001:DB8:A64:6D00::/64
                    2002:A01:10A::       0    100      0 i

ACE1#ping ipv6 2001:db8:a64:6800::1 source 2001:db8:a64:6400::1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:DB8:A64:6800::1, timeout is 2 seconds:
Packet sent with a source address of 2001:DB8:A64:6400::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 148/205/276 ms
ACE1#ping ipv6 2001:db8:a64:6c00::1 source 2001:db8:a64:6400::1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:DB8:A64:6C00::1, timeout is 2 seconds:
Packet sent with a source address of 2001:DB8:A64:6400::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 128/167/204 ms

And there you have it! Dynamic routing of IPv6 over an IPv4-only MPLS network without the MPLS provider supporting IPv6.

Tuesday, November 13, 2012

Fourth Annual RI 6 Hour Ultramarathon

On Sunday, November 11, 2012, I ran in the fourth annual RI 6 Hour Ultramarathon. This is quickly becoming a favorite race of mine - like RTB.

My goal - as in past years, was to do at least as well as I did the previous year. Given a good training build up during the past few months and last year's performance, I didn't think it would be too hard.

I started quite easy on a mild November day but the heat started to become an issue by 11 AM. Sixty degrees may not sound too hot to run in, but when you're getting to marathon distance with the intent of going much farther, it does matter. I started to get a little cramping due to dehydration - I was sweating more than I anticipated and drinking too little to compensate. I grabbed my running bottle for a lap and that eased the cramps.

Food intake was good this time. No stomach issues or lack of appetite. I stayed content throughout the race.

As I crossed the start/finish line to end my 13th lap and start my 14th - which was potentially my last and all I needed to equal last year's distance - I saw my wife and mother pull in to the parking lot beeping and waving at me. I yelled a quick "hello" and "1 more lap" and then started on my 14th lap.

On my 14th lap - the one to complete 37.8 miles and equal last year's distance - I kept saying this was it. My wife and mother were waiting to see me finish - a nice ending to the day. Looking at my watch, I could maybe have enough time to make it past the start/finish line to the first split timer at the 50k mark - an additional 1.35 miles. Although I was well past 50k at this point, the timing mat is still there and crossed on each lap and we were told by the race director at the start that partial laps to either the 50k or marathon split timing mats would count. But I kept talking myself out of it saying I would finish 14 laps and be done.

I crossed the start/finish line to end my 14th lap just shy of 5 hours, 42 minutes. I walked to the aid station and the volunteers asked if I was going to do a partial lap to the 50k split mat. That did it. I had 18 minutes. Even with my slow pace, I could do it. Jen was walking to me to congratulate me and instead, I quickly told her, "get in the car and meet me at the entrance of the park." Then I turned and started running.

I think part of me didn't want to run the extra 1.35 miles - literally half the course - and end up having to walk back to the start/finish line. I liked the idea of finishing at the start/finish line and being done. But with an unexpected taxi service in the form of my wife and mom, it seemed perfect.

There is a slight crest at the 50k timing mat and I crossed it at 5:54:08 completing 39.15 miles. My wife had parked behind another truck, so I didn't see her car right away, but then I saw her, waved and walked (painfully) towards my ride. Some congratulations from them and a quick explanation and thank you from me and we were on our way back to the start/finish for the post race activities.

The official results place me 5/43 with an official total mileage of 39.173 miles in 5:55:55.5 (although that time is wrong).

The table below documents my miles and times (by my watch).

RI 6 Hour Ultramarathon: November 11, 2012
LapMileageCumm.
Mile.
Lap SplitCumm.
Time
Lap PaceAvg. Pace
12.72.721:53.560:21:53.608:06.508:06.5
22.75.422:09.940:44:03.508:12.608:09.5
32.78.121:55.901:05:59.408:07.408:08.8
42.710.822:30.581:28:30.008:20.208:11.7
52.713.522:51.231:51:21.208:27.908:14.9
62.716.222:14.742:13:35.908:14.308:14.8
72.718.922:48.342:36:24.308:26.808:16.5
82.721.623:30.162:59:54.508:42.308:19.7
92.724.324:19.563:24:14.009:00.608:24.3
Marathon26.2--3:41:58.0--08:28.3
102.72725:18.303:49:32.309:22.308:30.1
112.729.726:39.654:16:12.009:52.508:37.6
50K31.25--4:30:26.0--08:39.2
122.732.427:53.004:44:05.010:19.608:46.1
132.735.128:55.015:13:00.010:42.608:55.0
142.737.828:53.375:41:53.310:42.009:02.7
14+1.3539.1512:15.565:54:08.909:04.909:02.8
Totals:39.155:54:0809:02.7

Friday, November 02, 2012

Windows Virtual PC IPv6: Part 3

The original title of the first post in the this series was "Windows Virtual PC Wireless IPv6", but dropped the "Wireless" before publishing. At that point, I had Part 1 and Part 2 written and knew the problem was with the wireless card versus the wired card, but didn't yet know the root cause. And since I had exhausted my troubleshooting tools (tcpdump and network based analysis) and wasn't about to dive into wireless driver software reverse engineering, I figured I may never have the exact answer. Instead, I focused the posts on discussing the problem and how it relates to the question, "is 'X' IPv6 ready?"

I did want to close the loop and exhaust all possible angles. So I called my friend and colleague Randy who had experience with wireless bridging / routing and virtual machines from a previous client. I remember he would lament about the issues he faced and custom drivers and wireless cards needed to get things only partially working. Since I was only an observer, I didn't have the intimate details, so now I sought them out over a phone call.

I explained my set up and issue and Randy immediately knew the problem. It wasn't IPv6 specific nor was it related to Windows Virtual PC. In fact, it wasn't even the wireless card or its respective drivers (per se), it was the 802.11 protocol itself. Randy explained the technical issues and gave me the proper Google terms to search to flush out the entire explanation.

And sure enough, after our call I started finding links such as:

that detail the IPv6 neighbor discovery problem I encountered when using wireless bridging. In my case, it wasn't a standalone bridge device, but the virtual network bridge when using a virtual machine. Note that in my testing the issue happened with Windows Virtual PC, but Randy's previous work involved VMware, which also had the issue. Again, this is protocol / driver related, not specific to IPv6 (network) or application layer software.

Further complicating the matter was the "incorrect" 'tcpdump' decodes. While the Ethernet header in the packets I posted showed source and destination MAC addresses, it wasn't the full picture. Wireless 802.11 has a different frame format than wired 802.3 Ethernet. However, the *pcap (winpcap in my case) libraries can't decode the 802.11 header if the wireless driver software doesn't pass it along. With my stock Broadcom wireless on a Dell laptop running Windows 7, I was seeing the "fake" header.

This final link from the OpenWRT project does a good job visualizing what is happening. Again, the link details physical bridges versus the virtual bridge introduced with machine virtualization software, but the same holds true.

So what does all this mean? Depending on how you look at this problem, it could be hardware, protocol or software related. For me, it manifested when trying IPv6 on Windows Virtual PC - so that was my first thought. It turns out the answer was much more involved and complicated than I imagined. However, broken IPv6 connectivity was the symptom and the casual user experiencing that will probably just say, "the network is down." No amount of planning is going to identify these unique use cases until they occur - hopefully during a pilot, more likely during production. You're going to need some smart people when you start rolling out IPv6.

Thursday, November 01, 2012

Windows Virtual PC IPv6: Part 2

In the previous post we saw the wireless card was responsible for some IPv6 connectivity issues between a Windows XP Virtual PC and the Internet due to it rewriting the VPC virtual MAC address to the MAC address of the HOST.

Suspecting the wireless card may be the culprit, I physically connected the HOST to the switch on the router and changed the VPC settings to use the wired NIC instead of the wireless one. A quick reset and back to testing - this time in somewhat reverse order.

I first checked the router to see what the MAC address for the VPC was. It was correct!

ROUTER# arp -a
? (192.168.10.102) at C4:17:FE:12:7D:75 [ether]  on br0
? (192.168.10.104) at 00:03:FF:13:7D:75 [ether]  on br0

So I started my 'tcpdump' captures and launched the pings from the VPC.

HOST> tcpdump -i2 -nevvXX icmp or icmp6
00:03:ff:13:7d:75 > 58:6d:8f:78:ad:40, ethertype IPv6 (0x86dd),
length 94: (hlim 128, next-header: ICMPv6 (58), length: 40)
2001:db8:192:168:203:FFFF:FE13:7D75 > 2607:F8B0:400C:C03::68
[icmp6 sum ok] ICMP6, echo request, length 40, seq 553
  0x0000:  586d 8f78 ad40 0003 ff13 7d75 86dd 6000  Xm.x.@....}u..`.
  0x0010:  0000 0028 3a80 2001 0db8 0192 0168 0203  ...(:....p...|..
  0x0020:  ffff fe13 7d75 2607 f8b0 400c 0c03 0000  ....}u&...@.....
  0x0030:  0000 0000 0068 8000 9120 0000 0229 6162  .....h.......)ab
  0x0040:  6364 6566 6768 696a 6b6c 6d6e 6f70 7172  cdefghijklmnopqr
  0x0050:  7374 7576 7761 6263 6465 6667 6869       stuvwabcdefghi
00:03:ff:13:7d:75 > 58:6d:8f:78:ad:40, ethertype IPv4 (0x0800),
length 74: (tos 0x0, ttl 128, id 25380, offset 0, flags [none], 
proto: ICMP (1), length: 60)
192.168.10.104 > 74.125.228.80
ICMP echo request, id 512, seq 9728, length 40
  0x0000:  586d 8f78 ad40 0003 ff13 7d75 0800 4500  Xm.x.@....}u..E.
  0x0010:  003c 6324 0000 8001 ddbe c0a8 0a68 4a7d  .< c$.........hJ}
  0x0020:  e450 0800 255c 0200 2600 6162 6364 6566  .P..%\..&.abcdef
  0x0030:  6768 696a 6b6c 6d6e 6f70 7172 7374 7576  ghijklmnopqrstuv
  0x0040:  7761 6263 6465 6667 6869                 wabcdefghi

The two packets show the IPv6 and IPv4 pings (echo requests) respectively. Notice the first line of each packet has the VPC source MAC address - '00:03:ff:13:7d:75' - not the HOST MAC address as seen in the previous test on the wireless card.

And the satisfying result:

VM> ping 2607:f8b0:400c:c03::68
Reply from 2607:f8b0:400c:c03::68: time=50ms

VM> ping 74.125.228.80
Reply from 74.125.228.80: bytes=32 time=166ms TTL=52

Just to make sure this whole testing regime wasn't an anomaly, I rebooted and reset to my wireless configuration and tested again with same failed results described in the previous post.

Why do the wireless and wired cards behave differently? I haven't answered that yet. Certainly, they are from different manufacturers and have different settings as verified in the "Properties" page, "Configure..." button, "Advanced" tab of each adapter. I did verify the common settings were matched between cards. I have some more research to do to get to the bottom of this one.

So, "does Windows Virtual PC support IPv6?" It's complicated. As we've seen, it depends on the application, the host and virtual machine operating systems, and in this case, the hardware used.

 

Copyright © VinsWorld. All Rights Reserved.