Subject: Re: subidwrite/substr draft-ietf-snmpconf-pm-05.txt questions

From: Steve Waldbusser <[email-masked]>
Date: Tue, 17 Jul 2001 00:07:50 -0700

Cleaning up some old email...

Steve Moulton wrote:
> 
> A couple of questions have come up in implementing the policy language.
> 
> . Page 48, 49, draft-ietf-snmpconf-pm-05.txt, para 9.4.7:
> 
>   subidwrite returns -1 on error.  What does subidwrite
>   return if there is no error?

Good call. I've modified this to say it returns zero if no error.

> . Page 52, draft-ietf-snmpconf-pm-05.txt, para 9.4.16:
> 
>     string substr(string &str, integer offset,
>                   integer len [, string replacement])
> 
>    The substr prototype only shows the replacement argument as
>    optional, but the description says that len may be omitted (to
>    get the rest of the string after offset regardless of length).
>    The len argument is not bracketed in the prototype.
> 
>    It makes sense to be able to specify the replacement string
>    without the length (replace everything starting at offset), but
>    one must intuit the argument types to figure out to which
>    argument the third string must be assigned.
> 
>    I see two choices here:
> 
>    .  Remove the replacement functionality from this function.
>       String replacement is orthogonal to extracting a substring.
>       At the risk of cluttering up the language, I think this is
>       the correct solution.
> 
>    .  Make the len argument nonoptional when doing string replacement.
>       This means that one is always going to have to think about
>       len (i.e., there is no way to specify "replace everything after
>       offset 5 with this string, expanding or contracting the
>       string as necessary).  I guess just supplying a huge value
>       would be adequate.

Substr is borrowed from perl where it has all these semantics (including
replace). I'd like to use it unchanged, if possible.

I like your second choice, or a third choice:

- the len argument must be present if the replacement argument is
present. This is the solution whenever there is more than one optional
argument to a function and there are many examples in this library.

I'd prefer #3.

Steve

---

From: Steve Moulton <[email-masked]>
Date: Wed, 18 Jul 2001 17:00:08 -0400

Steve (W),

I'm combining several issues together to minimize mailing list traffic.

> argument to a function and there are many examples in this library.

When did Larry Wall sneak in the substitute argument?  I missed that
entirely!  Just now found it on a redhat 7.1 system.

How about 

string substr(string &str, integer offset [,
                integer len [, string replacement]])

This solves the "what must be present" issue, and disambiguates
the arguments, as well as aligning with the Perl semantics.

