Saturday, February 19, 2011

IGS: first steps of the baby

The code responsible for the Internet sharing is committed to the repository. It is working just fine with my use cases.

The dislocation and settings of nodes in my house slightly changed.
Firstly, I replaced the Dell mini 9 with the EeePC. This machine (luca-eeepc) is now providing the ad-hoc wireless network (essid luca-ntk) which legacy DHCP clients can connect to.
Secondly, the server in the garage hasn't got anymore a direct route towards the Internet router over the roof. It will use the IGS mechanism to reach the Internet. As such it will be able, I hope, in the future to exploit more than one ISP connections. As I said before, it is problematic to exploit the IGS as a user and have a direct connection at the same time.

Configuration changes

The nodes luca-desktop and luca-laptop now have the file
/etc/netsukuku/settings.conf
with a line that says:
IGS_MODE='USE'
whilst the node luca-eeepc has in the same file the line:
IGS_MODE='SHARE'

The commands that I issue on each node before launching the netsukuku daemon change a bit.
I note them down, for the sake of completeness. Feel free to skip this section.
Just note a little change to the route of the EeePC towards its DHCP clients. Previously I forgot to add the parameter 'src 192.168.3.1' and this was confusing the DNS resolver of the DHCP clients.

on the EeePC

# disable network management
sudo stop network-manager
sudo killall dhclient
sudo ip route flush table main
sudo ip address flush dev eth0
sudo ip address flush dev wlan0
# connection to the WISP via eth0
sudo ip link set eth0 up
sudo ip address add 192.168.1.195/24 dev eth0
sudo ip route add default via 192.168.1.1 dev eth0 src 192.168.1.195
# activate adhoc wifi
sudo ip link set wlan0 down
sudo iw dev wlan0 del
sleep 1
sudo iw phy phy0 interface add adhoc0 type ibss
sleep 1
sudo ip link set adhoc0 up
sleep 1
# join network luca-ntk
sudo iw dev adhoc0 ibss join luca-ntk 2462 fixed-freq

# prepare to use ANDNA
sudo tee /etc/resolv.conf <<EOF >/dev/null
nameserver 127.0.0.1
EOF
# launch the daemon
(
cd ~/netsukuku/pyntk
sudo /opt/stackless/bin/python2.6 ntkd -i eth0 adhoc0 -vvvv 2>&1 | sudo tee -a /var/log/netsukuku.all.log >/dev/null
) &

# prepare and launch the dhcp server
sudo ip addr add 192.168.3.1 dev adhoc0
sudo ip route add 192.168.3.0/24 dev adhoc0 src 192.168.3.1
sudo iptables -t nat -A POSTROUTING -s 192.168.3.0/24 \! -d 192.168.3.0/24 -j MASQUERADE
sudo dhcpd3 adhoc0

on the server

# stop networkManager
sudo stop network-manager
sudo killall dhclient
sudo ip route flush table main
sudo ip address flush dev eth0
sleep 1

# prepare to use ANDNA
sudo tee /etc/resolv.conf <<EOF >/dev/null
nameserver 127.0.0.1
EOF
# launch the daemon
(
cd ~/netsukuku/pyntk
sudo /opt/stackless/bin/python2.6 ntkd -i eth0 -vvvv 2>&1 | sudo tee -a /var/log/netsukuku.all.log >/dev/null
) &

on the laptop

# disable network management
sudo stop network-manager
sudo killall dhclient
sudo ip route flush table main
sudo ip address flush dev eth0
sudo ip address flush dev wlan0
# activate adhoc wifi
sudo ip link set wlan0 down
sudo iw dev wlan0 del
sleep 1
sudo iw phy phy0 interface add adhoc0 type ibss
sleep 1
sudo ip link set adhoc0 up
sleep 1
# join network luca-ntk
sudo iw dev adhoc0 ibss join luca-ntk 2462 fixed-freq

# prepare to use ANDNA
sudo tee /etc/resolv.conf <<EOF >/dev/null
nameserver 127.0.0.1
EOF
# launch the daemon
(
cd ~/netsukuku/pyntk
sudo /opt/stackless/bin/python2.6 ntkd -i eth0 adhoc0 -vvvv 2>&1 | sudo tee -a /var/log/netsukuku.all.log >/dev/null &
)


Achievements

What I achieve is that every node in the network can reach the Internet. Obviously the sweet thing is that most nodes don't need to have a direct connection to an ISP for that, and don't need even to be configured to have a knowledge, before-hand, of which node will provide to them a path to reach the Internet.
And of course, each node can reach all the nodes in netsukuku with all the benefits of its dynamic routing protocol. E.g. today I was in front of my laptop in the kitchen, connected via wireless. I started a copy of a file from the server in the garage and the "copy dialog" was telling me that at a rate of 1.7 MB/s it would have finished in about 10 minutes. Without canceling the copy I moved the laptop to a position where I have a plug, and I plugged the laptop into the wired LAN. In about 5 seconds I saw the rate going up to 70 MB/s. That's what I call plug'n'play! When the copy finished I unplugged the laptop again, I tried to reload an Internet web page and it was already up and running through the wireless link.

Now let me show you some technical details of what rules have been injected in the nodes.

on the EeePC

This is the node that has IGS_MODE='SHARE'.

luca@luca-eeepc:~$ sudo iptables -n -t nat -L POSTROUTING
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination        
MASQUERADE  all  --  192.168.3.0/24      !192.168.3.0/24     
MASQUERADE  all  --  10.0.0.0/8          !10.0.0.0/8         

