Parcourir la source

Merge branch 'mesh-proto'

Matthias Schiffer il y a 7 ans
Parent
commit
8343278bbf
30 fichiers modifiés avec 421 ajouts et 365 suppressions
  1. 18 0
      docs/dev/mac_addresses.rst
  2. 1 0
      docs/index.rst
  3. 14 7
      package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network
  4. 0 0
      package/gluon-core/files/lib/gluon/core/mesh/setup.d/.keep
  5. 0 0
      package/gluon-core/files/lib/gluon/core/mesh/teardown.d/.keep
  6. 39 0
      package/gluon-core/files/lib/netifd/proto/gluon_mesh.sh
  7. 183 17
      package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless
  8. 16 0
      package/gluon-core/luasrc/lib/gluon/upgrade/210-interface-wan
  9. 5 6
      package/gluon-core/luasrc/lib/gluon/upgrade/220-interface-lan
  10. 24 0
      package/gluon-core/luasrc/lib/gluon/upgrade/800-migrate-batadv
  11. 13 17
      package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua
  12. 1 1
      package/gluon-luci-portconfig/Makefile
  13. 12 15
      package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua
  14. 0 2
      package/gluon-mesh-batman-adv-14/Makefile
  15. 3 0
      package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-14
  16. 3 0
      package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-14
  17. 0 47
      package/gluon-mesh-batman-adv-14/luasrc/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14
  18. 0 2
      package/gluon-mesh-batman-adv-15/Makefile
  19. 3 0
      package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-15
  20. 3 0
      package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-15
  21. 0 47
      package/gluon-mesh-batman-adv-15/luasrc/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15
  22. 1 1
      package/gluon-mesh-batman-adv-core/Makefile
  23. 64 0
      package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/mesh-batman-adv-core/config_mesh_interface
  24. 0 9
      package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan
  25. 1 9
      package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh
  26. 10 0
      package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-mac-addresses
  27. 0 147
      package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless
  28. 0 18
      package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-mesh-on-wan
  29. 0 13
      package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/350-gluon-mesh-batman-adv-core-rssid
  30. 7 7
      package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd

+ 18 - 0
docs/dev/mac_addresses.rst

@@ -0,0 +1,18 @@
+MAC addresses
+=============
+
+Many devices don't have enough unique MAC addresses assigned by the vendor
+(in batman-adv, each mesh interface needs an own MAC address that must be unique
+mesh-wide).
+
+Gluon tries to solve this issue by using a hash of the primary MAC address as a
+45 bit MAC address prefix. The resulting 8 addresses are used as follows:
+
+* 0: client0; WAN
+* 1: mesh0
+* 2: ibss0
+* 3: wan_radio0 (private WLAN); batman-adv primary address
+* 4: client1; LAN
+* 5: mesh1
+* 6: ibss1
+* 7: wan_radio1 (private WLAN); mesh VPN

+ 1 - 0
docs/index.rst

@@ -43,6 +43,7 @@ Developer Documentation
    dev/configmode
    dev/wan
    dev/i18n
+   dev/mac_addresses
 
 Packages
 --------

+ 14 - 7
package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network

@@ -1,16 +1,16 @@
 #!/usr/bin/lua
 
 local sysconfig = require 'gluon.sysconfig'
+
+local lutil = require 'luci.util'
 local uci = require('luci.model.uci').cursor()
 
 
-if not uci:get('network', 'client') then
-  uci:section('network', 'interface', 'client',
-    {
-      type = 'bridge',
-    }
-  )
-end
+uci:section('network', 'interface', 'client',
+  {
+    type = 'bridge',
+  }
+)
 
 local ifname = uci:get('network', 'client', 'ifname')
 
@@ -21,6 +21,13 @@ if type(ifname) == 'string' then
   end
 end
 
+if sysconfig.lan_ifname and not ifname and not uci:get_bool('network', 'mesh_lan', 'auto') then
+  for _, lanif in ipairs(lutil.split(sysconfig.lan_ifname, ' ')) do
+    uci:add_to_set('network', 'client', 'ifname', lanif)
+  end
+end
+
+
 uci:set('network', 'client', 'macaddr', sysconfig.primary_mac)
 
 uci:save('network')

