Add bird2 as an alternative babel implementation #121

Closed
fbl wants to merge 5 commits from fbl:bird2 into master
21 changed files with 488 additions and 84 deletions

View File

@ -15,7 +15,7 @@ ROUTINGREV="10d3ffd8b30186b49538167bac1fa1bf9c88f860"
GLUONREV="12e41d0ff07ec54bbd67a31ab50d12ca04f2238c"
OPENWRT_PKGS="gpioctl-sysfs libugpio fastd haserl micrond mtr bmon"
ROUTING_PKGS="kmod-batman-adv batctl alfred babeld"
ROUTING_PKGS="kmod-batman-adv batctl alfred babeld bird2"
GLUON_PKGS="simple-tc uradvd"
FFF_VARIANTS="node layer3"

View File

@ -0,0 +1,29 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-babel-bird2
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/fff-babel-bird2
SECTION:=base
CATEGORY:=Freifunk
TITLE:=Freifunk-Franken babel-bird2
URL:=https://www.freifunk-franken.de
DEPENDS:=+bird2 +bird2c +owipcalc
PROVIDES:=fff-babel-implementation
endef
define Package/fff-babel-bird2/description
This is the Freifunk Franken Firmware babel-bird2 package.
endef
define Build/Compile
# nothing
endef
define Package/fff-babel-bird2/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,fff-babel-bird2))

View File

@ -0,0 +1,123 @@
# router id is not required for babeld, but necessary for bird startup
router id 192.0.2.0;
ipv4 table fff4;
ipv6 sadr table fff6;
protocol device {
scan time 15;
fbl marked this conversation as resolved Outdated

Die beiden tables local4 und local6 werden hier zwar deklariert, aber sonst nirgendwo in der Konfiguration verwendet. Man könnte sie daher auch weglassen.

Die beiden tables `local4` und `local6` werden hier zwar deklariert, aber sonst nirgendwo in der Konfiguration verwendet. Man könnte sie daher auch weglassen.
}
# device routes for ipv4 peering address
protocol direct {
ipv4 {
table fff4;
import filter {
include "/tmp/bird/include/nat-filter.conf";
if (net ~ 10.50.0.0/16 || net ~ 10.83.0.0/16) && net.len = 32 then {
accept;
}
reject;
};
};
}
# device routes on loopback interface
protocol direct {
ipv4 {
table fff4;
import filter {
include "/tmp/bird/include/nat-filter.conf";
if net ~ 10.50.0.0/16 || net ~ 10.83.0.0/16 then {
accept;
}
reject;
};
};
ipv6 sadr {
table fff6;
import filter {
if net ~ fdff::/64 from ::/0 then {
reject;
}
# only import GUA + ULA addresses
if net !~ 2000::/3 from ::/0 || net !~ fc00::/7 from ::/0 then {
reject;
}
accept;
};
import keep filtered;
};
interface "lo";
}
# ipv6 kernel route interface
protocol kernel {
ipv6 sadr {
table fff6;
import filter {
# only import routes from kernel with proto static
if krt_source != 4 then {
reject;
}
if net ~ fdff::/64 from ::/0 then {
reject;
fbl marked this conversation as resolved Outdated

Dieser Block importiert alle proto static Routen aus der fff-table in die bird-internen Tabellen. Im Unterschied dazu gibt es bei der babeld-Variante aber noch redistribute-Filter, welche Einschränkungen in der Routenauswahl treffen. Es gibt aktuell in der Firmware z.B. eine Route fdff::/64 dev br-client proto static metric 1024 pref medium in der fff-table, welche dadurch in der bird2-Variante mit importiert und an andere babel-Nachbarn weitergegeben wird. Das ist vllt. nicht unbedingt gewollt und notwendig.

Dieser Block importiert *alle* `proto static` Routen aus der fff-table in die bird-internen Tabellen. Im Unterschied dazu gibt es bei der babeld-Variante aber noch redistribute-Filter, welche Einschränkungen in der Routenauswahl treffen. Es gibt aktuell in der Firmware z.B. eine Route `fdff::/64 dev br-client proto static metric 1024 pref medium` in der fff-table, welche dadurch in der bird2-Variante mit importiert und an andere babel-Nachbarn weitergegeben wird. Das ist vllt. nicht unbedingt gewollt und notwendig.
Outdated
Review

Dazu hatte ich mich entschieden, weil das nachrüsten von passenden Regeln (nötig für eigene IPv6 Präfixe) mit bird etwas fummeliger wäre. An fdff:: hatte ich nicht gedacht, guter Fund!

Für den Moment würde ich fdff::/64 daher explizit ausschließen.
In Zukunft sollte man aber auf jeden Fall beide Implementierungen in dieser Hinsicht aneinander angleichen.

Dazu hatte ich mich entschieden, weil das nachrüsten von passenden Regeln (nötig für eigene IPv6 Präfixe) mit bird etwas fummeliger wäre. An fdff:: hatte ich nicht gedacht, guter Fund! Für den Moment würde ich fdff::/64 daher explizit ausschließen. In Zukunft sollte man aber auf jeden Fall beide Implementierungen in dieser Hinsicht aneinander angleichen.
}
accept;
};
export all;
preference 200;
};
kernel table 10;
scan time 15;
learn yes;
}
# ipv4 kernel route interface
protocol kernel {
ipv4 {
table fff4;
import filter {
include "/tmp/bird/include/nat-filter.conf";
# only import routes from kernel with proto static
if krt_source = 4 then {
accept;
}
reject;
};
export all;
preference 200;
};
kernel table 10;
scan time 15;
learn yes;
}
protocol babel {
# required due to static configuration of global router id.
# also improves reconnect speed after restart.
randomize router id yes;
ipv4 {
table fff4;
fbl marked this conversation as resolved Outdated

Die hier angegebenen Filter bestehen nur aus einem accept; Statement und keiner weiteren Funktionalität, man könnte sie daher auch überall durch import all; bzw. export all; ersetzen.

Die hier angegebenen Filter bestehen nur aus einem `accept;` Statement und keiner weiteren Funktionalität, man könnte sie daher auch überall durch `import all;` bzw. `export all;` ersetzen.
import all;
export all;
};
ipv6 sadr {
table fff6;
import all;
export all;
};
include "/tmp/bird/include/babelpeers.conf";
};

View File

@ -0,0 +1,45 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2010-2017 OpenWrt.org
USE_PROCD=1
START=70
BIRD_BIN="/usr/sbin/bird"
BIRD_CONF="/etc/bird.conf"
BIRD_PID_FILE="/var/run/bird.pid"
start_service() {
mkdir -p /var/run
set_include_path
procd_open_instance
procd_set_param command $BIRD_BIN -f -c $BIRD_CONF -P $BIRD_PID_FILE
procd_set_param file "$BIRD_CONF"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn
procd_close_instance
}
reload_service() {
set_include_path
procd_send_signal fff-bird
}
set_include_path() {
# Change include file path, so bird uses the correct configuration, depending on the configuration state:
# - If test mode is active (and /tmp/bird/fff exists), switch to the temporary configuration to be tested.
# - If new settings are applied or the old settings are restored after an unsuccessful test (and /tmp/bird/fff does not exist),
# switch back to the permanent configuration (/etc/bird/fff).
mkdir -p /tmp/bird/include
if [ -d /tmp/bird/fff ]; then
echo 'include "/tmp/bird/fff/babelpeers/*.conf";' > /tmp/bird/include/babelpeers.conf
echo 'include "/tmp/bird/fff/nat-filter.conf";' > /tmp/bird/include/nat-filter.conf
else
echo 'include "/etc/bird/fff/babelpeers/*.conf";' > /tmp/bird/include/babelpeers.conf
echo 'include "/etc/bird/fff/nat-filter.conf";' > /tmp/bird/include/nat-filter.conf
fi
}

View File

@ -0,0 +1,4 @@
/etc/init.d/bird disable
rm -f /etc/init.d/bird
exit 0

View File

@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-3.0-only
mv /etc/bird-fff.conf /etc/bird.conf
exit 0

View File

