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. -- Wireless channel.
channel = 1, channel = 1,
-- ESSID used for client network.
ssid = 'entenhausen.freifunk.net',
-- Specifies the channel width in 802.11n and 802.11ac mode. -- Specifies the channel width in 802.11n and 802.11ac mode.
-- Possible values are: -- Possible values are:
-- HT20 (single 20MHz channel), -- HT20 (single 20MHz channel),
@ -45,32 +42,33 @@
-- HT40+ (2x 20MHz channels, secondary above) -- HT40+ (2x 20MHz channels, secondary above)
htmode = 'HT20', htmode = 'HT20',
-- ESSID used for client network.
ap = {
ssid = 'entenhausen.freifunk.net',
-- disabled = true, (optional)
},
mesh = {
-- Adjust these values! -- Adjust these values!
mesh_ssid = 'xe:xx:xx:xx:xx:xx', -- ESSID used for mesh id = 'ffxx-mesh',
mesh_bssid = 'xe:xx:xx:xx:xx:xx', -- BSSID used for mesh mcast_rate = 12000,
-- 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,
}, },
-- Wireless configuration for 5 GHz interfaces. -- Wireless configuration for 5 GHz interfaces.
-- This should be equal to the 2.4 GHz variant, except -- This should be equal to the 2.4 GHz variant, except
-- for channel and htmode. -- for channel and htmode.
wifi5 = { wifi5 = {
ssid = 'entenhausen.freifunk.net',
channel = 44, channel = 44,
htmode = 'HT20', htmode = 'HT20',
mesh_ssid = 'xx:xx:xx:xx:xx:xx', ap = {
mesh_bssid = 'xx:xx:xx:xx:xx:xx', ssid = 'entenhausen.freifunk.net',
mesh_mcast_rate = 12000, },
-- mesh_vlan = 14, mesh = {
-- client_disabled = true, id = 'ffxx-mesh',
-- mesh_disabled = false, mcast_rate = 12000,
},
}, },
-- The next node feature allows clients to always reach the node it is -- The next node feature allows clients to always reach the node it is

View File

@ -62,24 +62,46 @@ regdom
regdom = 'DE' regdom = 'DE'
wifi24 wifi24
WLAN Configuration of your community in the 2.4Ghz radio. Consisting WLAN configuration for 2.4 GHz devices.
of ``ssid`` of your client network, the ``channel`` your community is using, ``channel`` must be set to a valid wireless channel for your radio.
``htmode``, the adhoc ssid ``mesh_ssid`` used between devices, the adhoc ``htmode`` selects the desired htmode (e.g. HT20, HT40- or HT40+).
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 There are currently three interface types available. You many choose to
ad-hoc interface. The options ``mesh_disabled`` and ``client_disabled`` configure any subset of them:
are optional, too. They allow to disable the SSID by default, e.g. for
preconfigured node. This only affects first configuraton. - ``ap`` creates a master interface where clients may connect
Combined in an dictionary, e.g.: - ``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 = { wifi24 = {
ssid = 'entenhausen.freifunk.net',
channel = 11, channel = 11,
htmode = 'HT40-', htmode = 'HT20',
mesh_ssid = 'ff:ff:ff:ee:ba:be', ap = {
mesh_bssid = 'ff:ff:ff:ee:ba:be', ssid = 'entenhausen.freifunk.net',
mesh_mcast_rate = 12000, },
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 wifi5

View File

@ -5,14 +5,20 @@ local site = require 'gluon.site_config'
local uci = require('luci.model.uci').cursor() local uci = require('luci.model.uci').cursor()
local function configure_mtu(radio, config) local function configure_mtu(radio, config, mtu)
local mesh = 'mesh_' .. radio if config.ibss then
local network = 'ibss_' .. radio
if config.mesh_vlan then if config.ibss.vlan then
uci:set('network', mesh, 'mtu', 1532) uci:set('network', network, 'mtu', mtu + 4)
uci:set('network', mesh .. '_vlan', 'mtu', 1528) uci:set('network', network .. '_vlan', 'mtu', mtu)
else else
uci:set('network', mesh, 'mtu', 1528) uci:set('network', network, 'mtu', mtu)
end
end
if config.mesh then
uci:set('network', 'mesh_' .. radio, 'mtu', mtu)
end end
end end
@ -25,13 +31,15 @@ uci:foreach('wireless', 'wifi-device',
end end
) )
local mtu = 1528
for _, radio in ipairs(radios) do for _, 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 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 elseif hwmode == '11a' or hwmode == '11na' then
configure_mtu(radio, site.wifi5) configure_mtu(radio, site.wifi5, mtu)
end end
end end

View File

@ -5,14 +5,20 @@ local site = require 'gluon.site_config'
local uci = require('luci.model.uci').cursor() local uci = require('luci.model.uci').cursor()
local function configure_mtu(radio, config) local function configure_mtu(radio, config, mtu)
local mesh = 'mesh_' .. radio if config.ibss then
local network = 'ibss_' .. radio
if config.mesh_vlan then if config.ibss.vlan then
uci:set('network', mesh, 'mtu', 1536) uci:set('network', network, 'mtu', mtu + 4)
uci:set('network', mesh .. '_vlan', 'mtu', 1532) uci:set('network', network .. '_vlan', 'mtu', mtu)
else else
uci:set('network', mesh, 'mtu', 1532) uci:set('network', network, 'mtu', mtu)
end
end
if config.mesh then
uci:set('network', 'mesh_' .. radio, 'mtu', mtu)
end end
end end
@ -25,13 +31,15 @@ uci:foreach('wireless', 'wifi-device',
end end
) )
local mtu = 1532
for _, radio in ipairs(radios) do for _, 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 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 elseif hwmode == '11a' or hwmode == '11na' then
configure_mtu(radio, site.wifi5) configure_mtu(radio, site.wifi5, mtu)
end end
end end

