Linux

用於 SNMP 的 Linux ifIndex 持久性

  • September 25, 2015

我們正在使用 OpManager 來監控遠端 linux 機器上的介面設備。這些盒子有 VLAN,我們使用這些 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 更改為動態,我們已經看到了這一點。

簡短的回答,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”等)。

引用自:https://serverfault.com/questions/167520