@ -0,0 +1,72 @@
# SPDX-License-Identifier: GPL-3.0-only
babel_get_version() {
/usr/sbin/bird --version 2>&1 | sed "s/BIRD version /bird-/"
}
babel_add_interface() {
[ "$#" -ne "4" ] && return 1
local name="$1"
local interface="$2"
local type="$3"
local rxcost="$4"
mkdir -p /tmp/bird/fff/babelpeers
echo "interface \"$interface\" { type $type; rxcost $rxcost; };" > /tmp/bird/fff/babelpeers/$name.conf
return 0
}
babel_delete_interface() {
[ "$#" -ne "1" ] && return 1
local name="$1"
# Removing peers from /etc is not necessary, as all peers are generated into /tmp on every configuration run,
# which completely overwrites existing peers in /etc in the apply step.
rm -f /tmp/bird/fff/babelpeers/$name.conf
return 0
}
babel_add_redistribute_filter() {
return 0
}
babel_add_private_prefix_filter() {
[ "$#" -ne "1" ] && return 1
local prefix="$1"
prefix=$(owipcalc "$prefix" network prefix "$prefix")
mkdir -p /tmp/bird/fff
echo "if net ~ $prefix then reject;" > /tmp/bird/fff/nat-filter.conf
return 0
}
babel_remove_custom_redistribute_filters() {
mkdir -p /tmp/bird/fff
> /tmp/bird/fff/nat-filter.conf
return 0
}
babel_apply_implementation() {
# error output hidden because apply might be executed without a preceding configure step.
if [ -d /tmp/bird/fff ]; then
rm -rf /etc/bird/fff
mv /tmp/bird/fff /etc/bird/fff
fi
return 0
}
babel_reload_implementation() {
/etc/init.d/fff-bird reload
}
babel_revert() {
rm -r /tmp/bird/fff
}

View File

@ -0,0 +1,20 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
set -e
set -o pipefail
if ! birdc show status >/dev/null 2>&1; then
# bird daemon not running or unavailable. exit.
exit 0
fi
neighbours="$(birdc -r show babel neighbors |
tail -n +5 |
awk '{ printf "<neighbour><ip>%s</ip><outgoing_interface>%s</outgoing_interface><link_cost>%s</link_cost></neighbour>", $1, $2, $3 }'
)"
echo -n "<babel_neighbours>$neighbours</babel_neighbours>"
exit 0

View File

@ -0,0 +1,28 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fff-babel
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/fff-babel
SECTION:=base
CATEGORY:=Freifunk
TITLE:=Freifunk-Franken babel
URL:=https://www.freifunk-franken.de
DEPENDS:=+fff-babel-implementation
fbl marked this conversation as resolved Outdated

Im Makefile von fff-babel-bird2 gibt es an dieser Stelle noch ein CONFLICTS:=, welches das fff-babeld package ausschließen soll, das Gleiche in umgekehrt könnte man hier auch noch hinzufügen.

Im Makefile von fff-babel-bird2 gibt es an dieser Stelle noch ein `CONFLICTS:=`, welches das fff-babeld package ausschließen soll, das Gleiche in umgekehrt könnte man hier auch noch hinzufügen.
Outdated
Review

Das stimmt. Funktioniert so auch, weil dennoch nie beide gleichzeitig da sein können. Ich habs jetzt so gelassen, da das voraussichtlich sowieso bald wieder weg fliegt, siehe #201

Das stimmt. Funktioniert so auch, weil dennoch nie beide gleichzeitig da sein können. Ich habs jetzt so gelassen, da das voraussichtlich sowieso bald wieder weg fliegt, siehe #201
endef
define Package/fff-babel/description
This is the Freifunk Franken Firmware babel package.
endef
define Build/Compile
# nothing
endef
define Package/fff-babel/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,fff-babel))

View File

