diff --git a/hoodselector/README.md b/hoodselector/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..193c1c1eb7d7b9984e4aafe578b8046dd184d84a
--- /dev/null
+++ b/hoodselector/README.md
@@ -0,0 +1,18 @@
+# Hoodselector
+
+## Command Line Options
+
+### Enable the Hoodselector
+```
+hoodselector enable
+```
+
+### Disable the Hoodselector
+```
+hoodselector disable
+```
+### Print Hoodfile Path
+```
+hoodselector hoodfile
+```
+
diff --git a/hoodselector/files/etc/config/hoodselector b/hoodselector/files/etc/config/hoodselector
new file mode 100644
index 0000000000000000000000000000000000000000..6f735b57adb56d3f964a381cc01e88f2cb26a264
--- /dev/null
+++ b/hoodselector/files/etc/config/hoodselector
@@ -0,0 +1,4 @@
+config settings 'hoodselector'
+    option hoodfile '/lib/ffnw/hoods/hoods.json'
+    option static '0'
+    option enabled '1'
\ No newline at end of file
diff --git a/hoodselector/luasrc/lib/gluon/upgrade/540-ffnw-hoodselector b/hoodselector/luasrc/lib/gluon/upgrade/540-ffnw-hoodselector
new file mode 100755
index 0000000000000000000000000000000000000000..f7426b30b754204ac9710ac4ad9e11d7ae3b571a
--- /dev/null
+++ b/hoodselector/luasrc/lib/gluon/upgrade/540-ffnw-hoodselector
@@ -0,0 +1,161 @@
+#!/usr/bin/lua
+
+local json = require ("luci.jsonc")
+local uci = require('luci.model.uci').cursor()
+
+-- Read the full hoodfile. Return nil for wrong format or no such file
+local function readHoodfile(file)
+  local jhood = io.open(file, 'r')
+  if not jhood then return nil end
+    local obj, _, err = json.parse (jhood:read('*a'), 1, nil)
+  if err then
+    return nil
+  else
+    return obj
+  end
+end
+
+local function vpn_reconfigure(hood_serverlist,local_serverlist)
+  -- remove all servers
+  for config_index, _ in pairs(local_serverlist) do
+    uci:delete('fastd',config_index)
+  end
+
+  -- add servers from hoodfile
+  local group = 'mesh_vpn_backbone'
+  for _,hood_server in pairs(hood_serverlist) do
+    uci:section('fastd', 'peer', group .. '_peer_' .. hood_server.host:split('.')[1]:gsub("%-", "%_") .. "_" .. hood_server.port,
+      {
+        enabled = 1,
+        net = 'mesh_vpn',
+        group = group,
+        key = hood_server.publickey,
+        remote = {'\"'..hood_server.host..'\"'..' port '..hood_server.port}
+      }
+    )
+  end
+
+  uci:save('fastd')
+end
+
+-- Reconfigure wireless
+local function wireless_reconfigure(radios, hood_bssid)
+  for _, radio in ipairs(radios) do
+    if not ( uci:get('wireless', 'ibss_' .. radio, 'bssid') == hood_bssid ) then
+      uci:section('wireless', 'wifi-iface', 'ibss_' .. radio, {
+          bssid = hood_bssid
+      })
+    end
+  end
+  uci:save('wireless')
+end
+
+-- Retun a table of current peers from /etc/config/fastd
+local function getCurrentPeers()
+  local configPeers = {}
+  local err = uci:foreach('fastd', 'peer',
+    function(s)
+      if s['.name'] then
+        for prefix,peer in pairs(s) do
+          local tmpPeer = {}
+          if prefix:match(".name") then
+            if peer:match("mesh_vpn_backbone_peer_") then
+              -- val tmpRemote does not need uci exception check because its already include by "uci:foreach"
+              local tmpRemote = uci:get('fastd', peer, 'remote')
+              tmpRemote = tmpRemote[1]:split(" ")
+              local remote = {}
+              remote['host'] = tmpRemote[1]
+              remote[tmpRemote[2]] = tmpRemote[3]
+              -- uci:get does not need uci exception check because its already include by "uci:foreach"
+              tmpPeer['key'] = tostring(uci:get('fastd', peer, 'key'))
+              tmpPeer['remote'] = remote
+              configPeers[peer] = tmpPeer
+            end
+          end
+        end
+      end
+    end
+  )
+  if not err then
+    os.exit(1)
+  end
+  return configPeers
+end
+
+local function getHoodByName(jhood,hoodname)
+  for _, h in pairs(jhood) do
+    if h.name == hoodname then
+        return h
+    end
+  end
+  return nil
+end
+
+-- Get a list of wifi devices return an emty table for no divices
+local function getWifiDevices()
+  local radios = {}
+  uci:foreach('wireless', 'wifi-device',
+    function(s)
+      table.insert(radios, s['.name'])
+    end
+  )
+  return radios
+end
+
+local function getDefaultHood(jhood)
+  for _, h in pairs(jhood) do
+    if h.defaulthood then
+      return h
+    end
+  end
+  return nil
+end
+
+-- START HERE
+
+local hoodfile = uci:get('hoodselector', 'hoodselector', 'hoodfile')
+local hoodname = uci:get('hoodselector', 'hoodselector', 'hood')
+local static = uci:get('hoodselector', 'hoodselector', 'static')
+local enabled = uci:get('hoodselector', 'hoodselector', 'enabled')
+
+if hoodfile == nil then
+  os.exit(1)
+end
+
+if static == nil then
+  static = '0'
+end
+
+if enabled == nil then
+  enabled = '1'
+end
+
+local jhood = readHoodfile(hoodfile)
+if jhood == nil then
+  enabled = 0
+end
+
+if hoodname == nil then
+  if jhood ~= nil then
+    hoodname = (getDefaultHood(jhood)).name
+  end
+end
+
+uci:section('hoodselector', 'settings', 'hoodselector', {
+  hood = hoodname,
+  hoodfile = hoodfile,
+  static = static,
+  enabled = enabled
+})
+uci:save('hoodselector')
+
+local hood = getHoodByName(jhood,hoodname)
+if hood == nil then
+  os.exit(1)
+end
+
+local radios = getWifiDevices()
+vpn_reconfigure(hood["servers"],getCurrentPeers())
+if radios ~= nil then
+    wireless_reconfigure(radios, hood["bssid"])
+end
\ No newline at end of file
diff --git a/hoodselector/luasrc/usr/sbin/hoodselector b/hoodselector/luasrc/usr/sbin/hoodselector
index 21b6f3498d484f5a01e855c339593d66950e2fde..9822ad9d2c1aa36a34792894fd6ddaab4fcf53c6 100755
--- a/hoodselector/luasrc/usr/sbin/hoodselector
+++ b/hoodselector/luasrc/usr/sbin/hoodselector
@@ -58,6 +58,42 @@ local function log(msg)
   end
 end
 
