Babel und dnsmasq in unsere firmware: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
|||
(31 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
{{Outdated}} | |||
[[Kategorie:Scripte]] | |||
'''Mittlerweile sind babeld und dnsmasq in der offiziellen Firmware. Siehe auch [[Gatewayfirmware]]''' | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: auto"> | |||
__TOC__ | __TOC__ | ||
Um aus einem Router ein Gateway zu machen, muss in die Firmware Babel und dnsmasq mit eingebaut werden. Dieses Patch baut diese 2 Programme plain mit ein, es müssen danach noch diverse Konfigurationen und Routingparameter gesetzt werden. Es kann sich dazu ganz grob an die Anleitung zum [[Freifunk-Gateway_aufsetzen|Gateway aufsetzen]] gehalten werden. | |||
[[ | |||
Achtung! Man sollte sich bei solchen Experiementen immer gut überlegen wie man den Router noch erreichen kann, man kann sich relativ leicht selbst komplett aussperren. | |||
Achtung | Achtung Patch ist nur für ar71xx muss u.U. auch für andere Hardware manuell angepasst werden! | ||
<pre> | <pre> | ||
From | From d2db4645831742269a391fddbedad8d8a46ad3c6 Mon Sep 17 00:00:00 2001 | ||
From: Christian Dresel <fff@chrisi01.de> | From: Christian Dresel <fff@chrisi01.de> | ||
Date: | Date: Sun, 18 Dec 2016 17:44:20 +0100 | ||
Subject: [PATCH] Add | Subject: [PATCH] Add Babel and dnsmasq | ||
Signed-off-by: Christian Dresel <fff@chrisi01.de> | |||
--- | --- | ||
bsp/ar71xx/.config | bsp/ar71xx/.config | 2 +- | ||
buildscript | buildscript | 2 +- | ||
2 files changed, 2 insertions(+), 2 deletions(-) | |||
diff --git a/bsp/ar71xx/.config b/bsp/ar71xx/.config | diff --git a/bsp/ar71xx/.config b/bsp/ar71xx/.config | ||
index | index e827685..4abc536 100644 | ||
--- a/bsp/ar71xx/.config | --- a/bsp/ar71xx/.config | ||
+++ b/bsp/ar71xx/.config | +++ b/bsp/ar71xx/.config | ||
@@ - | @@ -16,7 +16,7 @@ CONFIG_CLEAN_IPKG=y | ||
# CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC is not set | # CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC is not set | ||
# CONFIG_FASTD_ENABLE_METHOD_GENERIC_GMAC is not set | # CONFIG_FASTD_ENABLE_METHOD_GENERIC_GMAC is not set | ||
# CONFIG_PACKAGE_ALFRED_VIS is not set | # CONFIG_PACKAGE_ALFRED_VIS is not set | ||
-# CONFIG_PACKAGE_dnsmasq is not set | -# CONFIG_PACKAGE_dnsmasq is not set | ||
+CONFIG_PACKAGE_babeld=y | |||
# CONFIG_PACKAGE_firewall is not set | # CONFIG_PACKAGE_firewall is not set | ||
CONFIG_PACKAGE_gpioctl-sysfs=y | CONFIG_PACKAGE_gpioctl-sysfs=y | ||
CONFIG_PACKAGE_kmod-ifb=y | CONFIG_PACKAGE_kmod-ifb=y | ||
diff --git a/buildscript b/buildscript | diff --git a/buildscript b/buildscript | ||
index | index 25cf291..90af8a9 100755 | ||
--- a/buildscript | --- a/buildscript | ||
+++ b/buildscript | +++ b/buildscript | ||
@@ - | @@ -37,7 +37,7 @@ GLUON_PKGS="kmod-batman-adv-legacy micrond simple-tc uradvd" | ||
ROUTING=(routing | |||
https://github.com/openwrt-routing/packages.git | |||
e870c3373eea80df852d42fac3f40aaffd7a0f58) | |||
-ROUTING_PKGS="alfred" | |||
+ROUTING_PKGS="alfred babeld" | |||
FFF=(fff) | FFF=(fff) | ||
FFF_PKGS="-a" | FFF_PKGS="-a" | ||
-- | -- | ||
2.1.4 | 2.1.4 | ||
</pre> | </pre> | ||
das ganze liegt fertig kompiliert hier: | |||
http://fff-gw-cd1.fff.community/dev/babeld/ | |||
(!!ACHTUNG!! ungetestet!! Verwendung auf eigene Gefahr!) | |||
Ganz zwingend sollte nach dem flashen zuerst komplett unterbunden werden, das er noch eine BatmanVPN Verbindung aufbaut: | |||
<pre> | |||
rm /usr/sbin/vpn-select | |||
rm /usr/lib/micron.d/vpn-select | |||
rm /usr/lib/micron.d/fff-sysupgrade | |||
/etc/init.d/micrond restart | |||
</pre> | |||
Folgendes muss grundsätzlich danach noch getan werden damit er als Gateway verwendet werden kann: | Folgendes muss grundsätzlich danach noch getan werden damit er als Gateway verwendet werden kann: | ||
Zeile 211: | Zeile 81: | ||
bind any:1234; # UDP Port 1234 auf allen Interfaces | bind any:1234; # UDP Port 1234 auf allen Interfaces | ||
mode tun; | mode tun; | ||
interface " | interface "fffbabelVPN"; | ||
method "null"; | method "null"; | ||
mtu 1426; | mtu 1426; | ||
Zeile 217: | Zeile 87: | ||
#include peers from "peers"; | #include peers from "peers"; | ||
include peer "/etc/fastd/fff. | include peer "/etc/fastd/fff.babel/peers/router1"; | ||
on up " | on up " | ||
ip link set up $INTERFACE | ip link set up $INTERFACE | ||
Zeile 225: | Zeile 95: | ||
<pre> | <pre> | ||
fff-gw-cd1 /etc/fastd/fff. | fff-gw-cd1 /etc/fastd/fff.babel/peers # cat router1 | ||
key "PUBLIC KEY DES ROUTERS"; | key "PUBLIC KEY DES ROUTERS"; | ||
</pre> | </pre> | ||
Zeile 243: | Zeile 113: | ||
secret "EIGENER SECRET KEY"; | secret "EIGENER SECRET KEY"; | ||
on up " | on up " | ||
#/ | ip link set up fffgwcd1VPN | ||
ip address add 10.83.252.xx/32 dev $INTERFACE # eigene IP | |||
ip -6 addr add fe80::c11:xxxx dev $INTERFACE # gefakte Locallink | |||
ip rule add from 10.0.0.0/8 table fff prio 20 | |||
ip rule add to 10.0.0.0/8 table fff prio 20 | |||
ip route add 10.50.xxx.1/32 dev br-mesh proto static table fff # eigene Gatewayip der Hood | |||
ip route add 10.50.xxx.0/24 dev br-mesh proto static table fff # Range die per dhcp vergeben wird | |||
"; | "; | ||
secure handshakes no; | secure handshakes no; | ||
</pre> | </pre> | ||
Ebenfalls muss fastd noch in den Autostart | Ebenfalls muss fastd noch in den Autostart (/etc/rc.local -> "fastd -c /etc/fastd/CONFIGFILE &") das "&" am Ende keinesfalls vergessen! Sonst wird ab hier die File nicht mehr weiter ausgeführt und der ganze rest danach fehlt!! | ||
2 wertvolle Links die bei fastd extrem weiterhelfen: | 2 wertvolle Links die bei fastd extrem weiterhelfen: | ||
Zeile 271: | Zeile 142: | ||
</pre> | </pre> | ||
Weiterhin müssen folgende Regeln angelegt werden ( | Weiterhin müssen folgende Regeln angelegt werden falls dies noch nicht in den VPN Sachen gemacht wird (Router ohne VPN müssen es wo anders machen!): | ||
<pre> | <pre> | ||
Zeile 279: | Zeile 150: | ||
</pre> | </pre> | ||
das Interface br-mesh muss noch die Gateway IP bekommen: | falls man dies in der /etc/rc.local macht, aufpassen das jede Zeile mit & abgeschlossen wird, da er sonst u.U. beim booten hängen bleibt und die File nicht bis zu Ende ausführt, ganz ekliges Zeug... | ||
Das Interface br-mesh muss noch die Gateway IP bekommen: | |||
/etc/config/network | /etc/config/network | ||
<pre> | <pre> | ||
... | |||
config interface 'mesh' | config interface 'mesh' | ||
option type 'bridge' | option type 'bridge' | ||
option auto '1' | option auto '1' | ||
option macaddr '30:b5:c2: | option macaddr '30:b5:c2:XXXXXX' | ||
list ip6addr 'fdff:0::30b5:c20e: | list ip6addr 'fdff:0::30b5:c20e:XXXXX/64' | ||
list ip6addr 'fdff:0::1/64' | list ip6addr 'fdff:0::1/64' | ||
list ip6addr 'fdff:0::32b5:c2ff:fe0e: | list ip6addr 'fdff:0::32b5:c2ff:fe0e:XXXXX/64' | ||
option ipaddr '10.50. | option ipaddr '10.50.X.1' | ||
option netmask '255.255. | option netmask '255.255.X.0' | ||
option proto 'static' | option proto 'static' | ||
option ifname 'eth0.1 bat0' | option ifname 'eth0.1 bat0' | ||
... | |||
</pre> | </pre> | ||
ToDo: IPv6 muss auch angepasst werden! | ToDo: IPv6 muss auch angepasst werden! | ||
== | == dnsmasq konfigurieren == | ||
ebenfalls muss noch dnsmasq konfiguriert werden: | |||
/etc/dnsmasq.conf | |||
<pre> | <pre> | ||
dhcp-range=10.50.131.1,10.50.131.127,255.255.254.0,1h | |||
dhcp-option=3,10.50.130.1 | |||
dhcp-option=option:dns-server,10.83.252.11,10.50.40.10,10.50.252.0 | |||
log-queries | |||
</pre> | |||
natürlich die IP Adressen entsprechend anpassen der Syntax lautet: | |||
<pre> | |||
dhcp-range=DHCP_RANGE_START,DHCP_RANGE_ENDE,SUBNETZMASK,LEASETIME | |||
dhcp-option=3,STANDARTGATEWAYIP | |||
dhcp-option=option:dns-server,DNSSERVER | |||
log-queries | |||
</pre> | |||
Danach den Router neu starten, dnsmasq neu starten hat hier irgendwie nicht geholfen! | |||
== Babel konfigureren == | |||
# | die Datei /etc/babeld.conf öffnen, alles löschen und dies einfügen: | ||
<pre> | |||
# For more information about this configuration file, refer to | |||
# babeld(8) | |||
interface IF1 wired true max-rtt-penalty 128 | |||
interface IF2 wired true max-rtt-penalty 128 | |||
#... einfach weiterführen für mehr Interfaces. | |||
export-table 10 | |||
import-table 10 | |||
# redistribute IPv4 default route into babel | |||
## redistribute local ip 0.0.0.0/0 le 0 metric 128 | |||
# Babel refuses to redistribute routes with a protocol number of "boot"; | |||
# this is standard practice, and means that you cannot easily | |||
# redistribute the default route installed by dhcp. It is however | |||
# possible to redistribute such route by explicitly specifying "proto 3" | |||
# on the redistribute line. | |||
## redistribute ip 0.0.0.0/0 le 0 proto 3 metric 128 | |||
# same but for IPv6 | |||
## redistribute local ip ::/0 le 0 metric 128 | |||
redistribute metric 128 #grad nicht ganz sicher ob so richtig | |||
redistribute local ip 10.0.0.0/8 | |||
redistribute local deny | |||
local-port 33123 | |||
#local-port-readwrite 34567 #funktioniert anscheinend nicht! | |||
</pre> | </pre> | ||
dabei ganz oben die Interfaces anpassen. /etc/config/babeld löschen! Danach /etc/init.d/babeld start und Router nochmals neu starten. Fertig. | |||
== Alfred == | |||
/ | Inzwischen gibt es den [https://github.com/kratz00/firmware/tree/calfred/src/packages/fff/fff-alfred-monitoring-proxy alfred-monitoring-proxy] und [https://github.com/kratz00/firmware/tree/calfred/src/packages/fff/alfred-json alfred-json] gibt es als OpenWRT Packages. | ||
Allerdings ist ein Fehler im alfred-monitoring-proxy in Zeile 9: | |||
Anstatt <pre>--data "{$fetch_id: $data}"</pre> müsste es <pre>--data "{\"$fetch_id\": $data}"</pre> heißen. | |||
== WLAN Parameter == | == WLAN Parameter == | ||
Zeile 699: | Zeile 252: | ||
Die eigene Hood kann aber auch mit ganz anderen Parametern betrieben werden, so ist z.b. denkbar die Hood auf 802.11s umzustellen oder gar eine andere Batmanversion zu verwenden. | Die eigene Hood kann aber auch mit ganz anderen Parametern betrieben werden, so ist z.b. denkbar die Hood auf 802.11s umzustellen oder gar eine andere Batmanversion zu verwenden. | ||
== und das geilste daran... == | |||
Wenn man auch den Layer 3 Endpunkt selbst betreibt und dort genug L3 Peerings zu verschiedenen Personen hat, ist dieser Aufbau absolut dezentral und kann von keiner zentralen Position mehr abgeschaltet werden. Es wird kein KeyXchange und auch sonst keine "zentrale Instanz" mehr benötigt. | |||
=== Beispiel Neunhof und Unterfürberg === | |||
Diese zwei Layer 2 Netze hängen jeweils an [http://vm2-fff-gw-cd1.fff.community:8080/ vm2-fff-gw-cd1.fff.community] angebunden. Dieser Server wird auch von mir alleine administriert. Auf diesen Server habe ich mich um viele Layer 3 Peerings zu anderen Personen gekümmert. Wenn ich mich nicht gerade verzählt habe, müssten darin 6 Personen hängen die alle das Peering zu mir kappen müssten um mein Netz vom Freifunk zu trennen und selbst dann würde es durch eigenen Internetexit (Mullvad) zumindest noch Internet haben. | |||
Das ist für mich dezentralität. | |||
</div> |
Aktuelle Version vom 15. August 2019, 23:44 Uhr
Diese Seite enthält veraltete Informationen!
Möglicherweise hat der Inhalt aktuell keine Relevanz mehr oder muss aktualisiert werden.
Mittlerweile sind babeld und dnsmasq in der offiziellen Firmware. Siehe auch Gatewayfirmware
Um aus einem Router ein Gateway zu machen, muss in die Firmware Babel und dnsmasq mit eingebaut werden. Dieses Patch baut diese 2 Programme plain mit ein, es müssen danach noch diverse Konfigurationen und Routingparameter gesetzt werden. Es kann sich dazu ganz grob an die Anleitung zum Gateway aufsetzen gehalten werden.
Achtung! Man sollte sich bei solchen Experiementen immer gut überlegen wie man den Router noch erreichen kann, man kann sich relativ leicht selbst komplett aussperren.
Achtung Patch ist nur für ar71xx muss u.U. auch für andere Hardware manuell angepasst werden!
From d2db4645831742269a391fddbedad8d8a46ad3c6 Mon Sep 17 00:00:00 2001 From: Christian Dresel <fff@chrisi01.de> Date: Sun, 18 Dec 2016 17:44:20 +0100 Subject: [PATCH] Add Babel and dnsmasq Signed-off-by: Christian Dresel <fff@chrisi01.de> --- bsp/ar71xx/.config | 2 +- buildscript | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp/ar71xx/.config b/bsp/ar71xx/.config index e827685..4abc536 100644 --- a/bsp/ar71xx/.config +++ b/bsp/ar71xx/.config @@ -16,7 +16,7 @@ CONFIG_CLEAN_IPKG=y # CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC is not set # CONFIG_FASTD_ENABLE_METHOD_GENERIC_GMAC is not set # CONFIG_PACKAGE_ALFRED_VIS is not set -# CONFIG_PACKAGE_dnsmasq is not set +CONFIG_PACKAGE_babeld=y # CONFIG_PACKAGE_firewall is not set CONFIG_PACKAGE_gpioctl-sysfs=y CONFIG_PACKAGE_kmod-ifb=y diff --git a/buildscript b/buildscript index 25cf291..90af8a9 100755 --- a/buildscript +++ b/buildscript @@ -37,7 +37,7 @@ GLUON_PKGS="kmod-batman-adv-legacy micrond simple-tc uradvd" ROUTING=(routing https://github.com/openwrt-routing/packages.git e870c3373eea80df852d42fac3f40aaffd7a0f58) -ROUTING_PKGS="alfred" +ROUTING_PKGS="alfred babeld" FFF=(fff) FFF_PKGS="-a" -- 2.1.4
das ganze liegt fertig kompiliert hier:
http://fff-gw-cd1.fff.community/dev/babeld/ (!!ACHTUNG!! ungetestet!! Verwendung auf eigene Gefahr!)
Ganz zwingend sollte nach dem flashen zuerst komplett unterbunden werden, das er noch eine BatmanVPN Verbindung aufbaut:
rm /usr/sbin/vpn-select rm /usr/lib/micron.d/vpn-select rm /usr/lib/micron.d/fff-sysupgrade /etc/init.d/micrond restart
Folgendes muss grundsätzlich danach noch getan werden damit er als Gateway verwendet werden kann:
Verbindung ins L3 Netz
Irgendeine Art von Verbindung in unser L3 Netz. Ich habe dazu fastd im tun Modus verwendet um ein Gateway über das Internet zu erreichen, natürlich sind auch Glasfaser, WLAN, Laser, Morsecode o.ä. Verbindungen denkbar.
Server:
bind any:1234; # UDP Port 1234 auf allen Interfaces mode tun; interface "fffbabelVPN"; method "null"; mtu 1426; secret "SECRET KEY DES SERVERS"; #include peers from "peers"; include peer "/etc/fastd/fff.babel/peers/router1"; on up " ip link set up $INTERFACE ip address add 10.50.252.****/32 dev $INTERFACE # eigene Tunnelip setzen ";
fff-gw-cd1 /etc/fastd/fff.babel/peers # cat router1 key "PUBLIC KEY DES ROUTERS";
Client:
log to syslog level warn; method "null"; mode tun; interface "fffgwcd1VPN"; mtu 1426; peer "fffgwcd1" { remote ipv4 "SERVERIP" port 1234; key "SERVER PUBLIC KEY"; } secret "EIGENER SECRET KEY"; on up " ip link set up fffgwcd1VPN ip address add 10.83.252.xx/32 dev $INTERFACE # eigene IP ip -6 addr add fe80::c11:xxxx dev $INTERFACE # gefakte Locallink ip rule add from 10.0.0.0/8 table fff prio 20 ip rule add to 10.0.0.0/8 table fff prio 20 ip route add 10.50.xxx.1/32 dev br-mesh proto static table fff # eigene Gatewayip der Hood ip route add 10.50.xxx.0/24 dev br-mesh proto static table fff # Range die per dhcp vergeben wird "; secure handshakes no;
Ebenfalls muss fastd noch in den Autostart (/etc/rc.local -> "fastd -c /etc/fastd/CONFIGFILE &") das "&" am Ende keinesfalls vergessen! Sonst wird ab hier die File nicht mehr weiter ausgeführt und der ganze rest danach fehlt!!
2 wertvolle Links die bei fastd extrem weiterhelfen: [1] [2]
Folgende Routingregeln müssen am Router angelegt werden
Auf dem Router muss ebenfalls die 10 fff angelegt werden:
vi /etc/iproute2/rt_tables
... 10 fff ...
Weiterhin müssen folgende Regeln angelegt werden falls dies noch nicht in den VPN Sachen gemacht wird (Router ohne VPN müssen es wo anders machen!):
ip rule add from 10.0.0.0/8 table fff prio 20 ip rule add to 10.0.0.0/8 table fff prio 20 ip route add 10.50.XXX.XXX/XX dev br-mesh table fff # eigenes Subnetz das später per DHCP vergeben wird
falls man dies in der /etc/rc.local macht, aufpassen das jede Zeile mit & abgeschlossen wird, da er sonst u.U. beim booten hängen bleibt und die File nicht bis zu Ende ausführt, ganz ekliges Zeug...
Das Interface br-mesh muss noch die Gateway IP bekommen:
/etc/config/network
... config interface 'mesh' option type 'bridge' option auto '1' option macaddr '30:b5:c2:XXXXXX' list ip6addr 'fdff:0::30b5:c20e:XXXXX/64' list ip6addr 'fdff:0::1/64' list ip6addr 'fdff:0::32b5:c2ff:fe0e:XXXXX/64' option ipaddr '10.50.X.1' option netmask '255.255.X.0' option proto 'static' option ifname 'eth0.1 bat0' ...
ToDo: IPv6 muss auch angepasst werden!
dnsmasq konfigurieren
ebenfalls muss noch dnsmasq konfiguriert werden:
/etc/dnsmasq.conf
dhcp-range=10.50.131.1,10.50.131.127,255.255.254.0,1h dhcp-option=3,10.50.130.1 dhcp-option=option:dns-server,10.83.252.11,10.50.40.10,10.50.252.0 log-queries
natürlich die IP Adressen entsprechend anpassen der Syntax lautet:
dhcp-range=DHCP_RANGE_START,DHCP_RANGE_ENDE,SUBNETZMASK,LEASETIME dhcp-option=3,STANDARTGATEWAYIP dhcp-option=option:dns-server,DNSSERVER log-queries
Danach den Router neu starten, dnsmasq neu starten hat hier irgendwie nicht geholfen!
Babel konfigureren
die Datei /etc/babeld.conf öffnen, alles löschen und dies einfügen:
# For more information about this configuration file, refer to # babeld(8) interface IF1 wired true max-rtt-penalty 128 interface IF2 wired true max-rtt-penalty 128 #... einfach weiterführen für mehr Interfaces. export-table 10 import-table 10 # redistribute IPv4 default route into babel ## redistribute local ip 0.0.0.0/0 le 0 metric 128 # Babel refuses to redistribute routes with a protocol number of "boot"; # this is standard practice, and means that you cannot easily # redistribute the default route installed by dhcp. It is however # possible to redistribute such route by explicitly specifying "proto 3" # on the redistribute line. ## redistribute ip 0.0.0.0/0 le 0 proto 3 metric 128 # same but for IPv6 ## redistribute local ip ::/0 le 0 metric 128 redistribute metric 128 #grad nicht ganz sicher ob so richtig redistribute local ip 10.0.0.0/8 redistribute local deny local-port 33123 #local-port-readwrite 34567 #funktioniert anscheinend nicht!
dabei ganz oben die Interfaces anpassen. /etc/config/babeld löschen! Danach /etc/init.d/babeld start und Router nochmals neu starten. Fertig.
Alfred
Inzwischen gibt es den alfred-monitoring-proxy und alfred-json gibt es als OpenWRT Packages.
Allerdings ist ein Fehler im alfred-monitoring-proxy in Zeile 9:
Anstatt--data "{$fetch_id: $data}"müsste es
--data "{\"$fetch_id\": $data}"heißen.
WLAN Parameter
Ebenfalls müssen die WLAN Parameter angepasst werden, wenn eine eigene Hood entsteht sollten mindestens folgende Parameter geändert werden:
Mesh:
- BSSID
- SSID
AP:
- SSID
Die eigene Hood kann aber auch mit ganz anderen Parametern betrieben werden, so ist z.b. denkbar die Hood auf 802.11s umzustellen oder gar eine andere Batmanversion zu verwenden.
und das geilste daran...
Wenn man auch den Layer 3 Endpunkt selbst betreibt und dort genug L3 Peerings zu verschiedenen Personen hat, ist dieser Aufbau absolut dezentral und kann von keiner zentralen Position mehr abgeschaltet werden. Es wird kein KeyXchange und auch sonst keine "zentrale Instanz" mehr benötigt.
Beispiel Neunhof und Unterfürberg
Diese zwei Layer 2 Netze hängen jeweils an vm2-fff-gw-cd1.fff.community angebunden. Dieser Server wird auch von mir alleine administriert. Auf diesen Server habe ich mich um viele Layer 3 Peerings zu anderen Personen gekümmert. Wenn ich mich nicht gerade verzählt habe, müssten darin 6 Personen hängen die alle das Peering zu mir kappen müssten um mein Netz vom Freifunk zu trennen und selbst dann würde es durch eigenen Internetexit (Mullvad) zumindest noch Internet haben. Das ist für mich dezentralität.