Hi all,
I wrote a simple patch which lets snmpd daemon identifies
the speed (ifSpeed) of a gigabit ethernet card linked with
1000Mb/s. Please find the attachment for your reference.
Now, I'm having a difficulty dealing with a 1000BASE-SX
fibre channel card, as e1000 driver does not seem to
support this standard. Basically, two ioctl() operations
attempted at the beginning of speed detection fails with
"operation not supported". Question here is what is the
legitimate value of ifSpeed should it return to satisfy
MIB2 standard?
If I refer to RFC1213, the definition of ifSpeed is stated
as:
"An estimate of the interface's current bandwidth
in bits per second. For interfaces which do not
vary in bandwidth or for those where no accurate
estimation can be made, this object should contain
the nominal bandwidth."
According to my understanding, since ioctl() failed, we
are not aware that whether the link is active or not,
and it would fit into the situation "where no accurate
estimation can be made". If such case arises, snmpd
should return "the nominal value", which is 10Mb/s under
the current implementation of net-snmp.
Our customer wants it to return an error code. According
to RFC1157, error status is defined as:
ErrorStatus ::=
INTEGER {
noError(0),
tooBig(1),
noSuchName(2),
badValue(3),
readOnly(4)
genErr(5)
}
and they are suggesting that returning noSuchName(2)
should be the right value or code to return.
My opinion is that ioctl() is the very first step of
speed detection and without its result snmpd daemon
would have no idea of whether the link is active or
not. In that case "0" may be an appropriate value.
So, we have three differenct interpretations, 0, 10Mb/s
or noSuchname(2), and I would like to ask you folks for
your opinions. Thank you for spending time reading this
lengthy mail and I would appreciate any comments or
feedbacks from you.
Best regard,
Shiro
diff -uNr net-snmp-5.1.org/agent/mibgroup/mibII/interfaces.c
net-snmp-5.1/agent/mibgroup/mibII/interfaces.c
--- net-snmp-5.1.org/agent/mibgroup/mibII/interfaces.c Thu Feb 17 15:06:38 2005
+++ net-snmp-5.1/agent/mibgroup/mibII/interfaces.c Thu Feb 17 15:09:45 2005
@@ -1413,7 +1413,7 @@
unsigned char new_ioctl_nums = 0;
int mii_reg, i;
ushort mii_val[32];
- ushort bmcr, bmsr, nway_advert, lkpar;
+ ushort bmcr, bmsr, nway_advert, lkpar, giga_state;
const unsigned int media_speeds[] = {10000000, 10000000, 100000000,
100000000, 10000000, 0};
/* It corresponds to "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD",
"100baseT4", "Flow-control", 0, */
@@ -1430,7 +1430,7 @@
}
/* Begin getting mii register values */
phy_id = data[0];
- for (mii_reg = 0; mii_reg < 8; mii_reg++){
+ for (mii_reg = 0; mii_reg < 11; mii_reg++){
data[0] = phy_id;
data[1] = mii_reg;
if(ioctl(fd, new_ioctl_nums ? 0x8948 : SIOCDEVPRIVATE+1, &ifr)
<0){
@@ -1449,6 +1449,7 @@
bmsr = mii_val[1]; /* basic mode status register*/
nway_advert = mii_val[4]; /* autonegotiation advertisement*/
lkpar = mii_val[5]; /*link partner ability*/
+ giga_state = mii_val[10]; /* gigabit status */
/*Check for link existence, returns 0 if link is absent*/
if ((bmsr & 0x0016) != 0x0004){
@@ -1457,6 +1458,12 @@
return retspeed;
}
+/* Check for gigabit link */
+ if ((bmsr & 0x0100) && (giga_state & (0x0800|0x0400))) {
+ retspeed = 1000000000;
+ return retspeed;
+ }
+
if(!(bmcr & 0x1000) ){
DEBUGMSGTL(("mibII/interfaces", "Auto-negotiation
disabled.\n"));
retspeed = bmcr & 0x2000 ? 100000000 : 10000000;