+if arg[1] ~= nil then
+  if arg[1] == 'enable' then
+    io.stderr:write("Hoodselector enabled\n")
+    uci:set('hoodselector', 'hoodselector', 'enabled' , 1)
+    uci:save('hoodselector')
+    uci:commit('hoodselector')
+  elseif arg[1] == 'disable' then
+    io.stderr:write('Hoodselector disabled\n')
+    uci:set('hoodselector', 'hoodselector', 'enabled' , 0)
+    uci:save('hoodselector')
+    uci:commit('hoodselector')
+  elseif arg[1] == 'hoodfile' then
+    if uci:get('hoodselector', 'hoodselector', 'hoodfile') == nil then
+      io.stderr:write("Hoodfile Path not in Config\n")
+    else
+      io.stderr:write("Hoodfile Path: " .. uci:get('hoodselector', 'hoodselector', 'hoodfile') .. "\n")
+    end
+  else
+    io.stderr:write(
+           "Hoodselector usage: \n\n"
+        .. "hoodselector \t\t runs the Hoodselector\n"
+        .. "hoodselector enable \t enable the Hoodselector\n"
+        .. "hoodselector disable \t disable the Hoodselector\n"
+        .. "hoodselector hoodfile \t shows the path of the Hoodfile\n")
+  end
+  os.exit(0)
+end
+
+local hoodselectorenabled = uci:get('hoodselector', 'hoodselector', 'enabled')
+
+if hoodselectorenabled == '0' then
+  io.stderr:write("Hoodselector is disabled by UCI\n")
+  os.exit(0)
+end
+
+
 if io.open(pidPath, "r") ~=nil then
   log("The hoodselector is still running.")
   os.exit(1)
