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

AUGMENTS and SPARSE-AUGMENTS



Hi,

Here is an attempt to extend AUGMENTS to all complex data types,
in a way that is (hopefully) compatible with SMIv2 AUGMENTS. 
A new variant to AUGMENTS, called SPARSE-AUGMENTS is added as well.

AUGMENTS Syntax
---------------

  <aug-construct-type> <object-descriptor> "AUGMENTS" 
     <object-descriptor> <aug-object-decl>

  <aug-construct-type> ::= ( "SCALAR" | "ARRAY" | "UNION" | "STRUCT" )

  <aug-object-decl> ::= 
     ( <scalar-core-decl> | 
       <array-inline-core-decl> | <array-ref-core-decl> |
       <union-inline-core-decl> | <union-ref-core-decl> |
       <struct-inline-core-decl> | <struct-ref-core-decl> )


   - <aug-construct-type> now indicates the type of construct that is
     being conceptually added to the augmented container as another
     conceptual <object-decl>. 
   - first <object-descriptor> indicates name of augmenting variable
   - second <object-descriptor> indicates name of augmented variable
   - <aug-construct-decl> indicates the <object-decl> construct
     that is being conceptually added to the base variable. It must
     conform to the syntax indicated by <aug-construct-type> 
   - The OID naming algorithm is slightly modified for AUGMENTS:
     all index nodes for the augmented variable are pre-pended
     to the index buffer before adding any index nodes from
     the augmenting variable (see example 3 for details)

SPARSE-AUGMENTS Syntax
----------------------

  <aug-construct-type> <object-descriptor> "SPARSE-AUGMENTS"
      
     <object-descriptor> <condition-clause> <aug-object-decl>

  <condition-clause> ::=
     "CONDITION-DESCR" Text 
    ["CONDITION-EXPR" Text]

  - the expression syntax for CONDITION-EXPR is very TBD.
    The expression in example 3 is for demonstration purposes only
  - It may not be possible to express all SPARSE-AUGMENTS
    conditions and still keep the complexity manageable,
    so the CONDITION-EXPR clause is optional.

-----------------------------------------------

Example 1) Augmenting a STRUCT with a SCALAR
    -- from the 2d/3d Point example in SMI-DS I-D

TYPEDEF STRUCT Point {
    DESCRIPTION
        "A 2 dimensional point."

    SCALAR x {
       SYNTAX      Unsigned32
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The X-axis coordinate value for the point."
    } ::= 1

    SCALAR y {
       SYNTAX      Unsigned32
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The Y-axis coordinate value for the point."
    } ::= 2
}

STRUCT myPoint {
    SYNTAX      Point
    STATUS      current
    DESCRIPTION
       "An example variable instance of a 2d point."
} ::= { myObjects 1 }

SCALAR z AUGMENTS myPoint {
    SYNTAX      Unsigned32
    STATUS      current
    DESCRIPTION
       "An example augmentation of a point."
} ::= { myObjects 2 }

Note 1) 
Only variables of complex types can be augmented. The data objects
defined in 'z' are conceptually added to the base object 'myPoint'
outermost container as another <object-decl>. The naming algorithm
for the augmenting variable is inherited from the data type for 
augmented variable.

Note 2)
New OID Naming for this example:

   myPoint        ::=   { myObjects 1 }
   myPoint.x      ::=   { myPoint 1 1 }
   myPoint.y      ::=   { myPoint 1 2 }
   myPoint.z      ::=   { myObjects 2 1 1 }

------------------------------------------

Example 2) Augmenting an ARRAY with a STRUCT
   -- from the InetStats example in the SMI-DS I-D
      refer to the I-D for the InetHostStats and 
      HostStatsTimeData TYPEDEFs

ARRAY ipStats {
    SYNTAX      InetHostStats
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
       "The IP host statistics for this network device."
} ::= { myObjects 3 }

