[[Vorlage(Getestet, focal)]]
{{{#!vorlage Wissen
[:Programme_starten: Starten von Programmen]
[:Terminal: Ein Terminal öffnen]
[:mit Root-Rechten arbeiten:]
}}}

[[Inhaltsverzeichnis()]]

'''networkd-dispatcher''' ist ein Zusatzprogramm für [:systemd/networkd:systemd-networkd]. Während man bei systemd-networkd die Konfiguration der Netzwerkschnittstellen ausschließlich über Deklarationen vornimmt, erlaubt networkd-dispatcher auf Zustandsänderungen bei den Netzwerkschnittstellen zu reagieren und Programme zu starten.

Damit ist networkd-dispatcher für systemd-networkd das Pendant zu [:NetworkManager/Dispatcher:nm-dispatcher] für [:NetworkManager:] und den Skripten in '''/etc/network/if-*.d/''' für [:interfaces:ifupdown].

= Installation =
Das Paket '''networkd-dispatcher''' ist bei jedem Ubuntu-System als Standardkomponente bereits installiert. Bei Bedarf kann es so installiert werden:

{{{#!vorlage Paketinstallation
networkd-dispatcher
}}}

= Arbeitsweise =
Die beiden [:/systemd/Units:systemd-Units] '''systemd-networkd.service''' und '''networkd-dispatcher.service''' müssen aktiv sein. Kontrolle[2]:

{{{#!vorlage Befehl
systemctl status systemd-networkd.service
systemctl status networkd-dispatcher.service
}}}

Sobald systemd-networkd bei einer Schnittstelle einen Zustandswechsel erkennt, startet es networkd-dispatcher und dieser startet die Programme in dem Verzeichnis, welches zu dem neuen Zustand der Schnittstelle gehört. Dies funktioniert auch, wenn systemd-networkd die Schnittstelle nicht selber konfiguriert hat.

= Konfiguration =
networkd-dispatcher startet Programme in Unterverzeichnissen von

 * '''/etc/networkd-dispatcher''' und
 * '''/usr/lib/networkd-dispatcher''' 

Dabei überlagern Dateien unter '''/etc''' gleichnamige Dateien unter '''/usr'''. Man sollte eigene Dateien vorzugsweise unter '''/etc''' ablegen und '''/usr''' den Distributionen vorbehalten.

Es werden diese Unterverzeichnisse berücksichtigt:

{{{#!vorlage Befehl
ls /etc/networkd-dispatcher/
}}}

{{{carrier.d  degraded.d  dormant.d  no-carrier.d  off.d  routable.d }}}

Der Name des Unterverzeichnisses entspricht natürlich dem neuen Zustand der Schnittstelle.

{{{#!vorlage Tabelle
<-2 tableclass="zebra_start3" rowclass="titel" :> Zustände von Schnittstellen
+++
<rowclass="kopf" :> Zustand
<:>Bedeutung
+++
off
Schnittstelle ist nicht betriebsbereit.
+++
no-carrier
Das Schnittstellen-Gerät ist betriebsbereit, aber es ist kein Transport auf Netzwerkebene L2 aktiv, z.B. weil bei Ethernet kein Kabel gesteckt ist oder bei WLAN keine Mitgliedschaft zu einem Funknetz besteht.
+++
carrier
Die Schnittstelle ist betriebsbereit und es können auf L2 Pakete empfangen und gesendet werden, jedoch können keine IP-Pakete ausgetauscht werden.
+++
dormant
Die Schnittstelle ist grundsätzlich betriebsbereit wie bei `carrier`, jedoch momentan untätig (eingeschlafen).
+++
degraded
IP-Pakete können über die Schnittstelle empfangen, jedoch nicht oder nur eingeschränkt gesendet werden, weil der Schnittstelle keine global weiterleitbare IP-Adresse zugeordnet wurde.
+++
routeable
IP-Pakete können über die Schnittstelle empfangen und gesendet werden.
}}}

Die Konfigurationsverzeichnisse müssen `root` gehören und niemand außer `root` darf in diese Ordner schreiben können.


= Details zu den Skripten =
Als Programm kann man beispielsweise eine ausführbare Textdatei mit einem Shell-Skript in das passende Verzeichnis legen, und dies ist auch als Regelfall so vorgesehen. Die Datei muss `root` gehören und niemand außer `root` darf sie beschreiben dürfen.

Die Programme werden mit diesen Umständen ausgeführt:
 1. Sie werden als `root` ausgeführt.
 1. Bei mehreren Dateien in einem Verzeichnis kann man die Reihenfolge der Ausführung nicht steuern.
 1. Als Arbeitsverzeichnis ist die Wurzel des Dateibaums '''/''' gesetzt.
 1. Es gibt keine Argumente auf der „Kommandozeile“. `"$0"` ist der Dateiname.
 1. `stdin` ist geschlossen, `stdout` ist unbekannt und `stderr` schreibt in das Systemlog.
 1. Sie laufen in einer Programmumgebung mit diesen Variablen: \\
{{{#!vorlage Befehl
OperationalState=routable
IP6_ADDRS=
NOTIFY_SOCKET=/run/systemd/notify
JOURNAL_STREAM=9:18243
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
INVOCATION_ID=e1ed182dc4f34afca8368e7a7f677da4
LANG=de_DE.UTF-8
AdministrativeState=unmanaged
IP_ADDRS=
networkd_dispatcher_args=--run-startup-triggers
IFACE=radio
PWD=/
ADDR=
STATE=routable
}}} Die Werte sind natürlich nur Beispiele. Man kann sich nicht darauf verlassen, dass alle Variablen mit vernünftigen Werten versehen sind und es gibt situationsabhängig noch weitere Umgebungsvariablen. Bei einer WLAN-Schnittstelle wurde z.B. die richtige SSID als ESSID übergeben.

 * Die wichtigste Variable ist `IFACE`. Hier steht, um welche Schnittstelle es sich handelt.
 * Die Variablen `OperationalState` und `AdministrativeState` entsprechen wohl (d.h. nach bisherigen Erfahrungen) den Ausgaben von [:systemd/networkd/#Dienstprogramm-networkctl:networkctl].
 * Die Variable `STATE` entspricht wohl dem Verzeichnis bzw. dem neuen Zustand der Schnittstelle.


= Beispiele =
== Logger ==
Man kann dieses Skript als '''/etc/networkd-dispatcher/routable.d/00-logger''' ablegen, ausführbar machen und in den anderen Unterverzeichnissen von '''/etc/networkd-dispatcher/''' jeweils darauf verlinken:
{{{
#! /bin/bash -e

LOG ()	{ echo ${*:- } ;} >&2

LOG IFACE=$IFACE $OperationalState
}}}

Man erhällt dann im Systemlog Meldungen, wann immer sich der Zustand einer Schnittstelle ändert. Das kann bei der Fehlerdiagnose helfen:

{{{#!vorlage Befehl
journalctl -b -u networkd-dispatcher.service
}}}

Beispeilausgabe (gekürzt):
{{{
Mai 04 10:01:29 networkd-dispatcher[95390]: IFACE=eth0 routable
Mai 04 10:04:37 networkd-dispatcher[95577]: IFACE=eth0 off
Mai 04 10:04:38 networkd-dispatcher[95580]: IFACE=WLAN routable
}}}

= Links =

 * [http://manpages.ubuntu.com/manpages/focal/man8/networkd-dispatcher.8.html Manpage zu networkd-dispatcher] {en} – bei [:Focal_Fossa:Focal Fossa]
 * [:systemd:]
 * [:systemd/networkd:]
 * [:systemd/Units:]

# tag: System, systemd, Netzwerk