Neanderfunk 2023.2.6: Pakete, Patches, Buildsystem
Neue Neanderfunk-Stable-Firmware 26091920sta, noch Gluon 2023.2.6, aus Gründen (siehe unten). Was davon in eigenen Paketen liegt und was Patch geblieben ist:
- Feed, gepinnt auf den Stand in diesem Release: GitHub - Neanderfunk/packages at afccfac4709d5a8627a3592f51cedc847c984f2c · GitHub
- Images, je Domain ein Verzeichnis: Freifunk Neanderfunk Firmware Seite
- Firmware, site.conf und Release Notes, Tag
gluon-release-v2023.2.6_26091920sta: GitHub - Neanderfunk/firmware at gluon-release-v2023.2.6_26091920sta · GitHub
In den Images
Auswahl in templates/common/image-customization.lua, Feed-Pin in templates/common/modules.
- Auf allen Geräten: nodeplacer, ssid-changer, respondd, setup-mode, setup-wifi, preserve-wifichannel, hotfix, linkcheck, wifi-blackout, weeklyreboot, ap-timer, button-bind, node-whisperer, banner
- Nur ramips-mt7621, mediatek-mt7622, mediatek-filogic: mt7915-backlog
- Nur als DEPENDS: config-mode-theme, common
- 64 MB RAM, zwei von Hand gepflegte Gerätelisten (18 Dualband, 29 Singleband): zram-swap dazu,
procd-ujailraus. Gemessen am TL-WR1043ND v2: ujail kostete 3,7 MB RSS für dnsmasq, hostapd und ntpd zusammen. - Wie die Listen entstehen: Kandidaten aus einer Erhebung von RAM je Gerät (Gluon-Targets, OpenWrt Table of Hardware), aufgenommen wird, was sich im Feld als betroffen gezeigt hat. Die Listen sind nur für ath79 vollständig; Singleband-Geräte anderer Targets mit 64 MB fehlen noch, dort bleibt es beim Standard.
- Nicht an den Listen hängen die Einstellungen, die zur Laufzeit an
MemTotalentscheiden. Die greifen auf jedem Gerät mit 64 MB, auch auf denen, die in keiner Liste stehen; die Patches dazu stehen weiter unten. - Umsonst ist keine dieser Maßnahmen, meist zahlt es der Durchsatz.
- Nicht drin:
haveged(unter 23.05 liefert urngd die Entropie, 5.15 initialisiert den CRNG selbst; 1,6 MB RSS),ffmuc-ipv6-ra-filter(bleibt bei schnellem Supernode-Wechsel zu lange sticky)
Pakete im Einzelnen
Zur Zeile Upstream: gemeint ist fast überall freifunk-gluon/community-packages oder der Feed des jeweiligen Ursprungs-Maintainers, nicht Gluon-Core. Core betrifft es nur bei preserve-wifichannel, setup-wifi und setup-mode.
neanderfunk-preserve-wifichannel
- Funktion: hält Kanal und Kanalbreite über Updates, setzt sie nach Site- oder Domainwechsel einmal neu
- Mechanik: macht
wifi24.preserve_channelsaus der site.conf zum Default für Gluons uci-Option - Herkunft: Gluon 2023.2 wertet diesen site.conf-Key nicht aus. Bei uns war er jahrelang gesetzt und wirkungslos.
- site.conf:
wifi24.preserve_channels = 1 - Dependency: Das Ausblenden des Outdoor-Schalters im Wizard bei
preserve_channels=1braucht weiterhin einen Gluon-Patch (patches/gluon-config-mode/outdoor-schalter.patch), das Paket allein genügt dafür nicht. - Upstream: betrifft Gluon-Core. Gluon kennt die uci-Option
gluon.wireless.preserve_channels, aber keinen site.conf-Default dafür. Laufend: Gluon#3550 („RFC: configure wifi through gluon config“, offen seit 22.07.2025) baut die WLAN-Konfiguration um, Gluon#3601 (offener PR) ergänzt einen htmode-Override je Radio.
neanderfunk-setup-wifi
- Funktion: WLAN
setup.gluon_<MAC>im Setup-Mode, Einrichtung ohne Netzwerkkabel - Herkunft: vorher ein Firmware-Patch mit hardcodierten Werten
- site.conf:
setup_mode.wifimitstart(button,off,boot),security(open,wpa2),timeout(1200) - Start: per Taster im laufenden Betrieb (
button), beim Start in den Setup-Mode (boot) oder gar nicht (off). NachtimeoutSekunden schaltet das WLAN wieder ab. - Bleibt Patch, auch beim Nachnutzen:
S60dnsmasqausgluon-setup-mode(erste Instanz fest anbr-setup) undcgi-bin/portalausgluon-config-mode-core(Rückleitung aufSERVER_ADDR). Zwei Pakete können dieselbe Datei nicht besitzen. - Upstream: berührt Gluon-Core. Ohne Erweiterbarkeit dieser beiden Dateien bleibt es außerhalb ein Gespann aus Patch und Paket. Älterer PR dazu: Gluon#1563 („[RFC] gluon-setup-mode: add wifi interfaces“, PR vom 04.11.2018, am 05.07.2020 ungemergt geschlossen). Offener Punkt dort: ein aus der
primary_macabgeleiteter PSK trage nicht auf allen Geräten. Unser Vorgabeschlüssel ist ebenfalls aus der MAC ableitbar.
neanderfunk-setup-mode und neanderfunk-config-mode-theme
- Funktion: Setup-Mode auf einer Seite, Wizard und erweiterte Einstellungen, ein Speichern. Theme responsiv, mit Dark Mode.
- Herkunft: Neuentwicklung.
- DEPENDS:
setup-modeauf+neanderfunk-config-mode-theme - Einbinden:
'-gluon-config-mode-theme'ist Pflicht, beide liefernview/theme/layout.html. - Warum eine Seite: Wer in Gluons Setup-Mode vom Wizard in die erweiterten Einstellungen wechselt, verliert seine Eingaben. Ohne Wechsel kein Verlust. Oben der Wizard, darunter jedes Formular der erweiterten Einstellungen als eingeklappte Gruppe mit Zustandszeile, ein „Speichern & Neustarten“. Information und Firmware-Upgrade bleiben eigene Seiten.
- Die Formulare bleiben die von Gluon und den Paketen. Ein neues Paket mit
model()erscheint ohne Zutun als weitere Gruppe. „Außenbereich“ fragt Gluon an zwei Stellen ab, auf der Seite steht es einmal. - Speicherregeln: alles oder nichts, geschrieben wird nur bei durchweg gültigen Formularen; nur geänderte Formulare werden geschrieben (ein leeres Passwortformular hätte sonst
passwd -l rootausgeführt); der Wizard zuletzt und immer, er setztconfigured, ruftgluon-reconfigureund startet neu; solange die erweiterten Formulare schreiben, bleiben Commit und Reconfigure aus, sonst schriebe ein Formular mit altem uci-Cursor eine veraltete Kopie zurück. - Theme: ersetzt Gluons Theme über
PROVIDES gluon-config-mode-theme, liefert nurview/theme/layout.htmlund ein Stylesheet und stylt Gluons eigenes Markup, ohne eines seiner Templates zu ändern. Kein Gluon-Patch nötig. Dasselbe Muster wieffgraz-config-mode-theme-funkfeuer. - CSS ohne Breakpoints: keine einzige Breiten-Media-Query, das Layout richtet sich allein über Flex und Grid (26 Stellen). Die beiden einzigen
@media-Regeln sindprefers-color-scheme: darkundprefers-reduced-motion: reduce. Der Dark Mode folgt dem Browser, es gibt keinen Umschalter. - Größen, Rohbytes:
neanderfunk.css19 651 B (gzip -9: 5 168 B),layout.html5 142 B. Gluon zum Vergleich:gluon.css7 073 B,layout.html3 194 B. Unser Stylesheet deckt allerdings auch die Sammelseite mit ab, der Vergleich hinkt also. - Alles lokal: kein
@import, keinurl(), kein@font-face, kein externer Link. Nur System-Schriften (system-ui,-apple-system,Segoe UI, Roboto und weiter), das Logo als Inline-SVG. Im Setup-Mode hat der Client meist kein Internet, und Schriften kosten Flash. - Cache: das Stylesheet wird mit
?v=<Release>geladen. Gluon liefert/static/ohneCache-Controlund mit festemLast-Modifiedaus, sonst behält der Browser nach einem Update das alte CSS. - i18n: eigene
i18n/*.po(de, fr), geholt miti18n('neanderfunk-config-mode-theme'), weil der Dispatcher das Layout unter dem Namengluon-config-mode-themerendert. - Upstream: Das Theme deklariert
PROVIDES gluon-config-mode-theme, so wie das vorhandeneffgraz-config-mode-theme-funkfeuerin community-packages; Themes als eigenes Paket sind dort also vorgesehen. Zur Ein-Seiten-Form, die Gluon-Core berührt, kein Issue und kein PR gefunden. Ältere Issues und PRs: Gluon#2386 („Feature responsive“, PR, am 01.01.2023 ungemergt geschlossen), Gluon#528 (Farben änderbar, offen seit 16.10.2015), Gluon#1165 (Statusseite nutzt das config-mode-theme nicht, offen seit 2017).
Setup-Mode: Netze, Portal-Erkennung, Taster, LED, Timer
- Zwei Netze. Am Kabel
br-setup: Knoten 192.168.1.1, DHCP .2 bis .254, Router-Option leer, der Client bekommt also keine Default-Route über den Knoten. Im Setup-WLANbr-setupwifi: 198.51.100.1/24, DHCP .2 bis .254, Router und DNS sind der Knoten. - 198.51.100.0/24 ist TEST-NET-2 (RFC 5737), bewusst kein RFC 1918. Android öffnet sein Anmeldefenster nur, wenn der Probe-Host nicht auf eine RFC-1918-Adresse auflöst; am Galaxy S24 Ultra kam mit 192.168.2.1 nur „kein Internet“.
- DNS am Kabel gezielt, im WLAN Catch-all. Am Kabel löst dnsmasq nur
gluon.setup,setup.gluonund die Probe-Hosts auf, alles andere REFUSED, damit ein Laptop, der nebenher im Internet hängt, seinen anderen Resolver fragt und die OSM-Kacheln im Wizard bekommt. Im Setup-WLAN zeigt jeder Name auf den Knoten, dort lädt die Karte folglich nicht. - Die Probes sind Herstellerkonventionen, keine Standards. Eingetragen sind unter anderem
captive.apple.com,connectivitycheck.gstatic.com,connectivitycheck.android.com,clients3.google.com,www.msftconnecttest.com,dns.msftncsi.com,detectportal.firefox.com,nmcheck.gnome.org,connectivity-check.ubuntu.com,network-test.debian.org,networkcheck.kde.org,ping.archlinux.org,connect.rom.miui.com,connectivitycheck.platform.hicloud.com. - Alle URLs: uhttpd läuft mit
-E /cgi-bin/portal, also geht jeder Pfad, den es auf dem Knoten nicht gibt, an diesen Handler,/generate_204ebenso wie/hotspot-detect.html,/connecttest.txtoder/success.txt. - Die Antwort ist für alle gleich:
302 Found,Location: http://<Adresse>/cgi-bin/config,Cache-Control: no-store(RFC 9110, 15.4.3). Adresse ist die, über die die Anfrage kam. Weil die erwartete Antwort ausbleibt, meldet das System „Im Netzwerk anmelden“ und öffnet den Wizard. - Nicht umgesetzt: die standardisierte Signalisierung nach RFC 8910 (DHCPv4-Option 114, DHCPv6-Option 103, RA-Option 37) samt Captive-Portal-API nach RFC 8908. Die API müsste HTTPS mit validem Zertifikat sein, sonst muss der Client sie ignorieren, und ein Knoten im Setup-Mode hat keines: Er ist offline, solange er nicht konfiguriert ist, und kann sich in dieser Lage auch keines besorgen. Dazu kommt, dass iOS die API beim ersten Verbinden nicht nutzt und dass DHCPv6 wie RA ausfallen, weil Gluons dnsmasq ohne beides gebaut ist und der Setup-Mode kein IPv6 vergibt. RFC 6585 (HTTP 511) ebenfalls nicht, wir antworten mit 302.
- Geprüft ist Android, Galaxy S24 Ultra und ein Gerät mit Android 16 am 14.09.2026, dazu Laborläufe am Archer C25 v1. iOS, macOS, Windows, die Linux-Desktops und die Xiaomi- und Huawei-ROMs sind eingetragen, ihre Wirkung ist nicht nachgewiesen.
- Taster: Gluon selbst startet bei 3 s Halten auf reset, wps oder phone in den Setup-Mode. Unser Paket nimmt den Kurzdruck unter 3 s und nur im Setup-Mode: Setup-WLAN an, oder der Timeout beginnt von vorn. Einen Werksreset per Taster gibt es im Image nicht,
/etc/rc.button/resetfehlt. - LED: Setup-Mode 1000 ms an, 300 ms aus, also etwa 0,77 Hz. Läuft das Setup-WLAN, 200/60 ms, also etwa 3,8 Hz. Bis 14.09.2026 waren es 333/100, das war vom Setup-Mode-Takt zu schwer zu unterscheiden.
- Timer: Vorgabe 1200 s, erlaubt 60 bis 86400. Verlängert wird er nur durch einen erneuten Kurzdruck, Client-Verkehr verlängert nicht. Danach
wifi downund eine Logzeile, kein Neustart; der Zugang per Kabel bleibt. - Bei uns selbst:
start = button,security = open. Das Setup-WLAN ist also offen, geht aber nur per Kurzdruck am Gerät an.check_site.luaerzwingt diese Kombination, offen gibt es nur zusammen mitbutton. Am Genexis Pulse EX400 zählt die kapazitive wps-Fläche für den Kurzdruck mit, dort kann das offene Setup-WLAN ohne Finger angehen.
neanderfunk-hotfix
- Funktion: 16 Zustandsprüfungen, die WLAN neu initialisieren oder rebooten. Intervalle: healthcheck 7 min, IfNoWificlient 15 min, watchdog 5 min, WLAN-Firmware 3 min.
- Checks und Reaktion:
kernel_bug,ath_malloc,ksoftirqd_malloc,tunneldigger,br_client_ipv6,load,respondd,dropbear,wifi_firmware,ath10k_rxhang,eth_tx_stall,watchdog(Reboot);hostapd_pids,dfs_failcheck,no_wifi_clients(WLAN-Neustart);logremote(Neustart der logread-Instanz) - uci:
hotfix.settings.check_uptime_min(5),.reboot_uptime_min(60),.watchdog_interval_min(5),.autoupdater_stale_min(300),.hostapd_cooldown_min(60),.ath10k_restart_min(3); je Checkhotfix.<check>.disabledund.immediate;hotfix.load.per_cpu(2, Schwelle ist per_cpu mal Kerne über zwei Läufe);hotfix.eth_tx_stall.dry_run(1 = nur loggen),.strikes(3),.rx_strikes(5),.soft_reset(1,ethtool -rvor dem Reboot) - site.conf:
hotfix.check_uptime_min,.reboot_uptime_min,.disabled_checks,.load_per_cpu,.eth_tx_stall_dry_run - Herkunft:
eulenfunk/packages(Ruben Kelevra), enthält und ersetztffac-mt7915-hotfix. Neu gegenüber dem Vorgänger sind beide Uptime-Schwellen; das Original konnte zwei Minuten nach dem Boot rebooten. - Upstream: enthält und ersetzt
ffac-mt7915-hotfix(community-packages#132, 2024). Die Ursachen liegen tiefer:eth_tx_stallgehört zu openwrt/openwrt#17505 („Cudy TR3000: MT7981 ethernet disconnects“, offen, zuletzt 07.01.2025),kernel_bugstammt aus der Zeit von Gluon#680 (geschlossen). - DEPENDS:
+neanderfunk-common
neanderfunk-linkcheck
- Funktion: prüft WLAN- und batman-Neighbours sowie Gateway-Erreichbarkeit. Intervalle: linkcheck 5 min, gateway 8 min.
- Checks:
batadv_neighbours,bsses,batinterfaces,batman_originators,bridges,bridge_ports,mesh_neighbours(erst WLAN-Neustart, dann Reboot);no_gateway,ipv6_anycast,public_prefix(Reboot) - uci:
linkcheck.settings.check_uptime_min(5),.reboot_uptime_min(60), je Checklinkcheck.<check>.disabled - site.conf:
linkcheck.check_uptime_min,.reboot_uptime_min,.disabled_checks - Limits:
no_gatewayrebootet nach 4 Läufen, also etwa 32 min, aber nur, wenn seit dem Boot einmal ein Gateway gesehen wurde (Marker/tmp/linkcheck.gw-seen). Bei flackerndem Gateway ergibt das eine Reboot-Schleife von etwa 65 min;reboot_uptime_minverzögert, es verhindert nicht. Ein Knoten, der nie ein Gateway hatte, bleibt in Ruhe.bssesüberspringt wifi6- und mt7915-Radios, dort bricht der Scan die Mesh-Links.
- Herkunft:
eulenfunk/packages(Ruben Kelevra). - DEPENDS:
+neanderfunk-common
neanderfunk-wifi-blackout
- Funktion: kein assoziierter Client auf irgendeinem Radio über
blackoutwaitMinuten, dann WLAN-Neustart; hilft das nicht, Reboot. - uci:
wifi_blackout.settings.check_uptime_min(5),.restarts_before_reboot(1),.disabled(0) - site.conf, nicht per uci:
wifi_blackout.blackoutwait(171 min),.resetwait(281 min),.stepsize(10 min) - False Positive: Ein Knoten, an dem legitim nie Clients hängen, also ein reiner Mesh- oder Backbone-Knoten, startet periodisch neu. Am D-Link COVR-X1860 ohne Clients gemessen: etwa alle 14 h.
- Herkunft: FreifunkHochstift, über
eulenfunk-ath9kblackout. Umbenannt, weil der Fehler nicht ath9k-spezifisch ist. - DEPENDS:
+neanderfunk-common - CONFLICTS:
eulenfunk-ath9kblackout,gluon-ath9kblackout,neanderfunk-ath9kblackout
neanderfunk-mt7915-backlog
- Funktion: WLAN-Neustart, wenn der txq-Backlog eines mt7915-Radios über 50 Pakete wächst. Nur auf ramips-mt7621, mediatek-mt7622, mediatek-filogic.
- uci:
mt7915backlog.settings.threshold(50),.cooldown_min(30),.disabled(0),.check_uptime_min(5),.reboot_uptime_min(60) - Herkunft: Port von
ffac-mt7915-backlog. Neu sind 30 min Cooldown zwischen Neustarts, das Original startete bis zu alle 2 min neu. - Einordnung: Symptombehandlung, bei uns zusammen mit
ffac-mt7915-maxinactivity, das an der Ursache ansetzt. - Upstream:
ffac-mt7915-backlogexistiert nur als Branch in ffac/gluon-packages, PR #19 vom 30.09.2025 wurde ungemergt geschlossen. Die Ursache ist offen als openwrt/mt76#1009 („mt7915: wifi unresponsive - backlog fills - no tx activity“, zuletzt 22.04.2026). Gluon#3154 (MT7915e-Abstürze) ist seit 15.04.2025 geschlossen, behoben durch Gluon#3436 („mt76: fix system recovery routine for MT7915“, gemergt 09.03.2025), aber nur in main. Der Backport Gluon#3710 für v2023.2.x wurde nicht gemergt, Begründung im PR: „This issue is properly fixed in future Gluon releases“. Auf 2023.2.6 fehlt der Fix damit.
neanderfunk-ssid-changer
- Funktion: schaltet die Client-SSID auf eine Offline-SSID, wenn kein Gateway erreichbar ist, und zurück, sobald es wieder da ist.
- uci:
ssid-changer.settings.enabled,.switch_timeframe(30 min),.first(5 min),.prefix(FF_Offline_),.prefix_owe(FF_Off_OWE_),.suffix(nodename,mac,none),.tq_limit_enabled(false),.tq_limit_max(45),.tq_limit_min(35),.gwofflinemaxcount(3),.debug_log_enabled - site.conf: Block
ssid_changer - Limit: Die TQ-Limits funktionieren laut README nicht mit BATMAN_V.
- Zähler liegen nicht in uci, sondern als respondd-Werte unter
statistics.neanderfunk.ssid_changer.{gateway_losses, offline, switches}. - Herkunft: Fork von
ffac-ssid-changer(Basis-Commit91e5fa8). - DEPENDS:
+neanderfunk-common - CONFLICTS:
ffac-ssid-changer,gluon-ssid-changer - Upstream: beim Original offen: community-packages#180 („set offline ssid correctly for larger switch_timeframe“, offener PR vom 08.01.2026), #172 und #173 (Offloader ohne WLAN, 09/2025), #157 („Never sets offline SSID“, geschlossen).
neanderfunk-nodeplacer
- Funktion: verschiebt einzelne Knoten serverseitig in eine andere Domain, gesteuert über ein signiertes Manifest auf dem Firmware-Server.
- site.conf, alles optional, der Block selbst auch: installiert heißt aktiv.
nodeplacer.mirrors(nurhttp://),.pubkeys,.good_signatures(höchstens Zahl der pubkeys),.disable(0),.config_mode(Tab im Setup-Mode). Ohne Angabe gelten Mirrors, Keys und Schwelle des Autoupdater-Zweigs, auf dem der Knoten läuft. - uci:
nodeplacer.settings.* - Trust Anchor: dieselben Keys und dieselbe Schwelle wie der Autoupdater.
- Limits: nur innerhalb derselben Community; mit Single-Domain-Firmware getestet, Multidomain noch nicht an Geräten.
- CONFLICTS:
gluon-hoodselector - Doku:
neanderfunk-nodeplacer/docs/HOWTO.mdunddocs/MANIFEST-FORMAT.md - Upstream: Neuentwicklung. Verwandt, aber mit anderem Zweck:
gluon-scheduled-domain-switch(ganze Domain, zeitgesteuert),gluon-hoodselector(nach Geokoordinaten),gluon-config-mode-domain-select(Auswahl durch den Betreiber). Einzelne Knoten serverseitig deckt keins davon ab. README unddocs/DECISIONS.mdliegen im Paket, die README bittet um Tests durch andere Communities: packages/neanderfunk-nodeplacer at afccfac4709d5a8627a3592f51cedc847c984f2c · Neanderfunk/packages · GitHub
neanderfunk-respondd
- Funktion: respondd-Modul in C, liefert
statistics.neanderfunk.*: Hardware, Radios (Kanal, htmode, txpower, Land), Offline-SSID-Zähler, Ethernet-Links (Carrier, Speed, possible), Speicherdruck (refault_file, forks, zram), Temperaturen. - Konfiguration: keine, weder uci noch site.conf.
- Damit die Werte auf einer Karte erscheinen, braucht yanic eine Erweiterung. Unsere liegt öffentlich als Commit in unserem yanic-Fork: statistics.neanderfunk lesen und in die Zeitreihen schreiben · Neanderfunk/yanic@20c5b02 · GitHub
- Nicht alles davon landet dort: Die Hardware-Angaben (
vendor,soc,cpu_model,flash) liest yanic nicht, die stehen nur auf dem Knoten. - Upstream: Neuentwicklung. Die Feldnamen stehen bewusst unter
statistics.neanderfunk.*, also als Community-Erweiterung und nicht als Gluon-Standardfeld.
neanderfunk-ap-timer
- Funktion: Zeitschaltung für das Client-WLAN, mit Seite im Setup-Mode.
- uci:
ap-timer.settings.enabled,.type(dayoderweek), dazu je Tag beziehungsweise Wochelist on 'HH:MM'undlist off 'HH:MM' - site.conf:
ap_timer.web(Seite im Setup-Mode, Vorgabe true) - Herkunft: Fork von
ff-ap-timerundff-web-ap-timer, zu einem Paket zusammengefasst (community-packages#80, 2023, ursprünglich von FFHO). - CONFLICTS:
ff-ap-timer,ff-web-ap-timer
neanderfunk-button-bind
- Funktion: legt Funktionen auf die Gerätetaster.
- uci:
button-bind.wifi.function: 0 = WLAN an/aus (OpenWrt-Verhalten), 1 = keine Funktion (Vorgabe), 2 = WLAN-Reset, 3 = Nachtmodus (LEDs aus, nur beim Drücken an, braucht Reboot) - Herkunft: Port von
ffffm-button-bind(GitHub - freifunk-ffm/packages: Frankfurter Packages · GitHub), mit Bugfix im Upgrade-Skript. - CONFLICTS:
ffffm-button-bind - Upstream: das Ursprungs-Repo ist nicht archiviert, letzter Push 10.07.2024.
neanderfunk-node-whisperer
- Funktion: Diagnoseinformationen über WLAN-Beacons.
- site.conf:
node_whisperer.enabled,.information(Auswahl aus hostname, node_id, uptime, site_code, domain, system_load, firmware_version, batman_adv) - Herkunft: Fork von
ffda-node-whisperer. Unsere Änderungen liegen als Patches im Paket:-ENODATAstatt falscher Werte, Gateway-TQ überBATADV_CMD_GET_GATEWAYS, jeder Originator wird einmal gezählt. - CONFLICTS:
ffda-node-whisperer - Upstream: community-packages#182 (offen seit 03.04.2026) meldet wörtlich
node-whisperer: Error collecting Information for id=4 name=domain code=-1. Unser Patch 0001 setzt an genau dieser Meldung an:gluonutil_get_domain()liefert auf Single-Domain-Firmware NULL, der Collector gab dafür -1 zurück. Im Issue wird als Ursache eine unvollständige WLAN-Erkennung vermutet.
neanderfunk-banner
- Funktion: ersetzt
/etc/bannerund/etc/profiledurch Varianten mit Knotenstatus und Hilfsbefehlen. - Hinweis: macht DNS-Abfragen bei
asn.cymru.comfür die ASN-Anzeige. - CONFLICTS:
ffmuc-custom-banner(community-packages#115, 2024).
neanderfunk-common
- Funktion: gemeinsame Helfer für hotfix, linkcheck, weeklyreboot, ssid-changer und wifi-blackout, darunter das Reboot-Log
/lib/gluon/neanderfunk/reboot.log, das die letzten Reboot-Gründe über den Neustart hält. - uci:
neanderfunk.settings.reboot_log_max(6, 0 = aus) - site.conf:
neanderfunk.reboot_log_max
neanderfunk-weeklyreboot
- Funktion: Reboot donnerstags,
cron 15 3 * * 4plus 0 bis 9999 s Zufall, also zwischen 3:15 und etwa 6:02. - Übersprungen, solange der Autoupdater arbeitet, zweistufig:
flock -nauf/var/lock/autoupdater.lockdeckt Download und Prüfung ab,pgrep sysupgradeden Flash selbst, beides fail-safe. - Ohne gestellte Uhr hängt der Reboot an der Uptime statt am Wochentag. Die meisten Router haben keine RTC. Nach dem Boot setzt OpenWrt die Uhr auf den Zeitstempel der jüngsten Datei unter
/etc, also etwa auf die letzte Konfigurationsänderung. Liegt der kurz vor Donnerstag 3:15, erreicht der Knoten die cron-Zeit nach jedem Boot nach derselben kurzen Frist, und frühere Fassungen starteten ihn so immer wieder neu. Das Skript prüft deshalb einen Marker in/tmp, den das ntp-Hotplug-Ereignisstratumsetzt. Fehlt er, rebootet der Donnerstags-Lauf erst ab sieben Tagen Uptime, der Neustart fällt dann zwischen 7 und 14 Tagen. - Konfiguration: keine. Der Zeitplan ist fest; für andere Zeiten muss die cron-Zeile geändert und neu gebaut werden.
- CONFLICTS:
ffac-weeklyreboot,gluon-weeklyreboot - DEPENDS:
+neanderfunk-common - Upstream: Pendant ist
ffac-weeklyreboot(community-packages#34, 2023). Es prüfte/tmp/autoupdate.lock, eine Datei, die niemand anlegt. Korrigiert in community-packages#191, upstream gemergt am 10.09.2026, jetzt ebenfallsflock -nauf/var/lock/autoupdater.lock.flockist auf den 2023.2.6-Images vorhanden (busybox 1.36.1, geprüft an x86 und TL-WR1043ND v2). Die zweite Stufepgrep sysupgradeund der ntp-Schutz stehen upstream nicht.
Was noch Patch geblieben ist, und warum
40 Patches, feste Reihenfolge in templates/common/prepare.sh, gruppiert unter patches/<gruppe>/. Jede Gruppe ist in sich geschlossen, die Skripte sind idempotent; patches/README.md beschreibt, wie man einzelne Gruppen übernimmt.
Backports: upstream gelöst, in 2023.2 noch nicht drin
lowmem/limit-wireless-buffers- WLAN-Puffer nach RAM. Gluon8f38662f, ab v2025.1.lowmem/sysctl-64m-min-free-min_free_kbytes2048, kleine Fragmentpuffer. Gluona505f767plus Fixc6ac8914, nur in main, in keinem Release.status-page/statuspage-ssid- SSID und HT-Modus je Radio. Gluon7c040c2d04ee, ab v2025.1, bei uns mit zwei bewussten Abweichungen.kernel/rtl8221b-skip-mmd30- MMD 30 beim C45-PHY-Scan auslassen, sonst legt das Lesen den RTL8221B lahm, wenn beim Boot ein Kabel steckt. OpenWrt88dcd8c303b6, nur in main, weder 24.10 noch 23.05.devices/add-dlink-m30- in Gluon v2025.1.3 und main, nicht in v2023.2.x. OpenWrt 23.056e51ff88b0plus Fix aus 24.10d92fc99360. Ohne Recovery-Image, wie Gluon selbst seit freifunk-gluon/gluon#3816.
TLB-Kernelfreeze, Upstream-Regression im Gluon-2023.2.6-Release, gelöst
kernel/revert-mips-tlb-uniquifynimmt den Aufruf vonr4k_tlb_uniquify()heraus. Betroffene MIPS-Boards bleiben sonst beim Kaltstart intlb_init()stehen, überstehen aber Warmstarts und Updates.- Das ist der Grund für das „aus Gründen“ oben. An diesem Fehler ist bei uns im März eine Stable gescheitert: ausgerollt am 23.03.2026, zurückgerollt am 27.03.2026. Die Geräte liefen nach dem Update weiter, der Fehler zeigte sich erst beim nächsten Stromausfall, und dann war das Gerät weg. Auffallen konnte das also weder beim Ausrollen noch in der Update-Statistik.
- Zurückgerollt per Manifest: ein vordatiertes, neu signiertes Manifest mit der alten Version auf einem eigenen Zweig. Der Autoupdater nimmt eine ältere Firmware, wenn das Manifest sie als die aktuelle ausweist.
- Upstream hat es anders gelöst: 5.15.209 schreibt die Uniquifizierung neu (
540760b77b8f,Fixes: 9f048fa48740). Für die Router kein funktionaler Unterschied. - openwrt-23.05 hat 5.15.211 seit 11.07.2026, Gluon v2023.2.x seit 22.09.2026 (freifunk-gluon/gluon#3841).
- Unser Patch fällt beim nächsten Build zwingend weg, er setzt an Code an, den 5.15.209 umgeschrieben hat.
- Analyse und Messung öffentlich: freifunk-docs/mips-tlb-cold-start-5.15.md at 15fcc7bc579df8d400b12c3650a87fbf45994ea7 · Neanderfunk/freifunk-docs · GitHub
Hängt an offenen Issues upstream
kernel/mt7530-phy-disable-eee- EEE am MT7530-PHY aus. Nachbau von OpenWrt PR #25058 (offen, Basis main), von uns auf 5.15 übertragen. Ungeprüft: gebaut, die Wirkung am Gerät ist nicht gezielt nachgemessen.build/add-ffac-package-patches-max_inactivityim ffac-Paket, Umgehung für openwrt/mt76#1009 (offen): mt7915 reagiert nicht mehr, Backlog läuft voll.
Fehler und Lücken ohne Issue upstream
kernel/ag71xx-rx-ring-no-bug- unter RAM-Druck scheitert das Nachfüllen des RX-Rings,ag71xx_assert(0)löst einen Panic aus, obwohl der Treiber mitoom_timereinen Rückweg hat. OpenWrt main hat die Stelle unverändert (ag71xx_main.c,ag71xx_rx_packets).bugfixes/tunneldigger-reinit-backoff- Mesh-VPN an, kein WAN: Reinit ohne Pause, je Reinit zweimodprobe. Am WDR3600 gemessen: 115modprobein 30 s, CPU 0 % idle.lowmem/sysctl-no-watermark-boost-64mbundbugfixes/sysctl-firmware-no-sysfs-fallback(fehlende Firmware wietg3hielt den Boot 60 s unter RTNL auf). Beide ließen sich auch als Paket mitsysctl.d-Datei lösen.gluon-config-mode/wizard-save-lock- Doppelklick auf „Speichern & Neustarten“ startet parallelegluon-reconfigure-Läufe, Ergebnis HostnameOpenWrtund Zeitzone UTC.status-page/web-static-version- CSS und JS mit?v=<Release>gegen alten Browser-Cache.- Airtime-Teil aus
build/add-gluon-package-patches-respondd-module-airtimelässt Werte weg, bei denenbusy,rxodertxgrößer alsactiveist; die mt76-Survey-Zähler laufen je vif.
Prinzipiell kein Paket
lowmem/state-check-shell,lowmem/tunneldigger-watchdog-shell-gluon-state-checkundtunneldigger-watchdogals Shell statt Lua, weil die Lua-Laufzeit auf 64-MB-Geräten jede Minute beziehungsweise alle fünf Minuten vom Flash kam. Als Paket nicht lösbar: Sie ersetzen Dateien, die Gluon-Paketen gehören, das gäbe einen opkg-Konflikt.status-page/*- Gluons Statusseite hat in 2023.2 keinen Erweiterungspunkt. Die Daten kommen inzwischen ausneanderfunk-respondd, als Patch bleibt die Anzeige.setup-mode-network/*- Rumpf von 14 Zeilen: die Bindung vondnsmasqanbr-setupund die Portal-Umleitung. Den Rest hatneanderfunk-setup-wifiübernommen.- Geräte, die auch Gluon 2025.1 nicht hat: eap225-wall-v2, zyxel-nbg6616, fritz-repeater-3000, ea8300-dallas, cudy-m1800, rb750gr3, Cudy ap3000-v1 und tr3000-256mb-v1, FRITZ!Box 3390, zwei MikroTik ath79, zte-mf286r, MikroTik wAP ac, NanoPi R2C.
device-fixes/fix-xiaomi-ax6s-bootflags- der A/B-Bootloader des Redmi AX6S fällt sonst nach einigen Neustarts auf die Stock-Firmware zurück. Am Gerät verifiziert; ob OpenWrt das inzwischen anders löst, ist nicht geprüft.- Rein lokal:
network/interface-role-migration21(unsere Migration von 2021),build/patch-gluon-makefiles(GLUON_TARGETSper override).
Was neben den Images liegt
In jedem Domain-Verzeichnis liegt neben ./sysupgrade, ./factory und ./other ein Verzeichnis ./site, das den Build beschreibt. Damit hat, wer will, die Grundlage, den Build zu wiederholen. Ein reproducible build ist es nicht, es geht um Transparenz:
- Gluon-Standard, in einer Zeile abgehandelt:
site.conf,site.mk,modules,image-customization.luaundi18n/sind das, was jede Gluon-Site hat. build-info.txt- die Herkunft des Images: Release, Domain, Template, Branch, Start und Ende des Laufs, Buildhost und Aufruf, die vollen Commit-IDs von Firmware-Repo und Gluon mit dem Vermerk sauber oder N Änderungen, je Modul Soll-Commit und Ist-Stand, Target- und Domainliste, Kernel- und WLAN-Treiberversionen aus dem OpenWrt-Manifest und jeder angewendete Patch mit Ergebnis.build.conf- die Laufparameter vonbuild.sh, kommentiert: Versionsschema,make cleanundgit reset,-j, BROKEN, Autoupdater, Logoptionen, Name der Signierschlüsseldatei, Worker-Zahl und Platzprüfung. Welche Targets und Domains gebaut werden, steht nicht hier.targets.conf- welche Gluon-Targets gebaut werden. Abgewählte stehen mit-davor, je mit der Knotenzahl kommentiert.domains.conf- welche Domains in welcher Reihenfolge gebaut werden.build.sh- das Buildsystem selbst: Gluon-Baum zurücksetzen, prepare aufrufen, Golden Tree und Worker-Overlays, Build-Schleife über Targets und Domains, Manifest signieren, Ergebnis samt diesem Verzeichnis ablegen.prepare.sh- wendet die Patches auspatches/in fester Reihenfolge an, in zwei Phasen vor und nach Gluonsmake update.prepare.log- das vollständige Log der Vorbereitung, einmal je Lauf und für alle Domains gleich: Zurücksetzen,make updatemit Gluons Patches, unsere Patches, Feeds und Downloads. Ohne das Kompilieren.build.log.gz- das vollständigemake-Log mitV=sdieser einen Domain über alle 20 Targets, rund 367 000 Zeilen. Zu beachten: Die erste gebaute Domain kompiliert alles, in jeder weiteren steht fast nur noch der Image-Zusammenbau.
Wie gebaut wird
Messbericht (englisch) mit Rohdaten und Auswertungsskript, einschließlich des Release-Laufs: firmware/docs/parallel-builds/README.md at de00b9dba382a347eab20bbc783fc7b1fd1627ff · Neanderfunk/firmware · GitHub
- Golden Tree. Der Gluon-Baum wird einmal vollständig gebaut, seriell mit vollem
-j:git reset,make clean,make update, unsere Patches, dann die erste Domain für alle Targets. Danach wird er nur noch gelesen. Darin liegt alles, was OpenWrt baut, Toolchain, Pakete, Kernel,build_dirundstaging_dirje Target. - Wiederverwendet wird er über einen Fingerprint der Eingaben: Gluon-Commit, Targetliste, Geräteauswahl, BROKEN, gcc- und libc-Version des Hosts, SHA-256 aller Patches und gemeinsamen Templatedateien. Passt er, entfallen prepare und Golden Tree ganz. Die Patches werden dann nicht einmal neu angewendet, weil schon neue mtimes OpenWrt zum Neubau brächten.
- Warum das überhaupt trägt: Ein Domainwechsel kompiliert kein einziges Paket, nur
package/gluon-sitehängt am Site-Verzeichnis. Die Kosten liegen je Image, nicht je Konfiguration, gemessen rund 94 min je Domain für 448 Images, also etwa 12,6 s je Image. - Worker auf Kernel-overlayfs, nicht fuse-overlayfs: lower ist der Golden Tree, per Bind-Mount festgehalten, upper ein privates Verzeichnis je Worker. Gemountet wird am Originalpfad des Baums, weil OpenWrt absolute Pfade in seine
.prepared-Stempel schreibt. - Rootless: zwei User-Namespaces (
unshare -Urm), Overlay mituserxattr, danach zurück auf die normale UID, weil OpenWrt nicht als root baut. Voraussetzungen: Linux ab 5.11, util-linux ab 2.38, bash ab 5.1, unter Ubuntu ab 23.10 zusätzlichkernel.apparmor_restrict_unprivileged_userns=0.build.shprobiert einen echten Overlay-Mount vorab und baut seriell weiter, wenn er scheitert. - Aufgeteilt wird nach Targets, nicht nach Domains. Ein Worker baut ein Target für alle Domains, danach wird sein upper gelöscht. Grund ist der Platz: Das Overlay wächst je Target (erste Domain 2,8 GB, jede weitere 0,2 GB), auf der Target-Achse rund 11 GB je Worker, auf der Domain-Achse wären es rund 62 GB.
- Kosten des Overlays, gemessen: Mounten 0,00 s, Verwerfen rund 3 s für 3 GB und 70 000 Dateien. Der Overhead war mit allen Geräten von ramips-mt7621 nicht messbar (241/219 s direkt gegen 238/224 s im Overlay); mit nur zwei Geräten, wo die Fixkosten dominieren, 2,6 %.
- Was die Parallelität bringt, gemessen: Nachfolgende Domains liefen mit sechs Workern 2,7 bis 2,8 mal schneller als seriell, nicht sechs mal. Jeder einzelne Schritt dauert unter Last etwa 1,7 mal so lang, mit neun Workern etwa 1,85 mal. Die Ursache ist eingegrenzt, aber nicht bewiesen, am ehesten der Takt unter Volllast.
- Der Release-Lauf: 86 Varianten mal 20 Targets, 1720 Schritte, 8 Worker in drei Wellen, 37 066 Images mit zusammen 325,7 GB. Von Null an rund 40 h, verteilt auf zwei Anläufe, weil der erste nach 14 der 20 Golden-Schritte angehalten wurde. Der zweite Anlauf lief 36 h 29 min: prepare 82 min, die restlichen Golden-Schritte 136 min, Parallelphase 32,4 h bei im Mittel 6,8 von 8 belegten Workern, Abschluss 29 min. Einen seriellen Vergleichslauf dieses Umfangs gibt es nicht. Hochgerechnet aus gemessenen Einzelkosten wären es rund 138 h, gerechnet für 22 Targets.
- Grenzen:
- fuse-overlayfs ist untauglich. OpenWrt macht
rm -rf root.orig-<target>und direkt danachcp -fpR; dort taucht das lower-Verzeichnis wieder auf undcpscheitert mit „File exists“. Kernel-overlayfs setzt das Whiteout richtig. - Kein overlayfs auf overlayfs. Im Container taugt
/tmpnicht als upper, ein bind-gemounteter ext4-Pfad schon. - Der Golden Tree selbst ist seriell und bei wenigen Domains der größte Posten. Ihn zu parallelisieren ist schwer, weil alle Targets in denselben Baum bauen.
- Die Parallelphase ist nie kürzer als das längste Target, bei uns ath79-generic, und die letzte Welle läuft mit wenigen Workern.
- Belegt ist das auf einem Host mit wenigen Läufen. Nur eine Konfiguration wurde wiederholt, Abweichung etwa 1 %. x86-64 war nicht Teil der Overlay-Messungen.
- fuse-overlayfs ist untauglich. OpenWrt macht
Wenn Ihr etwas davon nachnutzen wollt
Die Pakete gehen einzeln, das Buildsystem eher nicht.
- Feed in
site/modules, gepinnt auf den Stand aus diesem Release:PACKAGES_NEANDERFUNK_REPO=https://github.com/Neanderfunk/packages.git,_BRANCH=v2023.2.x,_COMMIT=afccfac4709d5a8627a3592f51cedc847c984f2c. Gebaut für Gluon v2023.2.x. - Paketnamen in
image-customization.lua.neanderfunk-setup-modebringt ein eigenes Theme mit, ohne'-gluon-config-mode-theme'bricht der Build ab. - CONFLICTS stehen je Paket oben, das Original muss aus der Paketliste. Ausnahme:
hotfixundmt7915-backlogdeklarieren im Release-Stand kein CONFLICTS gegenffac-mt7915-hotfixundffac-mt7915-backlog. Wer beides hat, bekommt zwei parallel laufende Watchdogs, ohne Fehlermeldung. Die ffac-Pakete also von Hand herausnehmen. - Patches:
patches/README.mdim Tag, Abschnitt „Einzelne Patches übernehmen“. Gruppe kopieren,patches/lib-patch.shdazu, Skript aus dem Gluon-Verzeichnis aufrufen, Phase beachten. - Nicht übernehmen:
kernel/revert-mips-tlb-uniquify(in v2023.2.x seit 22.09.2026 überflüssig),lowmem/limit-wireless-buffers(entfällt mit 2025.1),network/interface-role-migration21(unsere Migration von 2021) und alles unterbuild/(unsere opkg-Schlüssel). build.sh,targets.conf, Domains und Site-Templates sind auf uns zugeschnitten und nicht dafür gebaut, anderswo zu laufen.
Fragen gern hier im Thread.