This command shows that the packets with source in 10.0.0.0/8 and destination elsewhere have to be masqueraded. This is the same that has been done manually to NAT the legacy DHCP clients, which obtain an address in 192.168.3.0/24.

luca@luca-eeepc:~$ ip link show tunl0
5: tunl0: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN 
    link/ipip 0.0.0.0 brd 0.0.0.0

This command shows that the node is accepting to tunnel traffic via IPIP.

on the laptop

This is a node that has IGS_MODE='USE'.

luca@luca-laptop:~$ ip link show ntk-to-inet-0
17: ntk-to-inet-0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN 
    link/ipip 0.0.0.0 peer 10.110.34.171

This command shows that the node has created a virtual interface through which it will tunnel traffic via IPIP to the node 10.110.34.171 (the current address of luca-eeepc)

luca@luca-laptop:~$ ip route list table main
default via 10.110.34.171 dev ntk-to-inet-0 

This command shows that the default route in the table main (which is examined only for addresses not found in the table ntk, that is for Internet addresses) is through the IPIP tunnel cited above.
In the current situation this would suffice. But we'd love to be able to exploit more than one tunnel. In this case we want to make sure that TCP connections initiated with one tunnel will always use that one. How is this achieved?

luca@luca-laptop:~$ sudo iptables -t mangle -n -v -L POSTROUTING
Chain POSTROUTING (policy ACCEPT 728K packets, 89M bytes)
 pkts bytes target     prot opt in     out     source               destination        
 2477  157K CONNMARK   all  --  *      ntk-to-inet-0  0.0.0.0/0            0.0.0.0/0           ctstate NEW CONNMARK xset 0x63/0xffffffff 

This command shows that every new TCP connection going out through the tunneled interface ntk-to-inet-0 has to be marked 99 (0x63).

luca@luca-laptop:~$ sudo iptables -t mangle -n -v -L OUTPUT
Chain OUTPUT (policy ACCEPT 665K packets, 72M bytes)
 pkts bytes target     prot opt in     out     source               destination        
31801 4678K CONNMARK   all  --  *      *       0.0.0.0/0            0.0.0.0/0           ctstate RELATED,ESTABLISHED CONNMARK restore 

This command shows that every TCP connection has to restore the mark it was created with (if any).

luca@luca-laptop:~$ ip rule
0:    from all lookup local 
32762:    from all fwmark 0xc6 lookup 198 
32763:    from all fwmark 0xc7 lookup 199 
32764:    from all fwmark 0x63 lookup 99 
32765:    from all lookup ntk 
32766:    from all lookup main 
32767:    from all lookup default 

This command shows that for packets marked with 99 we have to examine table 99.

luca@luca-laptop:~$ ip route list table 99
default via 10.110.34.171 dev ntk-to-inet-0  src 10.163.135.130 onlink 

This command shows that these packets will be sent through the tunnel ntk-to-inet-0.

Thus, when the default route in the table main will present many tunneled interfaces, we will rest assured that TCP connections initiated with one tunnel will always use that same tunnel for future packets.

on the server

The same configuration as the laptop.

ToDo

Every now and then I am experiencing wrong behavior from the ANDNA system. This comes not as a surprise: I was aware of some undiscovered bug in it. I am going to do some research on this side.


Stay tuned!

Sunday, February 13, 2011

Internet Gateway Sharing, soon

A first implementation of an Internet Gateway Sharing (IGS for short) mechanism will land in the repository very soon.
A node that is connected directly to the Internet will then be able to share its connection with other nodes. The nodes that haven't got a direct connection to the Internet receive informations on the 10 nearest nodes that allow to use their connection. Thus, they are able to use any number of them as gateways.
The current implementation (once again only linux is supported) allows to configure a node as a gateway or as a user. Theoretically it should be possible to be at the same time a gateway for other nodes and a user of other gateways but I had some troubles with this configuration in my tests, so I disabled this possibility.
The choice has to be made in the configuration file (/etc/netsukuku/settings.conf) by setting the variable IGS_MODE.
Set it to 'SHARE' to be a gateway. Set it to 'USE' to be a user. By default it is set to 'NONE' and the node will neither share its connection (if it has one) nor use the connection of others.
Further, if you set it to 'SHARE' you can indicate a Internet IP address to be periodically ping-ed in order to check if the Internet is at the moment reachable or not. This address can be set in the variable IGS_ANNOUNCE_INTERNET, which is by default set to 'ALWAYS', meaning that this node is to be considered always connected to the Internet.
Finally, if you set IGS_MODE to 'USE' you can indicate how many gateways you want to use at the same time. This can be set in the variable IGS_TUNNEL, by default 4. Min value is 1 and max value is 10.
With real hardware and real Internet I can only test one gateway. I hope to be able in a near future to test the real benefits one can get by using more than one ISP connection.

I want to test it a little bit more before doing a commit.

At the same time I am having some troubles with my netbook (Dell) wireless chipset. Its functioning is not reliable at all. I think it is a problem with the driver or with the hardware.
Since I have got another netbook, one of the first Eeepc shipped by Asus, I thought to use it. Its wireless chipset is much more reliable. The driver supports the new mac802 framework, so I can use the 'iw' commands instead of 'iwconfig' et al.
Thus, in the end, I will dedicate it to be running the DHCP daemon that I talked about in my previous post, for non-netsukuku clients.

While I am deploying this network I will also try to make use as much as possible of the methods we have got to try and mitigate the bufferbloat problem, that we so much experience these days on the Internet. I began to be aware of this problem by chance, on the blog of Jim Gettys.
So, if you feel brave enough when you build and deploy your very own TCP/IP mesh network, then look and ask for advices at www.bufferbloat.net.
You'll never regret!