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,
            },
    },
This commit is contained in:
Nils Schneider 2015-07-25 20:41:03 +02:00
parent 56e7753035
commit 2a93c58042
6 changed files with 230 additions and 146 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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