用于SNMP的Linux ifIndex持久性

我们使用OpManager来监视远程Linux机器上的接口设备。 这些盒子有VLAN,我们用这些VLAN来收集有关被中继到networking的networking的信息。 例如,我们有eth0.2,eth0.3,eth0.12,eth0.13,eth0.22,eth0.23(分别对应于2,3,12,13,22,23)。

我们在pipe理IP地址上使用SNMP来检查并确保接口已经启动。 但是,如果我们需要重新启动networking服务,则会遇到接口索引更改的问题。 我们会收到如下错误消息:

接口“eth0.23 – eth0.23”已closures。 接口描述为“eth0.23”,索引为11. Circuit ID未configuration。

即使界面已经启动并正在运行。

我们如何通过重新启动将索引值更改为持久性。 如果我们将接口从静态IP更改为dynamic,我们已经看到了这一点。

简而言之,SNMP RFC在networkingpipe理器重新初始化之间不需要ifIndex持久性。 net-snmp不提供任何特殊的function来提供这个function。

从RFC 2863:

对接口的ifIndex值的稳定性(重新初始化之间)的要求通过要求在dynamic地移除接口之后,其ifIndex值不被不同的dynamic添加接口重新使用,直到在接下来的重新初始化networkingpipe理系统。

值得注意的是,当系统重新初始化(即重新启动)时,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分配使用简单的增量algorithm。 这是相关的,因为在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的监控系统遇到这种性质的问题时,我最终使用了另一种方法来引用networking接口。 特别是,我使用接口名称而不是接口索引号(即“eth0”,“eth1”,“vlan150”等)。

你可以考虑使用if_indextoname(index_val,index_name)。 其中index_val是unsigned inttypes,而index_name是char *types。

通过index_val和linux内核将它映射到正确的index_name,你可以在你的代码中使用,因为index_name在重新启动时是相同的。