STRUCT hcIpStats AUGMENTS ipStats {
    DESCRIPTION
        "Adds HC counters and additional information to
         each ipStats statistics entry."

    SCALAR inHCPkts {
       SYNTAX      Counter64
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The number of packets received by the specified host
           on the specified interface."
    } ::= 1

    SCALAR outHCPkts {
       SYNTAX      Counter64
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The number of packets transmitted by the specified
           host on the specified interface."
    } ::= 2

    SCALAR inHCOctets {
       SYNTAX      Counter64
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The number of octets received by the specified host
           on the specified interface."
    } ::= 3

    SCALAR outHCOctets {
       SYNTAX      Counter64
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The number of octets transmitted by the specified
           host on the specified interface."
    } ::= 4

    STRUCT timeData {
       SYNTAX      HostStatsTimeData
       STATUS      current
       DESCRIPTION
          "Additional time-related information."
    } ::= 5
} ::= { myObjects 4 }

Note 1)
It may not be obvious (not shown in this example), but the SMI-DS algorithms 
for adding hierarchical containment to the SMI would break if the IMPLIED 
keyword were allowed in any situation other than a transformation of an 
SMIv2 table to an SMI-DS ARRAY.  AUGMENTS would also break in the same manner.

Note 2)
SMI-DS OID Naming for this example 
  (ifIndex=17, inetAddressType=1, inetAddress=192.168.0.1)

  ipStats                     ::=   { myObjects 3 }
  ipStats[17]                 ::=   N/A
  ipStats[17][1]              ::=   N/A
  ipStats[17][1][192.168.0.1] ::=   N/A
  ipStats[17][1][192.168.0.1].inPkts    ::= { ipStats 1 1 17 1 4 192 168 0 1 }
  ipStats[17][1][192.168.0.1].outPkts   ::= { ipStats 1 2 17 1 4 192 168 0 1 }
  ipStats[17][1][192.168.0.1].inOctets  ::= { ipStats 1 3 17 1 4 192 168 0 1 }
  ipStats[17][1][192.168.0.1].outOctets ::= { ipStats 1 4 17 1 4 192 168 0 1 }

  hcIpStats                     ::=   { myObjects 4 }
  hcIpStats[17]                 ::=   N/A
  hcIpStats[17][1]              ::=   N/A
  hcIpStats[17][1][192.168.0.1] ::=   N/A
  hcIpStats[17][1][192.168.0.1].inHCPkts    ::= { hcIpStats 1 1 17 1 4 192 168 0 1 }
  hcIpStats[17][1][192.168.0.1].outHCPkts   ::= { hcIpStats 1 2 17 1 4 192 168 0 1 }
  hcIpStats[17][1][192.168.0.1].inHCOctets  ::= { hcIpStats 1 3 17 1 4 192 168 0 1 }
  hcIpStats[17][1][192.168.0.1].outHCOctets ::= { hcIpStats 1 4 17 1 4 192 168 0 1 }
  hcIpStats[17][1][192.168.0.1].timeData    ::= { hcIpStats 1 5 17 1 4 192 168 0 1 }
  hcIpStats[17][1][192.168.0.1].timeData.createTime  ::= 
                                                { hcIpStats 1 5 1 17 1 4 192 168 0 1 }
  hcIpStats[17][1][192.168.0.1].timeData.updateInterval  ::= 
                                                { hcIpStats 1 5 2 17 1 4 192 168 0 1 }

Note 3)
Except for the timeData STRUCT in this example, the 4 SCALAR counters
demonstrate a transparent transformation of an SMIv2 table which uses the AUGMENTS
clause instead of an INDEX clause.

Note 4)
The augmenting container is conceptually unwrapped inside the augmented container,
instead of being added with another level of containment, i.e., 'hcIpStats' is not 
the descriptor conceptually added to 'ipStats', but rather its contents 
('inHCPkts', etc.). This doesn't apply to SCALARs, because they are not containers.

-----------------------------------