@ -26,7 +26,7 @@ configure() {
fi
}
config_load babeld
config_load network
config_foreach remove_babelpeer interface
#add new peers
@ -75,14 +75,14 @@ configure() {
babel_add_peer6addr "network.$prefixname.ip6addr"
# add babel interface
babel_add_interface "$prefixname" "$iface" "$type" "$rxcost" || { echo "Could not add babeld interface for babelpeer $name"; exit 1; }
babel_add_interface "$prefixname" "$iface" "$type" "$rxcost" || { echo "Could not add babel interface for babelpeer $name"; exit 1; }
}
config_load gateway
config_foreach add_babelpeer babelpeer
# configure babeld filters for custom ipv6 addresses
# configure babel filters for custom ipv6 addresses
## remove old filters
babel_remove_custom_redistribute_filters
@ -101,10 +101,14 @@ configure() {
apply() {
uci commit network
uci commit babeld
babel_apply
}
reload() {
babel_reload
}
revert() {
uci revert network
uci revert babeld
babel_revert
}

View File

@ -0,0 +1,116 @@
implementation=$(uci -q get babelimpl.impl.impl)
fbl marked this conversation as resolved Outdated

Da verweise ich mal wieder auf

#118 (comment)

ich wäre weiterhin dafür, alles Usereinstellbare nach /etc/config/fff zu legen. Das ist immerhin dann auch gleich Updatefest

Da verweise ich mal wieder auf https://git.freifunk-franken.de/freifunk-franken/firmware/issues/118#issuecomment-2558 ich wäre weiterhin dafür, alles Usereinstellbare nach /etc/config/fff zu legen. Das ist immerhin dann auch gleich Updatefest
Outdated
Review

Das ist immerhin dann auch gleich Updatefest

Ist es aktuell by-design nicht.

> Das ist immerhin dann auch gleich Updatefest Ist es aktuell by-design nicht.

ich hab keinen Grund gefunden was dagegen sprechen würde? So wie ich das verstehe, wir die Implementation über config-layer3 ausgewählt. Da darf das doch gerne Updatefest sein.
Gibts einen Grund warum das Design so gewählt ist?

ich hab keinen Grund gefunden was dagegen sprechen würde? So wie ich das verstehe, wir die Implementation über config-layer3 ausgewählt. Da darf das doch gerne Updatefest sein. Gibts einen Grund warum das Design so gewählt ist?
Outdated
Review

Aktuell ist das mehr so ein Test-Feature. Ich weiß noch überhaupt nicht, ob ich die Laufzeit-Auswahl langfristig unterstützen möchte, und ob dauerhaft zwei Daemons in der Firmware enthalten sein werden (eher nicht..). Die gibt es jetzt eigentlich mehr deshalb, damit man beide Implementierungen möglichst zügig testen kann.

Zudem ist die Auswahl des Daemons auch eine Entscheidung, die den Nutzer der Firmware erst mal überhaupt nicht interessieren soll. Langfristig möchte ich bird zum default machen.

Wenn das jetzt alles mit diesem Release gut funktioniert, kann man noch einmal evaluieren, ob man die Laufzeit-Auswahl des Daemons dauerhaft anbieten möchte.

Aktuell ist das mehr so ein Test-Feature. Ich weiß noch überhaupt nicht, ob ich die Laufzeit-Auswahl langfristig unterstützen möchte, und ob dauerhaft zwei Daemons in der Firmware enthalten sein werden (eher nicht..). Die gibt es jetzt eigentlich mehr deshalb, damit man beide Implementierungen möglichst zügig testen kann. Zudem ist die Auswahl des Daemons auch eine Entscheidung, die den Nutzer der Firmware erst mal überhaupt nicht interessieren soll. Langfristig möchte ich bird zum default machen. Wenn das jetzt alles mit diesem Release gut funktioniert, kann man noch einmal evaluieren, ob man die Laufzeit-Auswahl des Daemons dauerhaft anbieten möchte.

ok mit dieser Argumentation kann ich dann erstmal so mit leben wie es ist.

ok mit dieser Argumentation kann ich dann erstmal so mit leben wie es ist.
[ -z "$implementation" ] && implementation=babeld
. /lib/functions/fff/babeldaemon/$implementation
babel_add_iifrules() {
[ "$#" -ne "1" ] && return 1
local name="$1"
local table='10'
local prio='31'
uci set network.${name}_rule=rule
uci set network.${name}_rule.in="$name"
uci set network.${name}_rule.lookup="$table"
uci set network.${name}_rule.priority="$prio"
uci set network.${name}_rule6=rule6
uci set network.${name}_rule6.in="$name"
uci set network.${name}_rule6.lookup="$table"
uci set network.${name}_rule6.priority="$prio"
return 0
}
babel_delete_iifrules() {
[ "$#" -ne "1" ] && return 1
local name="$1"
uci -q del network.${name}_rule
uci -q del network.${name}_rule6
return 0
}
babel_add_peeraddr() {
[ "$#" -ne "1" ] && return 1
local option="$1"
if peer_ip=$(uci -q get gateway.@gateway[0].peer_ip); then
uci add_list "$option"="$peer_ip"
elif router_ip=$(uci -q get gateway.meta.router_ip); then
# use router_ip if no peer_ip is set
ip=$router_ip
# use only first ip
ip=${ip%% *}
# remove CIDR mask
ip=${ip%%/*}
uci add_list "$option"="$ip"
elif ipaddr=$(uci -q get gateway.@client[0].ipaddr); then
# use client interface address (without subnet) if no router_ip is set
uci add_list "$option"=${ipaddr%%/*}
else
echo "WARNING: No peer_ip, router_ip or client interface ipaddr set! IPv4 routing is not possible."
return 1
fi
return 0
}
babel_add_peer6addr() {
[ "$#" -ne "1" ] && return 1
local option="$1"
if peer_ip6=$(uci -q get gateway.@gateway[0].peer_ip6); then
uci add_list "$option"="$peer_ip6"
else
return 1
fi
return 0
}
babel_reload() {
# switch implementation temporarily
case $implementation in
bird2)
/etc/init.d/babeld stop 2>/dev/null
/etc/init.d/fff-bird start
;;
babeld)
/etc/init.d/fff-bird stop 2>/dev/null
/etc/init.d/babeld start
;;
esac
# call implementation-specific reload commands
babel_reload_implementation
return 0
}
babel_apply() {
# switch implementation persistently
case $implementation in
bird2)
/etc/init.d/babeld disable
/etc/init.d/fff-bird enable
;;
babeld)
/etc/init.d/fff-bird disable
/etc/init.d/babeld enable
;;
esac
babel_apply_implementation
return 0
}

View File

@ -11,6 +11,7 @@ define Package/fff-babeld
TITLE:=Freifunk-Franken babeld configuration example
URL:=https://www.freifunk-franken.de
DEPENDS:=+babeld
PROVIDES:=fff-babel-implementation
endef
define Package/fff-babeld/description

View File

@ -0,0 +1,3 @@
/etc/init.d/babeld disable
exit 0

View File

@ -1,75 +1,7 @@
babel_add_iifrules() {
[ "$#" -ne "1" ] && return 1
# SPDX-License-Identifier: GPL-3.0-only
local name="$1"
local table='10'
local prio='31'
uci set network.${name}_rule=rule
uci set network.${name}_rule.in="$name"
uci set network.${name}_rule.lookup="$table"
uci set network.${name}_rule.priority="$prio"
uci set network.${name}_rule6=rule6
uci set network.${name}_rule6.in="$name"
uci set network.${name}_rule6.lookup="$table"
uci set network.${name}_rule6.priority="$prio"
return 0
}
babel_delete_iifrules() {
[ "$#" -ne "1" ] && return 1
local name="$1"
uci -q del network.${name}_rule
uci -q del network.${name}_rule6
return 0
}
babel_add_peeraddr() {
[ "$#" -ne "1" ] && return 1
local option="$1"
if peer_ip=$(uci -q get gateway.@gateway[0].peer_ip); then
uci add_list "$option"="$peer_ip"
elif router_ip=$(uci -q get gateway.meta.router_ip); then
# use router_ip if no peer_ip is set
ip=$router_ip
# use only first ip
ip=${ip%% *}
# remove CIDR mask
ip=${ip%%/*}
uci add_list "$option"="$ip"
elif ipaddr=$(uci -q get gateway.@client[0].ipaddr); then
# use client interface address (without subnet) if no router_ip is set
uci add_list "$option"=${ipaddr%%/*}
else
echo "WARNING: No peer_ip, router_ip or client interface ipaddr set! IPv4 routing is not possible."
return 1
fi
return 0
}
babel_add_peer6addr() {
[ "$#" -ne "1" ] && return 1
local option="$1"
if peer_ip6=$(uci -q get gateway.@gateway[0].peer_ip6); then
uci add_list "$option"="$peer_ip6"
else
return 1
fi
return 0
babel_get_version() {
/usr/sbin/babeld -V 2>&1
}
babel_add_interface() {
@ -157,3 +89,15 @@ babel_remove_custom_redistribute_filters() {
return 0
}
babel_apply_implementation() {
uci commit babeld
}
babel_reload_implementation() {
return 0
}
babel_revert() {
uci revert babeld
}

View File

@ -11,7 +11,9 @@ define Package/fff-layer3
TITLE:=Freifunk-Franken gateway configuration
URL:=https://www.freifunk-franken.de
DEPENDS:=+fff-alfred-monitoring-proxy \
+fff-babel \
+fff-babeld \
+fff-babel-bird2 \
+fff-boardname \
+fff-dhcp \
+fff-layer3-config \

View File

@ -74,8 +74,12 @@ if [ -x /usr/bin/fastd ]; then
SYSTEM_DATA="$SYSTEM_DATA<fastd_version>$(/usr/bin/fastd -v | awk '{ print $2 }')</fastd_version>"
fi
if [ -x /usr/sbin/babeld ]; then
SYSTEM_DATA="$SYSTEM_DATA<babel_version>$(/usr/sbin/babeld -V 2>&1)</babel_version>"
if [ -e /lib/functions/fff/babel ]; then
. /lib/functions/fff/babel
babel_version=$(babel_get_version)
if [ $? -eq 0 ]; then
fbl marked this conversation as resolved Outdated

Wenn ich das richtig verstehe, sind im fertigen Build beide Implementationen vorhanden oder? D.h. hier würden beide Versionen geschickt werden?

Wenn ich das richtig verstehe, sind im fertigen Build beide Implementationen vorhanden oder? D.h. hier würden beide Versionen geschickt werden?
Outdated
Review

Zweiteres ist ein "elif", daher wird nur eins von beiden geschickt. Man müsste das eigentlich noch vom aktuellen config-Zustand abhängig machen. Ich würde das dann stattdessen vom babelimpl.impl.impl UCI-setting abhängig machen.

Zweiteres ist ein "elif", daher wird nur eins von beiden geschickt. Man müsste das eigentlich noch vom aktuellen config-Zustand abhängig machen. Ich würde das dann stattdessen vom babelimpl.impl.impl UCI-setting abhängig machen.

klingt sinnvoll es von babelimpl.impl.impl UCI-setting zu machen, ja

klingt sinnvoll es von babelimpl.impl.impl UCI-setting zu machen, ja
Outdated
Review

erledigt. Ganz sauber ist das eigentlich nicht, da das bereits wechselt bevor configure-layer3 ausgeführt wurde. Aber da es nur Statusdaten sind, ist es mir die aufwändigere Unterscheidung nicht Wert.

erledigt. Ganz sauber ist das eigentlich nicht, da das bereits wechselt bevor configure-layer3 ausgeführt wurde. Aber da es nur Statusdaten sind, ist es mir die aufwändigere Unterscheidung nicht Wert.
SYSTEM_DATA="$SYSTEM_DATA<babel_version>$babel_version</babel_version>"
fi
fi
# example for /etc/openwrt_release:

View File

@ -14,7 +14,7 @@ define Package/fff-wireguard
+kmod-wireguard \
+owipcalc \
+wireguard-tools \
+fff-babeld \
+fff-babel \
+fff-network
endef

View File

@ -31,7 +31,7 @@ configure() {
fi
}
config_load babeld
config_load network
config_foreach remove_wgpeer interface
@ -128,7 +128,7 @@ configure() {
babel_add_iifrules "$prefixname" || { echo "ERROR: Could not add iif-rules for wgpeer $name"; exit 1; }
# add babel interface
babel_add_interface "$prefixname" "$prefixname" 'wired' "$rxcost" || { echo "ERROR: Could not add babeld interface for wgpeer $name"; exit 1; }
babel_add_interface "$prefixname" "$prefixname" 'wired' "$rxcost" || { echo "ERROR: Could not add babel interface for wgpeer $name"; exit 1; }
}
config_load gateway
@ -137,12 +137,16 @@ configure() {
apply() {
uci commit network
uci commit babeld
uci commit gateway
babel_apply
}
reload() {
babel_reload
}
revert() {
uci revert network
uci revert babeld
uci revert gateway
babel_revert
}