スクリプトでifconfig
を使用してIPv6アドレスを要求します。このアドレスは、すぐにTCPポートでリッスンするために使用されます。
次のようなスクリプトを作成すると、サービスがリッスンできないため失敗します。
ifconfig igb0 inet6 2001:db8::10/64 add
service my_service start #fails
ただし、次のようにすると成功します。
ifconfig igb0 inet6 2001:db8::10/64 add
sleep 1
service my_service start
ifconfig
- operationを実行した直後にadd
の出力を書き込んでみました。 ifconfig
がIPアドレスを暫定として報告しているようです。これにより、サービスがそのIPをリッスンできなくなっているようです。
当然、ちょうど1秒待って、アドレスが使用可能になることを期待することは、これを処理するための非常に良い方法ではありません。仮のアドレスが利用可能になるのを待つ方法、または後でアドレスをすべてセットアップするためにifconfig
を返す方法はありますか?
住所にはいくつかの状態があり、暫定的なものはそのうちの1つです。 ifconfig
がアドレスが暫定的に離れるのを待つことは、単に設計と一致していません。
RFC 4429 で定義されているように、楽観的なDADを使用するように構成できます。目的は、DADがまだ完了していない場合でも、アプリケーションがアドレスを使用できるようにすることです。この機能を利用するには、カーネルの再構成が必要になる場合があります。
カーネルが楽観的DADを提供するように構築されたら、特定のsysctl-settingsを使用してそれを有効にすることができます。 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
つまり、次のようなことを行います
sysctl -w net.ipv6.conf.enp2s6.optimistic_dad=1
sysctl -w net.ipv6.conf.enp2s6.use_optimistic=1
ブート時。
NetBSD開発者に尋ね、同じことがFreeBSDにも当てはまることを確認した後、私は解決策を見つけました(これらは両方のOSに当てはまります):
重複アドレス検出(DAD)は、アドレスがすでに使用されているかどうかを検出するのにしばらく時間がかかります。これに使用する時間は、sysctl(3)の値net.inet6.ip6.dad_countで秒単位で定義されています。 NetBSDの/ etc/rc.d/network、関数network_start_ipv6_autoconfでは、スクリプトはこの量プラス1秒待機します。
DADがアドレスがすでにネットワークで使用されていることを検出すると、ifconfig(8)はアドレスをduplicated
として表示します。この状態では、アドレスがtentative
である場合と同様に、アドレスにバインドできません。
したがって、より完全で正しいソリューションは次のとおりです。
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
現在duplicated
状態にあるアドレスを追加すると、FreeBSDとNetBSDの動作が異なることがわかりました。
duplicated
状態を即座に削除し、アドレスを使用できるようにしますが、競合が発生する可能性があります。tentative
としてマークし、少なくとも数分間はそこから状態を変更しません。使用するには、アドレスを削除して再度追加する必要があります。