From f9a7d05d5d79eb00a9d9e23a4f73fdc253eab2f0 Mon Sep 17 00:00:00 2001 From: Jason Hawks Date: Wed, 15 Nov 2023 20:19:42 -0500 Subject: [PATCH] Fingers crossed we hit 88mph for some serious shit! --- Makefile | 2 +- luasrc/model/cbi/easymesh.lua | 14 +- root/easymesh/easymesh.sh | 326 +++++++++++++++++++--------------- 3 files changed, 198 insertions(+), 144 deletions(-) diff --git a/Makefile b/Makefile index 434f5f8..542b099 100755 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI Support for easymesh LUCI_DEPENDS:= +kmod-cfg80211 +batctl-default +kmod-batman-adv +dawn +bash -PKG_VERSION:=2.8.7 +PKG_VERSION:=2.8.8 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luasrc/model/cbi/easymesh.lua b/luasrc/model/cbi/easymesh.lua index cf512ce..57a7153 100755 --- a/luasrc/model/cbi/easymesh.lua +++ b/luasrc/model/cbi/easymesh.lua @@ -202,7 +202,7 @@ o.datatype = "ip4addr" o:depends({ipmode="static",role="off"}) -- DNS (Mesh Gateway IP Address) -o = s:taboption("apmode", Value, "gatewayIP", translate("Mesh Gateway IP Address")) +o = s:taboption("apmode", Value, "gateway", translate("Mesh Gateway IP Address")) o.default = "192.168.70.1" o.datatype = "ip4addr" o:depends({ipmode="static",role="off"}) @@ -213,18 +213,24 @@ o.default = "255.255.255.0" o.datatype = "ip4addr" o:depends({ipmode="static",role="off"}) +-- IPv4 netmask +o = s:taboption("apmode", Value, "dns", translate("DNS Server")) +o.default = "192.168.70.1" +o.datatype = "ip4addr" +o:depends({ipmode="static",role="off"}) + btnAPMode = s:taboption("apmode", Button, "_btn_apmode", translate("Enable Dumb AP Mode"), translate("WARNING: THIS WILL CHANGE THIS NODE'S IP ADDRESS, YOU WILL LOOSE ACCESS TO THIS UI")) function btnAPMode.write() - luci.sys.call("/easymesh/easymesh.sh dumbap &") + io.popen("/easymesh/easymesh.sh dumbap &") end btnAPMode:depends("role", "off") m.on_before_apply = function(self) local enabled = m:formvalue("cbid.easymesh.config.enabled") if enabled and enabled == "1" then - luci.sys.call("/easymesh/easymesh.sh enable &") + io.popen("/easymesh/easymesh.sh enable &") else - luci.sys.call("/easymesh/easymesh.sh disable &") + io.popen("/easymesh/easymesh.sh disable &") end end diff --git a/root/easymesh/easymesh.sh b/root/easymesh/easymesh.sh index 3949959..3db535d 100755 --- a/root/easymesh/easymesh.sh +++ b/root/easymesh/easymesh.sh @@ -2,155 +2,192 @@ # Dumb AP Mode Block set_apmode() { - touch /root/.madeap - # AP_MODE=$(uci -q get easymesh.config.ap_mode) - # if [ "$AP_MODE" = 1 ]; then - # Set a flag to indicate that we are in AP mode - # When we go to disable easymesh, we will check this flag and if it was set we restore settings - uci set easymesh.config.ap_mode_enabled=1 - - # Backup our configs - rm /etc/config/*.meshbak - cp /etc/config/wireless /etc/config/wireless.meshbak - cp /etc/config/network /etc/config/network.meshbak - cp /etc/config/dhcp /etc/config/dhcp.meshbak - - # Disabling and stopping services not needed - for service in firewall dnsmasq odhcpd; do - if /etc/init.d/$service enabled; then - echo "Disabling and stopping $service..." - /etc/init.d/$service disable - /etc/init.d/$service stop - else - echo "$service is not enabled, skipping..." - fi - done - - if [ $(uci -q get easymesh.config.ipmode) == "static" ]; then - # Set static IP - uci set network.lan.proto='static' - uci set network.lan.ipaddr=$(uci -q get easymesh.config.ipaddr) - uci set network.lan.netmask=$(uci -q get easymesh.config.netmask) - uci set network.lan.gateway=$(uci -q get easymesh.config.gatewayIP) - uci set network.lan.dns='1.1.1.1' + # Backup our configs + rm /etc/config/*.meshbak + cp /etc/config/wireless /etc/config/wireless.meshbak + cp /etc/config/network /etc/config/network.meshbak + cp /etc/config/dhcp /etc/config/dhcp.meshbak + cp /etc/config/system /etc/config/system.meshbak + cp /etc/config/firewall /etc/config/firewall.meshbak + + uci set easymesh.config.ap_mode_enabled=1 + + # Disabling and stopping services not needed + for service in firewall dnsmasq odhcpd; do + if /etc/init.d/$service enabled; then + echo "Disabling and stopping $service..." + /etc/init.d/$service disable >/dev/null 2>&1 + /etc/init.d/$service stop >/dev/null 2>&1 else - # Set LAN interface to DHCP client - uci del network.lan.ipaddr - uci del network.lan.netmask - uci set network.lan.proto='dhcp' + echo "$service is not enabled, skipping..." fi + done - # Delete wan interfaces - uci del network.wan - uci del network.wan6 + if [ $(uci -q get easymesh.config.ipmode) == "static" ]; then + # Set static IP + uci set network.lan.proto='static' + uci set network.lan.ipaddr=$(uci -q get easymesh.config.ipaddr) + uci set network.lan.netmask=$(uci -q get easymesh.config.netmask) + uci set network.lan.gateway=$(uci -q get easymesh.config.gateway) + uci set network.lan.dns=$(uci -q get easymesh.config.dns) + else + # Set LAN interface to DHCP client + uci del network.lan.ipaddr + uci del network.lan.netmask + uci set network.lan.proto='dhcp' + fi - # Set firewall disabled - uci del firewall.lan.network - uci del firewall.wan.network + # Delete wan interfaces + uci del network.wan + uci del network.wan6 - # Just in case, set lan to be ignored by dhcp - uci set dhcp.lan.ignore='1' - uci del dhcp.wan + # Set firewall disabled + uci del firewall.lan.network + uci del firewall.wan.network - # Fix this for proper variable name - HOSTNAME=$(uci -q get easymesh.config.hostname) - # Set netmask and gateway (assuming $netmask and $dns didn't break more stuff) - uci set system.@system[0].hostname=$HOSTNAME + # Just in case, set lan to be ignored by dhcp + uci set dhcp.lan.ignore='1' + uci del dhcp.wan - # Retrieve the list of ports for network.@device[0] - LAN_PORTS=$(uci get network.@device[0].ports) + # Fix this for proper variable name + HOSTNAME=$(uci -q get easymesh.config.hostname) + # Set netmask and gateway (assuming $netmask and $dns didn't break more stuff) + uci set system.@system[0].hostname=$HOSTNAME - # Check if 'wan' is already in the list of ports - if echo "$LAN_PORTS" | grep -q -w 'wan'; then - echo "'wan' is already in the list of ports for lan." - else - echo "'wan' is not in the list. Adding it to lan ports..." - uci add_list network.@device[0].ports='wan' - fi + # Retrieve the list of ports for network.@device[0] + LAN_PORTS=$(uci get network.@device[0].ports) - # Get the radio to be used for mesh from the config - AP_RADIO=$(uci -q get easymesh.config.apRadio) - - # Our config set mesh_id that we are looking for - MESH_ID=$(uci -q get easymesh.config.mesh_id) - - # Check if MESH_NAME and AP_RADIO are set, if so find set our network - if [ ! -z "$AP_RADIO" ] || [ ! -z "$MESH_ID" ]; then - # Get the output from uci show wireless - uci_output=$(uci show wireless) - - # Find the wireless network with the matching ssid and delete it - ssid=$(echo "$uci_output" | grep -o "wireless\.wifinet[0-9]*\.ssid='$MESH_ID'") - if [ ! -z "$ssid" ]; then - # Loop through radios and delete the wireless networks - for radio in $AP_RADIO; do - # Get the number from the radio name - radio_num="${radio#radio}" - # Delete the network - #uci del wireless.wifinet$radio_num - echo "Found wireless network with ssid '$MESH_NAME' on radio$radio_num" - done - fi - fi + # Check if 'wan' is already in the list of ports + if echo "$LAN_PORTS" | grep -q -w 'wan'; then + echo "'wan' is already in the list of ports for lan." + else + echo "'wan' is not in the list. Adding it to lan ports..." + uci add_list network.@device[0].ports='wan' + fi + # Get the radio to be used for mesh from the config + AP_RADIO=$(uci -q get easymesh.config.apRadio) - + # Our config set mesh_id that we are looking for + MESH_ID=$(uci -q get easymesh.config.mesh_id) - # # Loop through the selected radios - # for CURRENT_RADIO in $AP_RADIO; do - # echo "Multiple Radio Setup, Current Radio: $CURRENT_RADIO" - # # Extact the radio number from the radio name - # wifi_num="${cur_radio#CURRENT_RADIO}" - # uci set wireless.wifinet${wifi_num}.network="lan private_router_batman" - # done + # Check if MESH_NAME and AP_RADIO are set, if so find set our network + if [ ! -z "$AP_RADIO" ] && [ ! -z "$MESH_ID" ]; then + # Loop through the radios and update the network settings + for radio in $AP_RADIO; do + # Get the number from the radio name + radio_num="${radio#radio}" + echo "Checking wireless networks on radio${radio_num} for ssid '$MESH_ID'" + + # Loop through all the wireless interfaces associated with the current radio + uci show wireless | grep "wireless\.wifinet${radio_num}" | grep '\.ssid=' | while read -r ssid_line; do + # Extract the interface identifier + wifinet=$(echo "$ssid_line" | cut -d'.' -f2) + # Extract the ssid value + interface_ssid=$(echo "$ssid_line" | cut -d'=' -f2 | tr -d "'") + + if [ "$interface_ssid" = "$MESH_ID" ]; then + echo "Found target SSID '$MESH_ID' on wireless wifinet ${wifinet} on radio ${radio}" + + # Get the current network setting for this wifinet + current_network=$(uci get "wireless.${wifinet}.network") + echo "Current network setting for ${wifinet}: ${current_network}" + + # Check if 'private_router_batman' is part of the current network setting + if echo "$current_network" | grep -qv 'private_router_batman'; then + # 'private_router_batman' is not in the network setting, so we add it + new_network="${current_network} private_router_batman" + uci set "wireless.${wifinet}.network=${new_network}" + echo "Added 'private_router_batman' to the network setting for ${wifinet}." + uci commit wireless + else + echo "'private_router_batman' is already in the network setting for ${wifinet}." + fi + else + echo "SSID '$interface_ssid' on wireless wifinet ${wifinet} does not match target SSID '$MESH_ID'. Skipping..." + fi + done + done + fi - uci commit - # Tell openwrt to reload the configs + # Commit changes to make sure the wireless configuration is updated + uci commit + + # Restart wireless + wifi reload + + # Tell openwrt to reload the configs + reload_config + /etc/init.d/network reload +} + +disable_apmode() { + # Config Count Must Match 5 + local CONFIG_COUNT=0 + + # Check our configs exist, then restore them + [ -f /etc/config/wireless.meshbak ] && { + CONFIG_COUNT=$((CONFIG_COUNT+1)) + } + [ -f /etc/config/network.meshbak ] && { + CONFIG_COUNT=$((CONFIG_COUNT+1)) + } + [ -f /etc/config/dhcp.meshbak ] && { + CONFIG_COUNT=$((CONFIG_COUNT+1)) + } + [ -f /etc/config/system.meshbak ] && { + CONFIG_COUNT=$((CONFIG_COUNT+1)) + } + [ -f /etc/config/firewall.meshbak ] && { + CONFIG_COUNT=$((CONFIG_COUNT+1)) + } + + # Check if we have 5 configs to restore + if [ $CONFIG_COUNT -eq 5 ]; then + echo "Restoring configs from backup..." + echo "Existing configs will be moved to /etc/config/*.dumbap for reference." + rm /etc/config/*.dumbap + mv /etc/config/dhcp /etc/config/dhcp.dumbap + mv /etc/config/network /etc/config/network.dumbap + mv /etc/config/wireless /etc/config/wireless.dumbap + mv /etc/config/system /etc/config/system.dumbap + mv /etc/config/firewall /etc/config/firewall.dumbap + mv /etc/config/dhcp.meshbak /etc/config/dhcp + mv /etc/config/network.meshbak /etc/config/network + mv /etc/config/wireless.meshbak /etc/config/wireless + mv /etc/config/system.meshbak /etc/config/system + mv /etc/config/firewall.meshbak /etc/config/firewall + + # Enable and start services not needed + for service in firewall dnsmasq odhcpd; do + if /etc/init.d/$service disabled; then + echo "Enabling and starting $service..." + /etc/init.d/$service enable + /etc/init.d/$service start + else + echo "$service is not disabled, skipping..." + fi + done + + # Reload all the system configs reload_config /etc/init.d/network reload - # else - # # Set a flag to indicate that we are in AP mode - # uci set easymesh.config.ap_mode_enabled=0 - - # # Restore our configs - # [ -f /etc/config/wireless.meshbak ] && { - # mv /etc/config/wireless /etc/config/wireless.dumbap - # cp /etc/config/wireless.meshbak /etc/config/wireless - # } - # [ -f /etc/config/network.meshbak ] && { - # mv /etc/config/network /etc/config/network.dumbap - # cp /etc/config/network.meshbak /etc/config/network - # } - # [ -f /etc/config/dhcp.meshbak ] && { - # mv /etc/config/dhcp /etc/config/dhcp.dumbap - # cp /etc/config/dhcp.meshbak /etc/config/dhcp - # } - - # # Enable and start services not needed - # for service in firewall dnsmasq odhcpd; do - # if /etc/init.d/$service disabled; then - # echo "Enabling and starting $service..." - # /etc/init.d/$service enable - # /etc/init.d/$service start - # else - # echo "$service is not disabled, skipping..." - # fi - # done - - # reload_config - # /etc/init.d/network reload - # fi + wifi reload + else + echo "Unable to restore configs as none were found." + fi } -clear_mesh_radio() { +clear_by_mesh_id() { + # Passed mesh_id to clear, allows us to multipurpose this function + MESH_ID_TO_CLEAR=$1 + # Get the radio to be used for mesh from the config AP_RADIO=$(uci -q get easymesh.config.apRadio) - # Get the mesh name from the UCI configuration - OLD_MESH_NAME=$(uci -q get easymesh.config.old_mesh_id) # Check if MESH_NAME is not empty - if [ -z "$OLD_MESH_NAME" ]; then - echo "Old mesh name is not set. None to clear." + if [ -z "$MESH_ID_TO_CLEAR" ]; then + echo "No mesh_id passed to remove from wireless." return; fi @@ -158,7 +195,7 @@ clear_mesh_radio() { uci_output=$(uci show wireless) # Find the mesh network with the matching mesh_id and delete it - mesh_id=$(echo "$uci_output" | grep -o "wireless\.mesh_radio[0-9]*\.mesh_id='$OLD_MESH_NAME'") + mesh_id=$(echo "$uci_output" | grep -o "wireless\.mesh_radio[0-9]*\.mesh_id='$MESH_ID_TO_CLEAR'") if [ ! -z "$mesh_id" ]; then # Extract the number from the interface name mesh_radio=$(echo "$mesh_id" | grep -o "radio[0-9]*") @@ -166,12 +203,12 @@ clear_mesh_radio() { for radio in $AP_RADIO; do # Delete the network uci del wireless.mesh_$radio - echo "Deleted mesh network with mesh_id '$OLD_MESH_NAME' on $radio" + echo "Deleted mesh network with mesh_id '$MESH_ID_TO_CLEAR' on $radio" done fi # Find the wireless network with the matching ssid and delete it - ssid=$(echo "$uci_output" | grep -o "wireless\.wifinet[0-9]*\.ssid='$OLD_MESH_NAME'") + ssid=$(echo "$uci_output" | grep -o "wireless\.wifinet[0-9]*\.ssid='$MESH_ID_TO_CLEAR'") if [ ! -z "$ssid" ]; then # Loop through radios and delete the wireless networks for radio in $AP_RADIO; do @@ -179,14 +216,15 @@ clear_mesh_radio() { radio_num="${radio#radio}" # Delete the network uci del wireless.wifinet$radio_num - echo "Deleted wireless network with ssid '$OLD_MESH_NAME' on radio$radio_num" + echo "Deleted wireless network with ssid '$MESH_ID_TO_CLEAR' on radio$radio_num" done fi # Commit changes to make sure the wireless configuration is updated uci commit wireless + # Restart wireless to apply changes - wifi up + wifi reload echo "Wireless interfaces reloaded." } @@ -311,7 +349,6 @@ setup_mesh_radio() { ENCRYPTION_ENABLED=$(uci -q get easymesh.config.encryption) # Setup the interface for the mesh network - uci set wireless.mesh_$CURRENT_RADIO.disabled='0' uci set wireless.wifinet$RADIO_NUM=wifi-iface uci set wireless.wifinet$RADIO_NUM.device=$CURRENT_RADIO uci set wireless.wifinet$RADIO_NUM.mode='ap' @@ -320,9 +357,16 @@ setup_mesh_radio() { uci set wireless.wifinet$RADIO_NUM.mobility_domain=$MOBILITY_DOMAIN uci set wireless.wifinet$RADIO_NUM.ft_over_ds='0' uci set wireless.wifinet$RADIO_NUM.ft_psk_generate_local='0' - uci set wireless.wifinet$RADIO_NUM.network='lan' uci set wireless.wifinet$RADIO_NUM.disabled=0 + # Check if ap_mode_enabled is enabled, if so add private_router_batman to the network + # otherwise just add lan + if [ "$(uci -q get easymesh.config.ap_mode_enabled)" = 1 ]; then + uci set wireless.wifinet$RADIO_NUM.network='lan' + else + uci set wireless.wifinet$RADIO_NUM.network='lan private_router_batman' + fi + # Get the encryption key from the config NETWORK_KEY=$(uci -q get easymesh.config.key) @@ -427,7 +471,8 @@ disable_batman_interfaces() { # Enable easymesh enable_easymesh() { # Clear old radios then set "old values" - clear_mesh_radio + clear_by_mesh_id "$(uci -q get easymesh.config.mesh_id)" + clear_by_mesh_id "$(uci -q get easymesh.config.old_mesh_id)" uci set easymesh.config.old_mesh_id="$(uci -q get easymesh.config.mesh_id)" create_batman_network process_radios @@ -438,15 +483,15 @@ enable_easymesh() { # Disable easymesh disable_easymesh() { - # Clear old radios then clear "old values" - clear_mesh_radio + # Clear old radios then set "old values" + clear_by_mesh_id "$(uci -q get easymesh.config.mesh_id)" + clear_by_mesh_id "$(uci -q get easymesh.config.old_mesh_id)" uci del easymesh.config.old_mesh_id disable_batman_interfaces # Set at end to be sure it worked uci del easymesh.config.running } -sleep 5 if [ "$1" = "enable" ]; then enable_easymesh exit 0 @@ -456,6 +501,9 @@ elif [ "$1" = "disable" ]; then elif [ "$1" = "dumbap" ]; then set_apmode exit 0 +elif [ "$1" = "undumb" ]; then + disable_apmode + exit 0 else echo "Invalid argument. Please use 'start', 'stop' or 'dumbap'" exit 1