View File

@ -1,15 +1,27 @@
need_string('regdom') need_string('regdom')
for _, config in ipairs({'wifi24', 'wifi5'}) do for _, config in ipairs({'wifi24', 'wifi5'}) do
need_string(config .. '.ssid')
need_number(config .. '.channel') need_number(config .. '.channel')
need_string(config .. '.htmode') 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$') if need_table(config .. '.ap', nil, false) then
need_number(config .. '.mesh_mcast_rate') need_string(config .. '.ap.ssid')
need_number(config .. '.mesh_vlan', false) need_boolean(config .. '.ap.disabled', false)
need_boolean(config .. '.client_disabled', false) end
need_boolean(config .. '.mesh_disabled', false)
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 end
need_boolean('mesh_on_wan', false) need_boolean('mesh_on_wan', false)

View File

@ -6,70 +6,61 @@ local util = require 'gluon.util'
local uci = require('luci.model.uci').cursor() local uci = require('luci.model.uci').cursor()
local function configure_radio(radio, index, config) local function is_disabled(config, name)
uci:delete('wireless', radio, 'disabled') local disabled = config and config.disabled
if uci:get('wireless', name) then
uci:set('wireless', radio, 'channel', config.channel) disabled = uci:get_bool('wireless', name, 'disabled')
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 end
if uci:get('wireless', mesh) then return disabled and 1 or 0
disable_state_mesh = uci:get_bool('wireless', mesh, "disabled")
elseif config.mesh_disabled then
disable_state_mesh = true
end end
local client_ifname local function configure_client(config, radio, index, suffix)
local mesh_ifname local name = 'client_' .. radio
local radio_suffix = radio:match('^radio(%d+)$') local disabled = is_disabled(config, name)
if radio_suffix then
client_ifname = 'client' .. radio_suffix
mesh_ifname = 'mesh' .. radio_suffix
end
uci:delete('wireless', client) uci:delete('wireless', name)
uci:section('wireless', 'wifi-iface', client,
if config then
uci:section('wireless', 'wifi-iface', name,
{ {
device = radio, device = radio,
network = 'client', network = 'client',
mode = 'ap', mode = 'ap',
ssid = config.ssid, ssid = config.ssid,
macaddr = util.generate_mac(2, index), macaddr = util.generate_mac(2, index),
ifname = client_ifname, ifname = suffix and 'client' .. suffix,
disabled = disable_state_client and 1 or 0, disabled = disabled,
} }
) )
end
end
uci:delete('network', mesh) local function configure_ibss(config, radio, index, suffix)
uci:delete('network', mesh .. '_vlan') local name = 'ibss_' .. radio
local disabled = is_disabled(config, name)
if config.mesh_vlan then uci:delete('network', name)
uci:section('network', 'interface', mesh, uci:delete('network', name .. '_vlan')
uci:delete('wireless', name)
if config then
if config.vlan then
uci:section('network', 'interface', name,
{ {
proto = 'none', proto = 'none',
} }
) )
uci:section('network', 'interface', mesh .. '_vlan',
uci:section('network', 'interface', name .. '_vlan',
{ {
ifname = '@' .. mesh .. '.' .. config.mesh_vlan, ifname = '@' .. name .. '.' .. config.vlan,
proto = 'batadv', proto = 'batadv',
mesh = 'bat0', mesh = 'bat0',
} }
) )
else else
uci:section('network', 'interface', mesh, uci:section('network', 'interface', name,
{ {
proto = 'batadv', proto = 'batadv',
mesh = 'bat0', mesh = 'bat0',
@ -77,21 +68,66 @@ local function configure_radio(radio, index, config)
) )
end end
uci:delete('wireless', mesh) uci:section('wireless', 'wifi-iface', name,
uci:section('wireless', 'wifi-iface', mesh,
{ {
device = radio, device = radio,
network = mesh, network = name,
mode = 'adhoc', mode = 'adhoc',
ssid = config.mesh_ssid, ssid = config.ssid,
bssid = config.mesh_bssid, bssid = config.bssid,
macaddr = util.generate_mac(3, index), macaddr = util.generate_mac(3, index),
mcast_rate = config.mesh_mcast_rate, mcast_rate = config.mcast_rate,
ifname = mesh_ifname, ifname = suffix and 'ibss' .. suffix,
disabled = disable_state_mesh and 1 or 0, disabled = disabled,
} }
) )
end 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)
configure_client(config.ap, radio, index, suffix)
configure_ibss(config.ibss, radio, index, suffix)
configure_mesh(config.mesh, radio, index, suffix)
end
local radios = {} local radios = {}