Laissez ifconfig attendre que l'adresse IPv6 ne soit pas provisoire

Je réclame une adresse IPv6 en utilisant ifconfig dans un script. Cette adresse est ensuite immédiatement utilisée pour écouter sur un port TCP.

Lorsque j'écris le script comme ceci, il échoue parce que le service est incapable d'écouter:

 ifconfig igb0 inet6 2001:db8::10/64 add service my_service start #fails 

Cependant, il réussit quand je le fais comme ça:

 ifconfig igb0 inet6 2001:db8::10/64 add sleep 1 service my_service start 

J'ai essayé d'écrire la sortie de ifconfig directement après l'exécution de l' add opération. Il semble que ifconfig signale que l'adresse IP est provisoire , ce qui empêche apparemment un service d'écouter dessus.

Naturellement, attendre exactement une seconde et espérer que l'adresse est disponible n'est pas une très bonne façon de gérer cela. Comment puis-je attendre qu'une adresse provisoire soit disponible ou si ifconfig returnne plus tard pour que l'adresse soit configurée?

Une adresse peut être dans plusieurs états, tentative est l'un d'entre eux. Avoir ifconfig attendre qu'une adresse laisse l'état provisoire n'est tout simplement pas en accord avec le design.

Vous pouvez configurer pour utiliser le DAD optimiste comme défini dans la RFC 4429 . Le but est de rendre une adresse accessible aux applications même si la DAD n'est pas encore terminée. Vous devrez peut-être reconfigurer le kernel pour utiliser cette fonctionnalité.

Une fois que le kernel est construit pour fournir un DAD optimiste, vous pouvez utiliser certains parameters sysctl pour l'activer. De ip-sysctl.txt :

 /proc/sys/net/ipv6/* Variables: ... conf/interface/*: Change special settings per interface. The functional behaviour for certain settings is different depending on whether local forwarding is enabled or not. ... optimistic_dad - BOOLEAN Whether to perform Optimistic Duplicate Address Detection (RFC 4429). 0: disabled (default) 1: enabled use_optimistic - BOOLEAN If enabled, do not classify optimistic addresses as deprecated during source address selection. Preferred addresses will still be chosen before optimistic addresses, subject to other ranking in the source address selection algorithm. 0: disabled (default) 1: enabled 

C'est-à-dire, faire quelque chose comme

 sysctl -w net.ipv6.conf.enp2s6.optimistic_dad=1 sysctl -w net.ipv6.conf.enp2s6.use_optimistic=1 

au moment du démarrage.

Après avoir demandé à un développeur NetBSD et vérifié que la même chose s'applique à FreeBSD, j'ai trouvé la solution (qui s'applique à ces deux OS):

La détection d'adresse en double (DAD) utilisera un certain time pour détecter si l'adresse est déjà utilisée. Le time qu'il utilisera pour cela est défini en secondes dans la valeur sysctl (3) net.inet6.ip6.dad_count . Dans le file /etc/rc.d/network de NetBSD, la fonction network_start_ipv6_autoconf , le script attend cette quantité plus une seconde.

Lorsque DAD découvre que l'adresse est déjà utilisée sur le réseau, ifconfig (8) affiche l'adresse en tant que duplicated . Dans cet état, il n'est pas possible de se lier à l'adresse, comme lorsque l'adresse est tentative .

Une solution plus complète et plus correcte serait donc:

 ifconfig igb0 inet6 2001:db8::10/64 add dadcount=$(/sbin/sysctl -n net.inet6.ip6.dad_count 2>/dev/null) sleep $dadcount sleep 1 ifconfig igb0 | grep 2001:db8::10/64 | egrep '(duplicated|tentative)$' >&2 && exit 1 service my_service start 

J'ai observé que FreeBSD et NetBSD se comportent différemment lors de l'ajout d'une adresse actuellement en état duplicated :

  • FreeBSD 11 supprimera immédiatement l'état duplicated , permettant l'utilisation de l'adresse, ce qui pourrait causer des conflits.
  • NetBSD 7 marquera l'adresse comme tentative , et il ne changera pas l'état de là, du less pas pour quelques minutes. L'adresse doit être retirée et ajoutée à nouveau afin d'être utilisable.