gluon-mesh-vpn-fastd: extend site configuration to allow multiple and nested peer groups

This commit is contained in:
Matthias Schiffer 2015-04-30 13:05:15 +02:00
parent 531520032c
commit 00c47f2912
5 changed files with 159 additions and 66 deletions

View File

@ -90,24 +90,38 @@
-- List of crypto-methods to use. -- List of crypto-methods to use.
methods = {'salsa2012+umac'}, methods = {'salsa2012+umac'},
mtu = 1426, mtu = 1426,
backbone = { groups = {
-- Limit number of connected peers to reduce bandwidth. backbone = {
limit = 2, -- Limit number of connected peers to reduce bandwidth.
limit = 2,
-- List of peers. -- List of peers.
peers = { peers = {
peer1 = { peer1 = {
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-- This is a list, so you might add multiple entries. -- This is a list, so you might add multiple entries.
remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'}, remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'},
}, },
peer2 = { peer2 = {
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-- You can also omit the ipv4 to allow both connection via ipv4 and ipv6 -- You can also omit the ipv4 to allow both connection via ipv4 and ipv6
remotes = {'"xxx.somehost2.invalid" port xxxxx'}, remotes = {'"xxx.somehost2.invalid" port xxxxx'},
},
}, },
-- Optional: nested peer groups
-- groups = {
-- backbone_sub = {
-- ...
-- },
-- ...
-- },
}, },
-- Optional: additional peer groups, possibly with other limits
-- backbone2 = {
-- ...
-- },
}, },
}, },

View File

@ -103,13 +103,15 @@ fastd_mesh_vpn
fastd_mesh_vpn = { fastd_mesh_vpn = {
methods = {'salsa2012+umac'}, methods = {'salsa2012+umac'},
mtu = 1426, mtu = 1426,
backbone = { groups = {
limit = 2, backbone = {
peers = { limit = 2,
peer1 = { peers = {
key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', peer1 = {
remotes = {'ipv4 "vpn1.entenhausen.freifunk.net" port 10000'}, key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
}, remotes = {'ipv4 "vpn1.entenhausen.freifunk.net" port 10000'},
},
}
} }
} }
} }

View File

@ -1,14 +1,25 @@
need_string_array 'fastd_mesh_vpn.methods' need_string_array('fastd_mesh_vpn.methods')
need_number 'fastd_mesh_vpn.mtu' need_number('fastd_mesh_vpn.mtu')
need_number 'fastd_mesh_vpn.backbone.limit' need_boolean('fastd_mesh_vpn.enabled', false)
local function check_peer(k, _) local function check_peer(prefix)
local prefix = string.format('fastd_mesh_vpn.backbone.peers[%q].', k) return function(k, _)
local table = string.format('%s[%q].', prefix, k)
need_string(prefix .. 'key') need_string(table .. 'key')
need_string_array(prefix .. 'remotes') need_string_array(table .. 'remotes')
end
end end
need_table('fastd_mesh_vpn.backbone.peers', check_peer) local function check_group(prefix)
need_boolean('fastd_mesh_vpn.enabled', false) return function(k, _)
local table = string.format('%s[%q].', prefix, k)
need_number(table .. 'limit', false)
need_table(table .. 'peers', check_peer(table .. 'peers'), false)
need_table(table .. 'groups', check_group(table .. 'groups'), false)
end
end
need_table('fastd_mesh_vpn.groups', check_group('fastd_mesh_vpn.groups'))

View File

@ -1,32 +1,71 @@
local nixio = require('nixio') local json = require 'luci.json'
local ltn12 = require('luci.ltn12') local ltn12 = require 'luci.ltn12'
local json = require('luci.json') local nixio = require 'nixio'
local site = require 'gluon.site_config'
local uci = require('luci.model.uci').cursor() local uci = require('luci.model.uci').cursor()
local socket_path = uci:get('fastd', 'mesh_vpn', 'status_socket')
local fastd_sock = nixio.socket('unix', 'stream') local fastd_sock = nixio.socket('unix', 'stream')
local socket_path = uci:get('fastd', 'mesh_vpn', 'status_socket')
if not fastd_sock:connect(socket_path) then if not fastd_sock:connect(socket_path) then
return nil return nil
end end
decoder = json.Decoder() local decoder = json.Decoder()
ltn12.pump.all(ltn12.source.file(fastd_sock), decoder:sink()) ltn12.pump.all(ltn12.source.file(fastd_sock), decoder:sink())
local status = decoder:get() local status = decoder:get()
local output = {}
for key, peer in pairs(status.peers) do local peer_groups
local name, valid = peer.name:gsub('^mesh_vpn_backbone_peer_', '')
if valid == 1 then local function peer_connection(config)
local peer = status.peers[config.key]
if peer then
if peer.connection then if peer.connection then
output[name] = {} return {
output[name].established = peer.connection.established/1000 established = peer.connection.established/1000
}
else else
output[name] = json.null return json.null
end end
end end
end end
return output local function peer_group(config)
local ret = {}
if config.peers then
local peers = {}
for peername, peerconfig in pairs(config.peers) do
peers[peername] = peer_connection(peerconfig)
end
if next(peers) then
ret.peers = peers
end
end
ret.groups = peer_groups(config.groups)
if next(ret) then
return ret
end
end
function peer_groups(groups)
if groups then
local ret = {}
for name, group in pairs(groups) do
ret[name] = peer_group(group)
end
if next(ret) then
return ret
end
end
end
return peer_group(site.fastd_mesh_vpn)

View File

@ -36,33 +36,60 @@ uci:section('fastd', 'fastd', 'mesh_vpn',
) )
uci:delete('fastd', 'mesh_vpn', 'user') uci:delete('fastd', 'mesh_vpn', 'user')
uci:delete('fastd', 'mesh_vpn_backbone')
uci:section('fastd', 'peer_group', 'mesh_vpn_backbone',
{
enabled = 1,
net = 'mesh_vpn',
peer_limit = site.fastd_mesh_vpn.backbone.limit,
}
)
uci:delete_all('fastd', 'peer', local add_groups
function(peer)
return peer.net == 'mesh_vpn' and peer.group == 'mesh_vpn_backbone'
end
)
for name, config in pairs(site.fastd_mesh_vpn.backbone.peers) do local function add_peer(group, name, config)
uci:section('fastd', 'peer', 'mesh_vpn_backbone_peer_' .. name, uci:section('fastd', 'peer', group .. '_peer_' .. name,
{ {
enabled = 1, enabled = 1,
net = 'mesh_vpn', net = 'mesh_vpn',
group = 'mesh_vpn_backbone', group = group,
key = config.key, key = config.key,
remote = config.remotes, remote = config.remotes,
} }
) )
end end
local function add_group(name, config, parent)
uci:delete('fastd', name)
uci:delete_all('fastd', 'peer',
function(peer)
return (peer.net == 'mesh_vpn' and peer.group == name)
end
)
uci:section('fastd', 'peer_group', name,
{
enabled = 1,
net = 'mesh_vpn',
parent = parent,
peer_limit = config.limit,
}
)
if config.peers then
for peername, peerconfig in pairs(config.peers) do
add_peer(name, peername, peerconfig)
end
end
add_groups(name, config.groups, name)
end
-- declared local above
function add_groups(prefix, groups, parent)
if groups then
for name, group in pairs(groups) do
add_group(prefix .. '_' .. name, group, parent)
end
end
end
add_groups('mesh_vpn', site.fastd_mesh_vpn.groups)
uci:save('fastd') uci:save('fastd')
uci:commit('fastd') uci:commit('fastd')