@@ -68,7 +104,15 @@ else
   end
 end
 
-local FILE = '/lib/ffnw/hoods/hoods.json'
+
+local hoodstatic = 0
+
+local FILE = uci:get('hoodselector', 'hoodselector', 'hoodfile')
+if FILE == nil then
+  log("No hood file in config")
+  os.exit(1)
+end
+
 -- initialization done
 
 -- Read the full hoodfile. Return nil for wrong format or no such file
@@ -563,6 +607,18 @@ local function wireless_reconfigure(radios, hood_bssid)
   uci:commit('wireless')
 end
 
+-- Save selected hood to config to make a restore after a sysupgrade possible
+local function saveHoodToConfig(hoodname)
+    uci:section('hoodselector', 'settings', 'hoodselector', {
+      hood = hoodname,
+      hoodfile = FILE,
+      static = hoodstatic,
+      enabled = hoodselectorenabled
+    })
+  uci:save('hoodselector')
+  uci:commit('hoodselector')
+end
+
 -- This method sets a new hoodconfig and takes care that services are only
 -- stopped or restarted if reconfiguration is needed.
 -- Process:
@@ -574,15 +630,18 @@ end
 --   * If fastd needed reconfiguration start fastd now
 local function set_hoodconfig(hood, radios)
   local local_serverlist = getCurrentPeers()
+  local config_changed = false
   -- Check if VPN needs reconfiguration because in case of reconfiguration we
   -- need to stop VPN before we can reconfigure any other connection.
   local vpn_reconf_needed = vpn_reconfiguration_needed(hood["servers"],local_serverlist);
   if(vpn_reconf_needed) then
+    config_changed = true
     vpn_stop()
   end
 
   -- reconfigure wireless
   if(wireless_reconfiguration_needed(radios, hood["bssid"])) then
+    config_changed = true
     wireless_reconfigure(radios, hood["bssid"])
     wireless_restart()
     io.stderr:write('Wireless needed reconfiguration. Applied new settings and restarted.\n')
@@ -600,6 +659,13 @@ local function set_hoodconfig(hood, radios)
   io.stderr:write("Set hood \""..hood["name"].."\"\n")
   molwmtable["hoodname"] = "\"" .. hood["name"] .. "\""
 
+  if(uci:get('hoodselector', 'hoodselector' , 'hood') ~= hood["name"]) then
+    config_changed = true
+  end
+
+  if config_changed then
+    saveHoodToConfig(hood["name"])
+  end
   return true
 end
 
@@ -641,13 +707,10 @@ end
 
 -- Return hood from hood file based on a peer address. nil if no matching hood could be found
 local function getCurrentHood(jhood)
-  for _, local_server in pairs(getCurrentPeers()) do
-    for _, h in pairs(jhood) do
-      for _, peer in pairs(h.servers) do
-	if ( peer["host"] == local_server.remote.host:gsub("\"", "") ) then
-	  return h
-	end
-      end
+  local hoodname = uci:get('hoodselector', 'hoodselector', 'hood')
+  for _, h in pairs(jhood) do
+    if h.name == hoodname then
+      return h
     end
   end
   return nil