[SNMP4J] Single snmpset setting a RowStatus first to createAndWait and then to active not working on snmp4j-2.x

Iker Almandoz ialmandoz at assia-inc.com
Thu Jan 5 19:37:52 CET 2017


Hi Frank, 
Thanks for the quick response. 

I agree that the agent should implement createAndGo in this case.  Unfortunately I have to emulate a vendor element that doesn't support that and I must use the approach described with the single snmpset with createAndWait + active. 

If I were to change locally the code to newRow = false as it was in SNMP4j-Agent-1.x, are you aware of any problem I will generate in my agent outside of the agent not being fully compliant with the RFC2579 standard ?.  

Thanks a lot for your support on this !

best regards, 
Iker


-----Original Message-----
From: Frank Fock [mailto:fock at agentpp.com] 
Sent: Thursday, January 05, 2017 1:14 PM
To: Iker Almandoz <ialmandoz at assia-inc.com>
Cc: snmp4j at agentpp.org
Subject: Re: [SNMP4J] Single snmpset setting a RowStatus first to createAndWait and then to active not working on snmp4j-2.x

Hi Iker,
There was a bug/non-optimal code in SNMP4J-Agent 1.x which has now been fixed/improved. SNMP4J-Agent 2.x enforces now standard conformity which means you have to use RowStatus createAndGo to set a new row active with a single SET PDU.

Hope this helps anyway.

Best regards
Frank

> Am 05.01.2017 um 04:37 schrieb Iker Almandoz <ialmandoz at assia-inc.com>:
> 
> Hi Frank,
> 
> We have recently upgraded our snmp4j libraries from the 1.x branch to the 2.x newest versions in order to take advantage of the newest versions and have run into the following problem.
> As part of our usage of snmp4j, we simulate different vendors snmp interfaces in order to have a fully automated test suite of our product.
> For one such vendor, one of the scenarios we have to simulate the 
> dynamic row creation where in a single snmp packet, we set the 
> rowStatus first to createAndWait and in the same exact packet to 
> active Assuming the RowStatus OID is 
> SNMPv2-SMI::enterprises.30442.1.2.2.2.5.1.4 and I want to add a new 
> row with ifIndex = 8, I have to be able to do
> 
> snmpset -v2c -c public localhostot 
> SNMPv2-SMI::enterprises.30442.1.2.2.2.5.1.4.8 i 4 ... ( set a bunch of 
> other oIDs on that table to their initial value)... 
> SNMPv2-SMI::enterprises.30442.1.2.2.2.5.1.4.8 i 1
> 
> When using snmp4j-1.x, this was working fine.  I have been able to 
> narrow it down to here In the agent 1.4.3, in DefaultMOTable, we have
> 
>          if (row == null) {
>            // look for already prepared row
>            row = (MOTableRow)
>                getNewRows(request.getRequest()).get(cell.getIndex());
>          }
>          if (row != null) {
>            prepare(request, cell, mcol, row, false);
>            request.completed();
>            return;
>          }
> 
> So when the second RowStatus arrives, the row is found in getNEwRows, and we call prepare with newRow = false.
> This means that when the MoChangeEvent is created, the old value is 
> passed as creation is = false
> 
>      MOChangeEvent changeEvent =
>          new MOChangeEvent(this, new CellProxy(cell),
>                            cell.getCellOID(),
>                            (creation) ? null : row.getValue(cell.getColumn()),
>                            request.getVariableBinding().getVariable(),
>                            true);
> 
> and when the event is processed in the RowStatus class, in 
> beforePrepareMOChange I get a valid currentValue != notExistant so 
> setting it to active works fine
> 
> Now, if I move to agent-2.5.3, the first change in DefaultMoTable becomeso
>          R row = model.getRow(cell.getIndex());
>          boolean newRow = false;
>          if (row == null) {
>            // look for already prepared row
>            row = getNewRows(request.getRequest()).get(cell.getIndex());
>            newRow = true;
>          }
>          if (row != null) {
>            prepare(request, cell, mcol, row, newRow);
>            request.completed();
>          }
> 
> So now, as the getNewRows is returning the row, the MOChangeVent is created with a previous value of null which defaults to notExistant in RowStatus.
> Here, changeEvent.getOldValue() is null, so currentValue = notExistant and newValue = active.
>  public void beforePrepareMOChange(MOChangeEvent changeEvent) {
>    if (changeEvent.getOID().startsWith(oid)) {
>      int currentValue = notExistant;
>      if (changeEvent.getOldValue() instanceof Integer32) {
>        currentValue = ((Integer32) changeEvent.getOldValue()).getValue();
>      }
>      int newValue = ((Integer32) changeEvent.getNewValue()).getValue();
>      boolean ok = false;
>      switch (currentValue) {
> case notExistant:
>          ok = ((newValue == createAndGo) ||
>                (newValue == createAndWait) || (newValue == destroy));
>          break;
> 
> So with those values, I get within this method ok = false and the set request fails.
> 
> Any help/guidance you can give on this topic would be greatly appreciated as this is blocking our move to production with snmp4j-2.5 at this point.
> I can get our software run ok if I replace line 623 in DefaultMOTAble from
>            prepare(request, cell, mcol, row, newRow); to
>            prepare(request, cell, mcol, row, false);
> 
> however, I am not sure whether this is correct or why the newRow 
> variable is now passed instead of false as in 1.x Please let me know if you would need any additional information.
> 
> Best regards,
> Iker
> 
> 
> _______________________________________________
> SNMP4J mailing list
> SNMP4J at agentpp.org
> https://oosnmp.net/mailman/listinfo/snmp4j




More information about the SNMP4J mailing list