Reorganize MAC addresses, always explicitly set address for private WLAN
Fixes #842
This commit is contained in:
parent
0b3af14bf8
commit
e795f61252
18
docs/dev/mac_addresses.rst
Normal file
18
docs/dev/mac_addresses.rst
Normal file
@ -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
|
@ -43,6 +43,7 @@ Developer Documentation
|
|||||||
dev/configmode
|
dev/configmode
|
||||||
dev/wan
|
dev/wan
|
||||||
dev/i18n
|
dev/i18n
|
||||||
|
dev/mac_addresses
|
||||||
|
|
||||||
Packages
|
Packages
|
||||||
--------
|
--------
|
||||||
|
@ -127,6 +127,21 @@ local function configure_mesh(config, radio, index, suffix, disabled)
|
|||||||
)
|
)
|
||||||
end
|
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)
|
local function configure_radio(radio, index, config)
|
||||||
if not config then
|
if not config then
|
||||||
return
|
return
|
||||||
@ -177,6 +192,8 @@ local function configure_radio(radio, index, config)
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fixup_wan(radio, index)
|
||||||
end
|
end
|
||||||
|
|
||||||
util.iterate_radios(configure_radio)
|
util.iterate_radios(configure_radio)
|
||||||
|
@ -114,18 +114,18 @@ local function get_addresses(radio)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Generates a (hopefully) unique MAC address
|
-- 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:
|
-- IDs defined so far:
|
||||||
-- 0: client0; mesh-vpn
|
-- 0: client0; WAN
|
||||||
-- 1: mesh0
|
-- 1: mesh0
|
||||||
-- 2: ibss0
|
-- 2: ibss0
|
||||||
-- 3: client1; mesh-on-wan
|
-- 3: wan_radio0 (private WLAN); batman-adv primary address
|
||||||
-- 4: mesh1
|
-- 4: client1; LAN
|
||||||
-- 5: ibss1
|
-- 5: mesh1
|
||||||
-- 6: mesh-on-lan
|
-- 6: ibss1
|
||||||
-- 7: unused
|
-- 7: wan_radio1 (private WLAN); mesh VPN
|
||||||
local function generate_mac(i)
|
function generate_mac(i)
|
||||||
if i > 7 or i < 0 then return nil end -- max allowed id (0b111)
|
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)
|
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.bor(m1, 0x02) -- set locally administered bit
|
||||||
m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit
|
m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit
|
||||||
|
|
||||||
-- It's necessary that the first 45 bits of the mac do
|
-- It's necessary that the first 45 bits of the MAC address don't
|
||||||
-- not vary on a single hardware interface, since some chips are using
|
-- vary on a single hardware interface, since some chips are using
|
||||||
-- a hardware mac filter. (e.g 'ramips-rt305x')
|
-- a hardware MAC filter. (e.g 'rt305x')
|
||||||
|
|
||||||
m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting)
|
m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting)
|
||||||
m6 = m6 + i -- add virtual interface id
|
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)
|
return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6)
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_mac(index)
|
local function get_wlan_mac_from_driver(radio, vif)
|
||||||
return generate_mac(3*(index-1))
|
|
||||||
end
|
|
||||||
|
|
||||||
function get_wlan_mac_from_driver(radio, vif)
|
|
||||||
local primary = sysconfig.primary_mac:lower()
|
local primary = sysconfig.primary_mac:lower()
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
@ -172,7 +168,7 @@ function get_wlan_mac(radio, index, vif)
|
|||||||
return addr
|
return addr
|
||||||
end
|
end
|
||||||
|
|
||||||
return generate_mac(3*(index-1) + (vif-1))
|
return generate_mac(4*(index-1) + (vif-1))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Iterate over all radios defined in UCI calling
|
-- Iterate over all radios defined in UCI calling
|
||||||
|
@ -2,11 +2,10 @@ local uci = luci.model.uci.cursor()
|
|||||||
local util = require 'gluon.util'
|
local util = require 'gluon.util'
|
||||||
|
|
||||||
local f, s, o, ssid
|
local f, s, o, ssid
|
||||||
local config = 'wireless'
|
|
||||||
|
|
||||||
-- where to read the configuration from
|
-- where to read the configuration from
|
||||||
local primary_iface = 'wan_radio0'
|
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 = SimpleForm("wifi", translate("Private WLAN"))
|
||||||
f.template = "admin/expertmode"
|
f.template = "admin/expertmode"
|
||||||
@ -19,7 +18,7 @@ s = f:section(SimpleSection, nil, translate(
|
|||||||
))
|
))
|
||||||
|
|
||||||
o = s:option(Flag, "enabled", translate("Enabled"))
|
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.rmempty = false
|
||||||
|
|
||||||
o = s:option(Value, "ssid", translate("Name (SSID)"))
|
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 = s:option(Value, "key", translate("Key"), translate("8-63 characters"))
|
||||||
o:depends("enabled", '1')
|
o:depends("enabled", '1')
|
||||||
o.datatype = "wpakey"
|
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)
|
function f.handle(self, state, data)
|
||||||
if state == FORM_VALID then
|
if state == FORM_VALID then
|
||||||
uci:foreach(config, "wifi-device",
|
util.iterate_radios(
|
||||||
function(s)
|
function(radio, index)
|
||||||
local radio = s['.name']
|
|
||||||
local name = "wan_" .. radio
|
local name = "wan_" .. radio
|
||||||
|
|
||||||
if data.enabled == '1' then
|
if data.enabled == '1' then
|
||||||
-- get_wlan_mac_from_driver will return nil (and thus leave the
|
local macaddr = util.get_wlan_mac(radio, index, 4)
|
||||||
-- MAC address unset) if the driver doesn't provide enough addresses
|
|
||||||
local macaddr = util.get_wlan_mac_from_driver(radio, 4)
|
|
||||||
|
|
||||||
-- set up WAN wifi-iface
|
-- set up WAN wifi-iface
|
||||||
uci:section(config, "wifi-iface", name,
|
uci:section('wireless', "wifi-iface", name,
|
||||||
{
|
{
|
||||||
device = radio,
|
device = radio,
|
||||||
network = "wan",
|
network = "wan",
|
||||||
@ -59,12 +55,13 @@ function f.handle(self, state, data)
|
|||||||
)
|
)
|
||||||
else
|
else
|
||||||
-- disable WAN wifi-iface
|
-- disable WAN wifi-iface
|
||||||
uci:set(config, name, "disabled", 1)
|
uci:set('wireless', name, "disabled", 1)
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
|
)
|
||||||
|
|
||||||
uci:save(config)
|
uci:save('wireless')
|
||||||
uci:commit(config)
|
uci:commit('wireless')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ local util = require 'gluon.util'
|
|||||||
local uci = require('luci.model.uci').cursor()
|
local uci = require('luci.model.uci').cursor()
|
||||||
|
|
||||||
|
|
||||||
-- fix up duplicate mac addresses (for meshing)
|
-- fix up potentially duplicate MAC addresses (for meshing)
|
||||||
uci:set('network', 'wan', 'macaddr', util.get_mac(1))
|
uci:set('network', 'wan', 'macaddr', util.generate_mac(0))
|
||||||
uci:set('network', 'mesh_lan', 'macaddr', util.get_mac(2))
|
uci:set('network', 'mesh_lan', 'macaddr', util.generate_mac(4))
|
||||||
uci:save('network')
|
uci:save('network')
|
||||||
|
@ -127,7 +127,7 @@ uci:section('network', 'interface', 'mesh_vpn',
|
|||||||
proto = 'gluon_mesh',
|
proto = 'gluon_mesh',
|
||||||
transitive = 1,
|
transitive = 1,
|
||||||
fixed_mtu = 1,
|
fixed_mtu = 1,
|
||||||
macaddr = util.get_mac(3),
|
macaddr = util.generate_mac(7),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user