A revised vendor MIB module keeps an object's OID but changes its SYNTAX from Counter32 to Gauge32; which SMIv2 rule does that break, and what should the revision have done?
answer
- registrations are forever
- the allowed-changes list
- primitive type may not change
- new meaning, new OID
- deprecate, never delete
basics
~20 sIt breaks RFC 2578's rule that a registered OID's semantics never change: a SYNTAX change outside the allowed list needs a new OID. The revision should define a new object at an unassigned OID and mark the old one deprecated or obsolete.
solid answer
~40 sRFC 2578 section 3.6 says that once an OID is registered, the semantics associated with it may not change, and section 10 forbids any revision that could cause interoperability problems over the wire. Section 10.2 lists the changes allowed in place: adding enumerations or named bits, swapping a `SYNTAX` for an equivalent textual convention, moving `STATUS` towards `deprecated` or `obsolete`, adding or updating `DEFVAL` and `REFERENCE`, adding `UNITS`, appending columns to a row, clarifying `DESCRIPTION`, and defining new objects. Turning `Counter32` into `Gauge32` is none of these, and section 9 adds that a refinement may never change the application type. The revision should register a **new object** at an unassigned OID, set the old one to `deprecated` or `obsolete` without deleting it, and record the change in `LAST-UPDATED` and a new `REVISION` clause.
go deeper
Know that an OID, once published in a MIB module, keeps its meaning forever.
List some of the changes SMIv2 allows in place, such as new enumerations, UNITS and appended columns, and say why anything else needs a new OID.
Explain what a silent counter-to-gauge switch does to rate calculations and how module diffs and on-the-wire type checks catch it before dashboards lie.
Set the policy for your own modules and your vendor intake: deprecate instead of mutate, review revisions at every upgrade, and push vendors back when they reuse OIDs.
## Why this change is forbidden An SNMP manager knows only what the module told it at the time it was loaded. If one software release reports a `Counter32` at an OID and the next reports a `Gauge32` at the same OID, every manager now holds a definition that is wrong for half the estate. SMIv2 (RFC 2578) prevents that with one principle stated several ways: - **Section 3.6:** after an OID is registered, the semantics associated with it are not allowed to change, the OID cannot be used for any other registration, and the descriptor cannot be changed. - **Section 9:** a refinement of `SYNTAX` may narrow a range, a size or an enumeration, but the object's primitive or application type must not change. - **Section 10:** no revision may have any potential to cause interoperability problems over the wire between implementations of the original and the updated module. `Counter32` and `Gauge32` are different application types with different meanings: a counter only increases and wraps to zero after 2^32-1, while a gauge goes up and down and stays at its maximum while the modelled value is at or above it. The change breaks all three rules. ## The changes RFC 2578 does allow in place Section 10.2 permits these, and only these, without a new OID: 1. adding enumerations, or named bits to `BITS`, and changing existing labels; 2. replacing a `SYNTAX` with a textual convention of the same primitive type, the same set of values and identical semantics; 3. moving `STATUS` from `current` to `deprecated` or `obsolete`, or from `deprecated` to `obsolete`; 4. adding or updating `DEFVAL`; 5. adding or updating `REFERENCE`; 6. adding `UNITS`; 7. appending new columns to the end of a conceptual row; 8. clarifying `DESCRIPTION`; 9. defining entirely new objects at previously unassigned OIDs. Anything else that changes an object's semantics requires a new OID. RFC 2578 also counts a **descriptor rename** as a semantic change, because other modules import descriptors by name. ## What the revision should have done | Step | Rule it follows | |---|---| | Register a new object, at an unassigned OID, with `SYNTAX Gauge32` | section 10.2 item 9 | | Set the old object's `STATUS` to `deprecated`, or to `obsolete` if no agent should keep it | section 10.2 item 3 | | Keep the old definition in the module; never reassign its OID | section 10 | | Update `LAST-UPDATED` and add a `REVISION` with a `DESCRIPTION` | section 10 | | Keep the module name, and keep definitions in the same module | section 10 | | Put the new object in a new `OBJECT-GROUP` and update the `MODULE-COMPLIANCE` | RFC 2580 | `deprecated` is the gentler choice: RFC 2578 says it still permits implementation to foster interoperability, so agents can report both objects during a transition while managers move to the new one. ## What breaks for the operator A manager polling the old OID with the old module computes a **rate** from successive readings. When the value is really a gauge, every decrease looks like a counter wrap, and the computed rate becomes a huge spike; every increase becomes a meaningless rate of change. Stored history now mixes two meanings under one name. Nothing errors, because the requests still succeed. That is what makes it dangerous. ## How to catch it 1. **Diff module revisions** on every software upgrade. `LAST-UPDATED` and the `REVISION` clauses tell you a module changed; a diff of the `SYNTAX`, `UNITS` and `DESCRIPTION` clauses tells you how. 2. **Check the type on the wire.** Each value carries its application tag, and `Counter32` and `Gauge32` have different tags, so a collector can compare the returned type against the loaded definition and flag a mismatch rather than silently computing a rate. This check cannot separate `Gauge32` from `Unsigned32`, which share a tag. 3. **Treat a mismatch as a vendor defect** and report it. Do not paper over it with per-release special cases in the collector unless there is no other way. ## A related legitimate OID change RFC 2578 section 4 describes one case where objects do get new OIDs on purpose: a module developed under `experimental(3)` that enters the standards track has its objects moved under `mgmt(2)`. That is a new registration, not an in-place edit, and managers must load the new module.
- May a revision add a new column to an existing table without a new OID for the row?Yes, at the end of the row. RFC 2578 section 10.2 allows a conceptual row to be augmented by adding new columnar objects at the end and updating the SEQUENCE definition. Existing columns keep their OIDs and meaning; older managers simply never ask for the new column.
- Why does SMIv2 forbid deleting an obsolete object from a module?Because other modules may still reference its descriptor in their IMPORTS, and because its OID must never be reassigned. Keeping the definition, marked obsolete, documents that the OID is taken and stops a later author from reusing it for something new.
saying these in an interview costs you the question
- Changing SYNTAX in place is fine if LAST-UPDATED is bumped
- An obsolete object should be deleted so its OID can be reused
- Renaming an object's descriptor is a harmless editorial change
- A deprecated object must no longer be implemented by any agent
- A manager will get an error when an object's type changes