pi2pi
NETWORKING PI ZEROS TOGETHER WITHOUT NETWORK ADAPTERS
Linux gadget mode lets you network two or more Zeros using only an OTG USB hub and some Micro USB cables. Furthermore, if you only need to connect two Zeros, you can replace the hub with an OTG adapter.
WHAT TO USE IT FOR
How about a video wall (using xinerama) using nothing but a bunch of Zeroes, monitors (or TVs), USB cables, and a USB hub? This has got to be the cheapest way to do this ever. Or a USB connected second monitor (again, using xinerama) for your Pi? (This is actually a two-screen video wall.) How about a cheap compute cluster? Or anything else where you need to network some Zeros at low cost. Or simply use it to log in to a Zero (using SSH) without having to attach a monitor, serial cable, or network adapter.
SETTING IT UP
There will be a master Zero and one or more slaves. The master only needs a small change. The slaves require several changes. However, the slaves are similar to each other, with the exception of hostname and ip address. If you're doing several slaves this should make things a little easier.
Get connected to the Internet on one of the slaves. See this project if you're having trouble - especially if you're working with the Raspbian Lite.
First, you need to install a DHCP server and update the kernel. Type the following, waiting for each command to finish before typing the next:
apt-get update
apt-get install dnsmasq
apt-get install rpi-update
BRANCH=next rpi-update
Each Zero needs a unique hostname for DHCP to work. Run raspi-config to set it. You probably also want to enable SSH.
The new network interface needs to be enabled. Edit the /etc/network/interfaces file and add the following to it:
auto usb0
allow-hotplug usb0
iface usb0 inet dhcp
You need to set a fixed ip address for the new network interface. Edit the /etc/dhcpcd.conf file and add the following to it:
interface usb0
static ip_address 10.0.0.1/24
The DHCP server needs to be configured. Edit the /etc/dnsmasq.conf file and add the following to it:
interface=usb0
dhcp-range=10.0.0.2,10.0.0.100,12h
dhcp-authoritative
dhcp-option=3
dhcp-option=6
The proper modules need to be loaded for gadget mode to work. Edit the /etc/modules file and add the following to it:
dwc2
g_ether
The alternate USB driver needs to be used. Edit the /boot/config.txt file and add the following to it:
dtoverlay=dwc2
Repeat all of the above steps on each slave, but use a different IP address and host name. For instance, in the dhcpd.conf file use 10.0.1.1/24 on the second one, 10.0.2.1/24 on the third etc. You also need to modify the dnsmasq.conf file on each to match: 10.0.1.2,10.0.1.100,12h for the second, and so forth.
When you're done with all of the slaves, set up the master. It only needs the new network interfaces enabled. Add the following lines to the /etc/network/interfaces file:
auto usb0
allow-hotplug usb0
iface usb0 inet dhcp
auto usb1
allow-hotplug usb1
iface usb1 inet dhcp
The above sample works for up to two slaves. If you have more than this you'll have to extend it with more sections.
NOTE: If the master or any of the slaves are using the Linux firewall the following rules need to be added:
#allow all on gadget
iptables -A INPUT -j ACCEPT -i usb0 -p all
iptables -A OUTPUT -j ACCEPT -o usb0 -p all
The master will need additional rules for it's other usb gadget interfaces: usb1 etc.
TESTING IT OUT
Connect the hub's micro USB cable to the master Zero. Connect each slave to the hub with a micro USB cable. The slaves and master will be powered by the hub and won't need power connections. The hub must be remote powered and must supply enough current. (Each slave draws about 100 milliamps.) Connect a keyboard to the hub. Connect a monitor to the master. Connect power to the hub, and everything should boot up.
The slaves may reboot a couple of times, but should settle down in a few minutes. Log in to the master, and run ifconfig. You should see one usb section for each slave, with a unique ip address. Ping each slave to verify network connectivity.
TROUBLESHOOTING
You'll have to disconnect the slaves from the hub and attach a monitor etc. Check that dnsmasq is running on each slave. Then check /var/log/daemon.log for any error messages. You may also get more information by manually starting the dnsmasq service using systemctl restart dnsmasq. Usually the problem is a mis-typed config file.
PROBLEMS
If you try to use WiFi on a slave (after unplugging it from the hub, attaching a monitor etc.) it won't work. To fix it, kill dnsmasq: it interferes with name resolution. I haven't been able to find a more elegant solution to this, but it's probably fixable in dnsmasq.conf. As for the master: if you plug a WiFi adapter into the hub and there are slaves attached, the master will use it properly. It's even possible to route this connection to the slaves using Linux's built-in routing capabilities, but I won't go into that here.
VARIATIONS
You can combine the master and hub into one device by using any Pi model that has full-size USB connectors. Be careful about overloading the master since it'll be powering the slaves. Or, a normal USB hub can be substituted for a OTG hub by connecting an OTG adapter to a USB A-B cable that's plugged into the hub's master port. (Make sure the hub is a powered one.) Or plug a non-Zero Pi into a regular hub with a A-B cable and use it as the master. It's also possible to use a Model A or A+ as a slave, but you'll need a custom kernel and an A-A usb cable, which isn't common.
CREDITS
Thanks to gbaman for the wonderful documentation of Gadget Mode setup. It's by far the easiest method to follow of the several available. Except maybe this one!
This site has been tested to display correctly using Epiphany on the Raspberry Pi