Monday, June 11, 2012

SIMH 3.9 - Using VDE for fun and flexibility

The recently released 3.9 version of the SIMH software has added new funcionality to the network interfaces for our virtual machines. Now we have more options to give connectivity to the simulated PDP-11s and VAXen. I don't use non-DEC simulators, so I can't write about how those enhancements affect other operating systems and architectures.

Being able to link the simulated machines to the external world has been quite a problem for some time. DECNET requires to change the external MAC address of the simulated (or physically shared) ethernet device to the infamous AA-00-04-00-XX-XX value corresponding to the decnet address of the machine we are using. If you don't have several physical interfaces in your host machine you have trouble if you want to run more than one simulator, or if you want to run DECNET in the host machine itself. Pre-3.8 you had not a lot of options to fix that, those being:
  • Not running the simulator directly in the host, but inside a virtualized environment with several virtual network interfaces. I've used VMWare and Virtualbox and I've got a certain degree of success doing that.
  • Configure a tun/tap interface in your host machine and attach your simulator to it. Different host operating systems have different methotds to configure tun/tap devices; in particular, MacOS has no easy way to do it, so you have to resort to use some sort of hack to enable this solution. 
Fortunately, the last SIMH has built-in support both for tun/tap interfaces AND a little thing called VDE, for Virtual Distributed Ethernet. Let's take a look on how do these new options work for linux/unix machines (yes, that includes MacOS).

Tun/tap support.

Those (virtual) devices allow us to link two "virtual interfaces" via a point-to-point link (tun) or to provide a virtual, broadcast and multicast capable virtual ethernet interface (tap). The tun devices work at IP level, while the tap devices work at the ethernet (level 2) tier. Since we will want to use DECnet, we will need to use a tap interface.

Enabling SIMH to use such an interface is really easy. Just use this line in the simulator init file:

attach xq tap:tapn

You have to substitute the n for a number unique between your simulated machines (and any other softeware using the tap mechanism!). Oh, and the simulator must run with root privileges to be able to do this trick...

Doing this your simulated machine will have a private ethernet device to use. It should be able to change its MAC address to use the DECNET-based one (and if it is unable to do so, you can pre-fix the MAC address in the .ini file). Of course, this tap device will be at this point isolated and unable to speak to the rest of the world...

To fix that, you need to bridge the tap interface with the main real interface your host uses to talk to the world. The magic incantations needed to do  (assuming eth0 is your internet interface, A.B.C.D is your eth0 IP address and tap0 is the tap device you are using)

