From 56e7753035bbffb604b869bfceaf35367bf88a17 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Sat, 25 Jul 2015 21:01:38 +0200 Subject: [PATCH 1/2] check_site: allow subcheck to be nil in need_table() --- scripts/check_site_lib.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/check_site_lib.lua b/scripts/check_site_lib.lua index ec2498ec..99489302 100644 --- a/scripts/check_site_lib.lua +++ b/scripts/check_site_lib.lua @@ -84,8 +84,10 @@ function need_table(varname, subcheck, required) assert_type(var, 'table', "site.conf error: expected `" .. varname .. "' to be a table") - for k, v in pairs(var) do - subcheck(k, v) + if subcheck then + for k, v in pairs(var) do + subcheck(k, v) + end end return var From 2a93c580428d10724116b0d2d1238e2745715a14 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Sat, 25 Jul 2015 20:41:03 +0200 Subject: [PATCH 2/2] mesh-batadv-core: introduce 11s mesh, refactor wireless config This is a site.conf-breaking change in regard to the wireless config. Make sure to read http://gluon.readthedocs.org/en/latest/user/site.html and update your site.conf accordingly! Support for 802.11s mesh interfaces has been added. Gluon now supports three interface types: ap, ibss and mesh. All of them are now optional and may be configured independently in site.conf. A sample site.conf may look like this: wifi24 = { channel = 1, htmode = 'HT40+', ap = { ssid = 'luebeck.freifunk.net', }, ibss = { ssid = '02:d1:11:37:fc:38', bssid = '02:d1:11:37:fc:38', mcast_rate = 12000, }, mesh = { id = 'ffhl-mesh', mcast_rate = 12000, }, }, --- docs/site-example/site.conf | 38 ++-- docs/user/site.rst | 50 +++-- .../upgrade/350-gluon-mesh-batman-adv-14 | 26 ++- .../upgrade/350-gluon-mesh-batman-adv-15 | 26 ++- .../gluon-mesh-batman-adv-core/check_site.lua | 26 ++- .../320-gluon-mesh-batman-adv-core-wireless | 210 ++++++++++-------- 6 files changed, 230 insertions(+), 146 deletions(-) diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index 6cffded8..1580d901 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -35,9 +35,6 @@ -- Wireless channel. channel = 1, - -- ESSID used for client network. - ssid = 'entenhausen.freifunk.net', - -- Specifies the channel width in 802.11n and 802.11ac mode. -- Possible values are: -- HT20 (single 20MHz channel), @@ -45,32 +42,33 @@ -- HT40+ (2x 20MHz channels, secondary above) htmode = 'HT20', - -- Adjust these values! - mesh_ssid = 'xe:xx:xx:xx:xx:xx', -- ESSID used for mesh - mesh_bssid = 'xe:xx:xx:xx:xx:xx', -- BSSID used for mesh + -- ESSID used for client network. + ap = { + ssid = 'entenhausen.freifunk.net', + -- disabled = true, (optional) + }, - -- Bitrate used for multicast/broadcast packets. - mesh_mcast_rate = 12000, - - -- (optional) mesh VLAN on 802.11 ad-hoc interface (1-4095) - -- mesh_vlan = 14, - -- client_disabled = true, - -- mesh_disabled = false, + mesh = { + -- Adjust these values! + id = 'ffxx-mesh', + mcast_rate = 12000, + -- disabled = true, (optional) + }, }, -- Wireless configuration for 5 GHz interfaces. -- This should be equal to the 2.4 GHz variant, except -- for channel and htmode. wifi5 = { - ssid = 'entenhausen.freifunk.net', channel = 44, htmode = 'HT20', - mesh_ssid = 'xx:xx:xx:xx:xx:xx', - mesh_bssid = 'xx:xx:xx:xx:xx:xx', - mesh_mcast_rate = 12000, - -- mesh_vlan = 14, - -- client_disabled = true, - -- mesh_disabled = false, + ap = { + ssid = 'entenhausen.freifunk.net', + }, + mesh = { + id = 'ffxx-mesh', + mcast_rate = 12000, + }, }, -- The next node feature allows clients to always reach the node it is diff --git a/docs/user/site.rst b/docs/user/site.rst index 50d1c224..ff67a6a6 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -62,24 +62,46 @@ regdom regdom = 'DE' wifi24 - WLAN Configuration of your community in the 2.4Ghz radio. Consisting - of ``ssid`` of your client network, the ``channel`` your community is using, - ``htmode``, the adhoc ssid ``mesh_ssid`` used between devices, the adhoc - bssid ``mesh_bssid`` and the adhoc multicast rate ``mesh_mcast_rate``. - Optionally ``mesh_vlan`` can be used to setup VLAN on top of the 802.11 - ad-hoc interface. The options ``mesh_disabled`` and ``client_disabled`` - are optional, too. They allow to disable the SSID by default, e.g. for - preconfigured node. This only affects first configuraton. - Combined in an dictionary, e.g.: + WLAN configuration for 2.4 GHz devices. + ``channel`` must be set to a valid wireless channel for your radio. + ``htmode`` selects the desired htmode (e.g. HT20, HT40- or HT40+). + + There are currently three interface types available. You many choose to + configure any subset of them: + + - ``ap`` creates a master interface where clients may connect + - ``mesh`` creates an 802.11s mesh interface with forwarding disabled + - ``ibss`` creates an ad-hoc interface + + Each interface may be disabled by setting ``disabled`` to ``true``. + This will only affect new installations. + Upgrades will not changed the disabled state. + + ``ap`` requires a single parameter, a string, named ``ssid`` which sets the interface's ESSID. + + ``mesh`` requires a single parameter, a string, named ``id`` which sets the mesh id. + + ``ibss`` requires two parametersr: ``ssid`` (a string) and ``bssid`` (a MAC). + An optional parameter ``vlan`` (integer) is supported. + + Both ``mesh`` and ``ibss`` accept an optional ``mcast_rate`` (kbit/s) parameter for setting the default multicast datarate. :: wifi24 = { - ssid = 'entenhausen.freifunk.net', channel = 11, - htmode = 'HT40-', - mesh_ssid = 'ff:ff:ff:ee:ba:be', - mesh_bssid = 'ff:ff:ff:ee:ba:be', - mesh_mcast_rate = 12000, + htmode = 'HT20', + ap = { + ssid = 'entenhausen.freifunk.net', + }, + mesh = { + id = 'entenhausen-mesh', + mcast_rate = 12000, + }, + ibss = { + ssid = 'ff:ff:ff:ee:ba:be', + bssid = 'ff:ff:ff:ee:ba:be', + mcast_rate = 12000, + }, }, wifi5 diff --git a/package/gluon-mesh-batman-adv-14/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14 b/package/gluon-mesh-batman-adv-14/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14 index b3ed1e88..05776c30 100755 --- a/package/gluon-mesh-batman-adv-14/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14 +++ b/package/gluon-mesh-batman-adv-14/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14 @@ -5,14 +5,20 @@ local site = require 'gluon.site_config' local uci = require('luci.model.uci').cursor() -local function configure_mtu(radio, config) - local mesh = 'mesh_' .. radio +local function configure_mtu(radio, config, mtu) + if config.ibss then + local network = 'ibss_' .. radio - if config.mesh_vlan then - uci:set('network', mesh, 'mtu', 1532) - uci:set('network', mesh .. '_vlan', 'mtu', 1528) - else - uci:set('network', mesh, 'mtu', 1528) + 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 @@ -25,13 +31,15 @@ uci:foreach('wireless', 'wifi-device', 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) + configure_mtu(radio, site.wifi24, mtu) elseif hwmode == '11a' or hwmode == '11na' then - configure_mtu(radio, site.wifi5) + configure_mtu(radio, site.wifi5, mtu) end end diff --git a/package/gluon-mesh-batman-adv-15/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15 b/package/gluon-mesh-batman-adv-15/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15 index 96f7d310..f9f54003 100755 --- a/package/gluon-mesh-batman-adv-15/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15 +++ b/package/gluon-mesh-batman-adv-15/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15 @@ -5,14 +5,20 @@ local site = require 'gluon.site_config' local uci = require('luci.model.uci').cursor() -local function configure_mtu(radio, config) - local mesh = 'mesh_' .. radio +local function configure_mtu(radio, config, mtu) + if config.ibss then + local network = 'ibss_' .. radio - if config.mesh_vlan then - uci:set('network', mesh, 'mtu', 1536) - uci:set('network', mesh .. '_vlan', 'mtu', 1532) - else - uci:set('network', mesh, 'mtu', 1532) + 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 @@ -25,13 +31,15 @@ uci:foreach('wireless', 'wifi-device', 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) + configure_mtu(radio, site.wifi24, mtu) elseif hwmode == '11a' or hwmode == '11na' then - configure_mtu(radio, site.wifi5) + configure_mtu(radio, site.wifi5, mtu) end end diff --git a/package/gluon-mesh-batman-adv-core/check_site.lua b/package/gluon-mesh-batman-adv-core/check_site.lua index e76ca9e9..25ae9dff 100644 --- a/package/gluon-mesh-batman-adv-core/check_site.lua +++ b/package/gluon-mesh-batman-adv-core/check_site.lua @@ -1,15 +1,27 @@ need_string('regdom') for _, config in ipairs({'wifi24', 'wifi5'}) do - need_string(config .. '.ssid') need_number(config .. '.channel') need_string(config .. '.htmode') - need_string(config .. '.mesh_ssid') - need_string_match(config .. '.mesh_bssid', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$') - need_number(config .. '.mesh_mcast_rate') - need_number(config .. '.mesh_vlan', false) - need_boolean(config .. '.client_disabled', false) - need_boolean(config .. '.mesh_disabled', false) + + if need_table(config .. '.ap', nil, false) then + need_string(config .. '.ap.ssid') + need_boolean(config .. '.ap.disabled', false) + end + + if need_table(config .. '.ibss', nil, false) then + need_string(config .. '.ibss.ssid') + need_string_match(config .. '.ibss.bssid', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$') + need_number(config .. '.ibss.mcast_rate', false) + need_number(config .. '.ibss.vlan', false) + need_boolean(config .. '.ibss.disabled', false) + end + + if need_table(config .. '.mesh', nil, false) then + need_string(config .. '.mesh.id') + need_number(config .. '.mesh.mcast_rate', false) + need_boolean(config .. '.mesh.disabled', false) + end end need_boolean('mesh_on_wan', false) diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless index 50753c8b..cd9f885a 100755 --- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless +++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless @@ -6,110 +6,146 @@ local util = require 'gluon.util' local uci = require('luci.model.uci').cursor() +local function is_disabled(config, name) + local disabled = config and config.disabled + if uci:get('wireless', name) then + disabled = uci:get_bool('wireless', name, 'disabled') + end + + return disabled and 1 or 0 +end + +local function configure_client(config, radio, index, suffix) + local name = 'client_' .. radio + local disabled = is_disabled(config, name) + + uci:delete('wireless', name) + + if config then + uci:section('wireless', 'wifi-iface', name, + { + device = radio, + network = 'client', + mode = 'ap', + ssid = config.ssid, + macaddr = util.generate_mac(2, index), + ifname = suffix and 'client' .. suffix, + disabled = disabled, + } + ) + end +end + +local function configure_ibss(config, radio, index, suffix) + local name = 'ibss_' .. radio + local disabled = is_disabled(config, name) + + uci:delete('network', name) + uci:delete('network', name .. '_vlan') + uci:delete('wireless', name) + + if config then + 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 = util.generate_mac(3, index), + mcast_rate = config.mcast_rate, + ifname = suffix and 'ibss' .. suffix, + disabled = disabled, + } + ) + end +end + +local function configure_mesh(config, radio, index, suffix) + local name = 'mesh_' .. radio + local disabled = is_disabled(config, name) + + uci:delete('network', name) + uci:delete('wireless', name) + + if config then + 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 = util.generate_mac(5, index), + mcast_rate = config.mcast_rate, + ifname = suffix and 'mesh' .. suffix, + disabled = disabled, + } + ) + end +end + local function configure_radio(radio, index, config) + local suffix = radio:match('^radio(%d+)$') + uci:delete('wireless', radio, 'disabled') uci:set('wireless', radio, 'channel', config.channel) uci:set('wireless', radio, 'htmode', config.htmode) uci:set('wireless', radio, 'country', site.regdom) - local client = 'client_' .. radio - local mesh = 'mesh_' .. radio - - local disable_state_client = false - local disable_state_mesh = false - - if uci:get('wireless', client) then - disable_state_client = uci:get_bool('wireless', client, "disabled") - elseif config.client_disabled then - disable_state_client = true - end - - if uci:get('wireless', mesh) then - disable_state_mesh = uci:get_bool('wireless', mesh, "disabled") - elseif config.mesh_disabled then - disable_state_mesh = true - end - - local client_ifname - local mesh_ifname - local radio_suffix = radio:match('^radio(%d+)$') - if radio_suffix then - client_ifname = 'client' .. radio_suffix - mesh_ifname = 'mesh' .. radio_suffix - end - - uci:delete('wireless', client) - uci:section('wireless', 'wifi-iface', client, - { - device = radio, - network = 'client', - mode = 'ap', - ssid = config.ssid, - macaddr = util.generate_mac(2, index), - ifname = client_ifname, - disabled = disable_state_client and 1 or 0, - } - ) - - uci:delete('network', mesh) - uci:delete('network', mesh .. '_vlan') - - if config.mesh_vlan then - uci:section('network', 'interface', mesh, - { - proto = 'none', - } - ) - uci:section('network', 'interface', mesh .. '_vlan', - { - ifname = '@' .. mesh .. '.' .. config.mesh_vlan, - proto = 'batadv', - mesh = 'bat0', - } - ) - else - uci:section('network', 'interface', mesh, - { - proto = 'batadv', - mesh = 'bat0', - } - ) - end - - uci:delete('wireless', mesh) - uci:section('wireless', 'wifi-iface', mesh, - { - device = radio, - network = mesh, - mode = 'adhoc', - ssid = config.mesh_ssid, - bssid = config.mesh_bssid, - macaddr = util.generate_mac(3, index), - mcast_rate = config.mesh_mcast_rate, - ifname = mesh_ifname, - disabled = disable_state_mesh and 1 or 0, - } - ) + configure_client(config.ap, radio, index, suffix) + configure_ibss(config.ibss, radio, index, suffix) + configure_mesh(config.mesh, radio, index, suffix) end local radios = {} uci:foreach('wireless', 'wifi-device', - function(s) - table.insert(radios, s['.name']) - end + function(s) + table.insert(radios, s['.name']) + end ) for index, radio in ipairs(radios) do - local hwmode = uci:get('wireless', radio, 'hwmode') + local hwmode = uci:get('wireless', radio, 'hwmode') - if hwmode == '11g' or hwmode == '11ng' then - configure_radio(radio, index, site.wifi24) - elseif hwmode == '11a' or hwmode == '11na' then - configure_radio(radio, index, site.wifi5) - end + if hwmode == '11g' or hwmode == '11ng' then + configure_radio(radio, index, site.wifi24) + elseif hwmode == '11a' or hwmode == '11na' then + configure_radio(radio, index, site.wifi5) + end end