FreeBSD 12.1 Probleme IPv6

  • Ich habe letzten Endes so viel Stress gemacht bis ich das zus. IPv6 Netz kostenlos dazu bekommen habe.


    Schöne Gruße

    Hi, I'm having similar issues on FreeBSD 13. I don't speak German so I had to translate the conversation here. Is there a solution for this ?

  • Hi, I'm having similar issues on FreeBSD 13. I don't speak German so I had to translate the conversation here. Is there a solution for this ?

    Apparently the issue can be solved by purchasing an additional IPv6 subnet, which is ridiculious considering that the servers are advertised to come with IPv6, if needed.


    Therefore, I would suggest that you contact the support team, since this is just a forum, where customers help customers.

  • Apparently the issue can be solved by purchasing an additional IPv6 subnet, which is ridiculious considering that the servers are advertised to come with IPv6, if needed.


    Therefore, I would suggest that you contact the support team, since this is just a forum, where customers help customers.

    Ah ok. Thank you for the heads up.

  • Mich würde der technische Hintergrund interessieren. Einfach aus Neugier. :)

    Damit ist Ausgangsrichtung (an fe80::1%vtnet0) ungleich der Eingangsrichtung (zu meiner IP).

    Das stimmt soweit, die Pakete in Ausgangsrichtung gehen an eine andere MAC-Adresse, als die ankommenden Pakete als Absender MAC haben. Die Frage ist, warum BSD ein Problem damit hat. Macht die Firewall auch auf Schicht 2 eine Art Connection Tracking?

  • Hallo!


    Ich muss den älteren Forenbeitrag nochmal ausgraben, da ich das gleiche Problem aktuell mit FreeBSD 13 habe. Ich habe mir angeschaut wie die NDP-Nachrichten ausgetauscht werden und konnte das Problem (vermutlich) dadurch lösen.


    Wie bereits geschrieben wird das primäre IPv6-Netz geswitched und nicht geroutet. D.h. der Router sollte sich in der gleichen Layer-2-Broadcast-Domäne (also in irgendeiner Form im gleichen IP-Subnetz) befinden und NDP-Solicitations herausschicken um zu Fragen, wer die IPv6-Adresse besitzt und um die MAC-Adresse auf Layer 2-Ebene zu erfahren. Üblicherweise sendet der Router das dann von seiner Link-Lokalen Adresse im fe80::/64 Netz.


    Ein tcpdump -e -n -i vtnet0 icmp6 trägt aber folgendes zutage:

    Code
    2c:6b:f5:a0:77:c0 > 33:33:ff:00:00:99, ethertype IPv6 (0x86dd), length 86: 2a03::4000:24::3 > ff02::1:ff00:yyyy: ICMP6, neighbor solicitation, who has 2a03:4000:24:xxxx::yyyy, length 32


    Nun ist 2a03::4000:24::3 aber für FreeBSD kein Nachbar, da auf vtnet0 lediglich 2a03:4000:24:xxxx::/64 eingerichtet. Ohne sysctl net.inet6.icmp6.nd6_onlink_ns_rfc4861=1 wird die Nachricht also verworfen. Wenn man den sysctl auf 1 gesetzt hat, dann wird ein NDP Advertisement von 2a03::4000:24::1 > 2a03::4000:24::3 gesendet. Nun ist aber die Destination immer noch kein Nachbar, kann also nicht direkt über Layer 2 addressiert werden. Stattdessen wird das Paket auf Layer 2 an den default Gateway adressiert (fe80::1%vtnet0 bei mir mit MAC 00:00:5e:00:02:02). In tcpdump sieht das so aus:

    Code
    36:5e:42:2f:df:55 > 00:00:5e:00:02:02, ethertype IPv6 (0x86dd), length 78: 2a03:4000:24:xxx::1 > 2a03:4000:24::3: ICMP6, neighbor advertisement, tgt is 2a03:4000:24:xxxx::yyyy, length 24

    Wie man sieht, wird das Paket geroutet. Das scheint der Netcup Router aber nicht zu akzeptieren. Bei Gelegenheit muss ich nochmal in den IPv6-RFC schauen, ob das Verhalten konform ist.


    Nachdem einiger NDP-Solicitations unbeantwortet bleiben, scheint der Netcup-Router erneut NDP-Solicitations von fe80::/64 zu senden. Dann klappt alles. Allerdings gehen in der Zwischenzeit 10-20 Pakete verloren.


    Jetzt weiß man ja aber schon, dass der Router offensichtlich doch ein direkter Layer 2-Nachbar ist. Also kann man das FreeBSD so beibringen:

    Code
    route add -inet6 2a03:4000:24::2 -iface vtnet0
    route add -inet6 2a03:4000:24::3 -iface vtnet0

    Eigentlich sollte es jetzt klappen. Und das NDP-Advertisement sollte direkt über Layer 2 zugestellt werden. Das sollte dann so aussehen:

    Code
    36:5e:42:2f:df:55 > 2c:6b:f5:a0:77:c0, ethertype IPv6 (0x86dd), length 78: 2a03:4000:24:xxx::1 > 2a03:4000:24::3: ICMP6, neighbor advertisement, tgt is 2a03:4000:24:xxxx::yyyy, length 24

    Der Unterschied ist lediglich die Destination-MAC-Adresse auf Layer 2-Ebene. In meinem Fall klappte das nicht, ich vermute, das wiederum die NDP-Solicitations von meinem Server für 2a03:4000:24::3 nicht beantwortet. Mein Fix dafür war nun noch die Einträge für die beiden betreffenden Routern aus dem tcpdump permanent in die NDP-Tabelle einzutragen. Meine /etc/rc.local sieht dann so aus:


    Code
    route add -inet6 2a03:4000:24::2 -iface vtnet0
    route add -inet6 2a03:4000:24::3 -iface vtnet0
    ndp -s 2a03:4000:24::2 10:0e:7e:26:f1:c0
    ndp -s 2a03:4000:24::3 2c:6b:f5:a0:77:c0


    Danach klappt bei mir alles. Der tcpdump sieht genauso aus, wie man erwarten würde. Der erste Verbindungsaufbau nach einem Reboot dauert immer noch ein paar Sekunden, etwa 3-5 Pakete gehen verloren, aber danach läuft soweit alles stabil. Vorher gab es Paketverlust alle paar Minuten. Vielleicht kann meine Beobachtungen jemand auf seinem Server bestätigen?


    Ich vermute Linux sendet die NDP-Advertisements einfach direkt an die Source-MAC-Adresse vom NDP-Solicitation-Paket und überspringt eventuell die Logik mit der Nachbarschaft und der Layer-2-Addressierung. Dadurch würde das das Problem überhaupt nicht auftreten. Wenn dem so wäre könnte man das im BSD-Kernel vermutlich relativ einfach ähnlich machen. In den kommenden Tagen würde ich nochmal das Verhalten von Linux und BSD vergleichen und im Standard nachlesen welche Verhalten eigentlich standardkonform wären.

  • Super Arbeit, danke dir, aber ich sag mal so: Urgs. :saint:


    Da frage ich mich vor allem, inwiefern man sich darauf verlassen kann, dass diese Nachbaradressen stabil bleiben? Es wäre wenig gewonnen, wenn man die alle naslang aktualisieren müsste.

  • Ich weiß jetzt, warum der Routing-Eintrag nicht ausreicht. Der NDP-Code schaut nicht in die Onlink-Routen (Routen ohne RTF_GATEWAY Flag). Er schaut nur in die NDP-Prefix Tabellen und die werden gefüllt, wenn man Adressen zum Interface hinzufügt oder wenn diese per Router-Advertisment empfangen werden.


    Ein "Trick" wäre am Uplink-Interface Router-Advertisements zu aktivieren , denn wenn ein Interface Router-Advertisments empfangen soll, aber keine Prefixe bisher empfangen hat, ist jede Adresse Nachbar, siehe hier. Gibt auch einen Bugreport dazu. Manuell die Einträge in die NDP-Tabelle zu schreiben hilft, da der Kernel es dann als Nachbarn ansieht und das Interface kennt. Aber alles nicht hübsch und alles andere als zufriedenstellend. Die MAC-Adressen können sich natürlich zukünftig auch ändern. Müsste man ein Script für schreiben.


    Etwas, was aber problemlos zu funktionieren scheint, ist das IPv6-Netz als /48 zu konfigurieren. Dann funktioniert alles ohne weiteren Tricks. Die Netcup-Router sind dann direkte Nachbarn und FreeBSD ist glücklich. In meinen Tests konnte ich auch fremde Netze am gleichen Router noch erreichen. Man selbst hat zwar nur ein /64er Netz, aber der Router scheint das komplett anliegende /48er-Netz zu switchen (gefiltert, so dass man nur Traffic sieht die für die eigene VM bestimmt ist). Das ist natürlich auch ein Implementierungsdetail, kann sich auch ändern, beinhaltet aber immerhin keine festen MAC-Adressen in der NDP-Tabelle…


    Also einfach:

    Code
    ifconfig_vtnet0_ipv6="inet6 2a03:4000:24:yyyy::1/48" # statt /64
    
    # Wenn man seine eigenen Adresse nicht über Uplink rausschicken will, weil z.B. noch nicht alle Jails gestartet wurden:
    ipv6_static_routes="protect_mynet"
    ipv6_route_protect_mynet="2a03:4000:24:yyyy::/64 -reject"


    Zusammenfassend kann man sagen, dass FreeBSD einfach keine IPv6-Onlink-Routen gescheit unterstützt. Gleichzeitig verwendet der NDP-Code die normale IPv6-Routing Logik und hat dann ein Problem wenn die Quelladresse in einem fremden Netz ist (was der RFC nicht ausschließt). Netcup könnte die Kompatibilität maximieren und das Problem relativ einfach komplett umgehen und machen was man üblicherweise tut: Für link-lokalen Traffic einfach durchgehend das fe80::/64 Netz nutzen. Aber der RFC schreibt das wiederum auch nicht zwingend vor.