Hyper-V NAT & virtual switches

Played with Hyper-V on my laptop after a long time today. For the past 6 months or so I’ve been exclusively with VMware Workstation on my primary laptop, and things are so much easier there if you just want some VMs running on your laptop. Installing VMs is a snap because most OSes will be automatically installed for you. Similarly, networking is straight-forward as VMware Workstation provides NAT out of the box. Hyper-V being more of an “enterprise” thingy (to be compared with VMware ESXi) you have to do these yourself.

For instance NAT. Hyper-V offers three type of network switches to connect your VM to the outside world. These are:

  • External switch: This creates a virtual switch that is bound to your physical network adapter. What happens when you make such a switch is that: (1) a new virtual switch is created with the name you provide, (2) this switch is bound to your physical network adapter (think of it as though your physical network adapter has become a switch), (3) a new virtual network adapter is created on your physical machine with the name “Hyper-V Virtual Ethernet Adapter #X” (replace X with a number), and (4) this virtual adapter is hooked up to the aforementioned switch and gets the IP address etc that was assigned to your physical adapter.

    So your physical adapter has become a virtual switch. And your physical machine uses a virtual adapter – connected to this virtual switch – to connect to the network.

    Other VMs you create and connect to this External switch have virtual adapters in them that too connect to this virtual switch. So it’s as if all these VMs and your physical machine are connected directly to a switch that is connected to your physical network. That’s why it’s called an External switch – everything is connected directly to the external world.

  • Internal switch: This too creates a virtual switch, but this virtual switch is not bound to your physical adapter. It’s just a virtual switch in a virtual ether of its own! What happens when you create an Internal switch is quite similar to the steps for an External switch: (1) a new virtual switch is created with the name you provide, (2) a new virtual network adapter is created on your physical machine with the name “Hyper-V Virtual Ethernet Adapter #X” (replace X with a number), and (3) this virtual adapter is hooked up to the aforementioned switch.

    Notice your physical adapter is left as it is. The newly created virtual adapter and switch have nothing to do with it. They exist in a world of their own. When you create new VMs connecting to this Internal switch, all their virtual adapters too connect to this virtual switch. The VMs and your physical machine can thus talk to each other, but they can’t jump over to the physical network.

    If you want your VMs to be able to talk to the outside world in such a scenario, you must make provisions for the communication. Like install & enable a routing service between the virtual adapter on the physical machine that’s connected to the Internal switch, and the physical adapter that’s connected to the physical network. Or enable NAT if routing isn’t possible. Either ways, the idea behind an Internal switch is that all your VMs are hooked up to that switch, and they can talk to your physical machine but they can’t talk to the outside world.

  • Private switch: Lastly we have a Private switch. This is just like an Internal switch, with the difference that there’s no virtual adapter created on the physical machine. So the physical machine has no connection to the Private switch. Meaning – all the VMs connected to the Private switch cannot contact the physical machine. They are in a bubble of their own.

So that’s that.

In my case I wanted to have all my VMs be in an Internal switch and also have them talk to the outside world. I couldn’t enable routing due to my network configuration, so I decided to enable NAT. To do this I created an Internal switch as usual and then (1) went to “Control Panel” > “Network and Internet” > “Network Connections”, (2) right clicked on my physical adapter that’s connected to the outside world, (3) went to the Sharing tab, (4) ticked the box that said “Allow other network users to connect …” and selected the adapter connected to the Internal switch from thee drop-down menu, and (5) clicked OK.

ICS

This enables NAT on my physical machine, as well as a DHCP server for the Internal switch network.

Here’s ipconfig for the virtual adapter connected to the Internal switch before I enable sharing:

And here’s the same once I enable sharing:

Unfortunately you don’t get much control over the NAT in terms of choosing the IP address network (it’s always the 192.168.137.0/24 network). You do get to choose what ports are forwarded (click “Settings” in the previous screenshot) and that’s about it.

If I check the VM now it has got an IP address from this network as expected:

The DNS server for this interface is set to the virtual adapter on the physical machine (which will perform the query on behalf of the VM and get back). The VM now has connectivity to the outside world as expected.

That’s all for now! Hope this helps someone.