Skip to content

Extend LLDP model with global TTL, custom TLV, and per-interface enhancements#1470

Open
ndas7 wants to merge 4 commits intoopenconfig:masterfrom
ndas7:master
Open

Extend LLDP model with global TTL, custom TLV, and per-interface enhancements#1470
ndas7 wants to merge 4 commits intoopenconfig:masterfrom
ndas7:master

Conversation

@ndas7
Copy link
Copy Markdown

@ndas7 ndas7 commented Apr 7, 2026

Change Scope

*   This PR proposes enhancements to the existing LLDP model with the following changes:
 
    1. Adding a global ttl configuration/state leaf under /lldp.
    2. Extending interface LLDP config and state with port-description and interface-level custom-tlv-names.
    3. Introducing a shared custom-TLV grouping so both config and state reuse the same custom TLV fields.    
    4. Adding a top-level /lldp/custom-tlvs/tlv[name] list for global custom TLV definitions.    
    5. Adding interface state timestamp counters for LLDP packet events.

  • This change is backwards compatible as it adds leaves to existing model.
     

Platform Implementations

*   LLDPCLI, LLDPAD (LLDP daemons for Linux): https://lldpd.github.io/usage.html

lldpcli configure lldp custom-tlv oui 00,00,00 subtype 1 oui-info "your data"

*   SONiC: https://github.com/cshivashgit/SONiC/blob/lldp-custom-tlv-hld/doc/lldp_custom_tlv/lldp-custom-tlv-hld.md#config-db-schema
*   Vendors use custom TLVs to support features like Cisco's LLDP-MED (Media Endpoint Discovery), which is itself a collection of organizationally specific TLVs. In Cisco NX-OS, you can select which TLVs to include using the lldp tlv-select command. Aruba's AOS-CX introduced a specific OUI (83A30) to help identify Aruba devices and automatically apply network profiles.

Tree View

 

module: openconfig-lldp
  +--rw lldp
     +--rw config
     |  +--rw enabled?                      boolean
     |  +--rw hello-timer?                  uint64
+    |  +--rw ttl?                          uint16
     |  +--rw suppress-tlv-advertisement*   identityref
     |  +--rw system-name?                  string
     |  +--rw system-description?           string
     |  +--rw chassis-id?                   string
     |  +--rw chassis-id-type?              oc-lldp-types:chassis-id-type
     |  +--rw management-interface?         oc-if:interface-id
     +--ro state
     |  +--ro enabled?                      boolean
     |  +--ro hello-timer?                  uint64
+    |  +--ro ttl?                          uint16
     |  +--ro suppress-tlv-advertisement*   identityref
     |  +--ro system-name?                  string
     |  +--ro system-description?           string
     |  +--ro chassis-id?                   string
     |  +--ro chassis-id-type?              oc-lldp-types:chassis-id-type
     |  +--ro management-interface?         oc-if:interface-id
     |  +--ro counters
     |     +--ro frame-in?           oc-yang:counter64
     |     +--ro frame-out?          oc-yang:counter64
     |     +--ro frame-error-in?     oc-yang:counter64
     |     +--ro frame-discard?      oc-yang:counter64
     |     +--ro tlv-discard?        oc-yang:counter64
     |     +--ro tlv-unknown?        oc-yang:counter64
     |     +--ro last-clear?         oc-yang:date-and-time
     |     +--ro tlv-accepted?       oc-yang:counter64
     |     +--ro entries-aged-out?   oc-yang:counter64
     +--ro mgmt-addresses
     |  +--ro mgmt-address* [address]
     |     +--ro address    -> ../state/address
     |     +--ro state
     |        +--ro address?                    union
     |        +--ro interface-number?           uint32
     |        +--ro interface-number-subtype?   oc-lldp-types:mgmt-interface-number-subtype
     +--rw interfaces
     |  +--rw interface* [name]
     |     +--rw name         -> ../config/name
     |     +--rw config
     |     |  +--rw name?               oc-if:base-interface-ref
     |     |  +--rw enabled?            boolean
+    |     |  +--rw port-description?   string
+    |     |  +--rw custom-tlv-names*   -> ../../../../custom-tlvs/tlv/name
     |     +--ro state
     |     |  +--ro name?               oc-if:base-interface-ref
     |     |  +--ro enabled?            boolean
+    |     |  +--ro port-description?   string
+    |     |  +--ro custom-tlv-names*   -> ../../../../custom-tlvs/tlv/name
     |     |  +--ro counters
     |     |     +--ro frame-in?                    oc-yang:counter64
     |     |     +--ro frame-out?                   oc-yang:counter64
     |     |     +--ro frame-error-in?              oc-yang:counter64
     |     |     +--ro frame-discard?               oc-yang:counter64
     |     |     +--ro tlv-discard?                 oc-yang:counter64
     |     |     +--ro tlv-unknown?                 oc-yang:counter64
     |     |     +--ro last-clear?                  oc-yang:date-and-time
     |     |     +--ro frame-error-out?             oc-yang:counter64
