Opennet Firmware
 Alle Dateien Funktionen Variablen Gruppen Seiten
olsr.sh
gehe zur Dokumentation dieser Datei
1 ## @defgroup olsr OLSR
2 ## @brief Konfiguration und Abfrage des OLSR-Diensts. Einlesen von Diensten announciert via olsrd-nameservice.
3 # Beginn der Doku-Gruppe
4 ## @{
5 
6 OLSR_NAMESERVICE_SERVICE_TRIGGER=/usr/sbin/on_nameservice_trigger
7 SERVICES_FILE=/var/run/services_olsr
8 OLSR_SERVICE_UPDATE_MARKER=/var/run/waiting_for_olsr_services_update
9 OLSR_HTTP_PORT=8080
10 # suche einen passenden nc-Kandidaten
11 # Die busybox-netcat-Implementation ist nicht geeignet, da ihr der "-w"-Schalter fehlt.
12 # Die Filterung erfolgt via "tail" anstelle von "head", um keine "SIGPIPE"-Fehler in cron-Jobs auszuloesen.
13 NETCAT_BIN=$( (echo nc; which nc ncat) | tail -1)
14 
15 
16 # uebertrage die Netzwerke, die derzeit der Zone "opennet" zugeordnet sind, in die olsr-Konfiguration
17 # Anschliessend wird olsr und die firewall neugestartet.
18 # Dieses Skript sollte via hotplug bei Aenderungen der Netzwerkkonfiguration ausgefuehrt werden.
19 update_olsr_interfaces() {
20  trap "error_trap update_olsr_interfaces '$*'" $GUARD_TRAPS
21  uci set -q "olsrd.@Interface[0].interface=$(get_zone_interfaces "$ZONE_MESH")"
22  apply_changes olsrd
23 }
24 
25 
26 # Pruefe das angegebene olsrd-Plugin aktiv ist und aktiviere es, falls dies nicht der Fall sein sollte.
27 # Das Ergebnis ist die uci-Sektion (z.B. "olsrd.@LoadPlugin[1]") als String.
28 get_and_enable_olsrd_library_uci_prefix() {
29  trap "error_trap get_and_enable_olsrd_library_uci_prefix '$*'" $GUARD_TRAPS
30  local new_section
31  local lib_file
32  local uci_prefix=
33  local library=olsrd_$1
34  local current=$(find_all_uci_sections olsrd LoadPlugin | while read uci_prefix; do
35  # die Bibliothek beginnt mit dem Namen - danach folgt die genaue Versionsnummer
36  uci_get "${uci_prefix}.library" | grep -q "^$library\.so" && echo "$uci_prefix"
37  done | tail -1)
38  if [ -n "$current" ]; then
39  uci_prefix=$(echo "$current" | cut -f 1 -d = | sed 's/\.library$//')
40  else
41  lib_file=$(find /usr/lib -type f -name "${library}.*")
42  if [ -z "$lib_file" ]; then
43  msg_info "FATAL ERROR: Failed to find olsrd '$library' plugin. Some Opennet services will fail."
44  trap "" $GUARD_TRAPS && return 1
45  fi
46  new_section=$(uci add olsrd LoadPlugin)
47  uci_prefix=olsrd.${new_section}
48  uci set "${uci_prefix}.library=$(basename "$lib_file")"
49  fi
50  # Plugin aktivieren; Praefix ausgeben
51  if [ -n "$uci_prefix" ]; then
52  # moeglicherweise vorhandenen 'ignore'-Parameter abschalten
53  uci_is_true "$(uci_get "${uci_prefix}.ignore" 0)" && uci set "${uci_prefix}.ignore=0"
54  echo "$uci_prefix"
55  fi
56  return 0
57 }
58 
59 
60 enable_ondataservice() {
61  trap "error_trap enable_ondataservice '$*'" $GUARD_TRAPS
62  local uci_prefix
63 
64  # schon vorhanden? Unberuehrt lassen ...
65  [ -n "$(uci show olsrd | grep ondataservice)" ] && return
66 
67  # add and activate ondataservice plugin
68  uci_prefix=$(get_and_enable_olsrd_library_uci_prefix "ondataservice_light")
69  uci set "${uci_prefix}.interval=10800"
70  uci set "${uci_prefix}.inc_interval=5"
71  uci set "${uci_prefix}.database=/tmp/database.json"
72 }
73 
74 
75 enable_nameservice() {
76  trap "error_trap enable_nameservice '$*'" $GUARD_TRAPS
77  local current_trigger
78  local uci_prefix
79 
80  # fuer NTP, DNS und die Gateway-Auswahl benoetigen wir das nameservice-Plugin
81  local uci_prefix=$(get_and_enable_olsrd_library_uci_prefix "nameservice")
82  if [ -z "$uci_prefix" ]; then
83  msg_info "Failed to find olsrd_nameservice plugin"
84  else
85  # Option 'services-change-script' setzen
86  current_trigger=$(uci_get "${uci_prefix}.services_change_script" || true)
87  [ -n "$current_trigger" ] && [ "$current_trigger" != "$OLSR_NAMESERVICE_SERVICE_TRIGGER" ] && \
88  msg_info "WARNING: overwriting 'services-change-script' option of olsrd nameservice plugin with custom value. You should place a script below /etc/olsrd/nameservice.d/ instead."
89  uci set "${uci_prefix}.services_change_script=$OLSR_NAMESERVICE_SERVICE_TRIGGER"
90  fi
91 }
92 
93 
94 # Setze die Einstellung MainIP in der olsr-Konfiguration:
95 # Quelle 1: der erste Parameter
96 # Quelle 2: on-core.settings.on_id
97 # Quelle 3: die vorkonfigurierte Standard-IP
98 # Anschliessend ist "apply_changes olsrd" erforderlich.
99 olsr_set_main_ip() {
100  trap "error_trap olsr_set_main_ip '$*'" $GUARD_TRAPS
101  # Auslesen der aktuellen, bzw. der Standard-IP
102  local main_ip
103  if [ $# -eq 1 ]; then
104  main_ip=$1
105  else
106  main_ip=$(get_main_ip)
107  fi
108 
109  # die Main-IP ist die erste IP dieses Geraets
110  uci set "olsrd.@olsrd[0].MainIp=$main_ip"
111 }
112 
113 
114 # Ermittle welche olsr-Module konfiguriert sind, ohne dass die Library vorhanden ist.
115 # Deaktiviere diese Module - fuer ein sauberes boot-Log.
116 disable_missing_olsr_modules() {
117  trap "error_trap disable_missing_olsr_modules '$*'" $GUARD_TRAPS
118  local libpath=/usr/lib
119  local libline
120  local libfile
121  local uci_prefix
122  local ignore
123  uci show olsrd | grep "^olsrd.@LoadPlugin\[[0-9]\+\].library=" | while read libline; do
124  uci_prefix=$(echo "$libline" | cut -f 1,2 -d .)
125  libfile=$(echo "$libline" | cut -f 2- -d =)
126  ignore=$(uci_get "${uci_prefix}.ignore")
127  [ -n "$ignore" ] && uci_is_true "$ignore" && continue
128  if [ ! -e "$libpath/$libfile" ]; then
129  msg_info "Disabling missing olsr module '$libfile'"
130  uci set "${uci_prefix}.ignore=1"
131  fi
132  done
133  apply_changes olsrd
134 }
135 
136 
137 ## @fn olsr_sync_routing_tables()
138 ## @brief Synchronisiere die olsrd-Routingtabellen-Konfiguration mit den iproute-Routingtabellennummern.
139 ## @details Im Konfliktfall wird die olsrd-Konfiguration an die iproute-Konfiguration angepasst.
141  trap "error_trap olsr_sync_routing_tables '$*'" $GUARD_TRAPS
142  local olsr_name
143  local iproute_name
144  local olsr_id
145  local iproute_id
146  while read olsr_name iproute_name; do
147  olsr_id=$(uci_get "olsrd.@olsrd[0].$olsr_name")
148  iproute_id=$(get_routing_table_id "$iproute_name")
149  # beide sind gesetzt und identisch? Alles ok ...
150  [ -n "$olsr_id" -a "$olsr_id" = "$iproute_id" ] && continue
151  # eventuell Tabelle erzeugen, falls sie noch nicht existiert
152  [ -z "$iproute_id" ] && iproute_id=$(add_routing_table "$iproute_name")
153  # olsr passt sich im Zweifel der iproute-Nummer an
154  [ "$olsr_id" != "$iproute_id" ] && uci set "olsrd.@olsrd[0].$olsr_name=$iproute_id" || true
155  done << EOF
156 RtTable $ROUTING_TABLE_MESH
157 RtTableDefault $ROUTING_TABLE_MESH_DEFAULT
158 EOF
159  apply_changes olsrd
160 }
161 
162 
163 # Einlesen eines olsrd-Nameservice-Service.
164 # Details zum Eingabe- und Ausgabeformat: siehe "get_olsr_services".
165 parse_olsr_service_definitions() {
166  trap "error_trap parse_olsr_service_definitions '$*'" $GUARD_TRAPS
167  local url
168  local proto
169  local service
170  local details
171  local scheme
172  local host
173  local port
174  local path
175  # verwende "|" und Leerzeichen als Separatoren
176  IFS='| '
177  while read url proto service details; do
178  scheme=$(echo "$url" | cut -f 1 -d :)
179  host=$(echo "$url" | cut -f 3 -d / | cut -f 1 -d :)
180  port=$(echo "$url" | cut -f 3 -d / | cut -f 2 -d :)
181  path=/$(echo "$url" | cut -f 4- -d /)
182  # Firmware-Versionen bis v0.4-5 veroeffentlichten folgendes Format:
183  # http://192.168.0.40:8080|tcp|ugw upload:50 download:15300 ping:23
184  [ "$scheme" = "http" -a "$port" = "8080" -a "$proto" = "tcp" ] && \
185  [ "$service" = "gw" -o "$service" = "ugw" ] && scheme=openvpn && port=1600 && proto=udp && service=gw
186  echo -e "$scheme\t$host\t$port\t$path\t$proto\t$service\t$details"
187  done
188 }
189 
190 
191 # Parse die olsr-Service-Datei
192 # Die Service-Datei enthaelt Zeilen streng definierter Form (durchgesetzt vom nameservice-Plugin).
193 # Beispielhafte Eintraege:
194 # http://192.168.0.15:8080|tcp|ugw upload:3 download:490 ping:108 #192.168.2.15
195 # dns://192.168.10.4:53|udp|dns #192.168.10.4
196 # Parameter: service-Type (z.B. "gw", "dns", "ntp", "mesh")
197 # Ergebnis (tab-separiert):
198 # SCHEME IP PORT PATH PROTO SERVICE DETAILS
199 # Im Fall von "http://192.168.0.15:8080|tcp|ugw upload:3 download:490 ping:108" entspricht dies:
200 # http 192.168.0.15 8080 tcp ugw upload:3 download:490 ping:108
201 get_olsr_services() {
202  trap "error_trap get_olsr_services '$*'" $GUARD_TRAPS
203  local filter_service
204  local url
205  local proto
206  local service
207  local details
208  local scheme
209  local host
210  local port
211  local path
212  [ ! -e "$SERVICES_FILE" ] && msg_debug "no olsr-services file found: $SERVICES_FILE" && return 0
213  # remove trailing commentary (containing the service's source IP address)
214  grep "^[^#]" "$SERVICES_FILE" | \
215  sed 's/[\t ]\+#[^#]\+//' | \
216  parse_olsr_service_definitions | \
217  # filtere die Ergebnisse nach einem Service-Typ, falls selbiger als erster Parameter angegeben wurde
218  if [ "$#" -ge 1 ]; then awk "{ if (\$6 == \"$1\") print \$0; }"; else cat -; fi
219  return 0
220 }
221 
222 
223 update_olsr_services() {
224  trap "error_trap update_olsr_services '$*'" $GUARD_TRAPS
225  local scheme
226  local ip
227  local port
228  local path
229  local proto
230  local service
231  local details
232  local timestamp
233  local service_name
234  local min_timestamp=$(($(get_time_minute) - $(get_on_core_default "service_expire_minutes")))
235  # aktuell verbreitete Dienste benachrichtigen
236  get_olsr_services | while read scheme ip port path proto service details; do
237  notify_service "$service" "$scheme" "$ip" "$port" "$proto" "$path" "$details" "olsr"
238  done
239  # veraltete Dienste entfernen
240  get_services | filter_services_by_value "source" "olsr" | while read service_name; do
241  timestamp=$(get_service_value "$service_name" "timestamp" 0)
242  # der Service ist zu lange nicht aktualisiert worden
243  [ "$timestamp" -lt "$min_timestamp" ] && delete_service "$service_name" || true
244  done
245  # aktualisiere DNS- und NTP-Dienste
246  apply_changes on-core
247 }
248 
249 
250 schedule_olsrd_service_update() {
251  touch "$OLSR_SERVICE_UPDATE_MARKER"
252 }
253 
254 
255 run_scheduled_olsrd_service_updates() {
256  [ -e "$OLSR_SERVICE_UPDATE_MARKER" ] || return 0
257  # zuerst loeschen - sonst verpassen wir eventuell ein Ereignis
258  rm -f "$OLSR_SERVICE_UPDATE_MARKER"
259  update_olsr_services
260 }
261 
262 
263 ## @fn request_olsrd_txtinfo()
264 ## @brief Sende eine Anfrage an das txtinfo-Interface von olsrd
265 ## @param request Der zu sende Request-Pfad (z.B. "links" oder "neighbours")
266 ## @details Bei Problemen mit dem Verbindungsaufbau erscheint ein Hinweis im syslog.
268  local request="$1"
269  echo "/$request" | "$NETCAT_BIN" -w 2 localhost 2006 2>/dev/null || msg_info "get_olsrd_txtinfo: olsrd is not running"
270 }
271 
272 # Ende der Doku-Gruppe
273 ## @}