How can I automatically switch my VMs' bridged adapters between eth0 and wlan0 depending on what's active?

3

1

In Virtualbox, I have a bunch of virtual machines. The host is a Debian laptop that frequently switches between a wired and a wireless connection. Every time I go wireless (or go wired), I have to change the Virtualbox settings of each virtual machine from eth0 to wlan0 (or the other way around) to have the guests connect to the network. How can I make this switch automatic?

Matt Alexander

Posted 2012-02-18T17:10:28.380

Reputation: 749

Are you saying that you're bridging your VM to a wireless interface? Because that's not possible. – Ambroz Bizjak – 2012-02-18T17:37:36.377

@AmbrozBizjak, Yes, that is what I'm saying. In fact, these words are being sent from a guest VM on a wireless Debian host. – Matt Alexander – 2012-02-18T17:39:33.477

Ah, so it seems that VBox is doing some hackery to make it work. Wireless client interfaces can't be bridged in the usual sense because each wireless client is assigned one and only one MAC address. – Ambroz Bizjak – 2012-02-18T17:41:10.363

Is it absolutely necessary that the VM is bridged? Why would routing not work? – Ambroz Bizjak – 2012-02-18T17:41:37.073

I'm using them as servers and so they need an IP. – Matt Alexander – 2012-02-18T17:44:52.707

The simplest solution is probably to use a "NAT"-type interface instead, and configure port forwarding in the VBox GUI. – Ambroz Bizjak – 2012-02-18T17:48:03.473

Thanks, but considering my setup, the port forwarding involved with switching over to NAT makes this solution too complicated to follow. – Matt Alexander – 2012-02-18T17:53:38.403

Answers

3

It is possible to change the type of the virtual network interface with a command like:

VBoxManage controlvm <VM_name> nic1 bridged eth0

This will make the first virtual interface in this VM be bridged to eth0. However, it only works when the guest is running. (I'm not sure exactly when it will update the persistent configuration, but some testing has shown that the command does nothing if the guest is not running, but if it is, it both changes the immediate state of the interface and updates the configuration.)

But it can be made to work if you have something running it frequently, specifying the interface you want to bridge to. You can use my NCD programming language to do this automatically. The NCD program below will observe the state of eth0 and wlan0, and will repeatedly invoke a command like above to make sure your VM is bridged the right interface. (in particular, the one which has the RUNNING flag; e.g. for wired interfaces this means that the cable is plugged in)

process vbox_iface {
    # Wait for link on either eth0 or wlan0. Prefer eth0.
    multidepend({"link-eth0", "link-wlan0"}) linkif;

    println("Using ", linkif.dev);

    # Enter loop (this is a hackish loop).
    multiprovide("loop-run");
    multidepend({"loop-again", "loop-run"});

    println("Setting bridged to ", linkif.dev);

    # Set VM NIC config.
    runonce({"/usr/bin/VBoxManage", "controlvm", "Windows XP", "nic1", "bridged", linkif.dev});

    # Wait some time (in milliseconds).
    sleep("2000", "0");

    # Continue loop.
    multiprovide("loop-again");
}

process lan_iface {
    var("eth0") dev;

    # Wait for device to appear and for link (e.g. cable).
    net.backend.waitdevice(dev);
    net.backend.waitlink(dev);

    multiprovide("link-eth0");
}

process wlan_iface {
    var("wlan0") dev;

    # Wait for device to appear and for link (e.g. cable).
    net.backend.waitdevice(dev);
    net.backend.waitlink(dev);

    multiprovide("link-wlan0");
}

You can use the above program by running (as your user account, not root):

badvpn-ncd --loglevel warning --config-file <file_with_above_script.ncd>

Be sure to adjust the interface names in the script, and the VM name. Once you have verified that it works, you can configure your desktop environment to autostart the badvpn-ncd process.

Ambroz Bizjak

Posted 2012-02-18T17:10:28.380

Reputation: 4 265