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 runtimedir = /run/systemd/network
[device] [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 batman=bat0
bridge=bridge0 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] [adhoc]
# All your nodes should have the same name # All your nodes should have the same name
name = NxMesh name = NxMesh

View File

@ -35,4 +35,4 @@ See README.md for documentation.
# #
# In case you forgot to change the version, skip the number # In case you forgot to change the version, skip the number
# and put the next number in the next commit. # 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", help="name of bridge interface",
) )
parser.add_argument(
"--gateway-mode",
default=config["gateway"]["mode"],
help="auto, server, client, or off",
)
parser.add_argument( parser.add_argument(
"--version", "--version",
"-V", "-V",

View File

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

View File

@ -40,7 +40,10 @@ class NetworkD:
self.variables = {} self.variables = {}
print(runtime_dir) print(runtime_dir)
self.runtime_path = Path(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): def set_vars(self, **variables):
"""set the variables to replace with str.format""" """set the variables to replace with str.format"""
@ -65,8 +68,27 @@ class NetworkD:
print(self.runtime_path / name) print(self.runtime_path / name)
destination.write_text(text, encoding="utf-8") destination.write_text(text, encoding="utf-8")
self.reload() self.reload()
self.files.append(name) # This allows to delete all configs later
self.files.append(destination.name)
def is_routable(self) -> bool: def is_routable(self) -> bool:
"""returns true if any interface is routable""" """returns true if any interface is routable"""
return self.proxy.AddressState == "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 sys
import time
from pathlib import Path from pathlib import Path
from dasbus.error import DBusError from dasbus.error import DBusError
from systemd.daemon import notify from systemd.daemon import notify
@ -53,17 +54,39 @@ def get_sorted_glob(directory: str, glob: str):
return sorted_list return sorted_list
def setup_mesh(): def any_interface_is_routable():
"""configure networkd to setup the mesh""" """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: try:
notify("STATUS=Configuring the network...") notify("STATUS=Configuring the network...")
logger.info("Copying network config files") logger.info("Copying network config files")
dest = Path(args.networkd_runtime_dir) 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 = 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): for i in get_sorted_glob(args.networkd_config_dir, MESH_GLOB):
logger.debug("Adding network config %s", i) logger.debug("Adding network config %s", i)
networkd.add_config(i) networkd.add_config(i)
@ -184,6 +207,22 @@ def main():
# Notify systemd that naxalnet is ready. # Notify systemd that naxalnet is ready.
# see man:sd_notify(3) # see man:sd_notify(3)
notify("READY=1") 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_devices()
setup_mesh() setup_mesh()

View File

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