set gateway mode automatically

Added arg and config option to manually set gw_mode.
When gateway_mode is auto, a temporary config will be added, and after a
ten sec delay, naxalnet will check if systemd-networkd shows a
'routable' connection. If the connection is routable, gw_mode will be
set to server; or client otherwise.
This commit is contained in:
Pranav Jerry 2021-09-27 12:43:09 +05:30
parent 8ba8d6af6c
commit d0389e5638
Signed by: pranav
GPG key ID: F1DCDC4FED0A0C5B
7 changed files with 87 additions and 10 deletions

View file

@ -12,9 +12,18 @@ confdir = /usr/share/naxalnet/networkd
runtimedir = /run/systemd/network
[device]
# These are better left this way
# Changing this won't do you any good, unless you have
# other network configs that would mess things up.
batman=bat0
bridge=bridge0
[gateway]
# This helps users choose the best network when multiple machines
# offer an internet connection, or to be more precise, a DHCP server
# Allowed values: auto, server, client or off
mode=auto
[adhoc]
# All your nodes should have the same name
name = NxMesh

View file

@ -35,4 +35,4 @@ See README.md for documentation.
#
# In case you forgot to change the version, skip the number
# and put the next number in the next commit.
__version__ = "0.4.0a5.dev1"
__version__ = "0.4.0a5.dev2"

View file

@ -170,6 +170,12 @@ def parse_args() -> Namespace:
help="name of bridge interface",
)
parser.add_argument(
"--gateway-mode",
default=config["gateway"]["mode"],
help="auto, server, client, or off",
)
parser.add_argument(
"--version",
"-V",

View file

@ -34,6 +34,7 @@ CONFIG = {
"device": {"batman": "bat0", "bridge": "bridge0"},
"adhoc": {"name": "NxMesh"},
"ap": {"ssid": "MeshWiFi", "passwd": "naxalnet256"},
"gateway": {"mode": "auto"},
}
# glob

View file

@ -40,7 +40,10 @@ class NetworkD:
self.variables = {}
print(runtime_dir)
self.runtime_path = Path(runtime_dir)
print(self.runtime_path)
# Create the runtime directory if it doesn't exist
self.runtime_path.mkdir(parents=True, exist_ok=True)
# print(self.runtime_path)
def set_vars(self, **variables):
"""set the variables to replace with str.format"""
@ -65,8 +68,27 @@ class NetworkD:
print(self.runtime_path / name)
destination.write_text(text, encoding="utf-8")
self.reload()
self.files.append(name)
# This allows to delete all configs later
self.files.append(destination.name)
def is_routable(self) -> bool:
"""returns true if any interface is routable"""
return self.proxy.AddressState == "routable"
def remove_config(self, name: str) -> None:
"""
remove the file called 'name' from the runtime dir and reload
"""
path = self.runtime_path / name
path.unlink()
self.reload()
def remove_all_configs(self) -> None:
"""
Remove all configs added by add_config().
The configs will be removed only if they were added in the same
instance of NetworkD, that is, only files in self.files will be
removed.
"""
for i in self.files:
self.remove_config(i)

View file

@ -27,6 +27,7 @@ When run from the commandline, the function main() is called.
"""
import sys
import time
from pathlib import Path
from dasbus.error import DBusError
from systemd.daemon import notify
@ -53,17 +54,39 @@ def get_sorted_glob(directory: str, glob: str):
return sorted_list
def setup_mesh():
"""configure networkd to setup the mesh"""
def any_interface_is_routable():
"""returns true if any of the interfaces is routable"""
networkd = NetworkD(runtime_dir=args.networkd_runtime_dir)
# First, add the temporary configs to networkd.
for i in get_sorted_glob(args.networkd_config_dir, TMP_NET_GLOB):
logger.debug("Adding temporary config %s", i)
networkd.add_config(i)
# Then, wait for some time to setup the network
time.sleep(10)
routable = networkd.is_routable()
networkd.remove_all_configs()
return routable
def setup_mesh(gateway_mode: str = "off"):
"""
configure networkd to setup the mesh
gateway_mode can be client, server, or off
"""
try:
notify("STATUS=Configuring the network...")
logger.info("Copying network config files")
dest = Path(args.networkd_runtime_dir)
# Create the volatile directory if it doesn't exist
dest.mkdir(parents=True, exist_ok=True)
networkd = NetworkD(runtime_dir=args.networkd_runtime_dir)
networkd.set_vars(batdev=args.batman_device, bridgedev=args.bridge_device)
networkd.set_vars(
batdev=args.batman_device,
bridgedev=args.bridge_device,
gateway_mode=gateway_mode,
)
for i in get_sorted_glob(args.networkd_config_dir, MESH_GLOB):
logger.debug("Adding network config %s", i)
networkd.add_config(i)
@ -184,6 +207,22 @@ def main():
# Notify systemd that naxalnet is ready.
# see man:sd_notify(3)
notify("READY=1")
if args.gateway_mode == "auto":
logger.info("Checking for internet connection")
notify("STATUS=Checking for internet")
# If any interface is routable, set gateway mode to server
if any_interface_is_routable():
gateway_mode = "server"
else:
gateway_mode = "client"
logger.info("gateway_mode set to %s", gateway_mode)
elif args.gateway_mode in ["server", "client", "off"]:
gateway_mode = args.gateway_mode
else:
logger.error("gateway-mode has an illegal value")
exit(5)
setup_devices()
setup_mesh()

View file

@ -5,6 +5,6 @@ Name={batdev}
Description=BATMAN interface
Kind=batadv
# Use default settings. Uncomment to change
# see man:systemd.netdev(5) § [BATMANADVANCED] SECTION OPTIONS
#[BatmanAdvanced]
[BatmanAdvanced]
GatewayMode={gateway_mode}