(Warning: use a local console to do this; don't do it remotely, since you will lose connectivity for a while)

sudo brctl addbr br0
sudo ifconfig tap0 up       # Notice there is no IP address assigned to tap0
sudo brctl addif br0 tap0
sudo ip addr delete A.B.C.D dev eth0      # You will lose IP connectivity here
sudo brctl addif br0 eth0
sudo ip addr add A.B.C.C. dev br0         # You should get back connectivity now

If your IP address is assigned via DHCP you could invoke DHCLIENT on the br0 interface instead of messing with ip addr.

At this point, the simulated machine should  be able to start DECNET and to get IP connectivity. Since the tap0 device is bridged, it should be able to see any machine in your local network,. including his own host machine.

You need to have installed some additional software: the bridge-utils and the tun/tap support. Your distribuituion could have those packages installed by default or not. Ubuntu, for instance, has tun/tap support enabled, but you must apt-get install bridge-utils. With MacOS you need to install the tuntap support extensions.

Does it work? Yes, it does. Is it easy to configure? Reasonabily. Is it flexible? In my opinion, you must take care of too many issues here, specially if you want to run several virtual machines in the same host. Specially, when there is the VDE option, which is much more flexible and easy to set up...

VDE support

VDE creates a virtual ethernet switch inside your host computer. This switch has almost all the features you will want in a high-end real switch, including VLAN tagging and loop avoidance. You can connect virtual things to this switch port using virtual plugs. And the switch itselfs provides a tap device to interact with.

You can install vde in linux via apt-get, synaptic or similar. You must install the -dev package to use it with SIMH (you'll need to rebuild SIMH from sources and the makefile will enable VDE support if it can find the development headers and libraries where it expects them to be). You can use macports to install VDE under MacOS, and you'll need to tweak a little bit the makefile so it is aware of the existence of VDE. Piece of cake :).

Creating and using a virtual switch

To use VDE you'll need to create the virtual switch. This needs to be done using root privileges. It is the only time when you will require to be root:

vde_switch -t tapn -s /tmp/vde.ctl -m 666 --mgmt /tmp/vde.mgmt --mgmtmode 666 --daemon 

This incantation does the following things:
  • It creates a tapn device and links it to the new virtual switch.
  • It creates two unix sockets: /tmp/vde.ctl and /tmp/vde.mgmt. The first one is the control socket (actually, it's a directory which contains other sockets), and the second one is the management socket. We will use the control socket to attach our simulators to the switch, and the management socket to... manage the switch itself.
  • It assigns the protections 666 to both the sockets. That's which allows us to use the switch without root privileges. You could do fine-grained protection assigning ownership of the sockets at user or group level, since 666 is perhaps too liberal.
  • It deamonizes the virtual switch.
Now you can connect to the virtual switch using the VDE provided unixterm utility. Just pass it the name of the management socket... Once there you can talk to the switch, display its stauts (port/print command) and shut down /kill it (shutdown). Use the logout command to leave unixterm and return to your shell.

To attach a simulator to the virtual switch, just use the following line in the init file:

attach xq vde:/tmp/vde.ctl

And that's all! Now, the simlator has its own ethernet device to play with. If you have more than a simulator sharing the same switch, they can see each other and communicate. So we just need to attach the virtual switch to the real ethernet. How? I guess you know the answer: brctl is again our friend. The sequence of incantations is just the same as before. The difference is we can now attach as many simulators as we want to the virtual switch, without having to worry about multiple tap devices. And we can do other cool things too!

If we want to attach to the switch something that does not support VDE natively, we can use one of the plugs included in the VDE package. The vde_plug2tap program allows us to attach a different tap device to the virtual switch:

vde_plug2tap -s /tmp/vde.ctl -m 666 -d tap1

This incantation creates a tap1 device and pluts it to the switch. The -d option makes it to deamonize. So now we have a tap1 device which we could attach, for instance, to KHL-10, which does not support natively VDE. 
We can also connect two virtual switches using the vde_plug program. This virtual plug just makes the switch available for plain programs writing to stdout and reading to stdin. Whatever you write, gets into the switch. Whatever goes thru the switch gets out of vde_plug. Using some smart pipe and nc magic you could tie two vde_plugs together thru the net. Fortunately, VDE includes a handy dpipe utility to link together to plugs. Add to this an ssh tunnel and you can do something like:

dpipe vde_plug /tmp/vde.ctl = ssh vdeuser@remote.machine.com vde_plug /tmp/vde.ctl

vdeuser is a "captive" user in remote.machine.com which has vde_plug as its command shell. This incantation opens a ssh pipe between your local machine and the remote one, and tunnels the ethernet traffic on both virtual switches to each other (assuming you have vde_switch running in your local machine, of course). If you set up automatic login using ssh keys it can be even easier. 

What do you get? Well, your local machine (a laptop, for instance) is now part of the remote LAN, at ethernet level (a regular VPN usually works at IP level). If you fiddle a little bit with the routing and name resolution you will be using this tunnel for IP. But if you don't (and you don't need to!) you will be able to use your DECnet remote network from your laptop. Yeah, the adjacency up comes instantly. If you are on the road, using networks out of your control, or a tethered iphone, or similar there is a really easy way to plug in your home DECnet. And its not really so hard to set up.

Automatic VDE setup

The ugliest part of this solution is the manual setup of the bridge between the tap interface which supports the virtual switch and the real ethernet interface in your host. Fortunately, this can be automated so everything gets properly configured at system startup. The recipe which follows is for linux distributions which use the debian style /etc/network/interfaces method, but it should be adaptable for other setups too.


# /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
     iface eth0 inet static

auto tap0
     iface tap0 inet manual
     vde2-switch -t tap0 -n 16 -s /tmp/vde.ctl \
                 -M /tmp/vde.mgmt -m 666 --mgmtmode 666

auto br0
     iface br0 inet static
     address 192.168.0.6
     network 192.168.0.0
     netmask 255.255.255.0
     broadcast 192.168.0.255
     gateway 192.168.0.128

The host local address (fixed) is 192.168.0.6/24. The gateway address is 192.168.0.128. The virtual switch is set up to use /tmp/vde.ctl as control socket directory and /tmp/vde.mgmt as management socket.  This setup starts automatically the virtual switch and links it to the real eth0 interface. I just have to fire up the simulators attaching the ethernet devices to vde:/tmp/vde.ctl and I'm set. And I use the ssh vde_plug trick to call home from my laptop, so I have DECnet on the road.

Foreword and disclaimer

I hope you'll find this instructions useful. And please apply the standard disclaimer: If you follow these instructions and end with a wrecked system/network, don't blame me :). Use them with an experimental setup first. On the other hand, I've not experienced anything not fixable with a reboot.

So have fun with VDE!

Credit

The information in this post is based mostly on the 0readme_ethernet.txt file, from the source distribution of SIMH. That file can be found in the project public source respository . The information about VDE and the several utilities it provides can be found in the manual files included in the package.