web-dev-qa-db-ja.com

ifconfigがIPv6-addressが一時的でなくなるのを待つ

スクリプトで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を返す方法はありますか?

6
jornane

住所にはいくつかの状態があり、暫定的なものはそのうちの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

ブート時。

2
countermode

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の動作が異なることがわかりました。

  • FreeBSD 11はduplicated状態を即座に削除し、アドレスを使用できるようにしますが、競合が発生する可能性があります。
  • NetBSD 7はアドレスをtentativeとしてマークし、少なくとも数分間はそこから状態を変更しません。使用するには、アドレスを削除して再度追加する必要があります。
2
jornane