diff --git a/docs/features/multidomain.rst b/docs/features/multidomain.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7fa55a3f20e6a8b858d9c9faddf2cc83f47cd6da
--- /dev/null
+++ b/docs/features/multidomain.rst
@@ -0,0 +1,272 @@
+Multidomain Support
+===================
+
+Preamble
+--------
+
+There comes a time when a mesh network grows past sensible boundaries.
+As broadcast traffic grows, mesh networks experience scaling issues and
+using them becomes very unpleasant. An approach to solve this follows
+the well-known “divide and conquer” paradigm and splits a large network
+into multiple smaller networks. These smaller networks start with a
+dedicated layer 2 network each, which are interconnected via their
+gateways by layer 3 routing. Gluon is already field-tested handling a
+single domain and the multidomain feature allows for the reconfiguration
+of key parameters that decide which domain a node participates in,
+without the need of a distinct set of firmware images for each mesh domain.
+
+Overview
+--------
+
+Multidomain support allows to build a single firmware with multiple,
+switchable domain configurations. The nomenclature is as follows:
+
+-  ``site``: an aggregate over multiple domains
+-  ``domain``: mesh network with connectivity parameters that prevent
+   accidental bridging with other domains
+-  ``domain code``: unique domain identifier
+-  ``domain name``: pretty name for a domain code
+
+By default Gluon builds firmware with a single domain embedded into
+``site.conf``. To use multiple domains, enable it in ``site.mk``:
+
+::
+
+    GLUON_MULTIDOMAIN=1
+
+In the site repository, create the ``domains/`` directory, which will
+hold your domain configurations. Each domain configuration file is named
+after its primary ``domain_code``, additional domain codes and names are
+supported.
+
+::
+
+    site/
+    |-- site.conf
+    |-- site.mk
+    |-- i18n/
+    |-- domains/
+      |-- alpha_centauri.conf
+      |-- beta_centauri.conf
+      |-- gamma_centauri.conf
+
+The domain configuration ``alpha_centauri.conf`` could look like this.
+
+::
+
+    {
+      domain_names = {
+        alpha_centauri = 'Alpha Centauri'
+      },
+
+      -- more domain specific config follows below
+    }
+
+In this example “Alpha Centauri” is the user-visible ``domain_name`` for the
+domain_code ``alpha_centauri``. Also note that the domain code
+``alpha_centauri`` matches the filename ``alpha_centauri.conf``.
+
+Additional domain codes/names can be added to ``domain_names``, which
+are treated as aliases for the their domain configuration. Aliases can
+be used to offer more fine-grained and well-recognizable domain choices
+to users. Having multiple aliases on a single domain is a helpful
+precursor to splitting the domain into even smaller blocks.
+
+Furthermore you have to specify the ``default_domain`` in the ``site.conf``.
+This domain is applied in following cases:
+
+- When the config mode is skipped.
+- When a domain is removed in a new firmware release, the default_domain
+  will be chosen then.
+- When a user selects a wrong domain code via uci.
+
+Please note, that this value is saved to uci, so changing the `default_domain`
+value in the `site.conf` in a new firmware release only affects the actual
+domain of a router, if and only if one of the above conditions matches.
+
+
+Switching the domain
+--------------------
+
+**via commandline**:
+
+::
+
+    uci set gluon.core.domain="newdomaincode"
+    gluon-reconfigure
+    reboot
+
+**via config mode:**
+
+To allow switching the domain via config mode, ``config-mode-domain-select``
+has to be added to GLUON_FEATURES in the site.mk.
+
+|image0|
+
+Allowed site variables
+----------------------
+
+Internally the site variables are merged from the ``site.conf`` and the
+selected ``domain.conf``, so the most variables are also allowed in
+``site.conf`` and in ``domain.conf``. But there are some exceptions,
+which do not make sense in a domain or site specific way. The following
+sections give an overview over variables that are only usable in either
+site or domain context.
+
+site.conf only variables
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+-  Used in as initial default values, when the firmware was just flashed
+   and/or the config mode is skipped, so they do not make sense in a
+   domain specific way:
+
+   -  authorized_keys
+   -  default_domain
+   -  poe_passthrough
+   -  mesh_on_wan
+   -  mesh_on_lan
+   -  single_as_lan
+   -  setup_mode.skip
+   -  autoupdater.branch
+   -  mesh_vpn.enabled
+   -  mesh_vpn.pubkey_privacy
+   -  mesh_vpn.bandwidth_limit
+   -  mesh_vpn.bandwidth_limit.enabled
+   -  mesh_vpn.bandwidth_limit.ingress
+   -  mesh_vpn.bandwidth_limit.egress
+
+-  Variables that influence the appearance of the config mode,
+   domain-independent because they are relevant before a domain was selected.
+
+   -  config_mode.geo_location.show_altitude
+   -  config_mode.hostname.optional
+   -  config_mode.remote_login
+   -  config_mode.remote_login.show_password_form
+   -  config_mode.remote_login.min_password_length
+   -  hostname_prefix
+   -  mesh_vpn.fastd.configurable
+   -  roles.default
+   -  roles.list
+
+-  Specific to a firmware build itself:
+
+   -  site_code
+   -  site_name
+   -  autoupdater.branches.*.name
+   -  autoupdater.branches.*.good_signatures
+   -  autoupdater.branches.*.pubkeys
+
+-  We simply do not see any reason, why these variables could be helpful
+   in a domain specific way:
+
+   -  mesh_vpn.fastd.syslog_level
+   -  wifi*.ibss.supported_basic_rates
+   -  wifi*.mesh.supported_basic_rates
+   -  timezone
+   -  regdom
+
+domain.conf only variables
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+-  Obviously:
+
+   -  domain_names
+
+      -  a table of domain codes to domain names
+         ``domain_names = { foo = 'Foo Domain', bar = 'Bar Domain', baz = 'Baz Domain' }``
+
+   -  hide_domain
+
+      -  prevents a domain name(s) from appearing in config mode, either
+         boolean or array of domain codes
+
+         -  ``true``, ``false``
+         -  ``{ 'foo', 'bar' }``
+
+-  Because each domain is considered as an own layer 2 network, these
+   values should be different in each domain:
+
+   -  next_node.ip4
+   -  next_node.ip6
+   -  next_node.name
+   -  prefix6
+   -  prefix4
+   -  extra_prefixes6
+
+-  To prevent accidential bridging of different domains, all meshing
+   technologies should be seperated:
+
+   -  domain_seed (wired mesh)
+
+      -  must be a random value used to derive the vxlan id for wired meshing
+
+   -  wifi*.ibss.ssid
+   -  wifi*.ibss.bssid
+   -  wifi*.mesh.id
+   -  mesh_vpn.fastd.groups.*.peers.remotes
+   -  mesh_vpn.fastd.groups.*.peers.key
+   -  mesh_vpn.tunneldigger.brokers
+
+-  Clients consider WiFi networks sharing the same ESSID as if they were
+   the same L2 network and try to reconfirm and reuse previous
+   addressing. If multiple neighbouring domains shared the same ESSID,
+   the roaming experience of clients would degrade.
+
+   -  wifi*.ap.ssid
+
+- Some values should be only set in legacy domains and not in new domains.
+   -  mesh.vxlan
+
+       -  By default, this value is `true`. It should be only set to `false`
+          for one legacy domain, since vxlan prevents accidental wired
+          merges of domains. For old domains this value is still available
+          to keep compatibility between all nodes in one domain.
+
+   -  next_node.mac
+
+       -  For new domains, the default value should be used, since there is
+          no need for a special mac (or domain specific mac). For old domains
+          this value is still available to keep compatibility between all
+          nodes in one domain.
+
+Example config
+--------------
+
+site.mk
+^^^^^^^
+
+.. literalinclude:: ../multidomain-site-example/site.mk
+  :language: makefile
+
+site.conf
+^^^^^^^^^
+
+.. literalinclude:: ../multidomain-site-example/site.conf
+  :language: lua
+
+domains/alpha_centauri.conf
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: ../multidomain-site-example/domains/alpha_centauri.conf
+  :language: lua
+
+i18n/en.po
+^^^^^^^^^^
+
+.. literalinclude:: ../multidomain-site-example/i18n/en.po
+  :language: po
+
+i18n/de.po
+^^^^^^^^^^
+
+.. literalinclude:: ../multidomain-site-example/i18n/de.po
+  :language: po
+
+modules
+^^^^^^^
+
+.. literalinclude:: ../multidomain-site-example/modules
+  :language: makefile
+
+
+.. |image0| image:: multidomain_configmode.gif
diff --git a/docs/features/multidomain_configmode.gif b/docs/features/multidomain_configmode.gif
new file mode 100644
index 0000000000000000000000000000000000000000..494840f59f418ac1c104c53c4e0dc3edc9fb65f7
Binary files /dev/null and b/docs/features/multidomain_configmode.gif differ
diff --git a/docs/index.rst b/docs/index.rst
index 03839d3d2eb468924db3fc63792a9079d8b5af9a..7c6d06eb9aaba0365b69afba0182978bb7ce4202 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -25,6 +25,7 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
    features/wired-mesh
    features/dns-forwarder
    features/monitoring
