From 00c47f2912604c75abd8cc3a4663ca12d471ed0e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 30 Apr 2015 13:05:15 +0200 Subject: [PATCH] gluon-mesh-vpn-fastd: extend site configuration to allow multiple and nested peer groups --- docs/site-example/site.conf | 42 +++++++---- docs/user/site.rst | 16 ++-- package/gluon-mesh-vpn-fastd/check_site.lua | 29 +++++--- .../lib/gluon/announce/statistics.d/mesh_vpn | 65 +++++++++++++---- .../lib/gluon/upgrade/400-mesh-vpn-fastd | 73 +++++++++++++------ 5 files changed, 159 insertions(+), 66 deletions(-) diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index d5372512..e2c03434 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -90,24 +90,38 @@ -- List of crypto-methods to use. methods = {'salsa2012+umac'}, mtu = 1426, - backbone = { - -- Limit number of connected peers to reduce bandwidth. - limit = 2, + groups = { + backbone = { + -- Limit number of connected peers to reduce bandwidth. + limit = 2, - -- List of peers. - peers = { - peer1 = { - key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + -- List of peers. + peers = { + peer1 = { + key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', - -- This is a list, so you might add multiple entries. - remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'}, - }, - peer2 = { - key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', - -- You can also omit the ipv4 to allow both connection via ipv4 and ipv6 - remotes = {'"xxx.somehost2.invalid" port xxxxx'}, + -- This is a list, so you might add multiple entries. + remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'}, + }, + peer2 = { + key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + -- You can also omit the ipv4 to allow both connection via ipv4 and ipv6 + remotes = {'"xxx.somehost2.invalid" port xxxxx'}, + }, }, + + -- Optional: nested peer groups + -- groups = { + -- backbone_sub = { + -- ... + -- }, + -- ... + -- }, }, + -- Optional: additional peer groups, possibly with other limits + -- backbone2 = { + -- ... + -- }, }, }, diff --git a/docs/user/site.rst b/docs/user/site.rst index b15d9d72..f555bb7d 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -103,13 +103,15 @@ fastd_mesh_vpn fastd_mesh_vpn = { methods = {'salsa2012+umac'}, mtu = 1426, - backbone = { - limit = 2, - peers = { - peer1 = { - key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', - remotes = {'ipv4 "vpn1.entenhausen.freifunk.net" port 10000'}, - }, + groups = { + backbone = { + limit = 2, + peers = { + peer1 = { + key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + remotes = {'ipv4 "vpn1.entenhausen.freifunk.net" port 10000'}, + }, + } } } } diff --git a/package/gluon-mesh-vpn-fastd/check_site.lua b/package/gluon-mesh-vpn-fastd/check_site.lua index fc9d8221..cade1c17 100644 --- a/package/gluon-mesh-vpn-fastd/check_site.lua +++ b/package/gluon-mesh-vpn-fastd/check_site.lua @@ -1,14 +1,25 @@ -need_string_array 'fastd_mesh_vpn.methods' -need_number 'fastd_mesh_vpn.mtu' -need_number 'fastd_mesh_vpn.backbone.limit' +need_string_array('fastd_mesh_vpn.methods') +need_number('fastd_mesh_vpn.mtu') +need_boolean('fastd_mesh_vpn.enabled', false) -local function check_peer(k, _) - local prefix = string.format('fastd_mesh_vpn.backbone.peers[%q].', k) +local function check_peer(prefix) + return function(k, _) + local table = string.format('%s[%q].', prefix, k) - need_string(prefix .. 'key') - need_string_array(prefix .. 'remotes') + need_string(table .. 'key') + need_string_array(table .. 'remotes') + end end -need_table('fastd_mesh_vpn.backbone.peers', check_peer) -need_boolean('fastd_mesh_vpn.enabled', false) +local function check_group(prefix) + 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')) diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn b/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn index 5e4e6a7a..a67b9a07 100644 --- a/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn +++ b/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn @@ -1,32 +1,71 @@ -local nixio = require('nixio') -local ltn12 = require('luci.ltn12') -local json = require('luci.json') +local json = require 'luci.json' +local ltn12 = require 'luci.ltn12' +local nixio = require 'nixio' +local site = require 'gluon.site_config' 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 socket_path = uci:get('fastd', 'mesh_vpn', 'status_socket') if not fastd_sock:connect(socket_path) then return nil end -decoder = json.Decoder() +local decoder = json.Decoder() ltn12.pump.all(ltn12.source.file(fastd_sock), decoder:sink()) local status = decoder:get() -local output = {} -for key, peer in pairs(status.peers) do - local name, valid = peer.name:gsub('^mesh_vpn_backbone_peer_', '') - if valid == 1 then +local peer_groups + +local function peer_connection(config) + local peer = status.peers[config.key] + if peer then if peer.connection then - output[name] = {} - output[name].established = peer.connection.established/1000 + return { + established = peer.connection.established/1000 + } else - output[name] = json.null + return json.null 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) diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd index 0585f5a7..f370bbf3 100755 --- a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd +++ b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd @@ -36,33 +36,60 @@ uci:section('fastd', 'fastd', 'mesh_vpn', ) 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', - function(peer) - return peer.net == 'mesh_vpn' and peer.group == 'mesh_vpn_backbone' - end -) +local add_groups -for name, config in pairs(site.fastd_mesh_vpn.backbone.peers) do - uci:section('fastd', 'peer', 'mesh_vpn_backbone_peer_' .. name, - { - enabled = 1, - net = 'mesh_vpn', - group = 'mesh_vpn_backbone', - key = config.key, - remote = config.remotes, - } - ) +local function add_peer(group, name, config) + uci:section('fastd', 'peer', group .. '_peer_' .. name, + { + enabled = 1, + net = 'mesh_vpn', + group = group, + key = config.key, + remote = config.remotes, + } + ) 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:commit('fastd')