diff --git a/docs/user/site.rst b/docs/user/site.rst
index a96e137d1f9e0b8830f0120390f6ee16f6a58478..fc82f314d2340aafea022c9612e29c01a3378e9f 100644
--- a/docs/user/site.rst
+++ b/docs/user/site.rst
@@ -49,10 +49,13 @@ node_prefix6
 
     node_prefix6 = 'fdca::ffee:babe:2::/64'
 
-node_client_prefix6
-  The ipv6 prefix from which the client-specific IP-address is calculated that
-  is assigned to each node by l3roamd to allow efficient communication when 
-  roaming. This is exclusively useful when running a routing mesh protocol
+node_client_prefix6 \: optional, deprecated
+  DEPRECATED: Don't specify it anymore, this prefix will then
+  automatically be generated from the domain_seed.
+
+  An IPv6 prefix internally used by the l3roamd protocol, used to allow
+  an efficient handover via unicast when a client roamed.
+  This is exclusively useful when running a routing mesh protocol
   like babel. e.g. ::
 
     node_client_prefix6 = 'fdca::ffee:babe:3::/64'
diff --git a/package/gluon-l3roamd/Makefile b/package/gluon-l3roamd/Makefile
index 4259bb8528c90575edbf4512d7b950481b57ec75..25cb830ffbc922df093bdf9c5bb2ea3524b00460 100644
--- a/package/gluon-l3roamd/Makefile
+++ b/package/gluon-l3roamd/Makefile
@@ -6,7 +6,7 @@ include ../gluon.mk
 
 define Package/gluon-l3roamd
   TITLE:=Configure l3roamd for babel
-  DEPENDS:=+gluon-core +l3roamd +uc
+  DEPENDS:=+gluon-core +gluon-mesh-layer3-common +l3roamd +uc
 endef
 
 $(eval $(call BuildPackageGluon,gluon-l3roamd))
diff --git a/package/gluon-l3roamd/check_site.lua b/package/gluon-l3roamd/check_site.lua
deleted file mode 100644
index 4e80ca2eac644592e77f1dd48e739a6d65b57744..0000000000000000000000000000000000000000
--- a/package/gluon-l3roamd/check_site.lua
+++ /dev/null
@@ -1 +0,0 @@
-need_string_match(in_domain({'node_client_prefix6'}), '^[%x:]+/64$', false)
diff --git a/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd b/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd
index c3ac189273adca211adefef31203cce0e36c70b9..40e4a7ebbf8dc036366bf0ba359af80ac316ef6e 100755
--- a/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd
+++ b/package/gluon-l3roamd/files/etc/init.d/gluon-l3roamd
@@ -43,7 +43,7 @@ start_service () {
 	local prefix4="$(lua -e 'prefix4 = require("gluon.site").prefix4() if prefix4 then print(" -p " .. prefix4) end')"
 	local prefix6="$(lua -e 'print(" -p " .. require("gluon.site").prefix6())')"
 	local localip="$(uci get network.loopback.ip6addr | cut -d/ -f1)"
-	local roamingprefix="$(lua -e 'roamingprefix = require("gluon.site").node_client_prefix6() if roamingprefix then print(" -P " .. roamingprefix) end')"
+	local roamingprefix="$(lua -e 'print(" -P " .. require("gluon.l3").node_client_prefix6())')"
 
 	/sbin/sysctl -w net.ipv6.neigh.default.gc_thresh1=2
 	/sbin/sysctl -w net.ipv4.neigh.default.gc_thresh1=2
diff --git a/package/gluon-mesh-babel/check_site.lua b/package/gluon-mesh-babel/check_site.lua
index acafaa6ef64e9454b7cef65f6613171a32237226..2182e833786d6eccc23c228f960cd4ccfe2a193a 100644
--- a/package/gluon-mesh-babel/check_site.lua
+++ b/package/gluon-mesh-babel/check_site.lua
@@ -1,5 +1,4 @@
 need_string_match(in_domain({'node_prefix6'}), '^[%x:]+/64$')
-need_string_match(in_domain({'node_client_prefix6'}), '^[%x:]+/64$')
 
 need_string_match(in_domain({'next_node', 'ip6'}), '^[%x:]+$', false)
 need_string_match(in_domain({'next_node', 'ip4'}), '^%d+.%d+.%d+.%d+$', false)
diff --git a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-mkconfig b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-mkconfig
index e9a62dbe60985ccdfa6521f5843560dcebadd528..7465494b55f0eae5f8a2c82afcfe7629823be7e1 100755
--- a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-mkconfig
+++ b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-mkconfig
@@ -1,6 +1,7 @@
 #!/usr/bin/lua
 
 local site = require 'gluon.site'
+local l3 = require 'gluon.l3'
 local uci = require('simple-uci').cursor()
 local nodeip = uci:get('network', 'loopback', 'ip6addr'):match('^[^/]+')
 local babelconf='/etc/gluon-babeld.conf'
@@ -14,7 +15,7 @@ file:write("import-table 254\n")
 file:write("out ip " .. site.next_node.ip6() .. "/128 deny\n")
 file:write("redistribute ip " .. site.next_node.ip6() .. "/128 deny\n")
 file:write("redistribute ip " .. site.prefix6() .. " eq 128  allow\n")
-file:write("redistribute ip " .. site.node_client_prefix6() .. " eq 128  allow\n")
+file:write("redistribute ip " .. l3.node_client_prefix6() .. " eq 128  allow\n")
 file:write("redistribute ip " .. site.node_prefix6() .. " eq 128  allow\n")
 file:write("redistribute ip 2000::/3 allow\n")
 file:write("redistribute local if br-wan deny\n")
diff --git a/package/gluon-mesh-layer3-common/check_site.lua b/package/gluon-mesh-layer3-common/check_site.lua
index dd6ee34893fa6191a26896a9ef2b6b1f0b4b7ecd..839b96b7a9caae432283462eee255f18e34c9d72 100644
--- a/package/gluon-mesh-layer3-common/check_site.lua
+++ b/package/gluon-mesh-layer3-common/check_site.lua
@@ -1,2 +1,2 @@
 need_string_match(in_domain({'node_prefix6'}), '^[%x:]+/64$')
-
+need_string_match(in_domain({'node_client_prefix6'}), '^[%x:]+/64$', false)
diff --git a/package/gluon-mesh-layer3-common/luasrc/usr/lib/lua/gluon/l3.lua b/package/gluon-mesh-layer3-common/luasrc/usr/lib/lua/gluon/l3.lua
new file mode 100644
index 0000000000000000000000000000000000000000..41c5d9a28297239b2e3ad1cc6f11744e079de259
--- /dev/null
+++ b/package/gluon-mesh-layer3-common/luasrc/usr/lib/lua/gluon/l3.lua
@@ -0,0 +1,20 @@
+local site = require("gluon.site")
+local util = require("gluon.util")
+
+local M = {}
+
+-- returns a prefix generated from the domain-seed
+-- for l3roamd -P <node-client-prefix>
+function M.node_client_prefix6()
+	local key = "gluon-l3roamd.node_client_prefix6"
+	local prefix = site.node_client_prefix6()
+
+	if not prefix then
+		local prefix_seed = util.domain_seed_bytes(key, 7)
+		prefix = ("fd" .. prefix_seed):gsub(("(%x%x%x%x)"):rep(4), "%1:%2:%3:%4" .. "::/64")
+	end
+
+	return prefix
+end
+
+return M