Subject: [NAT] NAT MIB

From: "Harrington, David" <[email-masked]>
Date: Mon, 3 Feb 2003 17:04:21 -0500

Here is my first review of the NAT MIB (draft-ietf-nat-natmib-05.txt):

section 4.3
"Likewise, the session entries are derived from the Binds and 
   an entry MUST not exist in the Session table without a 
   corresponding Bind table entry."

What is the behavior expected when a Bind table entry is deleted, and session entry exists? MUST the session entry be deleted as well, or MUST the Bind entry NOT be deleted while there is a reference to it?

section 5
"Following is the list of protocol specific information, identified at
this point, which could potentially require protocol specific
extensions to this mib:

o Each protocol could support its set of timers and/or other protocol
  specific configuration parameters for operation with NAT.
o Statistics could be maintained per protocol, and type of
  statistics could be protocol specific.
"

To ensure that extensions play by the same rules, these should probably be turned into SHOULDs. It will not help interoperability if extension X1 provides timers and counters, while X2 supports only timers, and X3 supports only counters, and so on. The purpose of IETF documents is to define standards - what is the *standard* to be followed when implementing extensions to this mib? When is it appropriate to add timers? When is it appropriate to add counters?

The MIB:
General comments:

I recommend putting the NAT-TC MIB before the NAT-MIB in the document, or simply defining the TC within the NAT-MIB (which will work better with many compilers).

I found it irritating to need to work past a long list of authors' addresses to get to the actual mib contents. I don't feel the long list is necessary.

I recommend using xxxRowStatus, not simply xxxStatus. Using xxxRowStatus clearly indicates that the object reflects the status of the row, not about the status of the thing modeled in the row.

