+usage() {
+ cat <<EOF
+usage: ${0##*/} [OPTS] start|stop NS_NAME
+Nat a network namespace. systemd friendly
+
+Also creates a mount namespace with a cloned /run/resolvconf.
+
+-c, --create Create or destroy a named network namespace. When running from
+ the same network namespace as pid 1, this is set automatically.
+ A systemd created private network is in a network namespace
+ different than pid 1.
+-n NETWORK x.x.x /24 private network to use. If not specified, uses
+ the first unused one starting at 10.173.1
+-h, --help Show this help and exit.
+
+From a normal shell:
+
+If we do create the netns, to join it with a shell, we can do (as root)
+/usr/bin/nsenter --mount=/root/mount_namespaces/NAME --net=/var/run/netns/NAME bash
+
+If you dont care about the mount namespace, you can leave that option off.
+
+
+For systemd:
+
+From within a systemd network namespace, we nat it to the outside. This
+would be called from ExecStartPre, and or subsequent units called with
+JoinsNamespaceOf= and PrivateNetwork=true.
+
+If resolvconf is installed, we create a named mount namespace under
+/root/mount_namespaces, so we can alter some system config for this
+namespace. systemd command lines would be prefixed with:
+
+/usr/bin/nsenter --mount=/root/mount_namespaces/NS_NAME
+
+Note, this means that they can't run as unpriveledged users, but once
+systemd 233 comes out, it will have a bind mount option from within unit
+files, so the mount namespace won't be needed for most use cases, and I
+will update the script to that the mount namespace not created unless a
+flag is passed in. Patch welcome to add that flag before then.
+
+This script has a dependency which you can download manually or it
+will be automatically downloaded into the same directory.
+It handles errors by printing stack trace and and cleaning up the namespaces.
+To download manually,
+git clone https://iankelling.org/git/errhandle
+into an adjacent directory, or
+export ERRHANDLE_PATH to point to the 'err' file in that repo.
+
+
+Background on this project (you can skip if you like):
+
+If we aren't creating a named network namespace, to join the namespace
+with a shell, I use:
+nsenter -n -m -t \$(pgrep PROCESS_IN_NAMESPACE) bash
+
+Note: if I knew how to easily ask systemd what pid a unit has, i would
+do that.
+
+"ip netns new ..." also does a mount namespace, then bind
+mounts each file/dir in /etc/netns/NS_NAME to /etc/NS_NAME. Note,
+for openvpn having it's own resolv.conf by using it's user script which
+calls resolvconf, this doesn't help much. What we actually want to do is
+copy /run/resolvconf somehwere then bind mount it on top of
+/run/resolvconf.
+
+
+Note: for debugging, adding set -x is a pretty good option.
+
+Please email me if you have a patches, bugs, feedback, or republish this
+somewhere else: Ian Kelling <ian@iankelling.org>.
+EOF
+ exit ${1:-0}
+}