+    |     |     +--ro last-packet-transmitted?     oc-yang:date-and-time
+    |     |     +--ro last-good-packet-received?   oc-yang:date-and-time
+    |     |     +--ro loopback-packets-received?   oc-yang:counter64
     |     +--ro neighbors
     |        +--ro neighbor* [id]
     |           +--ro id                -> ../state/id
     |           +--ro config
     |           +--ro state
     |           |  +--ro system-name?               string
     |           |  +--ro system-description?        string
     |           |  +--ro chassis-id?                string
     |           |  +--ro chassis-id-type?           oc-lldp-types:chassis-id-type
     |           |  +--ro management-interface?      oc-if:interface-id
     |           |  +--ro id?                        string
     |           |  +--ro age?                       uint64
     |           |  +--ro last-update?               int64
     |           |  +--ro ttl?                       uint16
     |           |  +--ro port-id?                   string
     |           |  +--ro port-id-type?              oc-lldp-types:port-id-type
     |           |  +--ro port-description?          string
     |           |  x--ro management-address?        string
     |           |  x--ro management-address-type?   string
     |           +--ro mgmt-addresses
     |           |  +--ro mgmt-address* [address]
     |           |     +--ro address    -> ../state/address
     |           |     +--ro state
     |           |        +--ro address?                    union
     |           |        +--ro interface-number?           uint32
     |           |        +--ro interface-number-subtype?   oc-lldp-types:mgmt-interface-number-subtype
     |           +--ro custom-tlvs
     |           |  +--ro tlv* [type oui oui-subtype]
     |           |     +--ro type           -> ../state/type
     |           |     +--ro oui            -> ../state/oui
     |           |     +--ro oui-subtype    -> ../state/oui-subtype
     |           |     +--ro config
     |           |     +--ro state
+    |           |        +--ro name?          string
     |           |        +--ro type?          int32
     |           |        +--ro oui?           string
     |           |        +--ro oui-subtype?   string
     |           |        +--ro value?         binary
     |           +--ro capabilities
     |              +--ro capability* [name]
     |                 +--ro name      -> ../state/name
     |                 +--ro config
     |                 +--ro state
     |                    +--ro name?      identityref
     |                    +--ro enabled?   boolean
+    +--rw custom-tlvs
+       +--rw tlv* [name]
+          +--rw name      -> ../config/name
+          +--rw config
+          |  +--rw name?          string
+          |  +--rw type?          int32
+          |  +--rw oui?           string
+          |  +--rw oui-subtype?   string
+          |  +--rw value?         binary
+          +--ro state
+             +--ro name?          string
+             +--ro type?          int32
+             +--ro oui?           string
+             +--ro oui-subtype?   string
+             +--ro value?         binary

…ncements

### Change Scope
*   This PR proposes enhancements to the existing LLDP model with the following changes:
 
    1. Adding a global ttl configuration/state leaf under /lldp.
    2. Extending interface LLDP config and state with port-description and interface-level custom-tlv-names.
    3. Introducing a shared custom-TLV grouping so both config and state reuse the same custom TLV fields.
    4. Adding a top-level /lldp/custom-tlvs/tlv[name] list for global custom TLV definitions.
    5. Adding interface state timestamp counters for LLDP packet events.
 
### Platform Implementations
*   LLDPCLI, LLDPAD (LLDP daemons for Linux): https://lldpd.github.io/usage.html