+ 0 - 0
package/gluon-core/files/lib/gluon/core/mesh/setup.d/.keep


+ 0 - 0
package/gluon-core/files/lib/gluon/core/mesh/teardown.d/.keep


+ 39 - 0
package/gluon-core/files/lib/netifd/proto/gluon_mesh.sh

@@ -0,0 +1,39 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_gluon_mesh_init_config() {
+	proto_config_add_boolean fixed_mtu
+	proto_config_add_boolean transitive
+}
+
+proto_gluon_mesh_setup() {
+	export CONFIG="$1"
+	export IFNAME="$2"
+
+	local fixed_mtu transitive
+	json_get_vars fixed_mtu transitive
+
+	export FIXED_MTU="$fixed_mtu"
+	export TRANSITIVE="$transitive"
+
+	for script in /lib/gluon/core/mesh/setup.d/*; do
+	        [ ! -x "$script" ] || "$script"
+	done
+
+        proto_init_update "$IFNAME" 1
+        proto_send_update "$CONFIG"
+}
+
+proto_gluon_mesh_teardown() {
+	export CONFIG="$1"
+	export IFNAME="$2"
+
+	for script in /lib/gluon/core/mesh/teardown.d/*; do
+	        [ ! -x "$script" ] || "$script"
+	done
+}
+
+add_protocol gluon_mesh

+ 183 - 17
package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless

@@ -1,10 +1,11 @@
 #!/usr/bin/lua
 
 local util = require 'gluon.util'
-local uci = require('luci.model.uci').cursor()
 local site = require 'gluon.site_config'
 local sysconfig = require 'gluon.sysconfig'
 
+local uci = require('luci.model.uci').cursor()
+
 -- Initial
 if not sysconfig.gluon_version then
   uci:delete_all('wireless', 'wifi-iface')
@@ -18,30 +19,195 @@ local function get_channel(radio, config)
   end
 end
 
+local function is_disabled(name)
+  if uci:get('wireless', name) then
+    return uci:get_bool('wireless', name, 'disabled')
+  end
+end
+
+-- Returns the first argument that is not nil; don't call without any non-nil arguments!
+local function first_non_nil(first, ...)
+  if first ~= nil then
+    return first
+  else
+    return first_non_nil(...)
+  end
+end
+
+
+local function configure_ibss(config, radio, index, suffix, disabled)
+  local name = 'ibss_' .. radio
+
+  uci:delete('network', name)
+  uci:delete('network', name .. '_vlan')
+  uci:delete('wireless', name)
+
+  if not config then
+    return
+  end
+
+  local macaddr = util.get_wlan_mac(radio, index, 3)
+  if not macaddr then
+    return
+  end
+
+  if config.vlan then
+    uci:section('network', 'interface', name,
+      {
+        proto = 'none',
+      }
+    )
+
+    uci:section('network', 'interface', name .. '_vlan',
+      {
+        ifname = '@' .. name .. '.' .. config.vlan,
+        proto = 'gluon_mesh',
+      }
+    )
+  else
+    uci:section('network', 'interface', name,
+      {
+        proto = 'gluon_mesh',
+      }
+    )
+  end
+
+  uci:section('wireless', 'wifi-iface', name,
+    {
+      device = radio,
+      network = name,
+      mode = 'adhoc',
+      ssid = config.ssid,
+      bssid = config.bssid,
+      macaddr = macaddr,
+      mcast_rate = config.mcast_rate,
+      ifname = suffix and 'ibss' .. suffix,
+      disabled = disabled and 1 or 0,
+    }
+  )
+end
+
+local function configure_mesh(config, radio, index, suffix, disabled)
+  local name = 'mesh_' .. radio
+  local macfilter = uci:get('wireless', name, 'macfilter')
+  local maclist = uci:get('wireless', name, 'maclist')
+
+  uci:delete('network', name)
+  uci:delete('wireless', name)
+
+  if not config then
+    return
+  end
+
+  local macaddr = util.get_wlan_mac(radio, index, 2)
+  if not macaddr then
+    return
+  end
+
+  uci:section('network', 'interface', name,
+    {
+      proto = 'gluon_mesh',
+    }
+  )
+
+  uci:section('wireless', 'wifi-iface', name,
+    {
+      device = radio,
+      network = name,
+      mode = 'mesh',
+      mesh_id = config.id,
+      mesh_fwding = 0,
+      macaddr = macaddr,
+      mcast_rate = config.mcast_rate,
+      ifname = suffix and 'mesh' .. suffix,
+      disabled = disabled and 1 or 0,
+      macfilter = macfilter,
+      maclist = maclist,
+    }
+  )
+end
+
+local function fixup_wan(radio, index)
+  local name = 'wan_' .. radio
+
+  if not uci:get('wireless', name) then
+    return
+  end
+
+  local macaddr = util.get_wlan_mac(radio, index, 4)
+  if not macaddr then
+    return
+  end
+
+  uci:set('wireless', name, 'macaddr', macaddr)
+end
+
 local function configure_radio(radio, index, config)
-  if config then
-    local channel = get_channel(radio, config)
+  if not config then
+    return
+  end
+
+  local suffix = radio:match('^radio(%d+)$')
+  if not suffix then
+    return
+  end
 
-    uci:delete('wireless', radio, 'disabled')
+  local channel = get_channel(radio, config)
 
-    uci:set('wireless', radio, 'channel', channel)
-    uci:set('wireless', radio, 'htmode', 'HT20')
-    uci:set('wireless', radio, 'country', site.regdom)
+  uci:delete('wireless', radio, 'disabled')
 
-    if config.supported_rates then
-      uci:set_list('wireless', radio, 'supported_rates', config.supported_rates)
-    else
-      uci:delete('wireless', radio, 'supported_rates')
-    end
+  uci:set('wireless', radio, 'channel', channel)
+  uci:set('wireless', radio, 'htmode', 'HT20')
+  uci:set('wireless', radio, 'country', site.regdom)
 
-    if config.basic_rate then
-      uci:set_list('wireless', radio, 'basic_rate', config.basic_rate)
-    else
-      uci:delete('wireless', radio, 'basic_rate')
-    end
+  if config.supported_rates then
+    uci:set_list('wireless', radio, 'supported_rates', config.supported_rates)
+  else
+    uci:delete('wireless', radio, 'supported_rates')
+  end
+
+  if config.basic_rate then
+    uci:set_list('wireless', radio, 'basic_rate', config.basic_rate)
+  else
+    uci:delete('wireless', radio, 'basic_rate')
   end
+
+
+  local ibss_disabled = is_disabled('ibss_' .. radio)
+  local mesh_disabled = is_disabled('mesh_' .. radio)
+
+  configure_ibss(config.ibss, radio, index, suffix,
+    first_non_nil(
+      ibss_disabled,
+      mesh_disabled,
+      (config.ibss or {}).disabled, -- will be nil if config.ibss or config.ibss.disabled is unset
+      false
+    )
+  )
+  configure_mesh(config.mesh, radio, index, suffix,
+    first_non_nil(
+      mesh_disabled,
+      ibss_disabled,
+      (config.mesh or {}).disabled, -- will be nil if config.mesh or config.mesh.disabled is unset
+      false
+    )
+  )
+
+  fixup_wan(radio, index)
 end
 
 util.iterate_radios(configure_radio)
 
+
+if uci:get('system', 'rssid_wlan0') then
+  if uci:get('wireless', 'mesh_radio0') then
+    uci:set('system', 'rssid_wlan0', 'dev', 'mesh0')
+  else
+    uci:set('system', 'rssid_wlan0', 'dev', 'ibss0')
+  end
+
+  uci:save('system')
+end
+
 uci:save('wireless')
+uci:save('network')

+ 16 - 0
package/gluon-core/luasrc/lib/gluon/upgrade/210-interface-wan

@@ -0,0 +1,16 @@
+#!/usr/bin/lua
+
+local site = require 'gluon.site_config'
+local uci = require('luci.model.uci').cursor()
+
+if not uci:get('network', 'mesh_wan') then
+  uci:section('network', 'interface', 'mesh_wan', {
+    ifname     = 'br-wan',
+    proto      = 'gluon_mesh',
+    transitive = 1,
+    fixed_mtu  = 1,
+    auto       = site.mesh_on_wan and 1 or 0,
+  })
+end
+
+uci:save('network')

+ 5 - 6
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan → package/gluon-core/luasrc/lib/gluon/upgrade/220-interface-lan

@@ -12,13 +12,12 @@ if not sysconfig.lan_ifname then
 end
 
 uci:section('network', 'interface', 'mesh_lan', {
-  ifname  = sysconfig.lan_ifname,
-  type    = 'bridge',
+  ifname        = sysconfig.lan_ifname,
+  type          = 'bridge',
   igmp_snooping = 0,
-  proto   = 'batadv',
-  mesh    = 'bat0',
-  mesh_no_rebroadcast = '1',
-  macaddr = util.get_mac(2),
+  proto         = 'gluon_mesh',
+  transitive    = 1,
+  fixed_mtu     = 1,
 })
 
 if uci:get('network', 'mesh_lan', 'auto') == nil then

+ 24 - 0
package/gluon-core/luasrc/lib/gluon/upgrade/800-migrate-batadv

@@ -0,0 +1,24 @@
+#!/usr/bin/lua
+
+local uci = require('luci.model.uci').cursor()
+
+local function migrate_iface(iface)
+	if iface.proto ~= 'batadv' or iface.mesh ~= 'bat0' then
+		return
+	end
+
+	local s = iface['.name']
+
+	uci:set('network', s, 'proto', 'gluon_mesh')
+	uci:set('network', s, 'fixed_mtu', '1')
+
+	if iface.mesh_no_rebroadcast then
+		uci:set('network', s, 'transitive', iface.mesh_no_rebroadcast)
+	end
+
+	uci:delete('network', s, 'mesh')
+	uci:delete('network', s, 'mesh_no_rebroadcast')
+end
+
+uci:foreach('network', 'interface', migrate_iface)
+uci:save('network')

+ 13 - 17
package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua

@@ -114,18 +114,18 @@ local function get_addresses(radio)
 end
 
 -- Generates a (hopefully) unique MAC address
--- The parameter defines the ID to add to the mac addr
+-- The parameter defines the ID to add to the MAC address
 --
 -- IDs defined so far:
--- 0: client0; mesh-vpn
+-- 0: client0; WAN
 -- 1: mesh0
 -- 2: ibss0
--- 3: client1; mesh-on-wan
--- 4: mesh1
--- 5: ibss1
--- 6: mesh-on-lan
--- 7: unused
-local function generate_mac(i)
+-- 3: wan_radio0 (private WLAN); batman-adv primary address
+-- 4: client1; LAN
+-- 5: mesh1
+-- 6: ibss1
+-- 7: wan_radio1 (private WLAN); mesh VPN
+function generate_mac(i)
   if i > 7 or i < 0 then return nil end -- max allowed id (0b111)
 
   local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12)
@@ -137,9 +137,9 @@ local function generate_mac(i)
   m1 = nixio.bit.bor(m1, 0x02)  -- set locally administered bit
   m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit
 
-  -- It's necessary that the first 45 bits of the mac do
-  -- not vary on a single hardware interface, since some chips are using
-  -- a hardware mac filter. (e.g 'ramips-rt305x')
+  -- It's necessary that the first 45 bits of the MAC address don't
+  -- vary on a single hardware interface, since some chips are using
+  -- a hardware MAC filter. (e.g 'rt305x')
 
   m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting)
   m6 = m6 + i                   -- add virtual interface id
@@ -147,11 +147,7 @@ local function generate_mac(i)
   return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
 end
 
-function get_mac(index)
-  return generate_mac(3*(index-1))
-end
-
-function get_wlan_mac_from_driver(radio, vif)
+local function get_wlan_mac_from_driver(radio, vif)
   local primary = sysconfig.primary_mac:lower()
 
   local i = 1
@@ -172,7 +168,7 @@ function get_wlan_mac(radio, index, vif)
     return addr
   end
 
-  return generate_mac(3*(index-1) + (vif-1))
+  return generate_mac(4*(index-1) + (vif-1))
 end
 
 -- Iterate over all radios defined in UCI calling

+ 1 - 1
package/gluon-luci-portconfig/Makefile

@@ -18,7 +18,7 @@ define Package/gluon-luci-portconfig
   SECTION:=gluon
   CATEGORY:=Gluon
   TITLE:=Luci module for advanced ethernet port configuration
-  DEPENDS:=+gluon-luci-admin +gluon-mesh-batman-adv
+  DEPENDS:=+gluon-luci-admin +gluon-client-bridge
 endef
 
 define Build/Prepare

+ 12 - 15
package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua

@@ -2,11 +2,10 @@ local uci = luci.model.uci.cursor()
 local util = require 'gluon.util'
 
 local f, s, o, ssid
-local config = 'wireless'
 
 -- where to read the configuration from
 local primary_iface = 'wan_radio0'
-local ssid = uci:get(config, primary_iface, "ssid")
+local ssid = uci:get('wireless', primary_iface, "ssid")
 
 f = SimpleForm("wifi", translate("Private WLAN"))
 f.template = "admin/expertmode"
@@ -19,7 +18,7 @@ s = f:section(SimpleSection, nil, translate(
 ))
 
 o = s:option(Flag, "enabled", translate("Enabled"))
-o.default = (ssid and not uci:get_bool(config, primary_iface, "disabled")) and o.enabled or o.disabled
+o.default = (ssid and not uci:get_bool('wireless', primary_iface, "disabled")) and o.enabled or o.disabled
 o.rmempty = false
 
 o = s:option(Value, "ssid", translate("Name (SSID)"))
@@ -30,22 +29,19 @@ o.default = ssid
 o = s:option(Value, "key", translate("Key"), translate("8-63 characters"))
 o:depends("enabled", '1')
 o.datatype = "wpakey"
-o.default = uci:get(config, primary_iface, "key")
+o.default = uci:get('wireless', primary_iface, "key")
 
 function f.handle(self, state, data)
   if state == FORM_VALID then
-    uci:foreach(config, "wifi-device",
-      function(s)
-        local radio = s['.name']
+    util.iterate_radios(
+      function(radio, index)
         local name   = "wan_" .. radio
 
         if data.enabled == '1' then
-          -- get_wlan_mac_from_driver will return nil (and thus leave the
-          -- MAC address unset) if the driver doesn't provide enough addresses
-          local macaddr = util.get_wlan_mac_from_driver(radio, 4)
+          local macaddr = util.get_wlan_mac(radio, index, 4)
 
           -- set up WAN wifi-iface
-          uci:section(config, "wifi-iface", name,
+          uci:section('wireless', "wifi-iface", name,
                       {
                         device     = radio,
                         network    = "wan",
@@ -59,12 +55,13 @@ function f.handle(self, state, data)
           )
         else
           -- disable WAN wifi-iface
-          uci:set(config, name, "disabled", 1)
+          uci:set('wireless', name, "disabled", 1)
         end
-    end)
+      end
+    )
 
-    uci:save(config)
-    uci:commit(config)
+    uci:save('wireless')
+    uci:commit('wireless')
   end
 end
 

+ 0 - 2
package/gluon-mesh-batman-adv-14/Makefile

@@ -24,12 +24,10 @@ define Build/Configure
 endef
 
 define Build/Compile
-	$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
 endef
 
 define Package/gluon-mesh-batman-adv-14/install
 	$(CP) ./files/* $(1)/
-	$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
 endef
 
 $(eval $(call BuildPackage,gluon-mesh-batman-adv-14))

+ 3 - 0
package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-14

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface setup 1528

+ 3 - 0
package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-14

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface teardown

+ 0 - 47
package/gluon-mesh-batman-adv-14/luasrc/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14

@@ -1,47 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-
-local uci = require('luci.model.uci').cursor()
-
-
-local function configure_mtu(radio, config, mtu)
-  if config.ibss then
-    local network = 'ibss_' .. radio
-
-    if config.ibss.vlan then
-      uci:set('network', network, 'mtu', mtu + 4)
-      uci:set('network', network .. '_vlan', 'mtu', mtu)
-    else
-      uci:set('network', network, 'mtu', mtu)
-    end
-  end
-
-  if config.mesh then
-    uci:set('network', 'mesh_' .. radio, 'mtu', mtu)
-  end
-end
-
-
-local radios = {}
-
-uci:foreach('wireless', 'wifi-device',
-	    function(s)
-	      table.insert(radios, s['.name'])
-	    end
-)
-
-local mtu = 1528
-
-for _, radio in ipairs(radios) do
-	local hwmode = uci:get('wireless', radio, 'hwmode')
-
-	if hwmode == '11g' or hwmode == '11ng' then
-	  configure_mtu(radio, site.wifi24, mtu)
-	elseif hwmode == '11a' or hwmode == '11na' then
-	  configure_mtu(radio, site.wifi5, mtu)
-	end
-end
-
-
-uci:save('network')

+ 0 - 2
package/gluon-mesh-batman-adv-15/Makefile

@@ -24,12 +24,10 @@ define Build/Configure
 endef
 
 define Build/Compile
-	$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
 endef
 
 define Package/gluon-mesh-batman-adv-15/install
 	$(CP) ./files/* $(1)/
-	$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
 endef
 
 $(eval $(call BuildPackage,gluon-mesh-batman-adv-15))

+ 3 - 0
package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-15

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface setup 1532

+ 3 - 0
package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-15

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface teardown

+ 0 - 47
package/gluon-mesh-batman-adv-15/luasrc/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15

@@ -1,47 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-
-local uci = require('luci.model.uci').cursor()
-
-
-local function configure_mtu(radio, config, mtu)
-  if config.ibss then
-    local network = 'ibss_' .. radio
-
-    if config.ibss.vlan then
-      uci:set('network', network, 'mtu', mtu + 4)
-      uci:set('network', network .. '_vlan', 'mtu', mtu)
-    else
-      uci:set('network', network, 'mtu', mtu)
-    end
-  end
-
-  if config.mesh then
-    uci:set('network', 'mesh_' .. radio, 'mtu', mtu)
-  end
-end
-
-
-local radios = {}
-
-uci:foreach('wireless', 'wifi-device',
-	    function(s)
-	      table.insert(radios, s['.name'])
-	    end
-)
-
-local mtu = 1532
-
-for _, radio in ipairs(radios) do
-	local hwmode = uci:get('wireless', radio, 'hwmode')
-
-	if hwmode == '11g' or hwmode == '11ng' then
-	  configure_mtu(radio, site.wifi24, mtu)
-	elseif hwmode == '11a' or hwmode == '11na' then
-	  configure_mtu(radio, site.wifi5, mtu)
-	end
-end
-
-
-uci:save('network')

+ 1 - 1
package/gluon-mesh-batman-adv-core/Makefile

@@ -13,7 +13,7 @@ define Package/gluon-mesh-batman-adv-core
   SECTION:=gluon
   CATEGORY:=Gluon
   TITLE:=Support for batman-adv meshing (core)
-  DEPENDS:=+gluon-core +libgluonutil +gluon-client-bridge +firewall +libiwinfo
+  DEPENDS:=+gluon-core +libgluonutil +gluon-client-bridge +firewall +libiwinfo +kmod-dummy
 endef
 
 define Build/Prepare

+ 64 - 0
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/mesh-batman-adv-core/config_mesh_interface

@@ -0,0 +1,64 @@
+#!/usr/bin/lua
+
+local util = require 'gluon.util'
+local fs = require 'nixio.fs'
+
+
+local ifname = os.getenv('IFNAME')
+local cmd = arg[1]
+
+
+if cmd == 'setup' then
+
+	local fixed_mtu = tonumber(os.getenv('FIXED_MTU')) or 0
+	local transitive = tonumber(os.getenv('TRANSITIVE')) or 0
+
+	local mtu = tonumber(arg[2])
+
+	if os.execute('ip link show primary0 >/dev/null 2>&1') ~= 0 then
+		os.execute([[
+			ip link add primary0 type dummy
+			echo 1 > /proc/sys/net/ipv6/conf/primary0/disable_ipv6
+			ip link set primary0 address ]] .. util.generate_mac(3) .. [[ mtu ]] .. mtu .. [[ up
+			echo 'bat0' > /sys/class/net/primary0/batman_adv/mesh_iface
+		]])
+	end
+
+	if fixed_mtu == 0 then
+		local lower = fs.glob('/sys/class/net/' .. ifname .. '/lower_*/wireless')()
+		if lower then
+			lower = lower:match('/lower_([^/]+)/wireless$')
+			util.exec('ip', 'link', 'set', 'dev', lower, 'mtu', tostring(mtu+4))
+		end
+
+		util.exec('ip', 'link', 'set', 'dev', ifname, 'mtu', tostring(mtu))
+	end
+
+	local file = assert(io.open('/sys/class/net/' .. ifname .. '/batman_adv/mesh_iface', 'w'))
+	file:write('bat0')
+	file:close()
+
+	file = assert(io.open('/sys/class/net/' .. ifname .. '/batman_adv/no_rebroadcast', 'w'))
+	file:write(tostring(transitive))
+	file:close()
+
+elseif cmd == 'teardown' then
+
+	local file = io.open('/sys/class/net/' .. ifname .. '/batman_adv/mesh_iface', 'w')
+	if file then
+		file:write('none')
+		file:close()
+	end
+
+	local other = false
+	for lower in fs.glob('/sys/class/net/bat0/lower_*') do
+		if lower ~= '/sys/class/net/bat0/lower_primary0' then
+			other = true
+			break
+		end
+	end
+
+	if not other then
+		os.execute('ip link del primary0')
+	end
+end

+ 0 - 9
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan

@@ -1,9 +0,0 @@
-#!/usr/bin/lua
-
-local util = require 'gluon.util'
-local uci = require('luci.model.uci').cursor()
-
-
--- fix up duplicate mac addresses (for mesh-on-WAN)
-uci:set('network', 'wan', 'macaddr', util.get_mac(1))
-uci:save('network')

+ 1 - 9
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh

@@ -5,7 +5,6 @@ local sysctl = require 'gluon.sysctl'
 local site = require 'gluon.site_config'
 
 local uci = require('luci.model.uci').cursor()
-local lutil = require 'luci.util'
 
 
 local gw_sel_class
@@ -25,15 +24,8 @@ uci:section('batman-adv', 'mesh', 'bat0',
 )
 uci:save('batman-adv')
 
-if not uci:get('network', 'client', 'ifname') then
-  uci:add_to_set('network', 'client', 'ifname', 'bat0')
 
-  if sysconfig.lan_ifname and not site.mesh_on_lan then
-    for _, lanif in ipairs(lutil.split(sysconfig.lan_ifname, ' ')) do
-      uci:add_to_set('network', 'client', 'ifname', lanif)
-    end
-  end
-end
+uci:add_to_set('network', 'client', 'ifname', 'bat0')
 
 uci:set('network', 'client', 'proto', 'dhcpv6')
 uci:set('network', 'client', 'reqprefix', 'no')

+ 10 - 0
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-mac-addresses

@@ -0,0 +1,10 @@
+#!/usr/bin/lua
+
+local util = require 'gluon.util'
+local uci = require('luci.model.uci').cursor()
+
+
+-- fix up potentially duplicate MAC addresses (for meshing)
+uci:set('network', 'wan', 'macaddr', util.generate_mac(0))
+uci:set('network', 'mesh_lan', 'macaddr', util.generate_mac(4))
+uci:save('network')

+ 0 - 147
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless

@@ -1,147 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-local util = require 'gluon.util'
-
-local uci = require('luci.model.uci').cursor()
-
-
-local function is_disabled(name)
-  if uci:get('wireless', name) then
-    return uci:get_bool('wireless', name, 'disabled')
-  end
-end
-
--- Returns the first argument that is not nil; don't call without any non-nil arguments!
-local function first_non_nil(first, ...)
-  if first ~= nil then
-    return first
-  else
-    return first_non_nil(...)
-  end
-end
-
-
-local function configure_ibss(config, radio, index, suffix, disabled)
-  local name = 'ibss_' .. radio
-
-  uci:delete('network', name)
-  uci:delete('network', name .. '_vlan')
-  uci:delete('wireless', name)
-
-  if not config then
-    return
-  end
-
-  local macaddr = util.get_wlan_mac(radio, index, 3)
-  if not macaddr then
-    return
-  end
-
-  if config.vlan then
-    uci:section('network', 'interface', name,
-      {
-        proto = 'none',
-      }
-    )
-
-    uci:section('network', 'interface', name .. '_vlan',
-      {
-        ifname = '@' .. name .. '.' .. config.vlan,
-        proto = 'batadv',
-        mesh = 'bat0',
-      }
-    )
-  else
-    uci:section('network', 'interface', name,
-      {
-        proto = 'batadv',
-        mesh = 'bat0',
-      }
-    )
-  end
-
-  uci:section('wireless', 'wifi-iface', name,
-    {
-      device = radio,
-      network = name,
-      mode = 'adhoc',
-      ssid = config.ssid,
-      bssid = config.bssid,
-      macaddr = macaddr,
-      mcast_rate = config.mcast_rate,
-      ifname = suffix and 'ibss' .. suffix,
-      disabled = disabled and 1 or 0,
-    }
-  )
-end
-
-local function configure_mesh(config, radio, index, suffix, disabled)
-  local name = 'mesh_' .. radio
-  local macfilter = uci:get('wireless', name, 'macfilter')
-  local maclist = uci:get('wireless', name, 'maclist')
-
-  uci:delete('network', name)
-  uci:delete('wireless', name)
-
-  if not config then
-    return
-  end
-
-  local macaddr = util.get_wlan_mac(radio, index, 2)
-  if not macaddr then
-    return
-  end
-
-  uci:section('network', 'interface', name,
-    {
-      proto = 'batadv',
-      mesh = 'bat0',
-    }
-  )
-
-  uci:section('wireless', 'wifi-iface', name,
-    {
-      device = radio,
-      network = name,
-      mode = 'mesh',
-      mesh_id = config.id,
-      mesh_fwding = 0,
-      macaddr = macaddr,
-      mcast_rate = config.mcast_rate,
-      ifname = suffix and 'mesh' .. suffix,
-      disabled = disabled and 1 or 0,
-      macfilter = macfilter,
-      maclist = maclist,
-    }
-  )
-end
-
-local function configure_radio(radio, index, config)
-  local suffix = radio:match('^radio(%d+)$')
-
-  local ibss_disabled = is_disabled('ibss_' .. radio)
-  local mesh_disabled = is_disabled('mesh_' .. radio)
-
-  configure_ibss(config.ibss, radio, index, suffix,
-                 first_non_nil(
-                   ibss_disabled,
-                   mesh_disabled,
-                   (config.ibss or {}).disabled, -- will be nil if config.ibss or config.ibss.disabled is unset
-                   false
-                 )
-  )
-  configure_mesh(config.mesh, radio, index, suffix,
-                 first_non_nil(
-                   mesh_disabled,
-                   ibss_disabled,
-                   (config.mesh or {}).disabled, -- will be nil if config.mesh or config.mesh.disabled is unset
-                   false
-                 )
-  )
-end
-
-util.iterate_radios(configure_radio)
-
-uci:save('wireless')
-uci:save('network')

+ 0 - 18
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-mesh-on-wan

@@ -1,18 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-local uci = require 'luci.model.uci'
-
-local c = uci.cursor()
-
-if not c:get('network', 'mesh_wan') then
-  c:section('network', 'interface', 'mesh_wan',
-            { ifname = 'br-wan'
-            , proto  = 'batadv'
-            , mesh   = 'bat0'
-            , mesh_no_rebroadcast = '1'
-            , auto   = site.mesh_on_wan and 1 or 0
-            })
-end
-
-c:save('network')

+ 0 - 13
package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/350-gluon-mesh-batman-adv-core-rssid

@@ -1,13 +0,0 @@
-#!/usr/bin/lua
-
-local uci = require('luci.model.uci').cursor()
-
-if uci:get('system', 'rssid_wlan0') then
-  if uci:get('wireless', 'mesh_radio0') then
-    uci:set('system', 'rssid_wlan0', 'dev', 'mesh0')
-  else
-    uci:set('system', 'rssid_wlan0', 'dev', 'ibss0')
-  end
-
-  uci:save('system')
-end

+ 7 - 7
package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd

@@ -122,13 +122,13 @@ uci:save('fastd')
 
 
 uci:section('network', 'interface', 'mesh_vpn',
-	  {
-		  ifname = 'mesh-vpn',
-		  proto = 'batadv',
-		  mesh = 'bat0',
-		  mesh_no_rebroadcast = 1,
-		  macaddr = util.get_mac(3),
-	  }
+  {
+    ifname = 'mesh-vpn',
+    proto = 'gluon_mesh',
+    transitive = 1,
+    fixed_mtu = 1,
+    macaddr = util.generate_mac(7),
+  }
 )
 
 uci:save('network')