diff --git a/gluon_patches/0004-add-pkg-gluon-hoodselector.patch b/gluon_patches/0004-add-pkg-gluon-hoodselector.patch
new file mode 100644
index 0000000000000000000000000000000000000000..eef1fae85807adb76111a26c3fe1134ef02e045a
--- /dev/null
+++ b/gluon_patches/0004-add-pkg-gluon-hoodselector.patch
@@ -0,0 +1,1911 @@
+From bfb90653c70a1f9c9573b4d0b4efc48702320f62 Mon Sep 17 00:00:00 2001
+From: Jan-Tarek Butt <tarek@ring0.de>
+Date: Mon, 18 Sep 2017 18:20:28 +0200
+Subject: [PATCH 5/5] add pkg gluon-hoodselector
+
+ * add pkg Makefile
+ * add respondd c file
+ * add respondd Makefile
+ * add etc config
+ * add micron.d file
+ * add upgrade script 540-hoodselector
+ * add hoodselector lua script
+ * rm gluon-hoods and gluon-mesh-vpn-fastd from DEPENDS
+ * config rm static option
+ * backport tested comunity version:
+   - Hoodselector: is now able to handle Polygon hoods. !60
+   - Hoodselector: does not use `scan dump` anymore which
+                   saved airtime
+   - Hoodselector: L2TP tunneldigger support #47
+   - Hoodselector: the upgrade script got a refactoring.
+                   Dead code is removed. desing failuer is
+                   fixed, the script use the hood BSSID
+                   instead the possible redundant hood name
+                   for hood identification. #107
+   - Hoodselector: New state, a router from hood A which is
+                   connected to an another router from hood B
+                   is now able to switch back in its own hood
+                   if a router from hood A viseble. #108
+   - Hoodselector: in state "radio less" is now ensured that
+                   mesh on LAN / WAN is enabled befor entering
+                   mode. #109
+   - Hoodselector: A bug in the function get_mesh_if() is
+                   fixed now. This function returns now a list
+                   of all mesh interfaces exzept the VPN
+                   interface #116
+   - Hoodselector: Old VPN configurations will be deleted now.
+                   If a hood without VPN peers got configured
+                   the old peers from the old hood was still
+                   presend. #117
+   - Hoodselector: many functions of the hoodselector are now
+                   placed in a lua libary. #118
+---
+ package/gluon-hoodselector/Makefile                |  43 +
+ .../files/etc/config/hoodselector                  |   3 +
+ .../files/usr/lib/micron.d/hoodselector            |   1 +
+ .../luasrc/lib/gluon/upgrade/540-hoodselector      |  88 ++
+ .../luasrc/usr/lib/lua/hoodselector/util.lua       | 898 +++++++++++++++++++++
+ .../luasrc/usr/sbin/hoodselector                   | 622 ++++++++++++++
+ package/gluon-hoodselector/src/Makefile            |   6 +
+ package/gluon-hoodselector/src/respondd.c          | 139 ++++
+ 8 files changed, 1800 insertions(+)
+ create mode 100644 package/gluon-hoodselector/Makefile
+ create mode 100644 package/gluon-hoodselector/files/etc/config/hoodselector
+ create mode 100644 package/gluon-hoodselector/files/usr/lib/micron.d/hoodselector
+ create mode 100755 package/gluon-hoodselector/luasrc/lib/gluon/upgrade/540-hoodselector
+ create mode 100644 package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua
+ create mode 100755 package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
+ create mode 100644 package/gluon-hoodselector/src/Makefile
+ create mode 100644 package/gluon-hoodselector/src/respondd.c
+
+diff --git a/package/gluon-hoodselector/Makefile b/package/gluon-hoodselector/Makefile
+new file mode 100644
+index 00000000..210e5200
+--- /dev/null
++++ b/package/gluon-hoodselector/Makefile
+@@ -0,0 +1,43 @@
++include $(TOPDIR)/rules.mk
++
++PKG_NAME:=gluon-hoodselector
++PKG_VERSION:=1
++PKG_RELEASE:=1
++
++PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
++PKG_BUILD_DEPENDS := respondd
++
++include ../gluon.mk
++
++define Package/gluon-hoodselector
++  SECTION:=network
++  CATEGORY:=Gluon
++  TITLE:=Automatic layer2 networksecmentation depending on geo coordinates
++  DEPENDS:=+luci-lib-jsonc +gluon-mesh-batman-adv-15 +respondd +iwinfo
++endef
++
++define Package/gluon-hoodselector/description
++	Automatic layer2 networksecmentation depending on geo coordinates
++endef
++
++define Build/Prepare
++	mkdir -p $(PKG_BUILD_DIR)
++	$(CP) ./src/* $(PKG_BUILD_DIR)/
++endef
++
++define Build/Configure
++endef
++
++define Build/Compile
++	$(call Build/Compile/Default)
++	$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
++endef
++
++define Package/gluon-hoodselector/install
++	$(CP) ./files/* $(1)/
++	$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
++	$(INSTALL_DIR) $(1)/lib/gluon/respondd
++	$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/hoodselector.so
++endef
++
++$(eval $(call BuildPackage,gluon-hoodselector))
+diff --git a/package/gluon-hoodselector/files/etc/config/hoodselector b/package/gluon-hoodselector/files/etc/config/hoodselector
+new file mode 100644
+index 00000000..24b2800c
+--- /dev/null
++++ b/package/gluon-hoodselector/files/etc/config/hoodselector
+@@ -0,0 +1,3 @@
++config settings 'hoodselector'
++    option hoodfile '/lib/gluon/hoods.json'
++    option enabled '1'
+diff --git a/package/gluon-hoodselector/files/usr/lib/micron.d/hoodselector b/package/gluon-hoodselector/files/usr/lib/micron.d/hoodselector
+new file mode 100644
+index 00000000..a4c9916d
+--- /dev/null
++++ b/package/gluon-hoodselector/files/usr/lib/micron.d/hoodselector
+@@ -0,0 +1 @@
++*/2 * * * * /usr/sbin/hoodselector 2>> /tmp/hoodselector_error
+diff --git a/package/gluon-hoodselector/luasrc/lib/gluon/upgrade/540-hoodselector b/package/gluon-hoodselector/luasrc/lib/gluon/upgrade/540-hoodselector
+new file mode 100755
+index 00000000..a0fe8d65
+--- /dev/null
++++ b/package/gluon-hoodselector/luasrc/lib/gluon/upgrade/540-hoodselector
+@@ -0,0 +1,88 @@
++#!/usr/bin/lua
++
++local uci = require('simple-uci').cursor()
++local hoodutil = require("hoodselector.util")
++
++-- Retun a table of current peers from /etc/config/fastd
++local function getCurrentPeers()
++  local configPeers = {}
++  local err = uci:foreach('fastd', 'peer',
++    function(s)
++      hoodutil.extrac_fastd_peer(s,configPeers)
++    end
++  )
++  if not err then
++    os.exit(1)
++  end
++  return configPeers
++end
++
++-- START HERE
++local hoodfile = uci:get('hoodselector', 'hoodselector', 'hoodfile')
++local hoodbssid = uci:get('hoodselector', 'hoodselector', 'hood')
++
++if hoodfile == nil then
++  os.exit(1)
++end
++
++local jhood = hoodutil.readHoodfile(hoodfile)
++if jhood == nil then
++  uci:set('hoodselector', 'hoodselector', 'enabled', false)
++  uci:save('hoodselector')
++  os.exit(1)
++end
++
++if hoodbssid == nil then
++  local defaulthood = hoodutil.getDefaultHood(jhood)
++  if defaulthood == nil then
++    os.exit(1)
++  end
++  if defaulthood.bssid == nil then
++    os.exit(1)
++  end
++  hoodbssid = defaulthood.bssid
++end
++
++local hood = hoodutil.gethoodByBssid(jhood,hoodbssid)
++if hood == nil then
++  os.exit(1)
++end
++
++uci:section('hoodselector', 'settings', 'hoodselector', {
++  hood = hoodbssid,
++  hoodfile = hoodfile,
++  enabled = true
++})
++uci:save('hoodselector')
++
++local radios = hoodutil.getWifiDevices()
++-- pre check if fastd conf exsist
++if uci:get('fastd', 'mesh_vpn_backbone', 'net') ~= nil then
++  hoodutil.fastd_reconfigure(hood["servers"],getCurrentPeers())
++end
++-- per check if tunneldigger conf exsist
++if uci:get('tunneldigger', 'mesh_vpn', 'interface') ~= nil then
++  hoodutil.tunneldigger_reconfigure(hood["servers"])
++end
++
++if next(radios) then
++  local ibss_exists = false
++  local mesh_exists = false
++  for _,radio in ipairs(radios) do
++    local ifname = uci:get('wireless', 'ibss_' .. radio, 'ifname')
++    if (ifname ~= nil) then
++      ibss_exists = true
++    end
++    ifname = uci:get('wireless', 'mesh_' .. radio, 'ifname')
++    if (ifname ~= nil) then
++      mesh_exists = true
++    end
++  end
++  if ibss_exists then
++    hoodutil.ibss_reconfigure(radios, hood["bssid"])
++  end
++  if mesh_exists then
++    local mesh_prefix = hoodutil.get_mesh_prefix(radios)
++    hoodutil.mesh_reconfigure(radios, mesh_prefix..hood["bssid"]:lower())
++  end
++end
+diff --git a/package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua b/package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua
+new file mode 100644
+index 00000000..05678809
+--- /dev/null
++++ b/package/gluon-hoodselector/luasrc/usr/lib/lua/hoodselector/util.lua
+@@ -0,0 +1,898 @@
++local json = require ("luci.jsonc")
++local uci = require('simple-uci').cursor()
++
++local M = {}
++
++function M.split(s, delimiter)
++  local result = {};
++  for match in (s..delimiter):gmatch("(.-)"..delimiter) do
++    table.insert(result, match);
++  end
++  return result;
++end
++
++local PID = M.split(io.open("/proc/self/stat", 'r'):read('*a'), " ")[1]
++
++function M.log(msg)
++  if msg then
++    io.stdout:write(msg.."\n")
++    os.execute("logger hoodselector["..PID.."]: "..msg)
++  end
++end
++
++-- Read the full hoodfile. Return nil for wrong format or no such file
++function M.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
++
++function M.mesh_on_wan_disable()
++  os.execute('ifdown mesh_wan')
++  io.stdout:write('Interface mesh_wan disabled.\n')
++end
++
++function M.mesh_on_wan_enable()
++  os.execute('ifup mesh_wan')
++  io.stdout:write('Interface mesh_wan enabled.\n')
++end
++
++function M.mesh_on_lan_disable()
++  os.execute('ifdown mesh_lan')
++  io.stdout:write('Interface mesh_lan disabled.\n')
++end
++
++function M.mesh_on_lan_enable()
++  os.execute('ifup mesh_lan')
++  io.stdout:write('Interface mesh_lan enabled.\n')
++end
++
++function M.fastd_installed()
++  if io.open("/usr/bin/fastd", 'r') ~= nil then
++    return true
++  end
++  return false
++end
++
++function M.tunneldigger_installed()
++  if io.open("/usr/bin/tunneldigger", 'r') ~= nil then
++    return true
++  end
++  return false
++end
++
++function M.filt_if(filt,str)
++  for _, c in ipairs(filt) do
++    -- check if - is contains because it is a magic character thus it musst be replace)
++    if c:gsub("%-", "0"):match(str:gsub("%-", "0")) then
++      return true
++    end
++  end
++  return false
++end
++
++function M.filter_redundancy(list)
++  local flag = {}
++  local ret = {}
++  for _,element in ipairs(list) do
++    if not flag[element] then
++      ret[#ret+1] = element
++      flag[element] = true
++    end
++  end
++  return ret
++end
++
++function M.trim(s)
++  -- from PiL2 19.4
++  return (s:gsub("^%s*(.-)%s*$", "%1"))
++end
++
++function M.sleep(n)
++  os.execute("sleep " .. tonumber(n))
++end
++
++function M.brclient_restart()
++  os.execute('ifconfig br-client down')
++  os.execute('ifconfig br-client up')
++  io.stdout:write('Interface br-client restarted.\n')
++end
++
++function M.vpn_stop()
++  -- check if fastd installed
++  if M.fastd_installed() then
++    if uci:get_bool('fastd','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/fastd stop')
++      io.stdout:write('Fastd stoped.\n')
++    end
++  end
++  -- check if tunneldigger installed
++  if M.tunneldigger_installed() then
++    if uci:get_bool('tunneldigger','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/tunneldigger stop')
++      io.stdout:write('Tunneldigger stoped.\n')
++    end
++  end
++end
++
++function M.vpn_start()
++  if M.fastd_installed() then
++    if uci:get_bool('fastd','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/fastd start')
++      io.stdout:write('Fastd started.\n')
++    end
++  end
++  if M.tunneldigger_installed() then
++    if uci:get_bool('tunneldigger','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/tunneldigger start')
++      io.stdout:write('Tunneldigger started.\n')
++    end
++  end
++  M.brclient_restart()
++end
++
++function M.vpn_disable()
++  if M.fastd_installed() then
++    if uci:get_bool('fastd','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/fastd disable')
++      io.stdout:write('Fastd disabled.\n')
++    end
++  end
++  if M.tunneldigger_installed() then
++    if uci:get_bool('tunneldigger','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/tunneldigger disable')
++      io.stdout:write('Tunneldigger disabled.\n')
++    end
++  end
++end
++
++function M.vpn_enable()
++  if M.fastd_installed() then
++    if not uci:get_bool('fastd','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/fastd enable')
++      io.stdout:write('Fastd enabled.\n')
++    end
++  end
++  if M.tunneldigger_installed() then
++    if not uci:get_bool('tunneldigger','mesh_vpn','enabled') then
++      os.execute('/etc/init.d/tunneldigger enable')
++      io.stdout:write('Tunneldigger enabled.\n')
++    end
++  end
++end
++
++function M.wireless_restart()
++  os.execute('wifi')
++  io.stdout:write('Wireless restarted.\n')
++end
++
++-- Get a list of wifi devices return an emty table for no divices
++function M.getWifiDevices()
++  local radios = {}
++  uci:foreach('wireless', 'wifi-device',
++    function(s)
++      table.insert(radios, s['.name'])
++    end
++  )
++  return radios
++end
++
++-- get signal strength
++function M.scan_filter_quality(scan_str, redirect)
++  local tmp_quality = redirect
++  if scan_str:match("signal:") then
++    tmp_quality = M.split(scan_str, " ")
++    tmp_quality = M.split(tmp_quality[2], "%.")
++    if tmp_quality[1]:match("-") then
++      tmp_quality = M.split(tmp_quality[1], "-")
++    end
++    tmp_quality = tonumber(tmp_quality[2]:match("(%d%d)"))
++  end
++  return tmp_quality
++end
++
++-- get frequency
++function M.scan_filter_frequency(scan_str, redirect)
++  local tmp_frequency = redirect
++  if scan_str:match("freq") then
++    tmp_frequency = M.split(scan_str, ":")
++    tmp_frequency = tmp_frequency[2]
++    if tmp_frequency ~= nil then
++      tmp_frequency = M.trim(tmp_frequency)
++    end
++  end
++  return tmp_frequency
++end
++
++function M.ibss_scan(radio,ifname,ssid,networks)
++  local wireless_scan = string.format( "iw %s scan", ifname)
++  local row = {}
++  row["radio"] = radio
++  -- loop through each line in the output of iw
++  for wifiscan in io.popen(wireless_scan, 'r'):lines() do
++    -- the following line matches a new network in the output of iw
++    if(row["bssid"] ~= nil and row["quality"] ~= nil and row["ssid"] == ssid) then
++      table.insert(networks, row)
++      row = {}
++      row["radio"] = radio
++    end
++
++    -- get ssid
++    if wifiscan:match("SSID:") then
++      row["ssid"] = M.split(wifiscan, ":")
++      row["ssid"] = row["ssid"][2]
++      if(row["ssid"] ~= nil) then
++        row["ssid"] = M.trim(row["ssid"])
++      end
++    end
++    row["frequency"] = M.scan_filter_frequency(wifiscan, row["frequency"])
++
++    -- get bssid
++    if wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then
++      row["bssid"] = wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)")
++    end
++    row["quality"] = M.scan_filter_quality(wifiscan, row["quality"])
++  end
++  return networks
++end
++
++function M.mesh_scan(radio,ifname,meshid,networks)
++  local wireless_scan = string.format( "iw %s scan", ifname)
++  local row = {}
++  row["radio"] = radio
++  -- loop through each line in the output of iw
++  for wifiscan in io.popen(wireless_scan, 'r'):lines() do
++    -- the following line matches a new network in the output of iw
++    if(row["bssid"] ~= nil and row["quality"] ~= nil and row["ssid"] == meshid) then
++      table.insert(networks, row)
++      row = {}
++      row["radio"] = radio
++    end
++    row["frequency"] = M.scan_filter_frequency(wifiscan, row["frequency"])
++    row["quality"] = M.scan_filter_quality(wifiscan, row["quality"])
++
++    -- get mesh-ID(ssid) and hoodbssid
++    if wifiscan:match("MESH ID:") then
++      local meshID = M.split(wifiscan, " ")[3]
++      if meshID ~= nil then
++        meshID = M.split(meshID, "_")
++        if meshID[1] ~= nil then
++          row["ssid"] = meshID[1].."_"
++        end
++        if meshID[2] ~= nil then
++          if meshID[2]:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then
++            row["bssid"] = meshID[2]:match("(%w+:%w+:%w+:%w+:%w+:%w+)")
++          end
++        end
++      end
++    end
++  end
++  return networks
++end
++
++-- Scans for wireless networks and returns a two dimensional array containing
++-- wireless mesh neighbour networks and their properties.
++-- The array is sorted descending by signal strength (strongest signal
++-- first, usually the local signal of the wireless chip of the router)
++function M.wlan_list_sorted(radios, mesh_prefix)
++  local networks = {}
++  for _, radio in ipairs(radios) do
++    local ifname = uci:get('wireless', 'ibss_' .. radio, 'ifname')
++    local ssid = uci:get('wireless', 'ibss_' .. radio, 'ssid')
++    if (ifname ~= nil and ssid ~= nil) then
++      --do ibss scan
++      networks = M.ibss_scan(radio,ifname,ssid,networks)
++    end
++    ifname = uci:get('wireless', 'mesh_' .. radio, 'ifname')
++    if (ifname ~= nil and mesh_prefix ~= nil) then
++      --do mesh scan
++      networks = M.mesh_scan(radio,ifname,mesh_prefix,networks)
++    end
++  end
++  table.sort(networks, function(a,b) return a["quality"] < b["quality"] end)
++  return networks
++end
++
++-- this method removes the wireless network of the router itself
++-- from the wlan_list
++function M.filter_my_wlan_network(wlan_list)
++  for i=#wlan_list,1,-1 do
++    local bssid = uci:get('wireless', 'ibss_' .. wlan_list[i].radio, 'bssid')
++    if bssid ~= nil then
++      if string.lower(wlan_list[i].bssid) == string.lower(bssid) then
++        table.remove(wlan_list, i)
++      end
++    else
++      local mesh = uci:get('wireless', 'mesh_' .. wlan_list[i].radio, 'mesh_id')
++      if mesh ~= nil then
++        if string.lower(wlan_list[i].ssid..wlan_list[i].bssid) == string.lower(mesh) then
++          table.remove(wlan_list, i)
++        end
++      end
++    end
++  end
++  return wlan_list
++end
++
++function M.filter_default_hood_wlan_networks(default_hood, wlan_list)
++  for i=#wlan_list,1,-1 do
++    if(string.lower(default_hood.bssid) == string.lower(wlan_list[i].bssid)) then
++      table.remove(wlan_list, i)
++    end
++  end
++  return wlan_list
++end
++
++-- Get Geoposition. Return nil for no position
++function M.getGeolocation()
++  return {["lat"] = tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'latitude')),
++  ["lon"] =  tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'longitude')) }
++end
++
++-- Source with pseudocode: https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan
++-- see also https://en.wikipedia.org/wiki/Point_in_polygon
++-- parameters: points A = (x_A,y_A), B = (x_B,y_B), C = (x_C,y_C)
++-- return value: −1 if the ray from A to the right bisects the edge [BC] (the lower vortex of [BC]
++-- is not seen as part of [BC]);
++--                0 if A is on [BC];
++--               +1 else
++function M.crossProdTest(x_A,y_A,x_B,y_B,x_C,y_C)
++  if y_A == y_B and y_B == y_C then
++    if (x_B <= x_A and x_A <= x_C) or (x_C <= x_A and x_A <= x_B) then
++      return 0
++    end
++    return 1
++  end
++  if not ((y_A == y_B) and (x_A == x_B)) then
++    if y_B > y_C then
++      -- swap B and C
++      local h = x_B
++      x_B = x_C
++      x_C = h
++      h = y_B
++      y_B = y_C
++      y_C = h
++    end
++    if (y_A <= y_B) or (y_A > y_C) then
++      return 1
++    end
++    local Delta = (x_B-x_A) * (y_C-y_A) - (y_B-y_A) * (x_C-x_A)
++    if Delta > 0 then
++      return 1
++    elseif Delta < 0 then
++      return -1
++    end
++  end
++  return 0
++end
++
++-- Source with pseudocode: https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan
++-- see also: https://en.wikipedia.org/wiki/Point_in_polygon
++-- let P be a 2D Polygon and Q a 2D Point
++-- return value:  +1 if Q within P;
++--               −1 if Q outside of P;
++--                0 if Q on an edge of P
++function M.pointInPolygon(poly, point)
++  local t = -1
++  for i=1,#poly-1 do
++    t = t * M.crossProdTest(point.lon,point.lat,poly[i][2],poly[i][1],poly[i+1][2],poly[i+1][1])
++    if t == 0 then break end
++  end
++  return t
++end
++
++-- Return hood from the hood file based on geo position or nil if no real hood could be determined
++-- First check if an area has > 2 points and is hence a polygon. Else assume it is a rectangular
++-- box defined by two points (south-west and north-east)
++function M.getHoodByGeo(jhood,geo)
++  for _, h in pairs(jhood) do
++    for _, area in pairs(h.boxes) do
++      if #area > 2 then
++        if (M.pointInPolygon(area,geo) == 1) then
++          return h
++        end
++      else
++        if ( geo.lat >= area[1][1] and geo.lat < area[2][1] and geo.lon >= area[1][2] and geo.lon < area[2][2] ) then
++          return h
++        end
++      end
++    end
++  end
++  return nil
++end
++
++-- This method checks if the fastd configuration needs to be rewritten from the
++-- hoodfile. Therefore the method performs 3 checks and returns false if all
++-- checks fail. If one of the checks results to true the method returns true:
++--   1. Check if the local fastd configuration has a server that does not exist
++--      in the hoodfile.
++--   2. Check if a server that does exist in the local fastd configuration AND
++--      in the hoodfile has a configuration change.
++--   3. Check if the hoodfile contains a server that does not exist in the
++--      local fastd configuration.
++function M.fastd_reconfiguration_needed(hood_serverlist,local_serverlist)
++
++  local tmp_hood_serverlist = {}
++  for _,hood_server in pairs(hood_serverlist) do
++    if (hood_server["type"] == "fastd") then
++      table.insert(tmp_hood_serverlist,hood_server)
++    end
++  end
++
++  -- Checks 1. and 2.
++  for local_server_config_name, local_server in pairs(local_serverlist) do
++    local local_server_exists_in_hoodfile = false
++    for _,hood_server in pairs(tmp_hood_serverlist) do
++      if (local_server_config_name == 'mesh_vpn_backbone_peer_'..
++        M.split(hood_server["host"], '.')[1]:gsub("%-", "%_") .. "_" .. hood_server['port']) then
++        local_server_exists_in_hoodfile = true
++        if ( local_server.key ~= hood_server['publickey'] ) then return true end
++        if ( local_server.remote.host ~= '\"'..hood_server["host"]..'\"' ) then return true end
++        if ( local_server.remote.port ~= hood_server['port'] ) then return true end
++      end
++    end
++    if not local_server_exists_in_hoodfile then return true end
++  end
++
++  -- Check 3.
++  for _,hood_server in pairs(tmp_hood_serverlist) do
++    local hood_server_exists_locally = false
++    for local_server_config_name, _ in pairs(local_serverlist) do
++      if (local_server_config_name == 'mesh_vpn_backbone_peer_'..
++        M.split(hood_server["host"], '.')[1]:gsub("%-", "%_") .. "_" .. hood_server['port']) then
++        hood_server_exists_locally = true
++      end
++    end
++    if not hood_server_exists_locally then return true end
++  end
++  return false
++end
++
++function M.tunneldigger_reconfiguration_needed(hood_serverlist,local_serverlist)
++
++  local tmp_hood_serverlist = {}
++  for _,hood_server in pairs(hood_serverlist) do
++    if (hood_server["type"] == "l2tp") then
++      table.insert(tmp_hood_serverlist,hood_server)
++    end
++  end
++
++  -- Checks 1. and 2.
++  for _,local_peer in pairs(local_serverlist) do
++    local local_server_exists_in_hoodfile = false
++    for _,hood_server in pairs(tmp_hood_serverlist) do
++      if (local_peer == hood_server["host"] .. ":" .. hood_server["port"]) then
++        local_server_exists_in_hoodfile = true
++      end
++    end
++    if not local_server_exists_in_hoodfile then return true end
++  end
++
++  -- Check 3.
++  for _,hood_server in pairs(tmp_hood_serverlist) do
++    local hood_server_exists_locally = false
++    for _,local_peer in pairs(local_serverlist) do
++      if (local_peer == hood_server["host"] .. ":" .. hood_server["port"]) then
++        hood_server_exists_locally = true
++      end
++    end
++    if not(hood_server_exists_locally) then return true end
++  end
++  return false
++end
++
++-- Reconfigure fastd
++function M.fastd_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
++    if (hood_server["type"] == "fastd") then
++      uci:section('fastd', 'peer', group .. '_peer_' ..
++      M.split(hood_server.host, '.')[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
++  end
++
++  uci:save('fastd')
++  uci:commit('fastd')
++  io.stdout:write('Fastd needed reconfiguration. Stopped and applied new settings.\n')
++end
++
++function M.tunneldigger_reconfigure(hood_serverlist)
++  -- remove all servers
++  uci:delete('tunneldigger', 'mesh_vpn', 'address')
++
++  -- add servers from hoodfile
++  local addresslist = {}
++  for _,hood_server in pairs(hood_serverlist) do
++    if (hood_server["type"] == "l2tp") then
++      local tmpAdrr =hood_server["host"] .. ":" .. hood_server["port"]
++      table.insert(addresslist, tmpAdrr)
++    end
++  end
++  if next(addresslist) then
++    uci:set('tunneldigger', 'mesh_vpn', 'address', addresslist)
++  end
++  uci:save('tunneldigger')
++  uci:commit('tunneldigger')
++  io.stdout:write('tunneldigger needed reconfiguration. Stopped and applied new settings.\n')
++end
++
++-- Checks if wireless needs a reconfiguration. Returns true if any of the checks
++-- passes. Otherwise the method returns false.
++function M.wireless_reconfiguration_needed(radios, prefix, hood_bssid)
++  local configure_ibss = false
++  local configure_mesh = false
++  for _, radio in ipairs(radios) do
++    if uci:get('wireless', 'ibss_' .. radio, 'ifname') ~= nil then
++      if ( uci:get('wireless', 'ibss_' .. radio, 'bssid') ~= hood_bssid ) then
++        configure_ibss = true
++      end
++    end
++    if uci:get('wireless', 'mesh_' .. radio, 'ifname') ~= nil then
++      if ( uci:get('wireless', 'mesh_' .. radio, 'mesh_id') ~= prefix..hood_bssid:lower() ) then
++        configure_mesh = true
++      end
++    end
++  end
++  if not configure_ibss and not configure_mesh then return 0 end --no changes
++  if configure_ibss and not configure_mesh then return 1 end --ibss changes
++  if not configure_ibss and configure_mesh then return 2 end --mesh changes
++  return 3 --bouth changes
++end
++
++-- Reconfigure wireless
++function M.ibss_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')
++  uci:commit('wireless')
++end
++
++function M.mesh_reconfigure(radios, meshid)
++  for _, radio in ipairs(radios) do
++    if not ( uci:get('wireless', 'mesh_' .. radio, 'mesh_id') == meshid ) then
++      uci:section('wireless', 'wifi-iface', 'mesh_' .. radio, {mesh_id = meshid})
++    end
++  end
++  uci:save('wireless')
++  uci:commit('wireless')
++end
++
++-- Save selected hood to config to make a restore after a sysupgrade possible
++function M.saveHoodToConfig(hoodbssid)
++  uci:set('hoodselector', 'hoodselector', 'hood', hoodbssid)
++  uci:save('hoodselector')
++  uci:commit('hoodselector')
++end
++
++-- Return the default hood in the hood list.
++-- This method can return the following data:
++-- * default hood
++-- * nil if no default hood has been defined
++function M.getDefaultHood(jhood)
++  for _, h in pairs(jhood) do
++    if h.defaulthood then
++      return h
++    end
++  end
++  return nil
++end
++
++-- boolean check if batman-adv has gateways
++function M.batmanHasGateway()
++  local file = io.open("/sys/kernel/debug/batman_adv/bat0/gateways", 'r')
++  if file ~= nil then
++    for gw in file:lines() do
++      if gw:match("Bit") then
++        return true
++      end
++    end
++  end
++  return false
++end
++
++-- Return hood from the hood file based on a given BSSID. nil if no matching hood could be found
++function M.gethoodByBssid(jhood, scan_bssid)
++  for _, h in pairs(jhood) do
++    if scan_bssid:lower():match(h.bssid:lower()) then
++      return h
++    end
++  end
++  return nil
++end
++
++-- Return hood from hood file based on a bssid address. nil if no matching hood could be found
++function M.getCurrentHood(jhood)
++  local hoodbssid = uci:get('hoodselector', 'hoodselector', 'hood')
++  for _, h in pairs(jhood) do
++    if h.bssid == hoodbssid then
++      return h
++    end
++  end
++  return nil
++end
++
++function M.test_batman_mesh_networks(sorted_wlan_list, meshprefix)
++  -- remove the ap network because we cannot change
++  -- the settings of the adhoc network if the ap network is still operating
++  for iface in io.popen(string.format("iw dev"),'r'):lines() do
++    if iface:match("Interface") then
++      iface = M.trim(M.split(iface, "Interface")[2])
++      if not ( iface:match("ibss") or iface:match("mesh")) then
++        os.execute("iw dev "..iface.." del")
++      end
++    end
++  end
++  for _, wireless in pairs(sorted_wlan_list) do
++    local ibss = uci:get('wireless', 'ibss_' .. wireless["radio"], 'ifname')
++    local mesh = uci:get('wireless', 'mesh_' .. wireless["radio"], 'ifname')
++    if wireless["ssid"] == uci:get('wireless', 'ibss_' .. wireless["radio"], 'ssid') then
++      io.stdout:write("Testing IBSS "..wireless["bssid"].."...\n")
++      -- leave the current adhoc network
++      os.execute("iw dev "..ibss.." ibss leave 2> /dev/null")
++      if mesh ~= nil then
++        os.execute("iw dev "..mesh.." mesh leave 2> /dev/null")
++      end
++      -- setup the adhoc network we want to test
++      os.execute("iw dev "..ibss.." ibss join "..wireless["ssid"].." "..wireless["frequency"].." "..wireless["bssid"])
++    end
++    if wireless["ssid"] == meshprefix then
++      io.stdout:write("Testing MESH "..wireless["bssid"].."...\n")
++      -- leave the current mesh network
++      os.execute("iw dev "..mesh.." mesh leave 2> /dev/null")
++      if ibss ~= nil then
++        os.execute("iw dev "..ibss.." ibss leave 2> /dev/null")
++      end
++      -- setup the mesh network we want to test
++      os.execute("iw dev "..mesh.." mesh join "..meshprefix..wireless["bssid"].." freq "..wireless["frequency"])
++    end
++    -- sleep 30 seconds till the connection is fully setup
++    local c = 0;
++    while(not M.batmanHasGateway()) do
++      if(c >= 30) then break end
++      M.sleep(1)
++      c = c +1;
++    end
++    if c < 30 then
++      return wireless["bssid"]
++    end
++  end
++  return nil
++end
++
++function M.get_batman_mesh_network(sorted_wlan_list, defaultHood, meshprefix)
++  io.stdout:write('Testing neighbouring adhoc networks for batman advanced gw connection.\n')
++  io.stdout:write('The following wireless networks have been found:\n')
++  for _, network in pairs(sorted_wlan_list) do
++    print(network["quality"].."\t"..network["frequency"].."\t"..network["bssid"].."\t"..network["ssid"])
++  end
++
++  -- we dont want to test the default hood because if there is no other
++  -- hood present we will connect to the default hood anyway
++  sorted_wlan_list = M.filter_default_hood_wlan_networks(defaultHood, sorted_wlan_list)
++
++  -- we dont want to test duplicated networks
++  sorted_wlan_list = M.filter_redundancy(sorted_wlan_list)
++
++  -- we dont want to get tricked by our signal
++  sorted_wlan_list = M.filter_my_wlan_network(sorted_wlan_list)
++
++  io.stdout:write('After filtering we will test the following wireless networks:\n')
++  for _, network in pairs(sorted_wlan_list) do
++    print(network["quality"].."\t"..network["frequency"].."\t"..network["bssid"].."\t"..network["ssid"])
++  end
++
++  local bssid = nil
++  if(next(sorted_wlan_list)) then
++    io.stdout:write("Prepare configuration for testing wireless networks...\n")
++    -- Notice:
++    -- we will use iw for testing the wireless networks because using iw does
++    -- not need any changes inside the uci config. This approach allows the
++    -- router to automatically reset to previous configuration in case
++    -- someone disconnects the router from power during test.
++
++    -- stop vpn to prevent two hoods from beeing connected in case
++    -- the router gets internet unexpectedly during test.
++    M.vpn_stop()
++    bssid = M.test_batman_mesh_networks(sorted_wlan_list, meshprefix)
++    M.vpn_start()
++    M.wireless_restart()
++    io.stdout:write("Finished testing wireless networks, restored previous configuration\n")
++  end
++
++  return bssid
++end
++
++function M.get_batman_GW_interface()
++  for gw in io.open("/sys/kernel/debug/batman_adv/bat0/gateways", 'r'):lines() do
++    if gw:match("=>") then
++      return M.trim(gw:match("%[.-%]"):gsub("%[", ""):gsub("%]", ""))
++    end
++  end
++  return nil
++end
++
++function M.get_radio_to_bssid(radios,iface,jhood)
++  for _, radio in ipairs(radios) do
++    local ifname = uci:get('wireless', 'ibss_' .. radio, 'ifname')
++    if ifname == iface then
++      return M.gethoodByBssid(jhood, uci:get('wireless', 'ibss_' .. radio, 'bssid'))
++    end
++    ifname = uci:get('wireless', 'mesh_' .. radio, 'ifname')
++    if ifname == iface then
++      local meshid = uci:get('wireless', 'mesh_' .. radio, 'mesh_id')
++      meshid = M.split(meshid, '_')
++      if meshid[2] ~= nil then
++        if meshid[2]:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then
++          return M.gethoodByBssid(jhood, meshid[2]:match("(%w+:%w+:%w+:%w+:%w+:%w+)"))
++        end
++      end
++    end
++  end
++  return nil
++end
++
++function M.mesh_lan_wan(iface)
++  if uci:get('network', 'mesh_wan') then
++    local if_wan = io.popen(string.format("ifstatus mesh_wan"), 'r'):read('*a')
++    if if_wan ~= nil then
++      local wan, _, _ = json.parse(if_wan, 1, nil)
++      if wan["device"] == iface then
++        io.stdout:write("gw source is wan\n")
++        return true
++      end
++    end
++  end
++  if uci:get('network', 'mesh_lan') then
++    local if_lan = io.popen(string.format("ifstatus mesh_lan"), 'r'):read('*a')
++    if if_lan ~= nil then
++      local lan, _, _ = json.parse(if_lan, 1, nil)
++      if lan["device"] == iface then
++        io.stdout:write("gw source is lan\n")
++        return true
++      end
++    end
++  end
++  return false
++end
++
++function M.conditional_increment(table,index)
++  if index["bssid"] ~= nil then
++    if not table[index["bssid"]] then
++      table[index["bssid"]] = 1
++    else
++      table[index["bssid"]] = table[index["bssid"]] + 1
++    end
++  end
++end
++
++-- Get BSSID from neighbour hoods over respondd
++function M.molw_get_bssid(iface)
++  -- differentiate between VPN and mesh only routers
++  local vpn_router_neighbour_bssids = {}
++  local mesh_router_neighbour_bssids = {}
++  local own_mac = uci:get('network', 'client', 'macaddr')
++  for _,respondd_if in ipairs(iface) do
++    local respondd = string.format("gluon-neighbour-info -i " ..
++    respondd_if .. " -p 1001 -d ff02::2 -r hoodselector -t 0.5")
++    print(respondd)
++    for line in io.popen(respondd, 'r'):lines() do
++      local obj, _, err = json.parse (line, 1, nil)
++      if err then
++        io.stdout:write("json parse error!\n")
++      else
++        if obj["mac"] ~= own_mac then
++          if obj["hoodinfo"] ~= nil then
++            if obj["hoodinfo"]["vpnrouter"] ~= nil then
++              if obj["hoodinfo"]["vpnrouter"]:match("true") then
++                if obj["mesh"] ~= nil then
++                  M.conditional_increment(vpn_router_neighbour_bssids, obj["mesh"])
++                end
++              else
++                if obj["mesh"] ~= nil then
++                  M.conditional_increment(mesh_router_neighbour_bssids, obj["mesh"])
++                end
++              end
++            end
++          end
++        end
++      end
++    end
++  end
++  local neighbour_bssids
++  if next(vpn_router_neighbour_bssids) then
++    -- molwm VPN router founds.
++    print("Found VPN routers over mesh on lan or wan")
++    neighbour_bssids = vpn_router_neighbour_bssids
++  else
++    -- molwm VPN router not founds. Get most presented bssid
++    print("No VPN routers over mesh on lan or wan")
++    neighbour_bssids = mesh_router_neighbour_bssids
++  end
++
++  local bssid = nil
++  local value = 0
++  for b,c in pairs(neighbour_bssids) do
++    io.stdout:write(b.."\t"..c.."\n")
++    if value < c then
++      bssid = b
++      value = c
++    end
++  end
++  local eq_cost_entrys = {}
++  for b,c in pairs(neighbour_bssids) do
++    if b == bssid then
++      table.insert(eq_cost_entrys,b)
++    end
++    if c == value and b ~= bssid then
++      table.insert(eq_cost_entrys,b)
++    end
++  end
++  if #eq_cost_entrys ~= 0 then
++    bssid = eq_cost_entrys[math.random(#eq_cost_entrys)]
++  end
++  return bssid
++end
++
++function M.get_mesh_prefix(radios)
++  local mesh_prefix = nil
++  for _,radio in ipairs(radios) do
++    local mesh_id = uci:get('wireless', 'mesh_' .. radio, 'mesh_id')
++    if mesh_id ~= nil then
++      mesh_id = M.split(mesh_id, '_')
++      if mesh_id[1] ~= "" then
++        mesh_prefix = mesh_id[1].."_"
++      else
++        if mesh_id[2] ~= "" then
++          mesh_prefix = mesh_id[2].."_"
++        end
++      end
++    end
++  end
++  return mesh_prefix
++end
++
++function M.extrac_fastd_peer(s,configPeers)
++  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 = M.split(tmpRemote[1], " ")
++          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
++
++return M
+diff --git a/package/gluon-hoodselector/luasrc/usr/sbin/hoodselector b/package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
+new file mode 100755
+index 00000000..b74f0362
+--- /dev/null
++++ b/package/gluon-hoodselector/luasrc/usr/sbin/hoodselector
+@@ -0,0 +1,622 @@
++#!/usr/bin/lua
++
++-- This is the hoodselector. The hoodselector is one of the main components for
++-- splitting a layer 2 mesh network into seperated network segments (hoods).
++-- The job of the hoodselector is to automatically detect in which hood
++-- the router is located based on geo settings or by scanning its environment.
++-- Based on these informations the hoodselector should select a hood from a
++-- list of known hoods (hoodlist) and adjust vpn, wireless and mesh on lan
++-- configuration based on the settings given for the selected hood.
++--
++-- The hoodlist containing all hood settings is located in a seperate hoodfile
++-- in the hoods package.
++--
++-- The hoodselector works with the folowing additional software:
++--  * fastd (vpn configuration) see getCurrentFastdPeers()
++--  * tunneldigger (vpn configuration) see getCurrentTunneldiggerPeers()
++--  * iw (wireless network scanning) see get_batman_mesh_network()
++--  * batman-adv (mesh protocol) see directVPN(), get_batman_GW_interface()
++--  * respondd (mesh on LAN or WAN) see molwm()
++--
++--  To detect the current hood the hoodselector knows 5 modes containing
++--  * 1. VPN mode (VPN Router)
++--    - set hood dependent on geo position.
++--  * 2. Gateway mode
++--    - set hood dependent on gateway source
++--  * 3. Scan mode
++--    - Set wifi conf on scanned BSSID
++--    - Set vpn conf getting by BSSID (if no VPN conf exsist disable vpn)
++--  * 4. Radio less mode
++--    - Set hood via mesh on lan wan managemand
++--  * 5. Default mode
++--    - Set default hood if no other hood matchs
++
++-- When selecting a hood, the hoodselector has the following priorities:
++--   1. Selecting a hood by geo position depending on direct VPN connection.
++--   2. force creating one mesh cloud with neighbour mesh routers
++--   3. if routers had only mesh setting vpn config depends on the BSSID
++--
++-- Resources
++--  * https://wireless.wiki.kernel.org/en/users/documentation/iw
++
++-- MOLWM respondd file
++local molwmFile="/tmp/.hoodselector"
++
++local molwmtable = {}
++molwmtable["md5hash"] = ""
++molwmtable["vpnrouter"] = ""
++molwmtable["hoodname"] = ""
++molwmtable["bssid"] = ""
++
++-- PID file to ensure the hoodselector isn't running parallel
++local pidPath="/var/run/hoodselector.pid"
++
++local json = require ("luci.jsonc")
++local uci = require('simple-uci').cursor()
++local hash = require("hash")
++local hoodutil = require("hoodselector.util")
++
++if not uci:get_bool('hoodselector', 'hoodselector', 'enabled') then
++  io.stdout:write("Hoodselector is disabled by UCI\n")
++  os.exit(0)
++end
++
++if io.open(pidPath, "r") ~=nil then
++  hoodutil.log("The hoodselector is still running.")
++  os.exit(1)
++else
++  if io.open(pidPath, "w") ==nil then
++    hoodutil.log("Can`t create pid file on "..pidPath)
++    os.exit(1)
++  end
++end
++
++-- Program terminating function including removing of PID file
++local function exit(exc)
++  if io.open(pidPath, "r") ~=nil then
++    os.remove(pidPath)
++  end
++  os.exit(tonumber(exc))
++end
++
++local FILE = uci:get('hoodselector', 'hoodselector', 'hoodfile')
++if FILE == nil then
++  hoodutil.log("No hood file in config")
++  exit(1)
++end
++
++-- initialization done
++
++local function get_mesh_vpn_interface()
++  local ret = {}
++  if hoodutil.fastd_installed() then
++    local vpnifac = uci:get('fastd', 'mesh_vpn_backbone', 'net')
++    if vpnifac  ~= nil then
++      vpnifac = vpnifac:gsub("%_",'-')
++      table.insert(ret,vpnifac)
++    else
++      hoodutil.log("fastd uci config broken! abort...")
++      exit(1)
++    end
++  end
++  if hoodutil.tunneldigger_installed() then
++    local vpnifac = uci:get('tunneldigger', 'mesh_vpn', 'interface')
++    if vpnifac  ~= nil then
++      table.insert(ret,vpnifac)
++    else
++      hoodutil.log("tunneldigger uci config broken! abort...")
++      exit(1)
++    end
++  end
++  return ret
++end
++
++-- Give a list of interfaces where respondd is listening
++local function get_mesh_if(radios)
++  -- get VPN interfaces
++  local filtert_if = get_mesh_vpn_interface()
++
++  -- get Wifi interfaces
++  for _, radio in ipairs(radios) do
++    local ifname = uci:get('wireless', 'ibss_' .. radio, 'ifname')
++    if ifname ~= nil then
++      table.insert(filtert_if,ifname)
++    end
++    ifname = uci:get('wireless', 'mesh_' .. radio, 'ifname')
++    if ifname ~= nil then
++      table.insert(filtert_if,ifname)
++    end
++  end
++
++  local respondd_if = {}
++  for line in io.popen(string.format("ubus call network.interface dump | jsonfilter -e \"@.interface[@.proto='gluon_mesh' && @.up=true].device\" -e \"@.interface[@.interface='$(cat /lib/gluon/respondd/client.dev 2>/dev/null)' && @.up=true].device\""), "r"):lines() do
++    -- filter vpn and wifi interfaces
++    if not hoodutil.filt_if(filtert_if,line) then
++      table.insert(respondd_if,line)
++    end
++  end
++
++  return hoodutil.filter_redundancy(respondd_if)
++end
++
++local function molwm(radios)
++  if uci:get_bool("network", "mesh_lan", "auto") or uci:get_bool("network", "mesh_wan", "auto") then
++    local mesh_en = true
++    for _,respondd_if in ipairs(get_mesh_if(radios)) do
++      local respondd = string.format("gluon-neighbour-info -i " .. respondd_if .. " -p 1001 -d ff02::2 -r hoodselector -t 0.5")
++      for line in io.popen(respondd, 'r'):lines() do
++        local obj, _, err = json.parse (line, 1, nil)
++        if err then
++          io.stdout:write("json parse error!\n")
++          mesh_en = false
++          break
++        else
++          if obj["hoodinfo"] ~= nil then
++            if obj["mesh"] ~= nil then
++              if ( obj["mesh"]["lan"] or obj["mesh"]["wan"] ) then
++                if not ( obj["hoodinfo"]["md5hash"] == molwmtable["md5hash"]:gsub('\"', '') ) then
++                  io.stdout:write("hashes are not equal! Souce " .. respondd .. "\n")
++                  mesh_en = false
++                  break
++                end
++              end
++            end
++          end
++        end
++      end
++    end
++    if uci:get('network', 'mesh_wan') then
++      local ifstatus_wan = io.popen(string.format("ifstatus mesh_wan"), 'r'):read('*a')
++      if ifstatus_wan ~= nil then
++        local wan, _, _ = json.parse (ifstatus_wan, 1, nil)
++        if wan["up"] and not mesh_en then
++          hoodutil.mesh_on_wan_disable()
++        end
++        if not wan["up"] and mesh_en then
++          hoodutil.mesh_on_wan_enable()
++        end
++      end
++    end
++    if uci:get('network', 'mesh_lan') then
++      local ifstatus_lan = io.popen(string.format("ifstatus mesh_lan"), 'r'):read('*a')
++      if ifstatus_lan ~= nil then
++        local lan, _, _ = json.parse (ifstatus_lan, 1, nil)
++        if lan["up"] and not mesh_en then
++          hoodutil.mesh_on_lan_disable()
++        end
++        if not lan["up"] and mesh_en then
++          hoodutil.mesh_on_lan_enable()
++        end
++      end
++    end
++  end
++end
++
++function table.val_to_str ( v )
++  if "string" == type( v ) then
++    v = string.gsub( v, "\n", "\\n" )
++    if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
++      return "'" .. v .. "'"
++    end
++    return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
++  else
++    return "table" == type( v ) and table.tostring( v ) or tostring( v )
++  end
++end
++
++function table.key_to_str ( k )
++  if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
++    return k
++  else
++    return "[" .. table.val_to_str( k ) .. "]"
++  end
++end
++
++function table.tostring( tbl )
++  local result, done = {}, {}
++  for k, v in ipairs( tbl ) do
++    table.insert( result, table.val_to_str( v ) )
++    done[ k ] = true
++  end
++  for k, v in pairs( tbl ) do
++    if not done[ k ] then
++      table.insert( result, table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
++    end
++  end
++  return "{" .. table.concat( result, "," ) .. "}"
++end
++
++local function molwm_to_file()
++  local file = io.open(molwmFile, "w")
++  if not file then
++    hoodutil.log(molwmFile ..' not found or not createble!')
++  else
++    file:write("\"md5hash\": " .. molwmtable["md5hash"] .. "\n")
++    file:write("\"vpnrouter\": " .. molwmtable["vpnrouter"] .. "\n")
++    file:write("\"hoodname\": " .. molwmtable["hoodname"] .. "\n")
++    file:write("\"bssid\": " .. molwmtable["bssid"] .. "\n")
++    file:close()
++  end
++end
++
++-- Write MOLWM content into file
++local function write_molwm(hood,radios)
++  if hood ~= nil then
++    molwmtable["md5hash"] = "\"" .. string.format(hash.md5(table.tostring(hood))) .. "\""
++    molwmtable["hoodname"] = "\"" .. hood["name"] .. "\""
++    molwmtable["bssid"] = "\"" .. hood["bssid"] .. "\""
++  end
++  molwm(radios)
++  molwm_to_file()
++end
++
++-- bool if direct VPN. The detection is realaise by searching the fastd network interface inside the originator table
++local function directVPN()
++  local vpnIfaceList = get_mesh_vpn_interface()
++  for _,vpnIface in ipairs(vpnIfaceList) do
++    local file = io.open("/sys/kernel/debug/batman_adv/bat0/originators", 'r')
++    if file ~= nil then
++      for outgoingIF in file:lines() do
++        -- escape special chars "[]-"
++        if outgoingIF:match(string.gsub("%[  " .. vpnIface .. "%]","%-", "%%-")) then
++          molwmtable["vpnrouter"] = "\"true\""
++          return true
++        end
++      end
++    end
++  end
++  molwmtable["vpnrouter"] = "\"false\""
++  return false
++end
++
++-- Retun a table of current peers from /etc/config/fastd
++local function getFastdCurrentPeers()
++  local configPeers = {}
++  local err = uci:foreach('fastd', 'peer',
++    function(s)
++      hoodutil.extrac_fastd_peer(s,configPeers)
++    end
++  )
++  if not err then
++    hoodutil.log("fastd uci config broken! abort...")
++    exit(1)
++  end
++  return configPeers
++end
++
++-- Retun a table of current peers from /etc/config/tunneldigger
++local function getTunneldiggerCurrentPeers()
++  local configPeers = {}
++  local err = uci:foreach('tunneldigger', 'broker',
++    function(s)
++      if s["address"] then
++        for _, peer in pairs(s["address"]) do
++          table.insert(configPeers, peer)
++        end
++      end
++    end
++  )
++  if not err then
++    hoodutil.log("tunneldigger uci config broken! abort...")
++    exit(1)
++  end
++  return configPeers
++end
++
++-- This method sets a new hoodconfig and takes care that services are only
++-- stopped or restarted if reconfiguration is needed.
++-- Process:
++--   * Check if wireless needs reconfiguration and prepare reconfiguration
++--   * Check if vpn needs reconfiguration and prepare reconfiguration
++--   * If vpn needs reconfiguration, stop vpn and apply new settings but
++--     dont restart it before wireless has been reconfigured
++--   * If wireless needs reconfiguration apply new settings and restart wireless
++--   * If vpn needed reconfiguration start fastd now
++local function set_hoodconfig(hood, prefix, radios)
++  local fastd_serverlist = {}
++  local fastd_reconf_needed = false
++  local tunneldigger_reconf_needed = false
++
++  -- pre check if fastd conf exsist
++  if uci:get('fastd', 'mesh_vpn_backbone', 'net') ~= nil then
++    fastd_serverlist = getFastdCurrentPeers()
++    -- Check if fastd needs reconfiguration because in case of reconfiguration we
++    -- need to stop fastd before we can reconfigure any other connection.
++    fastd_reconf_needed = hoodutil.fastd_reconfiguration_needed(hood["servers"], fastd_serverlist);
++  else
++    -- check if fastd uci conf broken
++    if hoodutil.fastd_installed() then
++      hoodutil.log("fastd uci config broken! abort...")
++      exit(1)
++    end
++  end
++
++  -- per check if tunneldigger conf exsist
++  if uci:get('tunneldigger', 'mesh_vpn', 'interface') ~= nil then
++    local tunneldigger_serverlist = getTunneldiggerCurrentPeers()
++    tunneldigger_reconf_needed = hoodutil.tunneldigger_reconfiguration_needed(hood["servers"], tunneldigger_serverlist)
++  else
++    -- check if tunneldigger uci conf broken
++    if hoodutil.tunneldigger_installed() then
++      hoodutil.log("tunneldigger uci config broken! abort...")
++      exit(1)
++    end
++  end
++
++  if fastd_reconf_needed or tunneldigger_reconf_needed then
++    hoodutil.vpn_stop()
++  end
++
++  -- reconfigure wireless
++  local wifi_reconf = hoodutil.wireless_reconfiguration_needed(radios, prefix, hood["bssid"])
++  if(wifi_reconf == 1 or wifi_reconf == 3) then
++    hoodutil.ibss_reconfigure(radios, hood["bssid"])
++    hoodutil.wireless_restart()
++    io.stdout:write('IBSS needed reconfiguration. Applied new settings and restarted.\n')
++  end
++  if(wifi_reconf == 2 or wifi_reconf == 3) then
++    hoodutil.mesh_reconfigure(radios, prefix..hood["bssid"]:lower())
++    hoodutil.wireless_restart()
++    io.stdout:write('MESH needed reconfiguration. Applied new settings and restarted.\n')
++  end
++
++  -- reconfigure fastd
++  if fastd_reconf_needed then
++    hoodutil.fastd_reconfigure(hood["servers"],fastd_serverlist)
++    io.stdout:write('fastd needed reconfiguration. Applied new settings and restarted.\n')
++  end
++
++  if tunneldigger_reconf_needed then
++    hoodutil.tunneldigger_reconfigure(hood["servers"])
++    io.stdout:write('tunneldigger needed reconfiguration. Applied new settings and restarted.\n')
++  end
++
++  if fastd_reconf_needed or tunneldigger_reconf_needed then
++    -- scan mode can disable VPN so we need to make shure that VPN is enabled
++    -- if the router selects a hood
++    hoodutil.vpn_enable()
++    hoodutil.vpn_start()
++  end
++
++  io.stdout:write("Set hood \""..hood["name"].."\"\n")
++  molwmtable["hoodname"] = "\"" .. hood["name"] .. "\""
++
++  if(uci:get('hoodselector', 'hoodselector' , 'hood') ~= hood["bssid"]) then
++    hoodutil.saveHoodToConfig(hood["bssid"])
++  end
++  return true
++end
++
++-- INITIALIZE AND PREPARE DATA --
++-- read hoodfile, exit if reading the hoodfile fails
++local jhood = hoodutil.readHoodfile(FILE)
++if jhood == nil then
++  hoodutil.log('There seems to have gone something wrong while reading hoodfile from ' .. FILE)
++  exit(1)
++end
++
++-- check if a default hood has been defined and exit if none has been defined
++local defaultHood = hoodutil.getDefaultHood(jhood)
++if defaultHood == nil then
++  hoodutil.log('No defaulthood defined.')
++  exit(1)
++end
++
++-- Get list of wifi devices
++local radios = hoodutil.getWifiDevices()
++
++local mesh_prefix = hoodutil.get_mesh_prefix(radios)
++
++-- VPN MODE
++-- If we have a VPN connection then we will try to get the routers location and
++-- select the hood coresponding to our location.
++-- If no hood for the location has been defined, we will select
++-- the default hood.
++-- If we can not get our routers location, we will fallback to scan mode.
++if directVPN() then
++  io.stdout:write('VPN connection found.\n')
++  local geo = hoodutil.getGeolocation()
++  if geo.lat ~= nil and geo.lon ~= nil then
++    io.stdout:write('Position found.\n')
++    local geoHood = hoodutil.getHoodByGeo(jhood, geo)
++    if geoHood ~= nil then
++      set_hoodconfig(geoHood, mesh_prefix, radios)
++      io.stdout:write('Hood set by VPN mode.\n')
++      write_molwm(geoHood,radios)
++      exit(0)
++    end
++    io.stdout:write('No hood has been defined for current position.\n')
++  else
++    io.stdout:write('No position found\n')
++  end
++  set_hoodconfig(defaultHood, mesh_prefix, radios)
++  io.stdout:write('Set defaulthood.\n')
++  write_molwm(defaultHood,radios)
++  exit(0)
++else
++  io.stdout:write('No VPN connection found\n')
++end
++
++if hoodutil.batmanHasGateway() then
++  io.stdout:write('Batman gateways found\n')
++  local gw_intf = {}
++  table.insert(gw_intf,hoodutil.get_batman_GW_interface())
++
++  if next(gw_intf) then
++    -- wifi interface
++    local bssidHood = hoodutil.get_radio_to_bssid(radios,gw_intf[1], jhood)
++    if bssidHood ~= nil then
++      --check if hood inside geo pos
++      local geo = hoodutil.getGeolocation()
++      if geo.lat ~= nil and geo.lon ~= nil then
++       io.stdout:write('Position found.\n')
++       local geoHood = hoodutil.getHoodByGeo(jhood, geo)
++       if geoHood ~= nil then
++         if string.format(hash.md5(table.tostring(bssidHood))) ~= string.format(hash.md5(table.tostring(geoHood))) then
++           io.stdout:write('Geo hood and bssid hood are not equal, do wifi scan...\n')
++           local sortedWlanList = hoodutil.wlan_list_sorted(radios, mesh_prefix)
++           for i=#sortedWlanList,1,-1 do
++             if(string.lower(geoHood.bssid) ~= string.lower(sortedWlanList[i].bssid)) then
++              table.remove(sortedWlanList, i)
++             end
++           end
++           if next(sortedWlanList) then
++             io.stdout:write('Try to switch back in our real hood!\n')
++             io.stdout:write('After filtering we will test the following wireless networks:\n')
++             for _, network in pairs(sortedWlanList) do
++              print(network["quality"].."\t"..network["frequency"].."\t"..network["bssid"].."\t"..network["ssid"])
++             end
++             io.stdout:write("Prepare configuration for testing wireless networks...\n")
++             local bssid = hoodutil.test_batman_mesh_networks(sortedWlanList, mesh_prefix)
++             hoodutil.wireless_restart()
++             io.stdout:write("Finished testing wireless networks, restored previous configuration\n")
++             if bssid ~= nil then
++              set_hoodconfig(geoHood, mesh_prefix, radios)
++              hoodutil.vpn_enable()
++              hoodutil.vpn_start()
++              io.stdout:write('Set Geo Hood by Gateway mode\n')
++              write_molwm(geoHood, radios)
++              exit(0)
++             else
++              io.stdout:write('No neighboring freifunk batman advanced mesh found.\n')
++             end
++           else
++             io.stdout:write('No networks left after filtering!\n')
++           end --end next(sortedWlanList)
++         else
++           io.stdout:write('Geo hood are equal to bssid hood no wifi scan necessary.\n')
++         end --end bssidHood ~= geoHood
++       else
++         io.stdout:write('No hood has been defined for current position.\n')
++       end --end geoHood ~= nil
++      else
++       io.stdout:write('No position found.\n')
++      end --end geo.lat ~= nil and geo.lon ~= nil
++      set_hoodconfig(bssidHood, mesh_prefix, radios)
++      io.stdout:write('Hood set by batmanHasGateway mode, GW source is wifi\n')
++      write_molwm(bssidHood,radios)
++      exit(0)
++    end --end bssidHood ~= nil
++
++    -- mesh lan or wan interface
++    if hoodutil.mesh_lan_wan(gw_intf[1]) then
++      -- if mesh_lan/wan try to get hood by selected bssid of neightbour vpnRouters
++      local neighbourBssid = hoodutil.molw_get_bssid(gw_intf)
++      if neighbourBssid ~= nil then
++        bssidHood = hoodutil.gethoodByBssid(jhood, neighbourBssid)
++        if bssidHood ~= nil then
++          set_hoodconfig(bssidHood, mesh_prefix, radios)
++          io.stdout:write('Hood set by batmanHasGateway mode, GW source is mesh on lan/wan\n')
++          molwmtable["md5hash"] = "\"" .. string.format(hash.md5(table.tostring(bssidHood))) .. "\""
++          molwmtable["hoodname"] = "\"" .. bssidHood["name"] .. "\""
++          molwmtable["bssid"] = "\"" .. bssidHood["bssid"] .. "\""
++          molwm_to_file()
++          exit(0)
++        end
++      end
++    end
++  end --end next(gw_intf)
++  local currendHood = hoodutil.getCurrentHood(jhood)
++  if currendHood ~= nil then
++    write_molwm(currendHood,radios)
++  end
++end
++
++-- SCAN MODE
++if next(radios) then
++  -- check if there exist a neighbouring freifunk batman advanced mesh
++  -- network with an active connection to a batman advanced gateway
++  local sortedWlanList = hoodutil.wlan_list_sorted(radios, mesh_prefix)
++  local meshBSSID = hoodutil.get_batman_mesh_network(sortedWlanList, defaultHood, mesh_prefix)
++  if meshBSSID ~= nil then
++    io.stdout:write("Neighoring freifunk batman advanced mesh with BSSID "..meshBSSID.." found\n")
++    local bssidHood = hoodutil.gethoodByBssid(jhood, meshBSSID)
++    if bssidHood ~= nil then
++      set_hoodconfig(bssidHood, mesh_prefix, radios)
++      io.stdout:write('Hood set by scan mode\n')
++      write_molwm(bssidHood,radios)
++      exit(0)
++    end
++
++    -- if the bssid does not corespond to any hood, we disable vpn and
++    -- just establish a wireless connection to the mesh without any vpn or
++    hoodutil.vpn_stop()
++    hoodutil.vpn_disable()
++    local ibss_exists = false
++    local mesh_exists = false
++    for _,radio in ipairs(radios) do
++      local ifname = uci:get('wireless', 'ibss_' .. radio, 'ifname')
++      if (ifname ~= nil) then
++        ibss_exists = true
++      end
++      ifname = uci:get('wireless', 'mesh_' .. radio, 'ifname')
++      if (ifname ~= nil) then
++        mesh_exists = true
++      end
++    end
++    if ibss_exists then
++      hoodutil.ibss_reconfigure(radios, meshBSSID)
++    end
++    if mesh_exists then
++      hoodutil.mesh_reconfigure(radios, mesh_prefix..meshBSSID:lower())
++    end
++    hoodutil.wireless_restart()
++    io.stdout:write('Could not select a hood but established a connection via wireless mesh.\n')
++    io.stdout:write('Disabled all connections except connections via wireless mesh.\n')
++    exit(0)
++  end
++  io.stdout:write('No neighbouring freifunk batman advanced mesh found.\n')
++end
++
++--Radio less router have mesh lan/wan neighbours
++local mesh_inf = get_mesh_if(radios);
++if next(mesh_inf) then
++  local wait_for_mesh_lan_wan = false
++  if uci:get('network', 'mesh_wan') then
++    local ifstatus_wan = io.popen(string.format("ifstatus mesh_wan"), 'r'):read('*a')
++    if ifstatus_wan ~= nil then
++      local wan, _, _ = json.parse (ifstatus_wan, 1, nil)
++      if not wan["up"] and uci:get_bool("network", "mesh_wan", "auto") then
++        hoodutil.mesh_on_wan_enable()
++        wait_for_mesh_lan_wan = true
++      end
++    end
++  end
++  if uci:get('network', 'mesh_lan') then
++    local ifstatus_lan = io.popen(string.format("ifstatus mesh_lan"), 'r'):read('*a')
++    if ifstatus_lan ~= nil then
++      local lan, _, _ = json.parse (ifstatus_lan, 1, nil)
++      if not lan["up"] and uci:get_bool("network", "mesh_lan", "auto") then
++        hoodutil.mesh_on_lan_enable()
++        wait_for_mesh_lan_wan = true
++      end
++    end
++  end
++  -- wait for network delay
++  if wait_for_mesh_lan_wan then
++    hoodutil.sleep(5)
++  end
++  local neighbourBssid = hoodutil.molw_get_bssid(mesh_inf)
++  if neighbourBssid ~= nil then
++    local bssidHood = hoodutil.gethoodByBssid(jhood, neighbourBssid)
++    if bssidHood ~= nil then
++      set_hoodconfig(bssidHood, mesh_prefix, radios)
++      io.stdout:write('Hood set by "Radio less router have mesh lan/wan neighbours"\n')
++      molwmtable["md5hash"] = "\"" .. string.format(hash.md5(table.tostring(bssidHood)    )) .. "\""
++      molwmtable["hoodname"] = "\"" .. bssidHood["name"] .. "\""
++      molwmtable["bssid"] = "\"" .. bssidHood["bssid"] .. "\""
++      molwm_to_file()
++      exit(0)
++    end
++  end
++  io.stdout:write('No molwm neighbours found\n')
++end
++
++-- DEFAULT-HOOD MODE
++-- If we do NOT have a VPN connection AND found no freifunk mesh network while
++-- scanning then we set the default hood if no current hood set.
++io.stdout:write("ENV does not give enough information set default hood\n")
++set_hoodconfig(defaultHood, mesh_prefix, radios)
++io.stdout:write('Set defaulthood.\n')
++write_molwm(defaultHood,radios)
++exit(0)
+diff --git a/package/gluon-hoodselector/src/Makefile b/package/gluon-hoodselector/src/Makefile
+new file mode 100644
+index 00000000..3ddc8a58
+--- /dev/null
++++ b/package/gluon-hoodselector/src/Makefile
+@@ -0,0 +1,6 @@
++all: respondd.so
++
++CFLAGS += -Wall
++
++respondd.so: respondd.c
++	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -luci
+diff --git a/package/gluon-hoodselector/src/respondd.c b/package/gluon-hoodselector/src/respondd.c
+new file mode 100644
+index 00000000..cc864a1c
+--- /dev/null
++++ b/package/gluon-hoodselector/src/respondd.c
+@@ -0,0 +1,139 @@
++#include <respondd.h>
++#include <json-c/json.h>
++#include <libgluonutil.h>
++#include <uci.h>
++#include <string.h>
++#include <net/if.h>
++
++#define _STRINGIFY(s) #s
++#define STRINGIFY(s) _STRINGIFY(s)
++
++bool strstw(const char *pre, const char *str) {
++	size_t lenpre = strlen(pre);
++	return strlen(str) < lenpre ? false : strncmp(pre, str, lenpre) == 0;
++}
++
++bool strrmbs(char *line, int begin, int end) { // <- ist es hier sinvoller pointer auf die ints zu setzen??
++	size_t len = strlen(line);
++	if (len < begin)
++		return false;
++
++	memmove(line, line+begin, len - begin + 1);
++	if (len < end)
++		return false;
++
++	line[len-end] = 0; //remove val of end characters on the end
++	return true;
++}
++
++// extract hood informations
++static struct json_object * get_hoodselector(void) {
++	FILE *f = fopen("/tmp/.hoodselector", "r");
++	if (!f)
++		return NULL;
++
++	struct json_object *ret = json_object_new_object();
++	char *line = NULL;
++	size_t len = 0;
++	while (getline(&line, &len, f) >= 0) {
++		//1. Get md5 hash from current selected hood.
++		if (strstw("\"md5hash\": ",line)) {
++			if (!strrmbs(line, 12, 14))
++				continue;
++
++			json_object_object_add(ret, "md5hash", gluonutil_wrap_string(line));
++		}
++		//2. Get true or false string for VPN Router.
++		if (strstw("\"vpnrouter\": ",line)) {
++			if (!strrmbs(line, 14, 16))
++				continue;
++
++			json_object_object_add(ret, "vpnrouter", gluonutil_wrap_string(line));
++		}
++		//3. Get hoodname
++		if (strstw("\"hoodname\": ",line)) {
++			if (!strrmbs(line, 13, 15))
++				continue;
++
++			json_object_object_add(ret, "hoodname", gluonutil_wrap_string(line));
++		}
++	}
++	free(line);
++	fclose(f);
++	return ret;
++}
++
++//Get uci mesh on lan wan
++static struct json_object * get_mesh_on_lan_wan(void){
++	struct uci_context *ctx = uci_alloc_context();
++	ctx->flags &= ~UCI_FLAG_STRICT;
++	struct uci_package *p;
++
++	if (!uci_load(ctx, "wireless", &p)) {
++		struct uci_element *e;
++		uci_foreach_element(&p->sections, e) {
++			struct uci_section *s = uci_to_section(e);
++			if (strcmp(s->type, "wifi-iface"))
++				continue;
++
++			if (strncmp(e->name, "ibss_", 5))
++				continue;
++
++			const char *bssid = uci_lookup_option_string(ctx, s, "bssid");
++			if (!bssid)
++				continue;
++
++			struct json_object *ret = json_object_new_object();
++			json_object_object_add(ret, "bssid", gluonutil_wrap_string(bssid));
++			free((char*)bssid);
++			if(ret) {
++				uci_free_context(ctx);
++				return ret;
++			}
++		}
++	}
++	uci_free_context(ctx);
++	FILE *f = fopen("/tmp/.hoodselector", "r");
++	if (!f)
++		return NULL;
++
++	struct json_object *ret = json_object_new_object();
++	char *line = NULL;
++	size_t len = 0;
++	while (getline(&line, &len, f) >= 0) {
++		//Get bssid from current selected hood.
++		if (strstw("\"bssid\": ",line)) {
++			if (!strrmbs(line, 10, 12))
++				continue;
++			json_object_object_add(ret, "bssid", gluonutil_wrap_string(line));
++			free(line);
++			fclose(f);
++			return ret;
++		}
++	}
++	free(line);
++	fclose(f);
++	return NULL;
++}
++
++// create final obj with logical structure
++static struct json_object * respondd_provider_hoodselector(void) {
++	struct json_object *ret = json_object_new_object();
++
++	struct json_object *hoodinfo = get_hoodselector();
++	if(hoodinfo)
++		json_object_object_add(ret, "hoodinfo", hoodinfo);
++
++	struct json_object *mesh_on_lan_wan = get_mesh_on_lan_wan();
++	if(mesh_on_lan_wan)
++		 json_object_object_add(ret, "mesh", mesh_on_lan_wan);
++
++	json_object_object_add(ret, "mac", gluonutil_wrap_and_free_string(gluonutil_get_sysconfig("primary_mac")));
++	return ret;
++}
++
++// related to respondd_provider_hoodselector
++const struct respondd_provider_info respondd_providers[] = {
++	{"hoodselector", respondd_provider_hoodselector},
++	{}
++};
+-- 
+2.15.1
+
diff --git a/site.mk b/site.mk
index 97e58cc1f028111a509c722a9c82748790a8915b..9b3673dfac2e9cc7ff598bc6352a7ae956e83fc4 100644
--- a/site.mk
+++ b/site.mk
@@ -15,13 +15,13 @@ GLUON_SITE_PACKAGES := \
 	gluon-status-page \
 %A
 	gluon-geolocator \
+	gluon-hoodselector \
 	haveged \
 	iwinfo \
 	ffnw-banner \
 	ffnw-config-mode-geo-location \
 	ffnw-config-mode-contact-info \
 	ffnw-hoods \
-	ffnw-hoodselector \
 	ffnw-multiple-v6-watchdoog
 
 USB_BASIC := \