Example 3)  Sparse Augmenting an ARRAY with an ARRAY
   -- from the InetStats example in the SMI-DS I-D
      refer to the I-D for the InetHostStats and GenericCounter TYPEDEFs


ARRAY portStats SPARSE-AUGMENTS ipStats 
    CONDITION-DESCR 
       "An entry exists in this array for each entry in the ipStats 
        array in which the inetAddress type is equal to ipv4(1)."
    CONDITION-EXPR
       "addrType==1"             
{
    DESCRIPTION
        "Adds an array indexed by TCP or UDP port number, 
         containing 2 counters."

    INDEX portNum {
        SYNTAX  InetPortNumber       -- range of the INDEX
        SIZE    (0..65535)           -- range of the instances
        DESCRIPTION
            "The transport layer port number for these statistics."
    }

    UNION pkts {
       SYNTAX      GenericCounter
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The number of packets..."
    } ::= 1

    UNION octets {
       SYNTAX      GenericCounter
       MAX-ACCESS  read-only
       STATUS      current
       DESCRIPTION
          "The number of octets..."
    } ::= 2
} ::= { myObjects 5 }

Note 1)
SMI-DS OID Naming for this example 
  (ifIndex=17, inetAddressType=1, 
   inetAddress=192.168.0.1, inetPortNumber=80)

  portStats                     ::=   { myObjects 5 }
  portStats[17]                 ::=   N/A
  portStats[17][1]              ::=   N/A
  portStats[17][1][192.168.0.1] ::=   N/A
  portStats[17][1][192.168.0.1][80] ::=   N/A
  portStats[17][1][192.168.0.1][80].pkts  ::= N/A
  portStats[17][1][192.168.0.1][80].pkts.c32 ::=
                                { portStats 1 1 1 17 1 4 192 168 0 1 80 }
  portStats[17][1][192.168.0.1][80].pkts.c64 ::=
                                { portStats 1 1 2 17 1 4 192 168 0 1 80 }
  portStats[17][1][192.168.0.1][80].pkts.c32pair ::= N/A
  portStats[17][1][192.168.0.1][80].pkts.c32pair.c32low ::=
                                { portStats 1 1 3 1 17 1 4 192 168 0 1 80 }
  portStats[17][1][192.168.0.1][80].pkts.c32pair.c32hi ::=
                                { portStats 1 1 3 2 17 1 4 192 168 0 1 80 }
  portStats[17][1][192.168.0.1][80].octets  ::= N/A
  portStats[17][1][192.168.0.1][80].octets.c32 ::=
                                { portStats 1 2 1 17 1 4 192 168 0 1 80 }
  portStats[17][1][192.168.0.1][80].octets.c64 ::=
                                { portStats 1 2 2 17 1 4 192 168 0 1 80 }
  portStats[17][1][192.168.0.1][80].octets.c32pair ::= N/A
  portStats[17][1][192.168.0.1][80].octets.c32pair.c32low ::=
                                { portStats 1 2 3 1 17 1 4 192 168 0 1 80 }
  portStats[17][1][192.168.0.1][80].octets.c32pair.c32hi ::=
                                { portStats 1 2 3 2 17 1 4 192 168 0 1 80 }

Note 2)
The naming scheme actually allows for intermediate containers
to be represented, that are marked N/A in the examples, such as:

  portStats[17][1][192.168.0.1][80].octets.c32pair ::=
                                { portStats 1 2 3 17 1 4 192 168 0 1 80 }

Such OIDs represent objects that are not accessible with SNMP.

------------------------------------------------

Summary)

I believe all affected SMIv2 --> SMI-DS transformations are now
transparent to existing SMIv2-based instrumentation SW.
   -- scalar
   -- table w/ INDEX
   -- table w/ AUGMENTS
   -- compatible with existing OID pointers
   -- compatible with VACM
I'm not claiming SMI-DS is done, just that we can switch to
hierarchical naming in a way that doesn't break existing SNMP code.
(Hopefully the WG will spend some time now to verify this claim ;-)


Andy