+   features/multidomain
    features/authorized-keys
    features/roles
    features/vpn
diff --git a/docs/multidomain-site-example/domains/alpha_centauri.conf b/docs/multidomain-site-example/domains/alpha_centauri.conf
new file mode 100644
index 0000000000000000000000000000000000000000..27558253e8a7cffb0a7244dd54fc1704af14ceea
--- /dev/null
+++ b/docs/multidomain-site-example/domains/alpha_centauri.conf
@@ -0,0 +1,61 @@
+{
+  -- multiple codes/names can be defined, the first one is the primary name
+  -- additional aliases can be defined
+  domain_names = {
+    alpha_centauri = 'Alpha Centauri',
+    rigil_kentaurus = 'Rigil Kentaurus',
+    proxima_centauri = 'Proxima Centauri',
+  },
+
+  -- 32 byte random data in hexadecimal encoding
+  -- Can be generated using: echo $(hexdump -v -n 32 -e '1/1 "%02x"' </dev/urandom)
+  domain_seed = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+
+  -- unique network prefixes per domain
+  prefix4 = '10.xxx.0.0/20',
+  prefix6 = 'fdxx:xxxx:xxxx:xxxx::/64',
+
+  next_node = {
+    ip4 = '10.xxx.yyy.zzz',
+    ip6 = 'fdxx:xxxx:xxxx:xxxx::xxxx',
+  },
+
+  wifi24= {
+    ap = {
+      ssid = "alpha-centauri.example.org",
+      channel = 1,
+    },
+    mesh = {
+      id = 'ueH3uXjdp', -- usually you don't want users to connect to this mesh-SSID, so use a cryptic id that no one will accidentally mistake for the client WiFi
+    },
+  },
+
+  wifi5= {
+    ap = {
+      ssid = "alpha-centauri.example.org",
+      channel = 44,
+    },
+    mesh = {
+      id = 'ueH3uXjdp',
+    },
+  },
+
+  mesh_vpn = {
+    fastd = {
+      groups = {
+        backbone = {
+          peers = {
+            peer1 = {
+              key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+              remotes = {'"peer1.example.org" port xxxxx'},
+            },
+            peer2 = {
+              key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+              remotes = {'"peer2.example.org" port xxxxx'},
+            },
+          },
+        },
+      },
+    },
+  },
+}
diff --git a/docs/multidomain-site-example/i18n b/docs/multidomain-site-example/i18n
new file mode 120000
index 0000000000000000000000000000000000000000..db297ce1073fbabcb4b35375de94c3115bf96e76
--- /dev/null
+++ b/docs/multidomain-site-example/i18n
@@ -0,0 +1 @@
+../site-example/i18n/
\ No newline at end of file
diff --git a/docs/multidomain-site-example/modules b/docs/multidomain-site-example/modules
new file mode 120000
index 0000000000000000000000000000000000000000..92ec2fa53824e1f86fce103ce11809d567bb5074
--- /dev/null
+++ b/docs/multidomain-site-example/modules
@@ -0,0 +1 @@
+../site-example/modules
\ No newline at end of file
diff --git a/docs/multidomain-site-example/site.conf b/docs/multidomain-site-example/site.conf
new file mode 100644
index 0000000000000000000000000000000000000000..25eaeb6958bd20c5268be84af8720489ba1633d1
--- /dev/null
+++ b/docs/multidomain-site-example/site.conf
@@ -0,0 +1,52 @@
+{
+  site_name = 'Centauri Mesh',
+  site_code = 'centauri',
+  default_domain = 'alpha_centauri',
+
+  timezone = 'CET-1CEST,M3.5.0,M10.5.0/3',
+  ntp_server = {'ntp1.example.org', 'ntp2.example.org'},
+  regdom = 'DE',
+
+  wifi24 = {
+    mesh = {
+      mcast_rate = 12000,
+    },
+  },
+
+  wifi5 = {
+    mesh = {
+      mcast_rate = 12000,
+    },
+  },
+
+  mesh_vpn = {
+    mtu = 1312,
+
+    fastd = {
+      methods = {'salsa2012+umac'},
+    },
+
+    bandwidth_limit = {
+      enabled = false,
+      egress = 200, -- kbit/s
+      ingress = 3000, -- kbit/s
+    },
+  },
+
+  autoupdater = {
+    branch = 'stable',
+
+    branches = {
+      stable = {
+        name = 'stable',
+        mirrors = {'http://update.example.org/stable/sysupgrade'},
+        good_signatures = 2,
+        pubkeys = {
+          'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', -- Alice
+          'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', -- Bob
+          'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', -- Mary
+        },
+      },
+    },
+  },
+}
diff --git a/docs/multidomain-site-example/site.mk b/docs/multidomain-site-example/site.mk
new file mode 100644
index 0000000000000000000000000000000000000000..1e16ca1a480fa2964f290c5b5f412c1d8166df4f
--- /dev/null
+++ b/docs/multidomain-site-example/site.mk
@@ -0,0 +1,60 @@
+##	gluon site.mk makefile example
+
+##	GLUON_FEATURES
+#		Specify Gluon features/packages to enable;
+#		Gluon will automatically enable a set of packages
+#		depending on the combination of features listed
+
+GLUON_FEATURES := \
+	autoupdater \
+	ebtables-filter-multicast \
+	ebtables-filter-ra-dhcp \
+	mesh-batman-adv-15 \
+	mesh-vpn-fastd \
+	radvd \
+	respondd \
+	status-page \
+	web-advanced \
+	web-wizard
+
+##	GLUON_MULTIDOMAIN
+#		Build gluon with multidomain support.
+
+GLUON_MULTIDOMAIN=1
+
+##	GLUON_SITE_PACKAGES
+#		Specify additional Gluon/LEDE packages to include here;
+#		A minus sign may be prepended to remove a packages from the
+#		selection that would be enabled by default or due to the
+#		chosen feature flags
+
+
+GLUON_SITE_PACKAGES := haveged iwinfo
+
+##	DEFAULT_GLUON_RELEASE
+#		version string to use for images
+#		gluon relies on
+#			opkg compare-versions "$1" '>>' "$2"
+#		to decide if a version is newer or not.
+
+DEFAULT_GLUON_RELEASE := 0.6+exp$(shell date '+%Y%m%d')
+
+# Variables set with ?= can be overwritten from the command line
+
+##	GLUON_RELEASE
+#		call make with custom GLUON_RELEASE flag, to use your own release version scheme.
+#		e.g.:
+#			$ make images GLUON_RELEASE=23.42+5
+#		would generate images named like this:
+#			gluon-ff%site_code%-23.42+5-%router_model%.bin
+
+GLUON_RELEASE ?= $(DEFAULT_GLUON_RELEASE)
+
+# Default priority for updates.
+GLUON_PRIORITY ?= 0
+
+# Region code required for some images; supported values: us eu
+GLUON_REGION ?= eu
+
+# Languages to include
+GLUON_LANGS ?= en de