blob
drs' stuff

Sunday, 05 June 2005

Peering the Foundation at GINX

Using my Netgraph layer 2 tunnel, I've connected the Foundation to GINX.

hippo:~$ traceroute turnip.foundation.org.za
traceroute to turnip.foundation.org.za (196.7.160.2), 64 hops max, 44 byte packets
 1  nortel8600a.switch.ru.ac.za (146.231.128.205)  0.571 ms  0.479 ms  0.460 ms
 2  porcupine (146.231.128.213)  0.173 ms  0.193 ms  0.168 ms
 3  turnip.foundation.org.za (196.7.160.2)  7.241 ms  7.160 ms  7.118 ms

turnip:~$ traceroute www.imaginet.co.za
traceroute to www.imaginet.co.za (196.15.145.5), 64 hops max, 40 byte packets
 1  imaginet.ginx.org.za (192.42.99.237)  20.409 ms  20.432 ms  20.985 ms
 2  ns1.imaginet.co.za (196.15.145.5)  23.922 ms  23.526 ms  23.966 ms
picture

Top-to-bottom: GINX route server, GINX switch, Imaginet SDSL bridge, Foundation Netgraph bridge.

posted at: 00:37 | path: | permanent link to this entry

Tunnelling a layer 2 network using Netgraph

Here's my method for creating a layer 2 tunnel with a few Netgraph nodes. I Google'd the FreeBSD mailing lists for a while and didn't find any published solutions to this problem, though a few people hinted that it should be possible.

One machine (I'll call it the "server") is directly connected to an Ethernet network that another machine (the "remote" machine) needs to be part of. Between them can be any number of routed networks.

This requires the Netgraph ether, bridge, ksocket and eiface nodes, so load the corresponding kernel modules. On the server, create a bridge node, and attach its link0 hook to the node that represents the server's interface on the network in question:

# ngctl mkpeer rl0: bridge lower link0
# ngctl name rl0:lower br0

Connect the link1 hook of that bridge to a new ksocket node:

# ngctl mkpeer br0: ksocket link1 inet/dgram/udp
# ngctl name br0:link1 ks0

Then bind the ksocket to a UDP port on the Internet-connected interface, and instruct it to direct encapsulated packets towards the remote machine:

# ngctl msg ks0: bind inet/a.b.c.d:nnnn
# ngctl msg ks0: connect inet/e.f.g.h:mmmm

On the remote machine, create a bridge node and a virtual Ethernet interface using an eiface node:

# ngctl -f - <<EOF
mkpeer bridge dummy link0
name dummy br0
mkpeer br0: eiface link1 ether
name br0:link1 ngeth0
EOF

Create and configure another ksocket:

# ngctl -f - <<EOF
mkpeer br0: ksocket link0 inet/dgram/udp
name br0:link0 ks0
msg ks0: bind inet/e.f.g.h:mmmm
msg ks0: connect inet/a.b.c.d:nnnn
EOF

Now that all the pieces are in place, the remote machine has an ngeth0 interface that is effectively connected to the real network that the physical interface on the server is actually connected to. Configure its MAC address to be the same as that of the physical interface so that ARP will work, then configure an IP address:

# ifconfig ngeth0 lladdr 00:0a:0b:0c:0d:0e
# ifconfig ngeth0 192.168.0.1/24

The remote machine should now have full connectivity to the local network.

Points that could be improved: If there's an IP address bound on the server's interface to the local network, it seems that that stops working when you use that interface's lower hook. Perhaps I should experiment with using the upper or orphans hooks.... Also, this is probably not terribly bandwidth efficient: all broadcast traffic (including ARP) will be carried over the tunnel.

Other ways of doing this: PPTP (using MPD), L2TP (maybe).

Nonetheless, this method has neatly solved my problem. And working with Netgraph is just like playing with Lego. :)

posted at: 00:29 | path: | permanent link to this entry

Powered by Blosxom Powered by Apache Powered by FreeBSD
This work is licensed under a Creative Commons License