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

Frank Fock fock at agentpp.com
Thu Jan 5 19:13:53 CET 2017


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