web-dev-qa-db-ja.com

SNMPのLinuxifIndex永続性

OpManagerを使用して、リモートLinuxボックスのインターフェイスデバイスを監視しています。これらのボックスには、ボックスにトランキングされているネットワークに関する情報を収集するために使用するVLANがあります。たとえば、eth0.2、eth0.3、eth0.12、eth0.13、eth0.22、eth0.23(それぞれVLAN 2、3、12、13、22、23に対応)があります。

管理IPアドレスでSNMPを使用して、インターフェイスが稼働していることを確認します。ただし、ネットワークサービスを再起動する必要がある場合、インターフェイスインデックスが変更されるという問題が発生します。次のようなエラーメッセージが表示されます。

インターフェイス 'eth0.23-eth0.23'がシャットダウンされます。インターフェイスの説明は「eth0.23」で、インデックスは11です。回線IDは設定されていません。

インターフェイスが稼働している場合でも。

再起動してもインデックス値が永続的になるように変更するにはどうすればよいですか。これは、インターフェイスを静的IPから動的IPに変更した場合にも見られます。

5
jinanwow

簡単に言うと、SNMP RFCは、ネットワークマネージャーの再初期化の間にifIndexの永続性を必要としません。 net-snmpは、この機能を提供するための特別な機能を提供していません。

RFC 2863から:

インターフェイスのifIndex値の(再初期化の間の)一定性の要件は、インターフェイスが動的に削除された後、そのifIndex値が異なる動的に追加されたインターフェイスによって再利用されないことを要求することによって満たされます。ネットワーク管理システムの次の再初期化。

重要な点は、システムが再初期化されたとき(つまり、再起動されたとき)に、ifIndexエントリを任意のインターフェイスで明示的に使用できるようにすることです。

Linuxカーネル(net/core/dev.c)から:

static int dev_new_index(struct net *net)
{
    static int ifindex;
    for (;;) {
        if (++ifindex <= 0)
            ifindex = 1;
        if (!__dev_get_by_index(net, ifindex))
            return ifindex;
    }
}

カーネル内のifindex割り当ては、単純なインクリメントアルゴリズムを使用します。 net-snmp(agent/mibgroup/if-mib/data_access/interface_ioctl.c)では、次のようになります。

oid
netsnmp_access_interface_ioctl_ifindex_get(int fd, const char *name)
{
#ifndef SIOCGIFINDEX
    return 0;
#else
    struct ifreq    ifrq;
    int rc = 0;

    DEBUGMSGTL(("access:interface:ioctl", "ifindex_get\n"));

    rc = _ioctl_get(fd, SIOCGIFINDEX, &ifrq, name);
    if (rc < 0) {
        DEBUGMSGTL(("access:interface:ioctl",
                   "ifindex_get error on inerface '%s'\n", name));
        return 0;
    }

    return ifrq.ifr_ifindex;
#endif /* SIOCGIFINDEX */
}

この関数は最終的に呼び出されてifindexにデータを入力し、IOCTLインターフェイスを使用してLinuxカーネルからSIOCGIFINDEX値を取得します。

SNMPベースの監視システムでこの種の問題に遭遇したとき、私はネットワークインターフェイスを参照するための代替手段を使用することになりました。特に、インターフェイスのインデックス番号の代わりにインターフェイス名を使用しました(つまり、「eth0」、「eth1」、「vlan150」など)。

6
chuckx

If_indextoname(index_val、index_name)の使用を考えることができます。ここで、index_valはunsigned intタイプであり、index_nameはchar *タイプです。

Index_valを渡すと、Linuxカーネルはそれを正しいindex_nameにマップします。これは、再起動後もindex_nameが同じであるため、コードで使用できます。

1
vikas