#!/bin/sh
# Le prefixe NAT64 reste joignable meme quand le WiFi est allume.
#
# ═══ CE QUI SE PASSAIT, mesure le 12/08 ═══
# La data de cet abonnement est IPv6-only. Le resolveur de l'operateur fait donc du
# DNS64 : pour un site qui n'a pas d'AAAA, il fabrique une adresse dans 64:ff9b::/96,
# que son NAT64 traduit ensuite vers l'IPv4 reelle.
#
# ☠️ Mais des que le WiFi est allume, c'est LUI qui porte la route IPv6 par defaut :
#
#     default via fe80::…  dev wlan0        metric 600   <- gagne
#     default via 2a04:…   dev qmapmux0.0   metric 700
#
#   Les adresses 64:ff9b:: partaient donc chez le FAI, qui ne connait pas ce prefixe.
#   Trou noir complet — mesure sur trois adresses, TCP 443 muet sur les trois :
#       ping 64:ff9b::a237:6713                        -> 100 % de perte
#       ping 64:ff9b::a237:6713 -I qmapmux0.0          -> 2/2, 65 ms
#
# 🔑 ET C'EST LE CLIENT QUI CHOISIT LE MAUVAIS CHEMIN, PAS LE RESEAU. Le nom resout
#   des DEUX cotes : l'AAAA synthetique par le lien mobile, l'A par le WiFi. Qt suit
#   la RFC 6724 et prefere l'IPv6 — donc il tombe dans le trou, attend son delai, puis
#   bascule. Effet mesure sur la recherche de lieux de RedMaps, meme URL :
#       IPv4 forcee    -> HTTP 200 en  0,6 s
#       choix normal   -> HTTP 200 en 12,7 s
#   L'application, elle, n'a rien fait de mal : elle a demande un nom.
#
# ⚖️ POURQUOI UNE ROUTE ET PAS UN CHANGEMENT DE RESOLVEUR. Couper le DNS64 aurait
#   marche aussi — le CLAT (clatd, depuis device r46) rend une IPv4 locale a tout le
#   systeme. Mais cela imposait un resolveur tiers a la place de celui de l'operateur,
#   donc toutes les requetes DNS de l'appareil chez un inconnu. Une route ne divulgue
#   rien et laisse chaque mecanisme a sa place.
#
# ⚠ Le prefixe est le « well-known » de la RFC 6052, confirme par la RFC 7050 sur CE
#   reseau : ipv4only.arpa y rend 64:ff9b::c000:aa. S'il changeait un jour, c'est cette
#   ligne qu'il faudrait suivre — et le symptome serait exactement celui du haut.

IFACE="$1"
ACTION="$2"

PREFIXE_NAT64=64:ff9b::/96

# ☠️☠️ CE FICHIER S'APPELAIT « 90-joyeuse-nat64-route » ET LE NUMERO ETAIT LE BUG.
#   Mesure du 19/08, au demarrage de l'appareil, journal de clatd :
#
#     22:06:20  clatd: Device facing the PLAT: wlan0
#     22:06:20  clatd: Using CLAT IPv6 address: 2a01:e0a:ebb:a8c0:...   <- la Freebox
#
#   clatd cherche son lien par « ip -6 route get 64:ff9b:: ». Sans la route posee
#   ici, cette question retombe sur la route PAR DEFAUT — le Wi-Fi. Le CLAT se
#   montait donc sur la Freebox, qui n'a aucun NAT64 : tun cree, route posee,
#   TAYGA demarre, ET RIEN NE SE TRADUIT. Aucune erreur nulle part.
#
# 🔑 Les dispatchers de NetworkManager tournent dans l'ORDRE ALPHABETIQUE, et
#   « 50-clatd » redemarre clatd a chaque evenement. En 90 on posait donc la route
#   APRES que clatd ait deja choisi son lien. Le CLAT n'etait juste que si un
#   evenement reseau retombait plus tard — c'est-a-dire par chance. En 40, la
#   route existe avant que clatd ne regarde.
#
# ⚠️ ET LA CONDITION D'ENTREE A CHANGE AVEC : elle exigeait un evenement « gsm »
#   ou l'interface « qrtr0 ». Un evenement Wi-Fi passait donc sans reposer la
#   route — alors que c'est exactement le moment ou clatd va se relancer. On ne
#   regarde plus l'evenement : on regarde s'il EXISTE un lien mobile portant une
#   adresse globale. C'est une condition sur l'etat, pas sur le hasard des
#   notifications, et elle est plus stricte que l'ancienne (voir ci-dessous : NM
#   annonce « qrtr0 », l'adresse vit sur « qmapmux0.0 »).

case "$ACTION" in
    up|down|dhcp6-change|dhcp4-change) ;;
    *) exit 0 ;;
esac

[ "${DEVICE_IFACE:-}" = "clat" ] && exit 0

# ⚠ L'interface qui PORTE l'adresse du bearer, pas celle que NM nomme (qrtr0).
#   Meme mesure que pour le MMS : le nom change entre les deux couches.
DATA_IF=$(ip -6 -br addr show scope global 2>/dev/null \
          | awk '$1 ~ /^qmapmux/ { sub(/@.*/,"",$1); print $1; exit }')

if [ -z "$DATA_IF" ]; then
    echo "joyeuse-nat64-route: aucune interface qmapmux avec adresse globale" >&2
    exit 0
fi

ip -6 route replace "$PREFIXE_NAT64" dev "$DATA_IF" metric 100 2>/dev/null \
    && echo "joyeuse-nat64-route: $PREFIXE_NAT64 via $DATA_IF"

exit 0
