diff --git a/packages/babeld-auto-gw-mode/Makefile b/packages/babeld-auto-gw-mode/Makefile new file mode 100644 index 000000000..7cdacab16 --- /dev/null +++ b/packages/babeld-auto-gw-mode/Makefile @@ -0,0 +1,22 @@ +# Copyright (C) 2021 Santiago Piccinini +# +# This is free software, licensed under the GNU Affero General Public License v3. +# + +include ../../libremesh.mk + +define Package/$(PKG_NAME) + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Babel auto Internet gateway module. + MAINTAINER:=Santiago Piccinini + DEPENDS:=+libubus-lua +watchping +lime-proto-babeld + PKGARCH:=all +endef + + +define Package/$(PKG_NAME)/description + Watchping hooks to set babeld Internet automatic announcements. +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/packages/babeld-auto-gw-mode/Readme.md b/packages/babeld-auto-gw-mode/Readme.md new file mode 100644 index 000000000..35d6eb13c --- /dev/null +++ b/packages/babeld-auto-gw-mode/Readme.md @@ -0,0 +1,16 @@ +# babeld-auto-gw-mode + +By default babeld will redistribute all the routes installed even if they "don't work". For example +when the internet provider use DHCP and the service is not working but interface is up, the route is +installed but not working and babeld will anounce the non working route to the network and also +this route will be used by this node to route the packets so also all its clients won't have internet. + +This package provides a solution using watchping hooks that: +* on wan OK + - adds a route with a special protocol number (7) +* on wan FAIL + - removes the default route with proto 7 + - changes the metric of the default route to 84831. If other nodes are also gateways their babel + redistributable routes will have priority over this route at this node and for that reason the + default gateway won't be the local non working connection. + diff --git a/packages/babeld-auto-gw-mode/files/etc/hotplug.d/lime-config/babeld-auto-gw.lua b/packages/babeld-auto-gw-mode/files/etc/hotplug.d/lime-config/babeld-auto-gw.lua new file mode 100755 index 000000000..2cdcc6bdd --- /dev/null +++ b/packages/babeld-auto-gw-mode/files/etc/hotplug.d/lime-config/babeld-auto-gw.lua @@ -0,0 +1,11 @@ +#!/usr/bin/lua + +local config = require("lime.config") +local uci = config.get_uci_cursor() + +-- Redistribute default routes only if they are of protocol 7. +-- This routes are installed and removed using watchping. + +uci:set("babeld", "default4", "proto", "7") +uci:set("babeld", "default6", "proto", "7") +uci:commit("babeld") diff --git a/packages/babeld-auto-gw-mode/files/etc/watchping/wan-fail.d/babeld-gw b/packages/babeld-auto-gw-mode/files/etc/watchping/wan-fail.d/babeld-gw new file mode 100755 index 000000000..4f8469204 --- /dev/null +++ b/packages/babeld-auto-gw-mode/files/etc/watchping/wan-fail.d/babeld-gw @@ -0,0 +1,30 @@ +#!/usr/bin/lua +--! Copyright (C) 2021 Santiago Piccinini +--! +--! This is free software, licensed under the GNU Affero General Public License v3. + +local ubus = require "ubus" +local utils = require "lime.utils" + +local NONWORKING_ROUTE_METRIC = 84831 + +local conn = ubus.connect() +if not conn then + error("Failed to connect to ubus") +end + +local wan4_status = conn:call("network.interface.wan", "status", {}) +local wan_ifc = wan4_status.device + +--! Do our best to select only the "original" default route installed. Using grep because +--! using the dev argument removes the dev part of the ip route output. +local route = utils.unsafe_shell("ip route show default metric 0 | grep " .. wan_ifc):gsub("\n","") + +--! replace the default route with one that has metric NONWORKING_ROUTE_METRIC +if route ~= '' then + os.execute("ip r add " .. route .. " metric " .. tonumber(NONWORKING_ROUTE_METRIC)) + os.execute("ip r del " .. route) +end + +--! remove the babel redistributable route +os.execute("ip r del default proto 7") diff --git a/packages/babeld-auto-gw-mode/files/etc/watchping/wan-ok.d/babeld-gw b/packages/babeld-auto-gw-mode/files/etc/watchping/wan-ok.d/babeld-gw new file mode 100755 index 000000000..72a5724ba --- /dev/null +++ b/packages/babeld-auto-gw-mode/files/etc/watchping/wan-ok.d/babeld-gw @@ -0,0 +1,30 @@ +#!/usr/bin/lua +--! Copyright (C) 2021 Santiago Piccinini +--! +--! This is free software, licensed under the GNU Affero General Public License v3. + +local ubus = require "ubus" +local utils = require "lime.utils" + +local conn = ubus.connect() +if not conn then + error("Failed to connect to ubus") +end + +local wan4_status = conn:call("network.interface.wan", "status", {}) +local wan_ifc = wan4_status.device + +--! change the default route from the nonworking metric value to the working metric value +local nonworking_route = utils.unsafe_shell("ip route show default metric 84831 | grep " .. wan_ifc):gsub("\n","") +if nonworking_route ~= '' then + os.execute("ip r add " .. nonworking_route .. " metric 0") + os.execute("ip r del " .. nonworking_route .. " metric 84831") +end + +--! install a route with proto value 7 that will be redistributed by babeld +for _, route4 in ipairs(wan4_status.route) do + if route4.target == "0.0.0.0" and route4.mask == 0 then + local r = ("ip r add default via " .. route4.nexthop .. " dev " .. wan4_status.device .. " proto 7 metric 10") + os.execute(r) + end +end