Freifunk-Gateway aufsetzen/Batman-Gatewayselection

Aus Freifunk Franken
Version vom 28. August 2018, 08:29 Uhr von ChristianD (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „== B.A.T.M.A.N Gateway Selection == Mit der BATMAN Gateway Selection werden DHCP Anfragen die eigentlich Multicasts sind in Unicast zu einzelnen Gateways auf…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu:Navigation, Suche

B.A.T.M.A.N Gateway Selection

Mit der BATMAN Gateway Selection werden DHCP Anfragen die eigentlich Multicasts sind in Unicast zu einzelnen Gateways auf den Knoten umgewandelt. Damit der Knoten weiß welche DHCP Server im Netz sind, muss man als DHCP Server sich mit einer Bandbreite announcen. Über eine recht komplexe Formel anhand der announcend Bandbreite und der Metrik des Gateways wird nun entschieden welches Gateway ausgewählt wird.

Es kann z.b. eine feste Bandbreite announced werden

batctl -m bat6 gw_mode server 256000

oder ein Script verwendet werden das die Bandbreite dynamisch anhand der Auslastung berechnet:

ACHTUNG: Diese Schritte sollte erst aktiviert werden wenn sicher feststeht das:

  • Babel alle Routen übertragen hat, "ip r s table fff" gibt viele routen zu 10.x.x.x und 172.x.x.x aus
  • Der Server als Gateway in den KeyXchange eingetragen ist (muss man wissen, falls unbekannt bitte an die dev Liste fragen oder einen KeyXChange Admin)
  • Ein funktionierender DHCP Server läuft

Man sich also prinzipiell sicher ist, das der Server komplett fertig ist. Dies sollte der allerletzte Schritt sein wenn der Server eigentlich schon Online ist.

Wird das announcen vorher aktiviert, announced man sich im Batman als Gateway obwohl man keine IPs vergibt (oder nicht richtig routet). Dies führt dazu das Clients keine IPs oder kein Routing ins Freifunknetz bekommen was sehr unschön ist.

Ab Version 0.5.1 der Router Firmware ist die B.A.T.M.A.N Gateway Selection aktiviert worden. Der Router wählt sein bevorzugtes Gateway anhand der Verbindungsqualität und dessen noch verfügbaren Bandbreite aus und selektiert das GW für die Clients vor.

Die noch verfügbare Bandbreite muss vom Gateway an die Router annonciert werden. Hierfür muss man vorab die maximal zur Verfügung stehende Up- und Downloadkapazität des Gateways festlegen. Dies kann z.B. unter folgenden Gesichtspunkten geschehen:

  • Bandbreite der Netzanbindung (z.B. 100 Mbit/sec, gesplittet in 50 Mbit/sec up/down)
  • Freier Traffic des Hosters (z.B.: 5 TByte/Monat, entspricht einer Grundlast von 15 Mbit/sec, z.B. gesplittet in 5 Mbit/sec down, 10 Mbit/sec up)
  • Erfahrungswerten / eigenes Ermessen
  • Bandbreite, bei dem der Gateway Prozessor ausgelastet ist

Eventuell muss zuerst bc nachinstalliert werden, falls nicht vorhanden: apt-get install bc

Wir sollten nur die Bandbreite annoncieren, die tatsächlich noch frei ist: Also unsere Gesamtkapazität abzüglich der verwendeten Bandbreite. Hierfür kann man ein Skript verwenden, dass die aktuell verwendete (zeitlich gemittelte) Bandbreite vom Gateway ausliest, mit der Gesamtkapazität vergleicht und die noch freie Bandbreite an die GW Selection weitergibt.

Importieren des Skripts aus einer Vorlage: wget https://raw.githubusercontent.com/FreifunkFranken/configs/master/dyn_announce_gw_bw.sh -P /usr/local/bin/

Alternativ kann das Skript auch als leere Datei erstellt werden: touch /usr/local/bin/dyn_announce_gw_bw.sh

Wir machen das Skript ausführbar und öffnen die Datei: chmod +x /usr/local/bin/dyn_announce_gw_bw.sh

vi /usr/local/bin/dyn_announce_gw_bw.sh

Und Füllen dieses mit Inhalt oder editieren den importierten Inhalt:

#!/bin/bash
gwsel_lockfile="/tmp/gwsel_lockfile"  # lockfile to allow for low bandwidth settings 

if [ -z "$1" ]; then
        echo
        echo "usage: $0 <network-interface> <update_interval [sec]> <total BW up [Mbit/sec]> <total BW down [Mbit/sec]>"
        echo
        echo "e.g. $0 eth0 60 10 10"
        echo
        exit
fi

while true
do
    if [ ! -e ${gwsel_lockfile} ]; then    # lockfile not present
        # Bandwidth currently used (time averaged)
        R1=$(cat "/sys/class/net/$1/statistics/rx_bytes")
        T1=$(cat "/sys/class/net/$1/statistics/tx_bytes")
        sleep "$2"
        R2=$(cat "/sys/class/net/$1/statistics/rx_bytes")
        T2=$(cat "/sys/class/net/$1/statistics/tx_bytes")
        TkbitPS=$(echo "scale=0; ($T2 - $T1) / 1024 * 8 / $2" | bc -l)
        RkbitPS=$(echo "scale=0; ($R2 - $R1) / 1024 * 8 / $2" | bc -l)
#        echo "BW used      -- up $1: $TkbitPS kBit/s; down $1: $RkbitPS kBit/s"

        # Remaining bandwidth available; cut-off negative values
        Tavail_kbitPS=$(echo "scale=0; if (($3 * 1024 - $TkbitPS) >0) ($3 * 1024 - $TkbitPS) else 0" | bc -l)
        Ravail_kbitPS=$(echo "scale=0; if (($4 * 1024 - $RkbitPS) >0) ($4 * 1024 - $RkbitPS) else 0" | bc -l)
#        echo "BW available -- up $1: $Tavail_kbitPS kBit/s; down $1: $Ravail_kbitPS kBit/s"
    else                                     # lockfile present
        Tavail_kbitPS=0
        Ravail_kbitPS=0
        sleep "$2"
    fi

    if [ `pidof dhcpd` != "" ]; then
        for bat in /sys/class/net/bat*; do
            iface=${bat##*/}
            batctl -m $iface gw_mode server "${Ravail_kbitPS}kbit/${Tavail_kbitPS}kbit"
        done
    else
        for bat in /sys/class/net/bat*; do
            iface=${bat##*/}
            batctl -m $iface gw_mode off
        done
        rm /var/run/dhcpd.pid >/dev/null 2>&1
        /etc/init.d/isc-dhcp-server restart
    fi
done

Achtung: Wenn man ein bat Interface hat, das nicht Gateway ist muss man dies aus der letzten Schleife ausschließen da sonst dort ebenfalls die Gatewayselection aktiviert wird und man eine Bandbreite announced.

Das Skript übernimmt als Parameter:

  • Netzwerkinterface, das es zu überwachen gilt (i.d.R. eth0)
  • Updateintervall in Sekunden, in denen ein neuer Wert durch die B.A.T.M.A.N GW Selection annonciert wird (Um nicht allzu volatil auf Kurzzeitschwankungen im Durchsatz zu reagieren empfiehlt sich ein Mittelungsintervall zwischen 30 und 120 Sekunden)
  • Upload Kapazität in Mbit/sec (insgesamt zur Verfügung stehend s.o.)
  • Download Kapazität in Mbit/sec (insgesamt zur Verfügung stehend s.o.)

Bei Existenz des oben definierten Lockfiles "/tmp/gwsel_lockfile", annonciert das Gateway nur noch eine minimale Bandbreite. Dies dient dazu, möglichst keine neuen Clients zu akquirieren, z.B. weil gerade der VPN Tunnel ausgefallen ist und nur noch eine Babel Defaultroute mit geringer Bandbreite verfügbar ist.

Ein Aufruf für eth0 als Interface, ein Update alle 5 Minuten, 12 Mbit/sec maximaler Upload und 10 Mbit/sec maximaler Download wäre z.B.: /usr/local/bin/dyn_announce_gw_bw.sh eth0 300 12 10

Bei Debian 9 muss das Interface angepasst werden. Als Beispiel: /usr/local/bin/dyn_announce_gw_bw.sh ens18 300 12 10

Um die Gateway Selection beim Systemsstart zu aktivieren, können wir das Skript z.B. in rc.local aufrufen: vi /etc/rc.local

um dort, leicht zeitverzögert, o.a. Befehl einzupflegen, wobei die Parametrisierung noch Gateway-spezifisch angepasst werden muss:

.
.
.
#enable batman GW selection with 15 seconds delay
(sleep 15; /usr/local/bin/dyn_announce_gw_bw.sh eth0 300 12 10) &
.
.
.


auf den Routern kann der vorselektierte Gateway mit

batctl gwl

angeguckt werden.

Gatewayselection abschalten wenn Lease voll

Wenn man mit den dhcp Leases am Limit ist, sollte das Script angepasst werden das es die Gatewayselection abschaltet wenn nur noch wenige Leases offen sind. Dazu muss vor den letzten "done" folgender Teil hinzugefügt werden, Beispiel für Hood Erlangen auf nue2-gw1. Das grep muss auf die entsprechende IP Range angepasst werden und der IF Vergleich auf die maximale Menge an Leases, man sollte dabei noch einen Puffer offen halten.

# Erlangen schalten wir die Gatewayselection zur Sicherheit bei 450 leases ab, damit noch etwas Puffer nach oben ist! 
leasecount=$(/usr/sbin/dhcp-lease-list --parsable --lease /var/lib/dhcp/dhcpd.leases 2>&1 | grep "10.50.6" | wc -l) 
if [ $leasecount -gt 450 ] 
then 
batctl -m bat1 gw_mode off 
fi