I still think we need to address the "replace everything
starting at OFFSET to the end of STR with REPLACEMENT" issue.
One could either specify a distinguished value for LEN with this
meaning (I don't favor this), or supply the example

   substr(str, offset, strlen(str) - offset, replacement)

which, due to the choice of 0-based offset (yay!), works without fencepost 
jiggering.  I think supplying this or a similar example would be 
adequate to close the issue.

> > 40. Definition of execution context - page 6
> > 
> >     I am having some trouble with the definition of context on page 6.
> > 
> >     The address of "this element' contains
> >     .  index of the element
> >     .  context the element was discovered in (contextName?)
> >     .  address of system element was discovered on
> > 
> >     according to the running text, but does not seem to contain
> >     any reference to the policy being executed or to the base OID
> >     of the element the policy is being executed on. I think
> >     the execution context is fully described by (index, context, address,
> >     object, policy).
> 
> The "address of this element" is different than the "execution context".
> You are right that the execution context is fully described by (index,
> context, address, object, policy). But within a script (where the policy
> is implicitly known), the script will want to know the address of the
> thing it is currently working on, and that is described by (index,
> context, address).

I've got it now.

Further explicative text would be helpful.  Let me know if you want
me to contribute something, but your explanation above forms the basis.
  
> >     There is currently no way to get the base OID for the element
> >     being considered, nor the index (say pmPolicyIndex) of the policy
> >     being executed.  I'm not sure it is necessary to be able to get
> >     the OID, since the policies are going to be highly object-specific,
> >     but it could be useful to be able to get the policy.
> 
> The base OID can be retrieved by elementName(). There isn't a way to get
> the policyIndex, but I don't think it is necessary for a script to
> reference the MIB row in which it is contained. Another way to say it is
> that I always know what policy I am.

I agree.  I can't think of a reason to want the ability to get the
script index right now.

> But I think there's a small hole here. If a policy can work with two
> kinds of elements, the base OID will need to be part of the "address".
> This just augments the terminology a bit: $1, $2, ... will still be
> index components only. If you need to get the base OID (infrequent), use
> elementName() (that's why it exists).

Got it.

> > 42. MIB knowledge
> > 
> >     Section 7 implies that there will be some mechanism $* to tell where
> >     the object ends and the index begins in an OID.  However,
> >     it has been made clear that the agent implementing this will
> >     not have MIB knowledge (can't use "ifType.7" as an OID, for
> >     example).
> > 
> >     Will this information be intuited from the pmPolicyElementTypeFilter?
> 
> The break point from base oid to index is specified by the length of the
> pmElementTypeRegOidPrefix. No MIB knowledge is required.

This makes sense.  A little additional text along the lines of 
the following would be helpful to implementers. 
After
        portSpeed = getVar("ifSpeed." + ev(0));
 
+   The ec() and ev() functions use the pmElementTypeRegOidPrefix
+   object to determine the base OID, and thus the index
+   subidentifiers.

> > 43. 9.1.1 SNMP Operations on Non-Local Systems.
> > 
> >     It appears (but is not completely unambiguous) that the contextName can
> >     be passed by the optional context argument that is associated
> >     with SNMP accessor functions.  However, there no mechanism to pass
> >     the contextEngineID that I can find.  While it seems unlikely that ther
e
> >     will be proxy agents between the policy MIB agent and the managed agent
,
> >     not providing a contextEngineID blocks out much of this possibility.
>  
> I think this is fine but I'll look at it again.

I'm going to push this a step further.  Since the IP address and
context does not uniquely identify an off-box SNMPv3 entity when
it is separated from the box by a proxy, the contextEngineID is
a necessary part of the information identifying an element.
(index, context, address) is not adequate.  It needs to be
(index, context, address, contextEngineID) (where the contextEngineID
should be empty if the destination off-box agent is not v3-capable, as
the identifying information should ride in the context).

> > 44. 6.9.2 Scope of Constants
> > 
> >     We simplified the language by removing scoping for variables.
> >     Unfortunately, we have re-complicated things by introducing
> >     scoping for constants (they only make sense in certain
> >     accessor function invocations).
> > 
> >     This leads to two problems:
> > 
> >     .  The compiler has to be sensitive as to the accessor function
> >        name when compiling the script.  This leads to unnecessary
> >        complexity in the compiler.
> > 
> >     .  Suppose a variable and a constant have the same name.  On
> >        invocation of an accessor function that accepts the constant
> >        values, which is used?
> > 
> >    This would be solved (and would make the language much neater)
> >    by declaring that the defined constants have global scope.
> 
> I have no problem with this. In fact, I never believed them to be scoped
> to begin with. Do you just want me to explicitely say that they are
> global (or did I inadvertently say they are locally scoped?).

That is the way I read 

        9.2.  Constants
        
        The following constants are defined for use in all SNMP
        Accessor Functions. Policy code will be executed in an
        environment where the following constants are declared. (Note
        that these constant declarations will not be visible in the
        policyCondition or policyAction code.)

I read this to say that you can only use the constants in SNMP
accessor function invocations, and that they are invisible 
elsewhere in scripts (since all scripts are either policyCondition
or policyAction code). 

This also seems to mean that I can't use the SNMP Error Constants in 
comparisons to determine what error is being returned.

I think if we omit the first and third sentences in the first paragraph
of 9.2, the problem will be resolved.

> > 45. 6 9.4.1 regexp
> >     The use of the word "copied" is ambiguous about the disposition
> >     of the original contents of the "match" string.  I'm guessing that
> >     the original contents of "match" are replaced.
> 
> I've reworded. How about:
>         If the optional argument 'match' is provided and a match is
>         found, 'match' will be replaced with the text of the first
>         substring of 'str' that matches 'pattern'. If no match is
>         found it will be unchanged.

Yes.  I like this.

> > 47. die() semantics
> > 
> >     From a recent message:  die() as used in Perl has different
> >     arguments than die() in policyScript.  Should the die() accessor
> >     function in policyScript be replaced?
> 
> I will rename it. I don't have a name in mind yet. How about term or
> terminate?

I rather prefer die(), but Wes does have a point; it is frequently used
in Perl.  Perl also has an exit().  

I like fail().

> > 48. pmPolicyTypeFilter SYNTAX
> > 
> >     Since multiple element types can be registered, is there any
> >     reason to limit the SYNTAX to (SIZE(0..128))?
> 
> I think it's arbitrary but sensible.

Whoops, make that pmPolicyElementTypeFilter.

I guess I was struck by the limitation being the same as that
of an OID, which is unrelated to the length of this octet string.
This does limit the number of element types to six if the OIDs are
similar to that of the ifTable.  I can't think of a practical
cost to it, but then again I haven't had to deal with long
base object identifiers.

	- Steve

---
Steve Moulton        SNMP Research, Inc            voice: +1 865 573 1434
Sr Software Engineer 3001 Kimberlin Heights Rd.    fax: +1 865 573 9197
[email-masked]     Knoxville, TN 37920-9716 USA  http://www.snmp.com

---

From: Steve Waldbusser <[email-masked]>
Date: Thu, 19 Jul 2001 15:57:41 -0700

> the arguments, as well as aligning with the Perl semantics.

I think we agree except on the notational convention to achieve this.
There are many functions that have multiple optional arguments. I
experimented with the nested [ A [, B]] notation and it proved to be
unwieldy. So I settled a while ago on the convention of describing it in
the text "if B exists, A must also exist". Also, the following
text is at the beginning of the accessor function library:

  "In the function prototype, the '[' and ']' characters surround
  arguments that are optional. In PolicyScript code, the optional
  argument may only be included if all optional arguments to the left
  of it are included. The function may place restrictions on when an
  optional argument must, or must not, be included."

Any, I clarified substr by making the declaration:
    string substr(string &str, integer offset
                  [, integer len, string replacement])

and declaring:
" If 'replacement' is included, the 'len' argument must also be
included."

> adequate to close the issue.

OK, I added the example.

> +   object to determine the base OID, and thus the index

I added the following text to the beginning "element discovery" section:
"The agent can
determine the index portion of discovered OIDs based on the length of
the pmElementTypeRegOIDPrefix for the portion of the MIB that is being
retrieved."

This is a better location because it describes the actual mechanics of
using the elementTypeReg table and passing element addresses to scripts.

> the identifying information should ride in the context).

You're right. I'll add contextEngineID.

> elsewhere in scripts (since all scripts are either policyCondition

No, that isn't what it says (or means to say). The first sentence says
that these constants exist to serve *all* SNMP Accessor Functions (i.e.
setVar() doesn't use a different const to mean "Integer" than
writeVar()). The second says that all policy code is treated as if the
const's had been declared. The part in parenthesis means that the
declaration itself won't be visible - it's as if there's an invisible
#include at the beginning of every script.

I'll see if I can reword it. My guess is that the first sentence was the
problem.

> in Perl.  Perl also has an exit().

I've changed it to fail().

Steve

---

From: Steve Moulton <[email-masked]>
Date: Tue, 24 Jul 2001 11:13:35 -0400

> " If 'replacement' is included, the 'len' argument must also be

I can go along with this, as long as this convention is described
early on in the document.  The nested square bracket convention
is nearly universal in software documentation, and, without something 
early on in the document, will be assumed by the reader regardless 
of running text.

> I'll see if I can reword it. My guess is that the first sentence was the

The last sentence is what confused me.

How about ...

"Note that these constant declarations are implicit in policyCondition
 or policyAction code."

The current text does say that, but I misread it three times to mean
the constants are not visible.  Maybe I'm the one with the parity
error, but I suspect others (as have others here) may misread it
the same way.

> > of 9.2, the problem will be resolved.

That would work too.  
I'd prefer s/constants are declared/constants are implicitly declared/

I'm happy with the closure on the rest of the issues I raised.

        - Steve
---