```
lldpcli configure lldp custom-tlv oui 00,00,00 subtype 1 oui-info "your data"
```
*   SONiC: https://github.com/cshivashgit/SONiC/blob/lldp-custom-tlv-hld/doc/lldp_custom_tlv/lldp-custom-tlv-hld.md#config-db-schema
*   Vendors use custom TLVs to support features like Cisco's [LLDP-MED](https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst9300/software/release/16-6/configuration_guide/int_and_hw/b_166_int_and_hw_9300_cg/b_166_int_and_hw_9300_cg_chapter_011.html) (Media Endpoint Discovery), which is itself a collection of organizationally specific TLVs. In Cisco [NX-OS](https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus9000/sw/6-x/system_management/configuration/guide/b_Cisco_Nexus_9000_Series_NX-OS_System_Management_Configuration_Guide/sm_lldp.pdf), you can select which TLVs to include using the lldp tlv-select command. Aruba's [AOS-CX](https://www.youtube.com/watch?v=lPbtpFcTqgE) introduced a specific OUI (83A30) to help identify Aruba devices and automatically apply network profiles.

### Tree View
 
```diff
module: openconfig-lldp
  +--rw lldp
     +--rw config
     |  +--rw enabled?                      boolean
     |  +--rw hello-timer?                  uint64
+    |  +--rw ttl?                          uint64
     |  +--rw suppress-tlv-advertisement*   identityref
     |  +--rw system-name?                  string
     |  +--rw system-description?           string
     |  +--rw chassis-id?                   string
     |  +--rw chassis-id-type?              oc-lldp-types:chassis-id-type
     |  +--rw management-interface?         oc-if:interface-id
     +--ro state
     |  +--ro enabled?                      boolean
     |  +--ro hello-timer?                  uint64
+    |  +--ro ttl?                          uint64
     |  +--ro suppress-tlv-advertisement*   identityref
     |  +--ro system-name?                  string
     |  +--ro system-description?           string
     |  +--ro chassis-id?                   string
     |  +--ro chassis-id-type?              oc-lldp-types:chassis-id-type
     |  +--ro management-interface?         oc-if:interface-id
     |  +--ro counters
     |     +--ro frame-in?           oc-yang:counter64
     |     +--ro frame-out?          oc-yang:counter64
     |     +--ro frame-error-in?     oc-yang:counter64
     |     +--ro frame-discard?      oc-yang:counter64
     |     +--ro tlv-discard?        oc-yang:counter64
     |     +--ro tlv-unknown?        oc-yang:counter64
     |     +--ro last-clear?         oc-yang:date-and-time
     |     +--ro tlv-accepted?       oc-yang:counter64
     |     +--ro entries-aged-out?   oc-yang:counter64
     +--ro mgmt-addresses
     |  +--ro mgmt-address* [address]
     |     +--ro address    -> ../state/address
     |     +--ro state
     |        +--ro address?                    union
     |        +--ro interface-number?           uint32
     |        +--ro interface-number-subtype?   oc-lldp-types:mgmt-interface-number-subtype
     +--rw interfaces
     |  +--rw interface* [name]
     |     +--rw name         -> ../config/name
     |     +--rw config
     |     |  +--rw name?               oc-if:base-interface-ref
     |     |  +--rw enabled?            boolean
+    |     |  +--rw port-description?   string
+    |     |  +--rw custom-tlv-names*   -> ../../../../custom-tlvs/tlv/name
     |     +--ro state
     |     |  +--ro name?               oc-if:base-interface-ref
     |     |  +--ro enabled?            boolean
+    |     |  +--ro port-description?   string
+    |     |  +--ro custom-tlv-names*   -> ../../../../custom-tlvs/tlv/name
     |     |  +--ro counters
     |     |     +--ro frame-in?                    oc-yang:counter64
     |     |     +--ro frame-out?                   oc-yang:counter64
     |     |     +--ro frame-error-in?              oc-yang:counter64
     |     |     +--ro frame-discard?               oc-yang:counter64
     |     |     +--ro tlv-discard?                 oc-yang:counter64
     |     |     +--ro tlv-unknown?                 oc-yang:counter64
     |     |     +--ro last-clear?                  oc-yang:date-and-time
     |     |     +--ro frame-error-out?             oc-yang:counter64
+    |     |     +--ro last-packet-transmitted?     oc-yang:date-and-time
+    |     |     +--ro last-good-packet-received?   oc-yang:date-and-time
+    |     |     +--ro loopback-packets-received?   oc-yang:date-and-time
     |     +--ro neighbors
     |        +--ro neighbor* [id]
     |           +--ro id                -> ../state/id
     |           +--ro config
     |           +--ro state
     |           |  +--ro system-name?               string
     |           |  +--ro system-description?        string
     |           |  +--ro chassis-id?                string
     |           |  +--ro chassis-id-type?           oc-lldp-types:chassis-id-type
     |           |  +--ro management-interface?      oc-if:interface-id
     |           |  +--ro id?                        string
     |           |  +--ro age?                       uint64
     |           |  +--ro last-update?               int64
     |           |  +--ro ttl?                       uint16
     |           |  +--ro port-id?                   string
     |           |  +--ro port-id-type?              oc-lldp-types:port-id-type
     |           |  +--ro port-description?          string
     |           |  x--ro management-address?        string
     |           |  x--ro management-address-type?   string
     |           +--ro mgmt-addresses
     |           |  +--ro mgmt-address* [address]
     |           |     +--ro address    -> ../state/address
     |           |     +--ro state
     |           |        +--ro address?                    union
     |           |        +--ro interface-number?           uint32
     |           |        +--ro interface-number-subtype?   oc-lldp-types:mgmt-interface-number-subtype
     |           +--ro custom-tlvs
     |           |  +--ro tlv* [type oui oui-subtype]
     |           |     +--ro type           -> ../state/type
     |           |     +--ro oui            -> ../state/oui
     |           |     +--ro oui-subtype    -> ../state/oui-subtype
     |           |     +--ro config
     |           |     +--ro state
+    |           |        +--ro name?          string
     |           |        +--ro type?          int32
     |           |        +--ro oui?           string
     |           |        +--ro oui-subtype?   string
     |           |        +--ro value?         binary
     |           +--ro capabilities
     |              +--ro capability* [name]
     |                 +--ro name      -> ../state/name
     |                 +--ro config
     |                 +--ro state
     |                    +--ro name?      identityref
     |                    +--ro enabled?   boolean
+    +--rw custom-tlvs
+       +--rw tlv* [name]
+          +--rw name      -> ../config/name
+          +--rw config
+          |  +--rw name?          string
+          |  +--rw type?          int32
+          |  +--rw oui?           string
+          |  +--rw oui-subtype?   string
+          |  +--rw value?         binary
+          +--ro state
+             +--ro name?          string
+             +--ro type?          int32
+             +--ro oui?           string
+             +--ro oui-subtype?   string
+             +--ro value?         binary
```

Signed-off-by: Neha Das <neha.das43@gmail.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the OpenConfig LLDP module to version 1.0.1, introducing global TTL configuration, interface-level port descriptions, and timestamps for packet transmission and reception. It also adds a global custom TLV list and allows interfaces to reference these TLVs. Review feedback recommends renaming the loopback packet timestamp for consistency, correcting the description of the port-description leaf to reflect the correct TLV type, and changing the TTL data type from uint64 to uint16 to align with the IEEE 802.1AB standard.

Comment thread release/models/lldp/openconfig-lldp.yang
Comment thread release/models/lldp/openconfig-lldp.yang
Comment thread release/models/lldp/openconfig-lldp.yang
ndas7 added 2 commits April 6, 2026 18:43
Signed-off-by: Neha Das <neha.das43@gmail.com>
Signed-off-by: Neha Das <neha.das43@gmail.com>
@ndas7 ndas7 marked this pull request as ready for review April 7, 2026 01:46
@ndas7 ndas7 requested a review from a team as a code owner April 7, 2026 01:46
for the LLDP protocol.";

oc-ext:openconfig-version "1.0.0";
oc-ext:openconfig-version "1.0.1";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
oc-ext:openconfig-version "1.0.1";
oc-ext:openconfig-version "1.1.0";

}

