mirror of https://github.com/aredn/aredn.git
Supernode support (#938)
* Supernode option * Change supernode 10/8 route injection. Identify supernode in sysinfo.json * Supernode tunnels use port 5526 * Advertise supernode-ness * Update DNS if supernodes are available * Open up supernodes DNS service to incoming mesh requests * Simply nameserver update * Support supernodes on hap ac2 * Improve supernode nameserver update reliability * Rework how supernode nameservers are managed * Improve supernode dns advertising * Add super mesh button * User supernode name not ip in advert * Less intustive way to identify supernode dns * Add supernode ignore options Change supernode enabled -> enable * Improve DNS updates * Remove tunnels when switching to/from supernode mode * Blackhole any unknown routes on the supernode to avoid recursing packets * Add explicit reverse lookup rule for supernode when available * Just use dnsmasq changes for both forward and reverse names * Improve supernode detection So it doesnt keep writing to flash * Add reverse tunnel ip lookup to supernode * enabled => enable * Supernode tunnels start 172.30 * Remove supernode switch * Simplify supernode check * Fix nav test
This commit is contained in:
parent
272d53bab5
commit
a494a8c374
|
@ -1 +1,2 @@
|
||||||
src-git arednpackages https://github.com/aredn/aredn_packages;develop
|
#src-git arednpackages https://github.com/aredn/aredn_packages;develop
|
||||||
|
src-git arednpackages https://github.com/kn6plv/aredn_packages;olsr-isolate-mode
|
||||||
|
|
|
@ -39,4 +39,4 @@ config Interface
|
||||||
|
|
||||||
config Interface
|
config Interface
|
||||||
list interface 'dtdlink'
|
list interface 'dtdlink'
|
||||||
option Mode 'ether'
|
option Mode '<olsrd_dtd_interface_mode>'
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
#!/usr/bin/lua
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
||||||
|
Copyright (C) 2023 Tim Wilkinson
|
||||||
|
See Contributors file for additional contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation version 3 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Additional Terms:
|
||||||
|
|
||||||
|
Additional use restrictions exist on the AREDN(TM) trademark and logo.
|
||||||
|
See AREDNLicense.txt for more info.
|
||||||
|
|
||||||
|
Attributions to the AREDN Project must be retained in the source code.
|
||||||
|
If importing this code into a new or existing project attribution
|
||||||
|
to the AREDN project must be added to the source code.
|
||||||
|
|
||||||
|
You must not misrepresent the origin of the material contained within.
|
||||||
|
|
||||||
|
Modified versions must be modified to attribute to the original source
|
||||||
|
and be marked in reasonable ways as differentiate it from the original
|
||||||
|
version
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
require("uci")
|
||||||
|
local olsr = require("aredn.olsr")
|
||||||
|
|
||||||
|
local dns_file = "/tmp/dnsmasq.d/supernode.conf"
|
||||||
|
|
||||||
|
local c = uci.cursor()
|
||||||
|
|
||||||
|
-- Supernodes themselves dont need supernode nameservers
|
||||||
|
if c:get("aredn", "@supernode[0]", "enable") == "1" then
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ignore supernodes?
|
||||||
|
if c:get("aredn", "@supernode[0]", "ignore") == "1" then
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Find the first supernode to use as a nameserver
|
||||||
|
local dns = ""
|
||||||
|
for _, hna in ipairs(olsr.getOLSRHNA())
|
||||||
|
do
|
||||||
|
if hna.genmask == 8 and hna.destination == "10.0.0.0" then
|
||||||
|
dns = "#" .. hna.gateway .. "\nserver=/local.mesh/" .. hna.gateway .. "\nrev-server=10.0.0.0/8," .. hna.gateway .. "\nrev-server=172.31.0.0/16," .. hna.gateway .. "\n"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Updae the dns and restart network if necessary
|
||||||
|
local odns = ""
|
||||||
|
local f = io.open(dns_file)
|
||||||
|
if f then
|
||||||
|
odns = f:read("*a")
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
if odns ~= dns then
|
||||||
|
f = io.open(dns_file, "w+")
|
||||||
|
if f then
|
||||||
|
f:write(dns)
|
||||||
|
f:close()
|
||||||
|
os.execute("/etc/init.d/dnsmasq restart")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,41 @@
|
||||||
|
<<'LICENSE'
|
||||||
|
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
||||||
|
Copyright (C) 2023 Tim Wilkinson
|
||||||
|
See Contributors file for additional contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation version 3 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Additional Terms:
|
||||||
|
|
||||||
|
Additional use restrictions exist on the AREDN(TM) trademark and logo.
|
||||||
|
See AREDNLicense.txt for more info.
|
||||||
|
|
||||||
|
Attributions to the AREDN Project must be retained in the source code.
|
||||||
|
If importing this code into a new or existing project attribution
|
||||||
|
to the AREDN project must be added to the source code.
|
||||||
|
|
||||||
|
You must not misrepresent the origin of the material contained within.
|
||||||
|
|
||||||
|
Modified versions must be modified to attribute to the original source
|
||||||
|
and be marked in reasonable ways as differentiate it from the original
|
||||||
|
version.
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
SUPERNODE_ENABLE=$(/sbin/uci -q get aredn.@supernode[0].enable)
|
||||||
|
|
||||||
|
if [ "${SUPERNODE_ENABLE}" = "1" ]; then
|
||||||
|
nft insert rule ip fw4 input_dtdlink udp dport 53 accept comment \"dns access\" 2> /dev/null
|
||||||
|
nft insert rule ip fw4 input_dtdlink tcp dport 53 accept comment \"dns access\" > /dev/null
|
||||||
|
ip route add blackhole 10.0.0.0/8 table 30
|
||||||
|
fi
|
|
@ -0,0 +1,8 @@
|
||||||
|
if nixio.fs.stat("/tmp/dnsmasq.d/supernode.conf") then
|
||||||
|
local ip = read_all("/tmp/dnsmasq.d/supernode.conf"):match("^#(%S+)")
|
||||||
|
if ip then
|
||||||
|
return { href = "http://" .. ip .. "/cgi-bin/mesh", display = "Super Mesh", hint = "See what is on the supernode mesh" }
|
||||||
|
end
|
||||||
|
elseif uci.cursor():get("aredn", "@supernode[0]", "enable") == "1" then
|
||||||
|
return { href = "/cgi-bin/mesh", display = "Super Mesh", hint = "See what is on the supernode mesh" }
|
||||||
|
end
|
|
@ -115,7 +115,8 @@ local cfg = {
|
||||||
lan_network_config = "",
|
lan_network_config = "",
|
||||||
wan_network_config = "",
|
wan_network_config = "",
|
||||||
dtdlink_network_config = "",
|
dtdlink_network_config = "",
|
||||||
wifi_network_config = ""
|
wifi_network_config = "",
|
||||||
|
olsrd_dtd_interface_mode = "ether"
|
||||||
}
|
}
|
||||||
|
|
||||||
function expand_vars(lines)
|
function expand_vars(lines)
|
||||||
|
@ -184,6 +185,13 @@ else
|
||||||
cfg.wifi_intf = "br-nomesh"
|
cfg.wifi_intf = "br-nomesh"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Supernode options
|
||||||
|
|
||||||
|
local is_supernode = (c:get("aredn", "@supernode[0]", "enable") == "1")
|
||||||
|
if is_supernode then
|
||||||
|
cfg.olsrd_dtd_interface_mode = "isolated"
|
||||||
|
end
|
||||||
|
|
||||||
-- delete some config lines if necessary
|
-- delete some config lines if necessary
|
||||||
|
|
||||||
if cfg.wan_proto == "dhcp" then
|
if cfg.wan_proto == "dhcp" then
|
||||||
|
@ -715,6 +723,10 @@ if nixio.fs.access("/etc/config.mesh/olsrd", "r") then
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if is_supernode then
|
||||||
|
of:write("config Hna4\n\toption netaddr 10.0.0.0\n\toption netmask 255.0.0.0\n\n")
|
||||||
|
end
|
||||||
|
|
||||||
if c:get("aredn", "@wan[0]", "olsrd_gw") == "1" then
|
if c:get("aredn", "@wan[0]", "olsrd_gw") == "1" then
|
||||||
of:write("config LoadPlugin\n\toption library 'olsrd_dyn_gw.so.0.5'\n\toption Interval '60'\n\tlist Ping '8.8.8.8'\n\tlist Ping '8.8.4.4'\n\n\n")
|
of:write("config LoadPlugin\n\toption library 'olsrd_dyn_gw.so.0.5'\n\toption Interval '60'\n\tlist Ping '8.8.8.8'\n\tlist Ping '8.8.4.4'\n\n\n")
|
||||||
end
|
end
|
||||||
|
|
|
@ -293,6 +293,13 @@ local settings = {
|
||||||
desc = "<b>Low Memory Max Routes</b> is the maximum number of routes shown on the Mesh Status page when low memory is detected<br><br><small>aredn.@meshstatus[0].lowroutes</small>",
|
desc = "<b>Low Memory Max Routes</b> is the maximum number of routes shown on the Mesh Status page when low memory is detected<br><br><small>aredn.@meshstatus[0].lowroutes</small>",
|
||||||
default = "1000"
|
default = "1000"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
category = "Supernode Settings",
|
||||||
|
key = "aredn.@supernode[0].ignore",
|
||||||
|
type = "boolean",
|
||||||
|
desc = "<b>Ignore any Supernodes</b> found on the mesh <br><br><small>aredn.@supernode[0].ignore</small>",
|
||||||
|
default = "0"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
category = "Network Tools",
|
category = "Network Tools",
|
||||||
key = "aredn.olsr.restart",
|
key = "aredn.olsr.restart",
|
||||||
|
@ -574,6 +581,14 @@ function supportsVLANChange()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function canBeSupernode()
|
||||||
|
local board = aredn.hardware.get_board_type()
|
||||||
|
if board == "mikrotik,hap-ac2" or board == "qemu-standard-pc-i440fx-piix-1996" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
-- callbacks
|
-- callbacks
|
||||||
|
|
||||||
local newval
|
local newval
|
||||||
|
|
|
@ -84,6 +84,11 @@ info['node_details']['firmware_version']=aredn_info.getFirmwareVersion()
|
||||||
-- Mesh Gatway
|
-- Mesh Gatway
|
||||||
info['node_details']['mesh_gateway']=aredn_info.getMeshGatewaySetting()
|
info['node_details']['mesh_gateway']=aredn_info.getMeshGatewaySetting()
|
||||||
|
|
||||||
|
-- Supernode
|
||||||
|
if ctx:get("aredn", "@supernode[0]", "enable") == "1" then
|
||||||
|
info['node_details']['mesh_supernode']=true
|
||||||
|
end
|
||||||
|
|
||||||
-- Mesh RF info
|
-- Mesh RF info
|
||||||
info['meshrf']={}
|
info['meshrf']={}
|
||||||
local radio=aredn_info.getMeshRadioDevice()
|
local radio=aredn_info.getMeshRadioDevice()
|
||||||
|
|
|
@ -117,7 +117,11 @@ function get_server_network_address()
|
||||||
if not server_net then
|
if not server_net then
|
||||||
local mac = aredn.hardware.get_interface_mac("eth0")
|
local mac = aredn.hardware.get_interface_mac("eth0")
|
||||||
local a, b = mac:match("^..:..:..:..:(..):(..)$")
|
local a, b = mac:match("^..:..:..:..:(..):(..)$")
|
||||||
server_net = "172.31." .. tonumber(b, 16) .. "." .. ((tonumber(a, 16) * 4) % 256)
|
local net_base = "172.31."
|
||||||
|
if cursor:get("aredn", "@supernode[0]", "enable") == "1" then
|
||||||
|
net_base = "172.30."
|
||||||
|
end
|
||||||
|
server_net = net_base .. tonumber(b, 16) .. "." .. ((tonumber(a, 16) * 4) % 256)
|
||||||
cursor:set("vtun", "@network[0]", "start", server_net)
|
cursor:set("vtun", "@network[0]", "start", server_net)
|
||||||
cursor:commit("vtun")
|
cursor:commit("vtun")
|
||||||
|
|
||||||
|
@ -182,6 +186,7 @@ end
|
||||||
|
|
||||||
if parms.button_reset then
|
if parms.button_reset then
|
||||||
cursor:revert("vtun")
|
cursor:revert("vtun")
|
||||||
|
cursor:delete("vtun", "@options[0]", "port")
|
||||||
cursor:delete("vtun", "@network[0]", "start")
|
cursor:delete("vtun", "@network[0]", "start")
|
||||||
cursor:delete("vtun", "@network[0]", "dns")
|
cursor:delete("vtun", "@network[0]", "dns")
|
||||||
cursor:commit("vtun")
|
cursor:commit("vtun")
|
||||||
|
@ -299,7 +304,14 @@ if not validate_fqdn(dns) then
|
||||||
err("Not a valid DNS name")
|
err("Not a valid DNS name")
|
||||||
end
|
end
|
||||||
if #cli_err == 0 then
|
if #cli_err == 0 then
|
||||||
local net = "172.31." .. parms.server_net1 .. "." .. parms.server_net2
|
local net_base = "172.31."
|
||||||
|
if cursor:get("aredn", "@supernode[0]", "enable") == "1" then
|
||||||
|
net_base = "172.30."
|
||||||
|
cursor:set("vtun", "@options[0]", "port", "5526")
|
||||||
|
else
|
||||||
|
cursor:delete("vtun", "@options[0]", "port")
|
||||||
|
end
|
||||||
|
local net = net_base .. parms.server_net1 .. "." .. parms.server_net2
|
||||||
cursor:set("vtun", "@network[0]", "start", net)
|
cursor:set("vtun", "@network[0]", "start", net)
|
||||||
cursor:set("vtun", "@network[0]", "dns", dns)
|
cursor:set("vtun", "@network[0]", "dns", dns)
|
||||||
end
|
end
|
||||||
|
|
|
@ -280,6 +280,11 @@ end
|
||||||
parms.conn_num = conn_num
|
parms.conn_num = conn_num
|
||||||
|
|
||||||
-- save the connections
|
-- save the connections
|
||||||
|
if cursor:get("aredn", "@supernode[0]", "enable") == "1" then
|
||||||
|
cursor:set("vtun", "@options[0]", "port", "5526")
|
||||||
|
else
|
||||||
|
cursor:delete("vtun", "@options[0]", "port")
|
||||||
|
end
|
||||||
local enabled_count = 0
|
local enabled_count = 0
|
||||||
for i = 0,parms.conn_num-1
|
for i = 0,parms.conn_num-1
|
||||||
do
|
do
|
||||||
|
|
Loading…
Reference in New Issue