From 803e2746df5b7180080fd482af5b9dae61562ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Bl=C3=A4se?= Date: Sun, 14 Feb 2021 23:49:58 +0100 Subject: [PATCH] Add bird2 as selectable babel implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bird 2 has a few advantages over babeld. Especially the possiblity to dynamically reload the configuration without restarting the daemon and birds significant performance advantage make it an interesting alternative to babeld for our firmware. This adds the necessary implementation-specific fff-babel-bird2 package, which allows to integrate bird2 into the fff firmware. Signed-off-by: Fabian Bläse Acked-by: Christian Dresel --- buildscript | 2 +- src/packages/fff/fff-babel-bird2/Makefile | 30 +++++ .../fff-babel-bird2/files/etc/bird-fff.conf | 123 ++++++++++++++++++ .../files/etc/bird/fff/nat-filter.conf | 0 .../fff-babel-bird2/files/etc/init.d/fff-bird | 45 +++++++ .../files/etc/uci-defaults/30-disable-bird2 | 4 + .../files/etc/uci-defaults/60-fff-bird-config | 5 + .../files/lib/functions/fff/babeldaemon | 68 ++++++++++ .../files/usr/lib/nodewatcher.d/80-bird2.sh | 20 +++ .../usr/lib/nodewatcher.d/10-systemdata.sh | 2 + 10 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 src/packages/fff/fff-babel-bird2/Makefile create mode 100644 src/packages/fff/fff-babel-bird2/files/etc/bird-fff.conf create mode 100644 src/packages/fff/fff-babel-bird2/files/etc/bird/fff/nat-filter.conf create mode 100755 src/packages/fff/fff-babel-bird2/files/etc/init.d/fff-bird create mode 100644 src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/30-disable-bird2 create mode 100644 src/packages/fff/fff-babel-bird2/files/etc/uci-defaults/60-fff-bird-config create mode 100644 src/packages/fff/fff-babel-bird2/files/lib/functions/fff/babeldaemon create mode 100755 src/packages/fff/fff-babel-bird2/files/usr/lib/nodewatcher.d/80-bird2.sh 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..eecddf76 --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/Makefile @@ -0,0 +1,30 @@ +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 + CONFLICTS:=fff-babeld +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 b/src/packages/fff/fff-babel-bird2/files/lib/functions/fff/babeldaemon new file mode 100644 index 00000000..5820aa6b --- /dev/null +++ b/src/packages/fff/fff-babel-bird2/files/lib/functions/fff/babeldaemon @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-3.0-only + +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() { + # 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() { + /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-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..34ba16c8 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 @@ -76,6 +76,8 @@ fi if [ -x /usr/sbin/babeld ]; then SYSTEM_DATA="$SYSTEM_DATA$(/usr/sbin/babeld -V 2>&1)" +elif [ -x /usr/sbin/bird ]; then + SYSTEM_DATA="$SYSTEM_DATA$(/usr/sbin/bird --version 2>&1 | sed "s/BIRD version /bird-/")" fi # example for /etc/openwrt_release: