diff --git a/buildscript b/buildscript index bd496baa..6ad4b112 100755 --- a/buildscript +++ b/buildscript @@ -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" diff --git a/src/packages/fff/fff-babel-bird2/Makefile b/src/packages/fff/fff-babel-bird2/Makefile new file mode 100644 index 00000000..b0591ccc --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/Makefile @@ -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)) diff --git a/src/packages/fff/fff-babel-bird2/files/etc/bird-fff.conf b/src/packages/fff/fff-babel-bird2/files/etc/bird-fff.conf new file mode 100644 index 00000000..271dc3b2 --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/files/etc/bird-fff.conf @@ -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; +} + +# 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; + } + + 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; + import all; + export all; + }; + + ipv6 sadr { + table fff6; + import all; + export all; + }; + + include "/tmp/bird/include/babelpeers.conf"; +}; diff --git a/src/packages/fff/fff-babel-bird2/files/etc/bird/fff/nat-filter.conf b/src/packages/fff/fff-babel-bird2/files/etc/bird/fff/nat-filter.conf new file mode 100644 index 00000000..e69de29b diff --git a/src/packages/fff/fff-babel-bird2/files/etc/init.d/fff-bird b/src/packages/fff/fff-babel-bird2/files/etc/init.d/fff-bird new file mode 100755 index 00000000..a23f4a37 --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/files/etc/init.d/fff-bird @@ -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 +} diff --git a/src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/30-disable-bird2 b/src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/30-disable-bird2 new file mode 100644 index 00000000..726c5f79 --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/30-disable-bird2 @@ -0,0 +1,4 @@ +/etc/init.d/bird disable +rm -f /etc/init.d/bird + +exit 0 diff --git a/src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/60-fff-bird-config b/src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/60-fff-bird-config new file mode 100644 index 00000000..7689bea0 --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/60-fff-bird-config @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-3.0-only + +mv /etc/bird-fff.conf /etc/bird.conf + +exit 0 diff --git a/src/packages/fff/fff-babel-bird2/files/lib/functions/fff/babeldaemon/bird2 b/src/packages/fff/fff-babel-bird2/files/lib/functions/fff/babeldaemon/bird2 new file mode 100644 index 00000000..866478bd --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/files/lib/functions/fff/babeldaemon/bird2 @@ -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 +} diff --git a/src/packages/fff/fff-babel-bird2/files/usr/lib/nodewatcher.d/80-bird2.sh b/src/packages/fff/fff-babel-bird2/files/usr/lib/nodewatcher.d/80-bird2.sh new file mode 100755 index 00000000..a7708eb9 --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/files/usr/lib/nodewatcher.d/80-bird2.sh @@ -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 "%s%s%s", $1, $2, $3 }' + )" + +echo -n "$neighbours" + +exit 0 diff --git a/src/packages/fff/fff-babel/Makefile b/src/packages/fff/fff-babel/Makefile new file mode 100644 index 00000000..abae858c --- /dev/null +++ b/src/packages/fff/fff-babel/Makefile @@ -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 +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)) diff --git a/src/packages/fff/fff-babeld/files/etc/layer3.d/40-babel b/src/packages/fff/fff-babel/files/etc/layer3.d/40-babel similarity index 92% rename from src/packages/fff/fff-babeld/files/etc/layer3.d/40-babel rename to src/packages/fff/fff-babel/files/etc/layer3.d/40-babel index 04b17c91..735d01f4 100644 --- a/src/packages/fff/fff-babeld/files/etc/layer3.d/40-babel +++ b/src/packages/fff/fff-babel/files/etc/layer3.d/40-babel @@ -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 } diff --git a/src/packages/fff/fff-babeld/files/etc/uci-defaults/26-babel-iproute b/src/packages/fff/fff-babel/files/etc/uci-defaults/26-babel-iproute similarity index 100% rename from src/packages/fff/fff-babeld/files/etc/uci-defaults/26-babel-iproute rename to src/packages/fff/fff-babel/files/etc/uci-defaults/26-babel-iproute diff --git a/src/packages/fff/fff-babeld/files/etc/uci-defaults/27-babel-network-rules b/src/packages/fff/fff-babel/files/etc/uci-defaults/27-babel-network-rules similarity index 100% rename from src/packages/fff/fff-babeld/files/etc/uci-defaults/27-babel-network-rules rename to src/packages/fff/fff-babel/files/etc/uci-defaults/27-babel-network-rules diff --git a/src/packages/fff/fff-babel/files/lib/functions/fff/babel b/src/packages/fff/fff-babel/files/lib/functions/fff/babel new file mode 100644 index 00000000..a6fdf3b0 --- /dev/null +++ b/src/packages/fff/fff-babel/files/lib/functions/fff/babel @@ -0,0 +1,116 @@ + +implementation=$(uci -q get babelimpl.impl.impl) +[ -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 +} diff --git a/src/packages/fff/fff-babeld/Makefile b/src/packages/fff/fff-babeld/Makefile index 2231e205..e21f03e6 100644 --- a/src/packages/fff/fff-babeld/Makefile +++ b/src/packages/fff/fff-babeld/Makefile @@ -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 diff --git a/src/packages/fff/fff-babeld/files/etc/uci-defaults/30-disable-babeld b/src/packages/fff/fff-babeld/files/etc/uci-defaults/30-disable-babeld new file mode 100644 index 00000000..e14dd4b9 --- /dev/null +++ b/src/packages/fff/fff-babeld/files/etc/uci-defaults/30-disable-babeld @@ -0,0 +1,3 @@ +/etc/init.d/babeld disable + +exit 0 diff --git a/src/packages/fff/fff-babeld/files/lib/functions/fff/babel b/src/packages/fff/fff-babeld/files/lib/functions/fff/babeldaemon/babeld similarity index 54% rename from src/packages/fff/fff-babeld/files/lib/functions/fff/babel rename to src/packages/fff/fff-babeld/files/lib/functions/fff/babeldaemon/babeld index fa4e7e9c..e5427dae 100644 --- a/src/packages/fff/fff-babeld/files/lib/functions/fff/babel +++ b/src/packages/fff/fff-babeld/files/lib/functions/fff/babeldaemon/babeld @@ -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 +} diff --git a/src/packages/fff/fff-layer3/Makefile b/src/packages/fff/fff-layer3/Makefile index 4d2e0b1d..16abaf41 100644 --- a/src/packages/fff/fff-layer3/Makefile +++ b/src/packages/fff/fff-layer3/Makefile @@ -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 \ diff --git a/src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh b/src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh index 9b8a7d44..b0bb74a0 100755 --- a/src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh +++ b/src/packages/fff/fff-nodewatcher/files/usr/lib/nodewatcher.d/10-systemdata.sh @@ -74,8 +74,12 @@ if [ -x /usr/bin/fastd ]; then SYSTEM_DATA="$SYSTEM_DATA$(/usr/bin/fastd -v | awk '{ print $2 }')" fi -if [ -x /usr/sbin/babeld ]; then - SYSTEM_DATA="$SYSTEM_DATA$(/usr/sbin/babeld -V 2>&1)" +if [ -e /lib/functions/fff/babel ]; then + . /lib/functions/fff/babel + babel_version=$(babel_get_version) + if [ $? -eq 0 ]; then + SYSTEM_DATA="$SYSTEM_DATA$babel_version" + fi fi # example for /etc/openwrt_release: diff --git a/src/packages/fff/fff-wireguard/Makefile b/src/packages/fff/fff-wireguard/Makefile index 64ec4f50..f2b33f1c 100644 --- a/src/packages/fff/fff-wireguard/Makefile +++ b/src/packages/fff/fff-wireguard/Makefile @@ -14,7 +14,7 @@ define Package/fff-wireguard +kmod-wireguard \ +owipcalc \ +wireguard-tools \ - +fff-babeld \ + +fff-babel \ +fff-network endef diff --git a/src/packages/fff/fff-wireguard/files/etc/layer3.d/50-wireguard b/src/packages/fff/fff-wireguard/files/etc/layer3.d/50-wireguard index 910755b3..04f20692 100644 --- a/src/packages/fff/fff-wireguard/files/etc/layer3.d/50-wireguard +++ b/src/packages/fff/fff-wireguard/files/etc/layer3.d/50-wireguard @@ -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 }