In addition, RowStatus objects should contain instructions in the description about modifications. From RFC2579, RowStatus Textual Convention:
" This textual convention may be used for a MIB table,
                 irrespective of whether the values of that table's
                 conceptual rows are able to be modified while it is
                 active, or whether its conceptual rows must be taken
                 out of service in order to be modified.  That is, it is
                 the responsibility of the DESCRIPTION clause of the
                 status column to specify whether the status column must
                 not be `active' in order for the value of some other
                 column of the same conceptual row to be modified.  If
                 such a specification is made, affected columns may be
                 changed by an SNMP set PDU if the RowStatus would not
                 be equal to `active' either immediately before or after
                 processing the PDU.  In other words, if the PDU also
                 contained a varbind that would change the RowStatus
                 value, the column in question may be changed if the
                 RowStatus was not equal to `active' as the PDU was
                 received, or if the varbind sets the status to a value
                 other than 'active'."

For StorageType objects, the REFERENCE identifies RFC2578. RowStatus objects however have no reference clause (even though RowStatus is far more complex); why the inconsistency?

RFC2119 wordings - there are a number of descriptions that are written with "requirements" that would be better expressed using RFC2119 keywords, to ensure interoperability.
For example: natConfLocalPortFrom says "if ..., the value of this object is 0."
It would be better to say that the value of this object MUST BE 0. (and it would probably be better to spell out "zero" rather than using the number 0.

There are objects called "local" and "global"; are these synonymous with "private" and "public"? If so, can the terminology be modified to use one set consistently?

Specific Objects:
natConfAddrMapIndex - is this a priority setting? "Address map entries are applied in the order specified by natConfAddrMapIndex." If so, why not name the object accordingly, such as natConfAddrPriority? The fact that it is part of the index should generally not influence the object name - the meaning of the object should be reflected in the name. "In the order specified" is ambiguous - is that ascending or descending order?

natConfLocalAddrFrom - why a size range of (0..20)? The description says the object specifies the IP address; why does it have to be an IP address? why not also provide support for other addressing formats? Is NAT supposed to be obsoleted for IPv6 networks?

natConfLocalPortFrom: would InetPortNumber from RFC3291 be appropriate here?

natConfGlobalAddrTo - "For a static NAT, the
             number of addresses in the range defined by
             natConfGlobalAddrFrom and natConfGlobalAddrTo should be
             equal to the number of addresses in the range defined by
             natConfLocalAddrFrom and natConfLocalAddrTo."
What is the expected behavior if the ranges are NOT equal? or should this be a MUST BE to ensure interoperability between applications and agent implementations?

natConfGlobalPortTo - it apperas the description might have benefitted from cut and paste; it is missing random words, such as "If this conceptual describes NAPT," and "in the range of ports being to."

natConfProtocol - "specifies a protocol identifier." - so should this be an enumeration that supports only one selection at a time, or BITS which allows multiple selections at a time? Can I reasonably select all four bits simultaneously? What is the expected behavior if I do so?

natConfUdpDefIdleTimeout, natConfIcmpDefIdleTimeout, natConfOtherDefIdleTimeout, natConfTcpDefIdleTimeout - why not put these into a table with a protocol identifier object, and reserved entry for defaults? (such as the natConfProtTable that follows?)

natConfProtEntry - what exactly is the purpose of these entries? If "Each entry points to a protocol-specific table", and each protocol type has one associated table, then why do I need multiple entries for the same protocol type? Don't they all point to the same table? or do the entries actually point to specific ROWS in a protocol-specific table?

The natConfProtTable seems complex to me, as does the whole set of protocol config scalars and tables. For TCP, the configuation parameters are all over the place - you have scalars for defaults; IdleTimeouts in natConfProtEntry, and NegTimeout in the natConfTcpTable. It seems to me this could all be greatly simplified by combining them:

natConfProtEntry
    natConfProtName             SnmpAdminString,
    natConfProtType             NATProtocolType,
    natConfProtSpecName         SnmpAdminString, -- "default" has the default values
    natConfProtIdleTimeout      Integer32,
    natConfProtNegTimeout       Integer32,
    natConfProtRowStatus        RowStatus	

If you believe it is important to have protocol-specific tables, then consider putting all the protocol-specific parameters into the same table:
natConfTcpEntry
    natConfTcpName              SnmpAdminString,  -- "default" has the default settings
    natConfProtIdleTimeout      Integer32,
    natConfTcpNegTimeout        Integer32,
    natConfTcpRowStatus         RowStatus
}

natConfProtName isn't very clear as to what the name is meant to refer to. Is it expected that it will be "tcp" or "tcp configuration #1" or "VoIP config"? Are these rows expected to be created by management applications, or by agents? Assuming applications, because there is a RowStatus, how is it expected that administrators will use this naming capability? Is this for grouping multiple configs into a single policy (e.g. "policy#1" = UDP(timout=3), TCP(timeout=7, negtimeout=12), ICMP(timeout=4))?

natConfProtType depends on the agent understanding the mapping between a type (tcp) and the table that supports that type. Why not just use an OID to identify the associated table? 

natConfProtSpecName - why not use a RowPointer (RFC2579), which would encode the OID of the protocol-specific table AND the desired row in the table into one object? I think that would leave you with one table to provide human-readable group names with pointers to the specific config rows, plus a per-protocol table with config parameters:

natConfProtEntry
    natConfProtGroupName        SnmpAdminString,
    natConfProtSpec             RowPointer
    natConfProtRowStatus        RowStatus	
}

natConfTcpEntry
    natConfTcpName              SnmpAdminString,  -- "default" has the default settings
    natConfProtIdleTimeout      Integer32,
    natConfTcpNegTimeout        Integer32,
    natConfTcpRowStatus         RowStatus
}

natConfAddressRiseThreshold - How does one calculate the usage percentage? I didn't see any object specifying the number of entries permitted in the table. Why does the number of entries need to be fixed? i.e. if I implement the table to grow dynamically as needed, would I ever use the notification? If one implementation uses statically-sized maps and another uses dynamically sized maps, what should the managing application know and expect? If I have a dynamically growing table, should there be some limit that can be specified by the administrator (or the agent implementor)?

natConfAddressRiseThreshold uses naming inconsistent with all other objects that use the template natConfAddrXXXX. Inconsistent naming like this make it much harder to utilize a mib.

natAddrBindTable and natAddrPortBindtable contain basically the same information, and the BindIDs need to be unique across both tables. Why not just build one table that can support both address and port binds, with port 0 being used for address-only binds?

natAddrBindTable - the description contains two sentences that seem to say the same thing.

natAddrBindDirection - if this is associated with an address map direction, whose value is the same, why do we need both objects? Can't one be derived from the other? If natConfAddrMapDirection depicts the direction (inbound vs outbound), then doesn't natAddrBindDirection depict something other than direction? 

natAddrXXXXLocalAddrXXXX objects discuss how they relate to natAddrXXXXGlobalAddrXXXX objects, and vice-versa. Why not use the description of natAddrBindTable or Entry to describe the intent to map between local and global addresses/ports? Then you can use the actual address object to discuss only that object.

natAddrBindAddrMapname - what happens if the address map is deleted? badValue is an SNMPv1 error code. This is not the correct error code to return when using SNMPv2c or SNMPv3 or SNMPvX or a non-SNMP protocol using this mib. It would be best to not specify the error code to be returned, and let the protocol define the correct error code for the situation.

natAddrBindOrigin - why is this needed? What does an application/operator use this for? Is the static/dynamic aspects of this somewhat redundant with natAddrBindType?

natSessionBindId - the wording needs to be cleaned up.

natSessionDirection - how does this differ from the direction in the bind table or the direction in the address map table?

natSessionUpTime - There is significantly more overhead involved in keeping this session-uptime accurate than would be involved in just statically recording the start time of the session, and then calculating the delta off the box. It would be simpler to record the sysUpTime at the start of the session and let the application calculate the uptime of the session by comparing the value to the current sysUpTime. This is done routinely in SNMP for other time-delta calculations.

natSessionProtocolType - I don't know why there is a tutorial contained in the description clause; how does this relate to this mib?

natSessionxxxxPort - could InetPortNumber be used here?

Would the private and public addresses in the session table be accurately described as local and global addresses, as used in the address map tables, and so on? There should be consistency in naming.

natSessionCurrentIdleTime - as discussed above, this might be better as a timestamp showing when a packet was last detected.

xxxSecondBindId - as mentioned above, it is better to not specify the error code.

natProtocolStatsName - this is a protocoltype, not a name; why not call it natProtocolStatsProtocol?

natAddrMapStatsAddrUsed - for static assignments, shouldn't the number be one?

natInterfaceStatsEntry - wouldn't it be useful to know how many were not translated?

natAddressUseRising - wouldn't this aalso be useful when an operator added so many static entries that it exceeded the threshold?

natPacketDiscard - shouldn't there be an object to specify the suppression time interval? It could default to 5 seconds, but be configurable by the administrator.

The compliance statements have lots of optional objects. If they are important, they shouldn't be optional. If they aren't important, they shouldn't be in the mib.

The boilerplates for section 2 and section 7 have changed; the document should be updated accordingly. SNMPv3 RFCs have been renumbered (when they were advanced); the references should be updated.

David Harrington
Network Management Architect
Office of the CTO
Enterasys Networks
 
_______________________________________________
midcom mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/midcom
_______________________________________________
nat mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/nat