PC-to-PC 101

Posted on 2014-October-15 in networking

RJ-45

Got my hands on an old but faithful laptop recently. The thing is a lot faster than my son's desktop, so I thought it would make a nice update for him. First thing I did was upgrade the laptop's disk to an SSD and install Linux Mint. This is now the fastest computer in the house, with a total Linux boot time averaging around 3-4 seconds from power button press to full windowed environment. Yay!

Next task: transfer his home directory from his desktop to his new laptop. Both machines are currently connected to the home network through Wi-Fi, and we are talking about transferring about 100 Gbytes. Even with a beefy router averaging around 1Mbyte/sec, we are talking about 24+ hours of transfer. Not ideal. One solution would be to connect an external hard drive, copy all contents, then restore on the other machine, but I thought there must be a better solution. Both machines have RJ-45 Gbit connectors, so why not take advantage of this?

Now comes the problem: how do you create an ad-hoc network between two Linux machines to allow them to exchange data through a single Ethernet cable? Bonus points if you do not use a router.

First thing that came to my mind was: install all necessary software to transform one of the PCs into a simple router. A simple DHCP server and very basic routes should be enough. But no, that is not even necessary: switch both PCs to fixed IP addresses like 10.0.0.1 and 10.0.0.2 and it should just work. Which I tried, without much success. A ping would work for a few seconds but both PCs lost their network connection almost immediately. Could not figure out why. I tried GUI configuration, modifying /etc/network/interfaces, manually switching with ip add, but nothing worked. The first packets would work fine, I could even connect with ssh, and after 10 seconds connectivity collapsed on both sides. We have been living with DHCP-configured networks for so long now that the default Linux networking tools are all assuming some kind of dynamic addressing scheme handled by a proper router. No luck.

I must have launched ifconfig half a million times and never got a proper answer about why this damn thing would disconnect itself after 30 seconds. And then suddenly I realized I had the solution to my problem just in front of me:

% ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
inet6 fe80::210:99ff:fe26:6db1  prefixlen 64  scopeid 0x20<link>

The answer is on the bottom line: the IPv6 link-local address, of course!

IPv6 local links are designed precisely to work without a router or DHCP server. Plug a cable, talk. No need for any kind of configuration, gateway, or network mask. Let's try:

% ping6 fe80::210:99ff:fe26:6db1%eth0
PING fe80::210:99ff:fe26:6db1%eth0(fe80::210:75ff:fe26:6db1) 56 data bytes
64 bytes from fe80::210:99ff:fe26:6db1: icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from fe80::210:99ff:fe26:6db1: icmp_seq=2 ttl=64 time=0.073 ms

NB: If you use link-local IPv6 addresses, you need to suffix the address by the NIC name (%eth0). Once that was cleared, I could start an ssh session from one box to the other without more thoughts. No software installation or configuration of any kind are required.

The remaining bit was to find out how to use IPv6 addresses with scp. A bit of googling revealed that scp needs IPv6 addresses to be surrounded by escaped brackets, which produces this kind of user-friendly command-line:

scp -6 nicolas@\[fe80::210:99ff:fe26:6db1%eth0\]:/home/music .

With both machines running on SSD drives and on Gbit NICs, the whole 100 Gbytes took just a few minutes to transfer.

Today I learned IPv6 can be useful immediately.