This patch reports correctly speed on gigabit interfaces. Works with ethtool calls. If this fails, it uses an old MII approach.
Radek Vokal rvokal@redhat.com
Logged In: YES user_id=1275132
--- net-snmp-5.2.1/agent/mibgroup/if-mib/data_access/interface_linux.c.ethtool 2004-10-18 05:49:50.000000000 +0200 +++ net-snmp-5.2.1/agent/mibgroup/if-mib/data_access/interface_linux.c 2005-05-04 10:26:56.000000000 +0200 @@ -20,8 +20,25 @@ #include "if-mib/data_access/interface.h" #include "interface_ioctl.h"
+#include <sys types.h=""> +#ifndef u8 +typedef __uint8_t u8; +#endif +#ifndef u16 +typedef __uint16_t u16; +#endif +#ifndef u32 +typedef __uint32_t u32; +#endif + +#include <linux ethtool.h=""> +#include <linux sockios.h=""> + unsigned int netsnmp_arch_interface_get_if_speed(int fd, const char *name); +/* old mii version */ +unsigned int +netsnmp_arch_interface_get_if_speed_mii(int fd, const char *name);
void netsnmp_arch_interface_init(void) @@ -373,10 +390,39 @@
/** - * Determines network interface speed. + * Determines network interface speed from ETHTOOL_GSET + */ +unsigned int +netsnmp_arch_interface_get_if_speed(int fd, const char *name) { + struct ifreq ifr; + struct ethtool_cmd edata; +
+ memset(&ifr, 0, sizeof(ifr)); + edata.cmd = ETHTOOL_GSET; + + strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)-1); + ifr.ifr_data = (char *) &edata; +
+ if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) + { + DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s failed\n", + ifr.ifr_name)); + return netsnmp_arch_interface_get_if_speed_mii(fd,name); + } + + if (edata.speed != SPEED_10 && edata.speed != SPEED_100 && + edata.speed != SPEED_1000) + /* try MII */ + return netsnmp_arch_interface_get_if_speed_mii(fd,name); + else /* return in bps */ + return edata.speed*1000*1000; +} + +/** + * Determines network interface speed from MII */ unsigned int -netsnmp_arch_interface_get_if_speed(int fd, const char *name) +netsnmp_arch_interface_get_if_speed_mii(int fd, const char *name) { unsigned int retspeed = 10000000; struct ifreq ifr;
Logged In: YES user_id=76148
applied for 5.1.3, 5.2.2 and 5.3.
Log in to post a comment.
Logged In: YES
user_id=1275132
---
net-snmp-5.2.1/agent/mibgroup/if-mib/data_access/interface_linux.c.ethtool
2004-10-18 05:49:50.000000000 +0200
+++
net-snmp-5.2.1/agent/mibgroup/if-mib/data_access/interface_linux.c
2005-05-04 10:26:56.000000000 +0200
@@ -20,8 +20,25 @@
#include "if-mib/data_access/interface.h"
#include "interface_ioctl.h"
+#include <sys types.h="">
+#ifndef u8
+typedef __uint8_t u8;
+#endif
+#ifndef u16
+typedef __uint16_t u16;
+#endif
+#ifndef u32
+typedef __uint32_t u32;
+#endif
+
+#include <linux ethtool.h="">
+#include <linux sockios.h="">
+
unsigned int
netsnmp_arch_interface_get_if_speed(int fd, const char *name);
+/* old mii version */
+unsigned int
+netsnmp_arch_interface_get_if_speed_mii(int fd, const char
*name);
void
netsnmp_arch_interface_init(void)
@@ -373,10 +390,39 @@
/**
- * Determines network interface speed.
+ * Determines network interface speed from ETHTOOL_GSET
+ */
+unsigned int
+netsnmp_arch_interface_get_if_speed(int fd, const char *name) {
+ struct ifreq ifr;
+ struct ethtool_cmd edata;
+
+ memset(&ifr, 0, sizeof(ifr));
+ edata.cmd = ETHTOOL_GSET;
+
+ strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)-1);
+ ifr.ifr_data = (char *) &edata;
+
+ if (ioctl(fd, SIOCETHTOOL, &ifr) == -1)
+ {
+ DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s
failed\n",
+ ifr.ifr_name));
+ return netsnmp_arch_interface_get_if_speed_mii(fd,name);
+ }
+
+ if (edata.speed != SPEED_10 && edata.speed != SPEED_100 &&
+ edata.speed != SPEED_1000)
+ /* try MII */
+ return netsnmp_arch_interface_get_if_speed_mii(fd,name);
+ else /* return in bps */
+ return edata.speed*1000*1000;
+}
+
+/**
+ * Determines network interface speed from MII
*/
unsigned int
-netsnmp_arch_interface_get_if_speed(int fd, const char *name)
+netsnmp_arch_interface_get_if_speed_mii(int fd, const char
*name)
{
unsigned int retspeed = 10000000;
struct ifreq ifr;
Logged In: YES
user_id=76148
applied for 5.1.3, 5.2.2 and 5.3.