Net-SNMP Version: 5.7.2
Operating System: Linux hostname 3.2.0-38-generic-pae #61-Ubuntu SMP Tue Feb 19 12:39:51 UTC 2013 i686 i686 i386 GNU/Linux
Distribution: ubuntu 12.04 LTS
Problem Description
I came across the problem while trying out the following simple program using the DISMAN-EXPRESSION-MIB implementation of net-snmp in agent/mibgroup/disman/expr. The program creates a simple expression that uses two objects from IF-MIB (ifInUcastPkts.1 and ifOutUcastPkts.1) and produces sum of their values, as following:
snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expExpressionEntryStatus.'"foo"'.'"bar"' = createAndWait snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expExpression.'"foo"'.'"bar"' = '$1+$2' snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expExpressionValueType.'"foo"'.'"bar"' = counter32 snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expExpressionEntryStatus.'"foo"'.'"bar"' = 'active' snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expObjectEntryStatus.'"foo"'.'"bar"'.1 = createAndWait snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expObjectID.'"foo"'.'"bar"'.1 = ifInUcastPkts.1 snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expObjectEntryStatus.'"foo"'.'"bar"'.1 = 'active' snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expObjectEntryStatus.'"foo"'.'"bar"'.2 = createAndWait snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expObjectID.'"foo"'.'"bar"'.2 = ifOutUcastPkts.1 snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expObjectEntryStatus.'"foo"'.'"bar"'.2 = 'active'
However it wasn't working as querying the expression value (as following) didn't return a value. It seemed like the expression wasn't getting evaluated.
snmpget -uuser Lo localhost DISMAN-EXPRESSION-MIB::expValueCounter32Val.'"foo"'.'"bar"'.0.0.0
While examining the code I found out that the following snippet (agent/mibgroup/disman/expr/expExpression.c, line 317) causes the expression data to be retrieved (by calling expExpression_getData()) only if delta (expExpressionDeltaInterval) is set to a non-zero value. Since this is the only place where expExpression_getData() is called, the expressions with detla value of 0 never get evaluated.
if (entry->expDeltaInterval) { entry->alarm = snmp_alarm_register( entry->expDeltaInterval, SA_REPEAT, expExpression_getData, entry ); expExpression_getData( entry->alarm, (void*)entry ); }
This means even if I have an expression with no regular delta-value sampling (i.e. with all objects with expObjectSampleType 'absoluteValue'), I will still have to set expExpressionDeltaInterval to a non-zero value to make it work. As expected, doing so (as following) fixed the problem and my program worked.
snmpset -uuser Lo localhost DISMAN-EXPRESSION-MIB::expExpressionDeltaInterval.'"foo"'.'"bar"' = 1
As per my understanding of the DISMAN-EXPRESSION-MIB RFC, this is not how it is supposed to work. expExpressionDeltaInterval is only relevant for objects with expObjectSampleType 'deltaValue' as the following text from RFC states:
expExpressionDeltaInterval OBJECT-TYPE SYNTAX Integer32 (0..86400) UNITS "seconds" MAX-ACCESS read-create STATUS current DESCRIPTION "Sampling interval for objects in this expression with expObjectSampleType 'deltaValue'. This object has no effect if the the expression has no deltaValue objects. A value of 0 indicates no automated sampling. In this case the delta is the difference from the last time the expression was evaluated...
Solution
The function expExpression_getData() must also be called for expressions with delta value of zero, i.e. on-demand as the comment inside expExpression_getData() also states.
In the attached patch I call expExpression_getData() every time an expression is evaluated, both if the expression has a zero delta value or non-zero. For expressions with non-zero delta, the call won't have any effect anyway because a check in the beginning of the expExpression_getData() makes it return without doing anything.
Thanks for the patch! It has been applied to all active branches.