Layer 2-Anycast-Routing mit BATMAN

Bisher wurde Traffic von Clientgeräten ins Internet via Unicast geroutet. Dazu musste das Clientgerät explizit angeben, über welchen Gateway der Traffic ins Internet geleitet werden sollte. Wenn das Clientgerät nicht den besten Gateway gewählt hat führte dieses Verhalten eventuell zu unnötigem Traffic zwischen unseren Gateways.

Wir haben am 13./14. Oktober Layer 2-Anycast-Routing ausgerollt. Hierbei gibt der Client nur noch an, dass der Traffic an irgendeinen Gateway geleitet werden soll und das Netz leitet den Traffic automatisch zum nächstgelegenen Gateway.

Die Idee selbst wurde bereits im BATMAN-Wiki beschrieben: Man aktiviert die Bridge Loop Avoidance batctl bl 1 und vergibt eine Anycast-MAC-Adresse und bindet an diese dann die Anycast IP-Adressen. Wir verwenden dazu, wie im Wiki vorgeschlagen, MAC-VLAN-Interfaces. Siehe dazu auch unsere Konfiguration auf Github.

Bei den MAC-VLAN-Interfaces ergibt sich ein Problem: Standardmäßig antwortet ein Linux-Host auf ARP-Anfragen an alle seine IP-Adressen mit der MAC-Adresse des Interfaces, an dem die Anfrage eingeht. Wenn also ein Client versucht die MAC-Adresse zur Anycast-IP-Adresse herauszufinden antwortet der Gateway mit seiner Unicast-MAC-Adresse, da das Unicast-Interface das Paket als erstes gesehen hat. Dieses Verhalten kann man umstellen auf „antworte nur dann, wenn du an diesen Client auch über dieses Interface routen würdest“. Das geht mit sysctl -w net.ipv4.conf.all.arp_filter=1. Siehe dazu auch die entsprechende Kernel-Dokumentation.

Als nächstes haben wir dann das Problem, dass der Gateway genau dann, wenn die Anycast-IP-Adresse im Spiel ist, das Anycast-Interface benutzen soll und sonst das normale Interface. Dieses Problem lässt sich mit Source-Routing lösen:

if ! grep -q anycast /etc/iproute2/rt_tables; then
	echo 11 anycast >> /etc/iproute2/rt_tables
fi

#the anycast-mesh-ip is routed via the anycast-mac
ip rule add from 10.172.0.10/32 table anycast
ip route add table anycast 10.172.0.0/16 dev fftr-gw-anycast

Jetzt haben wir eine Anycast-IP-Adresse, die man anpingen kann und die man für Services wie DNS benutzen kann. Darüber routen kann man aber noch nicht, denn der rp_filter verwirft Pakete, auf dem Anycast-Interface, da der Kernel zurückkommende Pakete nicht über das Anycast-Interface routen würde, da sie nicht die Anycast-IP-Adresse als Quelle haben. Daher schalten wir den rp_filter einfach ab: sysctl -w net.ipv4.conf.fftr-gw-anycast.rp_filter=0; sysctl -w net.ipv4.conf.br-fftr.rp_filter=0.

Nach diesen Änderungen hat man eine funktionsfähige Layer 2-Anycast-Adresse. Nun kann man den DHCP-Server anpassen, damit diese Adresse für IPv4-Traffic verwendet wird und das Programm, welches die IPv6-RAs sendet an das Anycast-Interface binden damit für IPv6-Traffic die link-local Anycast-Adresse verwendet wird. Auch seine iptables sollte man nicht vergessen anzupassen.

Unsere kompletten Konfigurationsänderungen lassen sich auf Github betrachten.

Update 09.11.2015:

Aufgrund von Meldungen verschiedener merkwürdiger Probleme durch unsere User und fehlender Zeit für weitere Analyse haben wir Anycast zur Zeit wieder abgeschaltet und fahren wieder Unicast.

5 Antworten auf “Layer 2-Anycast-Routing mit BATMAN

  1. RubenKelevra

    Habt ihr in euren Rechenzentren dann dafür auch eine Public-IPv4 Anycast-IP?

    Wie synchronisiert ihr eure NAT-Tabellen dann, damit nicht unnötig die Verbindungen beim Wechsel abbrechen?

    1. Ranlvor Autor

      Für was bräuchten wir eine Public-IPv4 Anycast-IP? Es geht hier erstmal um den Traffic vom Client zum Internet/ICVPN, das ist komplett ins BATMANs Hand.

      Wir haben keinen NAT bei uns, wir leiten alles mit privaten IPv4-Adressen nach Berlin, dort wird das NATing gemacht. Da es dort nur 2 ICVPN-Peers gibt und wir davon einen wegen geringerem Durchsatz herunterprioritisiert haben landet der Traffic dort immer im gleichen NAT, egal über welchen Supernode es geht und macht daher auch dort keine NAT-State-Probleme.

      1. lemoer

        Wie genau war euer Exitnode dazu konfiguriert? Bzw. woher weiß der Exitnode an welchen Supernode er die Antwortpakete aus dem Internet (in Richtung 10.172.X.Y) schicken soll? Oder wurden die “einfach” irgendwo hin geschickt?

        1. Ranlvor Autor

          Der Exitnode hat via BGP von jedem Supernode das gesammte Netz und die DHCP-Range des entsprechenden Supernode announced bekommen. IP-Adressen innerhalb einer DHCP-Range eines Supernodes gehen damit zu dem Supernode, der diese Adressen vergibt, alle anderen landen auf irgendeinem Supernode.

          Solange ein Client durchgehend vom gleichen Supernode versorgt wird ist das optimales Routing, wenn der Client roamed gibt es dagegen Crosstraffic, das ließ sich nicht verhindern.

          1. lemoer

            Ich habe gerade mit T_X im IRC ein bisschen darüber gequatscht. Wenn man den Plan fortsetzen will, dann müsste man in batman-adv nur reinpatchen, dass keine roaming-adv (unicast) Nachricht für die spezielle MAC-Adresse versendet wird. Das wäre aber verhältnismäßig wenig Code, da die meiste Magie schon über den BLA-Code in batman abgedeckt ist. Man muss halt lediglich verhindern, dass die Gateways sich gegenseitig dauernd Roaming-Hinweise schicken. Allein das Verhindern des Versendens dieser Nachrichten reicht aber aus, dass sie sich nicht mehr um die MAC streiten.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert