Subject: Creating DS0s and DS0Bundles.

From: Dave Fowler <[email-masked]>
Date: Sun, 01 Feb 1998 16:28:00 -0500

My 2 cents:

Whenever a DS1 is channelized, the 24, 30, or 31 DS0 entries should be
created
automatically in the ifTable.  Dynamic creation of DS0s does not make
sense.
The dsx0ChannelNumber value should be assigned by the agent. 
dsx0ChannelNumber should 
be read-only.  ds0s are not created as a result of a ds1 that represents
a ds2 (lineType
is dsx1DS2M12 or dsx1E2, OR if speed not equal to 1544000 or 2048000.

ds0Bundles should be created as required.  Below is a modified version
of the
ds0BundleStubTable that was in the last draft.  I've followed Keith's
suggestion 
to change the name.

If we agreee that there must be one of these for every ds0Bundle, then
the
ds0BondingGroup does not need to be mandatory.  I prefer this solution
since I
expect the frequency of bonding to be much lower than the frequency of
ds0Bundles.

I would also like to add text in the narrative above the MIB to clarify
that
ds0Bundles only bundle ds0s.  Once a bundle is created, rows in the
ifStackTable 
can be created to associate the bundle with the ds0s it is bundling.

Comments?

David

          dsx0BundleNextIndex OBJECT-TYPE
              SYNTAX  TestAndIncr
              MAX-ACCESS  read-write
              STATUS  current
              DESCRIPTION
                      "This object is used to assist the manager in
                      selecting a value for dsx0BundleIndex.
                      Because this object is of syntax TestAndIncr (see
                      the SNMPv2-TC document, RFC1903) it can also be
                      used to avoid race conditions with multiple
                      managers trying to create rows in the table.

                      If the result of the SET for dsx0BundleNextIndex
                      is not success, this means the value has been
changed
                      from index (i.e. another manager used the value). 
Also
                      the agent will not proceed with the second SET for
                      dsx0BundleRowStatus.

                      The algorithm is:
                      while done == false
                          index = GET (dsx0BundleNextIndex.0)
                          SET (dsx0BundleNextIndex.0=index,
                               dsx0BundleRowStatus.index=createAndGo)
                          if (set of first variable failed)
                            done = false
                          else
                            done = true
                            other error handling"
              ::= { ds0Bundle 2 }

          dsx0BundleTable OBJECT-TYPE
              SYNTAX  SEQUENCE OF Dsx0BundleEntry
              MAX-ACCESS  not-accessible
              STATUS  current
              DESCRIPTION
                      "There is an entry in this table for each
Ds0Bundle
                       interface.  The table can be used to (indirectly) 
                       create rows in the ifTable with
ifType='ds0Bundle(82)'."
              ::= { ds0Bundle 3 }

          dsx0BundleEntry OBJECT-TYPE
              SYNTAX  Dsx0BundleEntry
              MAX-ACCESS  not-accessible
              STATUS  current
              DESCRIPTION
                      "There is an entry in this table for each
ds0Bundle
                       interface."
              INDEX   { dsx0BundleIndex }
              ::= { dsx0BundleTable 1 }

          Dsx0BundleEntry ::=
              SEQUENCE {
                  dsx0BundleIndex     INTEGER,
                  dsx0BundleIfIndex   InterfaceIndex,
                  dsx0BundleRowStatus RowStatus
          }

          dsx0BundleIndex OBJECT-TYPE
              SYNTAX  INTEGER(0..2147483647)
              MAX-ACCESS  read-create
              STATUS  current
              DESCRIPTION
                      "A unique identifier for a ds0Bundle. This is
                      not the same value as ifIndex. This table is not
                      indexed by ifIndex because the manager has to
                      choose the index in a createable row and the agent
                      must be allowed to select ifIndex values."
              ::= { dsx0BundleEntry 1 }

          dsx0BundleIfIndex OBJECT-TYPE
              SYNTAX  InterfaceIndex
              MAX-ACCESS  read-only
              STATUS  current
              DESCRIPTION
                      "The ifIndex value the agent selected for the new
                      ds0Bundle interface."
              ::= { dsx0BundleEntry 2 }

          dsx0BundleRowStatus OBJECT-TYPE
              SYNTAX  RowStatus
              MAX-ACCESS  read-create
              STATUS  current
              DESCRIPTION
                      "This object is used to create and delete rows in
                      this table."
              ::= { dsx0BundleEntry 3 }

-- 
David Fowler                                   email:
[email-masked]
Newbridge Networks Corporation                 voice: (613) 599-3600 
ext.6559
600 March Rd, Kanata, Ontario, Canada K2K 2E6  fax:   (613) 599-3619

---

From: Gary Hanson <[email-masked]>
Date: Mon, 2 Feb 1998 10:16:09 -0800 (PST)

Dave,

I have some comments below that you and others in the WG may want to
consider about DS0 and DS0 bundle creation.

Regards,
Gary

 ______
| ///  |       TM   Gary Hanson                [email-masked]
|   ADC|Kentrox     14375 NW Science Park Dr.  503-641-3321 (FAX)
|______|            Portland, Oregon  97229    800-733-5511 x6333

> automatically in the ifTable.  Dynamic creation of DS0s does not make

I have several comments here, so I will put them under several headings:

When is a ds1 channelized?
--------------------------

When you say "Whenever a DS1 is channelized", I note that we cannot
assume that this means ANY framed ds1 (running at 1544000 or 2048000).

I agree with you that dynamic creation of ds0s does NOT make sense, but
ONLY IF it is known apriori that a ds1 is channelized.  In many cases,
it IS known apriori whether a ds1 is or is not channelized.  However, in
other cases, such as for structured vs. unstructured circuit emulation
over ATM, it is not, and it instead becomes a configuration option that
needs to be addressed in either a standard or an implementation-specific
manner.

In cases where the ds1 is NEVER channelized, I agree that the agent
should never be expected to create the ds0s, since their presence in
the ifTable would be an unnecessary waste of resources and an obstacle
to managers that need to walk over them.

In cases where the ds1 is ALWAYS channelized, I think it would be
important to mention explicitly in the DS0-MIB that a ds1 ifEntry for
a framed DS1 or E1 circuit would NEVER appear alone in an ifTable, but
would ALWAYS be accompanied by the appropriate number of corresponding
ds0 ifEntries, all of which are created (and given previously unused
ifIndex values) by the agent at the same time that the ds1 ifEntry is
created.

In cases where the manager must be able to turn channelization on and off
it would be my preference to have a standard object available that has
the read-write semantics of controlling and reporting whether a ds1 is
currently channelized or not.  For those ds1 interfaces that are fixed by
implementation to be always channelized, this object would be read-only.
For those ds1 interfaces that are fixed by implementation to be never
channelized, this object would not exist.

Such an object could either be put directly in the dsx1ConfigTable of the
DS1-MIB, although since it would relate to the existence/non-existence of
ds0 ifEntries, such an object could also be put in the DS0-MIB instead of
the DS1-MIB.  The latter approach would allow it to be used to control not
only the channelization of ds1 ifEntries down to ds0 ifEntries, but also
the channelization of higher aggregates (e.g, ds3 ifEntries) directly down
to ds0 ifEntries.

Here is some proposed ASN.1 for such a table, using the latter approach
of putting it in the DS0-MIB:

First, expand the comments for the DS0 Config Group to include a new
table:

          -- The DS0 Config Group

          -- Implementation of this group is mandatory for all
          -- systems that use a DS0 Interface.

          -- The DS0 Config Group consists of two tables:
          --    DS0 Configuration
          --    DS0 Channelization Control

Second, add the new table:

          dsx0ChanControlTable OBJECT-TYPE
              SYNTAX  SEQUENCE OF Dsx0ChanControlEntry
              MAX-ACCESS  not-accessible
              STATUS  current
              DESCRIPTION
                      "The DS0 Channelization Control table."
              ::= { ds0 3 }

          dsx0ChanControlEntry OBJECT-TYPE
              SYNTAX  Dsx0ChanControlEntry
              MAX-ACCESS  not-accessible
              STATUS  current
              DESCRIPTION
                      "An entry in the DS0 Channelization Control table.
                      There is an entry in this table corresponding to
                      each ifEntry that is itself capable of direct
                      channelization down to the individual ds0(81)
                      ifEntry level."
              INDEX   { ifIndex }
              ::= { dsx0ChanControlTable 1 }

          Dsx0ChanControlEntry ::=
              SEQUENCE {
                  dsx0ChannelizationEnabled  TruthValue
          }

          dsx0ChannelizationEnabled OBJECT-TYPE
              SYNTAX  TruthValue
              MAX-ACCESS  read-write
              STATUS  current
              DESCRIPTION
                      "This object controls whether the given interface is
                      channelized down to the individual ds0(81) level.
                      This can be applied to ds1(18) interfaces that are
                      capable of such channelization.  It can also apply to
                      interfaces of higher DS0 aggregation, such as ds3(30),
                      if there is no intervening ds1(18) ifEntry layer.

                      For interfaces where the DS0 channelization is always
                      enabled, this object may be read-only.  For interfaces
                      which never utilize DS0 channelization, this object
                      should not exist."
              ::= { dsx0ChanControlEntry 1 }

Third, add conformance information regarding the new table and objects:
- The dsx0ChanControlTable would be mandatory for those agents that
  support DS0 channelization.
- The dsx0ChannelizationEnabled object would be a mandatory object.

If this is acceptable, it would answer my original question of how a
management entity can "request" the agent to dynamically channelize a
particular ds1 ifEntry in a standard way, for those cases in which it
is appropriate to do so.

Number of DS0 entries
---------------------

I would like to request that the dsx0ChannelNumber be given a larger
range, of at least 0..31.  It is certainly conceivable that someone
may want to pass E1 timeslot 0 through some switched network, either
to pass SA bits containing an E1-style FDL, or for some other purpose
that we cannot foresee at this time.  Perhaps the agent can be allowed
the option whether to create 30, 31, or 32 DS0 entries for each of its
channelized E1 circuits, depending upon the selected framing format and
on its own capabilities with regard to cross-connecting timeslot 0.

In any case, it would be easier to change the range to 0..31 now rather
than later, when there may be religious debate about the propriety of
expanding the range.

To accommodate channelization of larger aggregates (e.g., DS3 or higher),
it would be more appropriate to remove the explicit INTEGER range for the
dsx0ChannelNumber altogether.  This would allow for unforeseen expansion
in the future without having to roll the DS0-MIB.  Appropriate text could
be added to the DESCRIPTION to indicate the intent of the numbering plan
for DS1 and E1 interfaces.  For example:

  "For DS1 interfaces, the channel numbers can range from 1 to 24.  For
  E1 interfaces, the channel numbers can range from 0 to 31, and it is an
  implementation choice whether entries in this table exist for channel 0
  and channel 16.  For direct DS0 channelization of other interfaces, such
  as ds3(30), the channel number assignments are implementation-specific."

In addition, I think it would be important to explicitly state that
the agent must automatically create the ifStackTable entries for the
various ds0 ifTable entries that it stacks over each ds1 ifTable entry.

Limitations of the ifStackTable
-------------------------------

I am concerned about a limitation of the current ifStackTable.  (I will
raise it to the trunk-mib WG before raising it to the if-mib WG, since
the limitation applies directly to the usage of the DS0-MIB.)

Since the ifStackTable only shows the high-to-low mapping, it is EASY
for a manager to find the ds1 ifEntry upon which a given ds0 ifEntry is
stacked.  However, it is comparatively DIFFICULT for a manager to find
the various ds0 ifEntries that are stacked above a given ds1 ifEntry.

For example, if you know that H is the ifIndex of a particular ds0
ifEntry, issuing a get-next of ifStackStatus.H that returns the value
L for ifStackStatus.H.L accomplishes a trivial table lookup for the
underlying ds1 ifEntry with an ifIndex of L.

However, if you know that L is the ifIndex of a particular ds1 ifEntry,
a manager must either walk the entire ifStackStatus column to find
entries of the form ifStackStatus.X.L, or else walk those portions of
the ifStackStatus.X column where X was seen as an ifIndex INDEX of the
dsx0ConfigTable.

Similarly, because the ifStackTable reveals the downward multiplexing
much more readily than the upward demultiplexing, it is EASY for a
manager to find the various ds0 ifEntries that are bundled with a given
ds0Bundle ifEntry.  However, it is comparatively DIFFICULT for a manager
to find the ds0Bundle ifEntry into which a particular ds0 ifEntry has
been bundled.

I raise this concern because I am not a big fan of requiring a manager
to walk over a whole table or multiple tables when it is possible to
instrument a MIB to replace this with a single table lookup.  While
some classes of management entities maintain their own cache copies of
the ifTable and the ifStackTable, and monitor them for the slightest
changes, other classes of management entities exist which do not even
pretend to remember all that is in a particular agent's ifTable and
ifStackTable, and must walk them for each such table lookup.  Since
the ifTable and ifStackTable can grow to large proportions in large
systems, especially in those that do DS0 channelization, it seems that
it would be wise for us to anticipate the need for facilitating the act
of finding low-to-high mapping values in the ifStackTable.

My first thought would be to re-invent the dsx1FracTable.  Except for
the minor indulgence of providing duplicate information covered by the
newer ifStackTable, and for the major indecency of allowing managers
to assign ifIndex values, it was not such a bad table after all.  What
it had going for it, that would help in the present case, was indexing
first by the ifIndex value of a ds1 ifEntry, followed by indexing by the
channel number.  In one shot this gave the ds1/chan to ds0 mapping
information that takes a potentially lengty walk over the ifStackTable
to find the various stacked ds0 ifEntries followed by table lookups of
the dsx0Ds0Number, an average of half of which might turn out to be
false hits, given that the DS0 channel number ordering is not explicitly
indicated within the ifStackTable.

My first preference would be to add an ifInverseStackTable to the
existing IF-MIB in RFC 2233.  Such a table would provide exactly the
same information as in the ifStackTable (which is one minor strike
against it), but it would also serve as a tool for demultiplexing
interfaces in general, and not only for the present case (which is one
major strike for it).  [Since it is too late to get that into the IF-MIB,
and since I don't think we want to churn the IF-MIB at proposed one more
time, I will assume that such a table may have to be added outside the
IF-MIB.  In any case, I won't present draft text for such a table, since
I think it is fairly obvious from what I have described.]

However, even if such an ifInverseStackTable were added to the IF-MIB,
it still would not solve the problem of having to check potentially many
dsx0Ds0Number values before finding the right ds1/chan to ds0 mapping.
This leads me back to considering whether a modified version of the
ds1FracTable would be warranted.  It would allow for immediate table
lookup of ds1/chan to ds0 mapping, but would NOT be used to indicate
the ds0 bundling, nor to allow the manager to assign ifIndex values.

Here is some proposed ASN.1 for such a revised dsx1FracTable.

First, expand the comments for the DS0 Config Group to include a second
new table:

          -- The DS0 Config Group

          -- Implementation of this group is mandatory for all
          -- systems that use a DS0 Interface.

          -- The DS0 Config Group consists of three tables:
          --    DS0 Configuration
          --    DS0 Channelization Control
	  --    DS0 Channel Mapping

Second, add the new table:

          dsx0ChanMappingTable OBJECT-TYPE
              SYNTAX  SEQUENCE OF Dsx0ChanMappingEntry
              MAX-ACCESS  not-accessible
              STATUS  current
              DESCRIPTION
                      "The DS0 Channel Mapping table."
              ::= { ds0 4 }

          dsx0ChanMappingEntry OBJECT-TYPE
              SYNTAX  Dsx0ChannelizationEntry
              MAX-ACCESS  not-accessible
              STATUS  current
              DESCRIPTION
                      "An entry in the DS0 Channel Mapping table.  There is
                      an entry in this table corresponding to each ds0(81)
                      ifEntry within any interface that is channelized to
                      the individual ds0(81) ifEntry level.

                      This table is intended to facilitate mapping from
                      channelized interface / channel number to DS0 ifEntry.

                      While this table provides information that can also
                      be found in the ifStackTable and dsx0ConfigTable,
                      it provides this same information with a single table
                      lookup, rather than by walking the ifStackTable to
                      find the various constituent ds0(81) ifTable entries,
                      and testing various dsx0ConfigTable entries to check
                      for the entry with the applicable DS0 channel number."
              INDEX   { ifIndex, dsx0Ds0Number }
              ::= { dsx0ChanMappingTable 1 }

          Dsx0ChanMappingEntry ::=
              SEQUENCE {
                  dsx0ChanMappedIfIndex  InterfaceIndex
          }

          dsx0ChanMappedIfIndex OBJECT-TYPE
              SYNTAX  InterfaceIndex
              MAX-ACCESS  read-only
              STATUS  current
              DESCRIPTION
                      "This object indicates the ifIndex value assigned by
                      the agent for the individual ds0(81) ifEntry that
                      corresponds to the given DS0 channel number (specified
                      by the INDEX element dsx0Ds0Number) of the given
                      channelized interface (specified by INDEX element
                      ifIndex)."
              ::= { dsx0ChanMappingEntry 1 }

Third, add conformance information regarding the new table and objects:
- The dsx0ChanMappingTable would be mandatory for those agents that
  support DS0 channelization.
- The dsx0ChanMappedIfIndex object would be a mandatory object.

> is dsx1DS2M12 or dsx1E2, OR if speed not equal to 1544000 or 2048000.

I fully agree with you here.  The dsx0ChannelNumber value should
definitely be assigned by the agent, AND should also be read-only.
Otherwise, it leaves the MIB wide open for interpretation about what
it means for the manager to assign arbitrary values.

[Saying this, I already anticipate some debate on this issue,
since I thought I remembered hearing someone say that they had
planned to implement cross-connects using this object....]

>                           if (set of first variable failed)

Another way to show this might be appropriate, in order to ensure that
it is understood that a multi-varbind SET operation is NOT necessarily
intended:

                      The algorithm is:
                      while done == false
                          index = GET (dsx0BundleNextIndex.0)
                          SET (dsx0BundleNextIndex.0=index)
                          if (set failed)
                            done = false
                          else
                            SET (dsx0BundleRowStatus.index=createAndGo)
                            if (set failed)
                              done = false
                            else
                              done = true
                              other error handling"