leaf last-packet-transmitted {
type oc-yang:date-and-time;
Copy link
Copy Markdown
Contributor

@earies earies Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type oc-yang:date-and-time;
type oc-types:timeticks64;

I know there is already a leaf w/ oc-yang:date-and-time here but imo this was incorrect per common and more programmatic friendly representation of time since unix epoch

}

leaf last-good-packet-received {
type oc-yang:date-and-time;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above although I would question more non-counter leafs under this counters container. Seems appropriate to move these up to a parent level

"Enable or disable the LLDP protocol on the interface.";
}

leaf port-description {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some clarification would need to surround this leaf as most implementations would derive this TLV from other areas (e.g. interface description) by default and your intention here appears to be a TLV specific override

"System level hello timer for the LLDP protocol.";
}

leaf ttl {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will this field conflict or relate to hello-timer for where in implementations this is derived/calculated?

}

leaf type {
type int32;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you are just reusing what was previously defined but this is an incorrect type for what is a 7-bit unsigned field per spec definition.

Suggest proposing/refactoring to a scoped uint8 to go in accordance to 8021AB-2016

}

leaf oui {
type string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would suggest considering typedef w/ constraints for these fields

}

leaf oui-subtype {
type string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would suggest considering typedef w/ constraints for these fields

unique subtype value assigned by the defining organization.";
}

// TODO: consider making this string type
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are proposing the ability for r/w in here, this probably should be revisited. If we maintain type binary this complicates the reading/writing for users

path "../../../../custom-tlvs/tlv/name";
}
description
"References to global custom TLV names associated with this interface.";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest being very specific here and state something like, if present in the list, the tlv is advertised and if not, the tlv will not be advertised

Comment on lines +647 to +650
"The description of the port to be advertised in the Port
Description TLV (Type 4) for LLDP PDUs transmitted on this
interface.";
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect that implementations today would use this leaf as the LLDP port-description.
/interfaces/interface/state/description

Discussing this, the desire is to override the interface description with an LLDP specific string. Please update the description to indicate what happens if this leaf is not populated and if it is. Thanks!

leaf name {
type string;
description
"Name of the custom TLV.";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please elaborate that this is for ease for human identification of the LLDP type.

@dplore
Copy link
Copy Markdown
Member

dplore commented Apr 7, 2026

/gcbrun

@OpenConfigBot
Copy link
Copy Markdown

No major YANG version changes in commit f1bd4f0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants