[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

snmpconf A non-trivial policyAction example




There are many, many simple examples of policyActions that can be
expressed in only 1 or 2 lines of code. (turn off a port, set a
configuration option, etc.)

In order to see if the current version of the language is up to some
more complex tasks, I started writing some examples. I figured an
RMON2 example would satisfy the non-triviality test.

The example below sets up RMON2 AlMatrix monitoring on an interface
(for the RMON-ignorant: basically this will keep track of
application conversations). This is done by creating and configuring
the hlMatrixControlEntry.

An action like this might be associated with a filter such as
'roleMatch("trunk")' which would be used to automatically set up
AlMatrix monitoring only on trunk ports (not on access ports). This is
a good configuration practice because the trunk port is a more
efficient place to sniff the traffic rather than double-counting it on
each access port.

Enough RMON2 background, here's the script:

    char oid[STRINGLEN], value[STRINGLEN];
    int index, pdu;

    pdu = 0; /* Use PDU #0 */
    if (!(index = setRowStatus("hlMatrixControlStatus.*", 20)))
        return; /* couldn't find a free entry */

    sprintf(oid, "hlMatrixControlDataSource.%d", index);
    sprintf(value, "ifIndex.%d", $1);
    writeVarbind(pdu, 0, oid, TYPE_OBJECT_IDENTIFIER, value, 0);

    sprintf(oid, "hlMatrixControlNlMaxDesiredEntries.%d", index);
    writeVarbind(pdu, 1, oid, TYPE_INTEGER, "1000", 0);

    sprintf(oid, "hlMatrixControlAlMaxDesiredEntries.%d", index);
    writeVarbind(pdu, 2, oid, TYPE_INTEGER, "1000", 0);

    sprintf(oid, "hlMatrixControlOwner.%d", index);
    writeVarbind(pdu, 3, oid, TYPE_OCTET_STRING, "policy manager", 14);

    sprintf(oid, "hlMatrixControlStatus.%d", index);
    writeVarbind(pdu, 4, oid, TYPE_INTEGER, "1", 0);

    snmpsend(0, 5, OP_SET);

It's pretty straightforward. Basically it uses setRowStatus to find
and reserve an unused row, and then creates a single PDU with all of
the column values filled in and sends the SET.

This is useful to illustrate how reasonable it is to do some fairly
complex stuff, but it has a flaw which I'll identify and then fix.
Scripts run periodically so that they can re-assert whatever state the
policy is expected to enforce. The script above would create a control
entry for every iteration.

The fix is to see if a control entry already exists and, if so,
exit. The first time we create an entry we store the dataSource in the
scratchpad and then every time we execute, we retrieve it from the
scratchpad (if it's there), check to see if it still represents a
matrix on "this" interface, and if so, return immediately.

Here's the complete example. The new code is lines 4-9 and 18:

    char oid[STRINGLEN], value[STRINGLEN];
    int index, length, pdu;

    /* retrieve dataSource and make sure it exists */
    if (getScratchpad(0, oid, &length) && exists(oid)){
        getvar(oid, value, &length);
        if (subid(value, 10) == $1) /* still points to this interface */

            return;
    }

    if (!(index = setRowStatus("hlMatrixControlStatus.*", 20)))
        return; /* couldn't find a free entry */

    pdu = 0; /* Use PDU #0 */
    sprintf(oid, "hlMatrixControlDataSource.%d", index);
    sprintf(value, "ifIndex.%d", $1);
    writeVarbind(pdu, 0, oid, TYPE_OBJECT_IDENTIFIER, value,
strlen(value));
    setScratchpad(0, oid, strlen(oid));

    sprintf(oid, "hlMatrixControlNlMaxDesiredEntries.%d", index);
    writeVarbind(pdu, 1, oid, TYPE_INTEGER, "1000", 0);

    sprintf(oid, "hlMatrixControlAlMaxDesiredEntries.%d", index);
    writeVarbind(pdu, 2, oid, TYPE_INTEGER, "1000", 0);

    sprintf(oid, "hlMatrixControlOwner.%d", index);
    writeVarbind(pdu, 3, oid, TYPE_OCTET_STRING, "policy manager", 14);

    sprintf(oid, "hlMatrixControlStatus.%d", index);
    writeVarbind(pdu, 4, oid, TYPE_INTEGER, "1", 0);

    snmpsend(0, 5, OP_SET);


I'm pretty happy how these examples turned out.

By the way, there are a couple of subtle differences in the API that are
reflected here but are not yet shown in the draft. The most obvious is
the inclusion of sprintf.


Steve