]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
config: add portdescription-source option
authortcollet <tcollet@iliad-free.fr>
Wed, 21 Jan 2026 08:45:24 +0000 (09:45 +0100)
committertcollet <tcollet@iliad-free.fr>
Thu, 19 Feb 2026 11:26:43 +0000 (12:26 +0100)
This new option allows to control the port description source
(alias vs ifname) when the portidsubtype is macaddress.

Usage:
  lldpcli configure lldp portidsubtype macaddress
  lldpcli configure lldp portdescription-source alias

Result: PortID = MAC address, PortDescr = interface alias

src/client/conf-lldp.c
src/client/display.c
src/daemon/client.c
src/daemon/interfaces.c
src/lib/atoms/config.c
src/lib/lldpctl.h
src/lldp-const.h
src/lldpd-structs.h

index c5ec33a0892498a341765a90ef2b5f2833ea0cba..1b168769e88a4460326dbc05d87fb20404e26e4d 100644 (file)
@@ -224,6 +224,52 @@ cmd_agent_type(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *en
        return 1;
 }
 
+static int
+cmd_portdescr_type(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, const void *arg)
+{
+       const char *value_str = arg;
+       int value = -1;
+
+       log_debug("lldpctl", "lldp port description source");
+
+       lldpctl_atom_t *config = lldpctl_get_configuration(conn);
+       if (config == NULL) {
+               log_warnx("lldpctl", "unable to get configuration from lldpd. %s",
+                   lldpctl_last_strerror(conn));
+               return 0;
+       }
+
+       for (lldpctl_map_t *b_map =
+                lldpctl_key_get_map(lldpctl_k_config_lldp_portdescr_type);
+            b_map->string; b_map++) {
+               if (!strcmp(b_map->string, value_str)) {
+                       value = b_map->value;
+                       break;
+               }
+       }
+
+       if (value == -1) {
+               log_warnx("lldpctl", "invalid value");
+               lldpctl_atom_dec_ref(config);
+               return 0;
+       }
+
+       if (lldpctl_atom_set_int(config, lldpctl_k_config_lldp_portdescr_type, value) ==
+           NULL) {
+               log_warnx("lldpctl",
+                   "unable to set port description source. %s",
+                   lldpctl_last_strerror(conn));
+               lldpctl_atom_dec_ref(config);
+               return 0;
+       }
+
+       log_info("lldpctl", "port description source set to %s", value_str);
+       lldpctl_atom_dec_ref(config);
+
+       return 1;
+}
+
 static int
 cmd_portid_type_local(struct lldpctl_conn_t *conn, struct writer *w,
     struct cmd_env *env, const void *arg)
@@ -765,6 +811,19 @@ register_commands_configure_lldp(struct cmd_node *configure,
                    b_map->string);
        }
 
+       /* Configure port description source */
+       struct cmd_node *configure_lldp_portdescr_type =
+           commands_new(configure_lldp, "portdescription-source",
+               "Port description source", NULL, NULL, NULL);
+       for (lldpctl_map_t *b_map =
+                lldpctl_key_get_map(lldpctl_k_config_lldp_portdescr_type);
+            b_map->string; b_map++) {
+               commands_new(commands_new(configure_lldp_portdescr_type,
+                                b_map->string, b_map->string, NULL, NULL, NULL),
+                   NEWLINE, "Set port description source", NULL,
+                   cmd_portdescr_type, b_map->string);
+       }
+
        /* Now handle the various portid subtypes we can configure. */
        struct cmd_node *configure_lldp_portid_type = commands_new(configure_lldp,
            "portidsubtype", "LLDP PortID TLV Subtype", NULL, NULL, NULL);
index 6d9be2a5a12863d69b30d08fd34aeb45615f2545..8a9d355efe082ba29130e7e828df0eac1e483bb0 100644 (file)
@@ -1034,6 +1034,10 @@ display_configuration(lldpctl_conn_t *conn, struct writer *w)
                lldpctl_k_config_bond_slave_src_mac_type));
        tag_datatag(w, "lldp-portid-type", "Port ID TLV subtype for LLDP frames",
            lldpctl_atom_get_str(configuration, lldpctl_k_config_lldp_portid_type));
+       tag_datatag(w, "lldp-portdescr-type",
+           "Port description source for LLDP frames",
+           lldpctl_atom_get_str(configuration,
+               lldpctl_k_config_lldp_portdescr_type));
        tag_datatag(w, "lldp-agent-type", "Agent type",
            lldpctl_atom_get_str(configuration, lldpctl_k_config_lldp_agent_type));
 
index efe20b57a136bb1d5eda9c6ea0ddd022ab7f645a..348d1f4ce908550b609878a172aa1997e21d8f48 100644 (file)
@@ -115,6 +115,14 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, void *i
                cfg->g_config.c_lldp_agent_type = config->c_lldp_agent_type;
                levent_update_now(cfg);
        }
+       if (CHANGED(c_lldp_portdescr_type) &&
+           config->c_lldp_portdescr_type >= LLDP_PORTDESCR_SRC_AUTO &&
+           config->c_lldp_portdescr_type <= LLDP_PORTDESCR_SRC_MAX) {
+               log_debug("rpc", "change lldp port description source to %d",
+                   config->c_lldp_portdescr_type);
+               cfg->g_config.c_lldp_portdescr_type = config->c_lldp_portdescr_type;
+               levent_update_now(cfg);
+       }
        /* Pause/resume */
        if (CHANGED(c_paused)) {
                log_debug("rpc", "client asked to %s lldpd",
index 2aaec7693806bddb67900a66079ca3fb9eb1b778..f54e059fcd4df6a482c6c35dedaf485afca204ff 100644 (file)
@@ -599,6 +599,7 @@ interfaces_helper_port_name_desc(struct lldpd *cfg, struct lldpd_hardware *hardw
        int has_alias = (iface->alias != NULL && strlen(iface->alias) != 0 &&
            strncmp("lldpd: ", iface->alias, 7));
        int portid_type = cfg->g_config.c_lldp_portid_type;
+       int portdescr_type = cfg->g_config.c_lldp_portdescr_type;
        if (portid_type == LLDP_PORTID_SUBTYPE_IFNAME ||
            (portid_type == LLDP_PORTID_SUBTYPE_UNKNOWN && has_alias) ||
            (port->p_id_subtype == LLDP_PORTID_SUBTYPE_LOCAL && has_alias)) {
@@ -615,14 +616,16 @@ interfaces_helper_port_name_desc(struct lldpd *cfg, struct lldpd_hardware *hardw
 
                if (port->p_descr_force == 0) {
                        /* use the actual alias in the port description */
-                       log_debug("interfaces", "using alias in description for %s",
-                           hardware->h_ifname);
                        free(port->p_descr);
-                       if (has_alias) {
+                       if (portdescr_type != LLDP_PORTDESCR_SRC_IFNAME && has_alias) {
+                               log_debug("interfaces", "using alias in description for %s",
+                                   hardware->h_ifname);
                                port->p_descr = strdup(iface->alias);
                        } else {
                                /* We don't have anything else to put here and for CDP
-                                * with need something non-NULL */
+                                * with need something non-NULL even if alias is requested */
+                               log_debug("interfaces", "using ifname in description for %s",
+                                   hardware->h_ifname);
                                port->p_descr = strdup(hardware->h_ifname);
                        }
                }
@@ -639,11 +642,18 @@ interfaces_helper_port_name_desc(struct lldpd *cfg, struct lldpd_hardware *hardw
                }
 
                if (port->p_descr_force == 0) {
-                       /* use the ifname in the port description until alias is set */
-                       log_debug("interfaces", "using ifname in description for %s",
-                           hardware->h_ifname);
+                       /* use the actual alias in the port description
+                        * if requested and set */
                        free(port->p_descr);
-                       port->p_descr = strdup(hardware->h_ifname);
+                       if (portdescr_type == LLDP_PORTDESCR_SRC_ALIAS && has_alias) {
+                               log_debug("interfaces", "using alias in description for %s",
+                                   hardware->h_ifname);
+                               port->p_descr = strdup(iface->alias);
+                       } else {
+                               log_debug("interfaces", "using ifname in description for %s",
+                                   hardware->h_ifname);
+                               port->p_descr = strdup(hardware->h_ifname);
+                       }
                }
        }
 }
index e2ed835202cd3ca1467c88fdaf190b26ce37c09b..5cef91090fd8d0168b10c1f9b4d286e27457198d 100644 (file)
@@ -56,9 +56,20 @@ static struct atom_map lldp_agent_map = {
        },
 };
 
+static struct atom_map lldp_portdescr_map = {
+       .key = lldpctl_k_config_lldp_portdescr_type,
+       .map = {
+               { LLDP_PORTDESCR_SRC_AUTO,   "auto"},
+               { LLDP_PORTDESCR_SRC_IFNAME, "ifname"},
+               { LLDP_PORTDESCR_SRC_ALIAS,  "alias"},
+               { 0, NULL},
+       },
+};
+
 ATOM_MAP_REGISTER(bond_slave_src_mac_map, 1);
 ATOM_MAP_REGISTER(lldp_portid_map, 2);
 ATOM_MAP_REGISTER(lldp_agent_map, 3);
+ATOM_MAP_REGISTER(lldp_portdescr_map, 4);
 
 static int
 _lldpctl_atom_new_config(lldpctl_atom_t *atom, va_list ap)
@@ -113,6 +124,8 @@ _lldpctl_atom_get_str_config(lldpctl_atom_t *atom, lldpctl_key_t key)
                return map_lookup(lldp_portid_map.map, c->config->c_lldp_portid_type);
        case lldpctl_k_config_lldp_agent_type:
                return map_lookup(lldp_agent_map.map, c->config->c_lldp_agent_type);
+       case lldpctl_k_config_lldp_portdescr_type:
+               return map_lookup(lldp_portdescr_map.map, c->config->c_lldp_portdescr_type);
        default:
                SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
                return NULL;
@@ -242,6 +255,8 @@ _lldpctl_atom_get_int_config(lldpctl_atom_t *atom, lldpctl_key_t key)
                return c->config->c_tx_hold;
        case lldpctl_k_config_max_neighbors:
                return c->config->c_max_neighbors;
+       case lldpctl_k_config_lldp_portid_type:
+               return c->config->c_lldp_portid_type;
        default:
                return SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
        }
@@ -311,6 +326,10 @@ _lldpctl_atom_set_int_config(lldpctl_atom_t *atom, lldpctl_key_t key, long int v
                config.c_lldp_agent_type = value;
                c->config->c_lldp_agent_type = value;
                break;
+       case lldpctl_k_config_lldp_portdescr_type:
+               config.c_lldp_portdescr_type = value;
+               c->config->c_lldp_portdescr_type = value;
+               break;
        default:
                SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
                return NULL;
index 0eb0265d104a387893b024f8cf33a3f64669bd4f..9e08f312c6d26d26f4a6655908986407015c6d98 100644 (file)
@@ -920,6 +920,7 @@ typedef enum {
        lldpctl_k_config_lldp_agent_type,  /**< `(I,WO)` LLDP agent type */
        lldpctl_k_config_max_neighbors,    /**< `(I,WO)`Maximum number of neighbors per
                                              port. */
+       lldpctl_k_config_lldp_portdescr_type, /**< `(I,WO)` LLDP port description source */
 
        lldpctl_k_custom_tlvs = 5000, /**< `(AL)` custom TLVs */
        lldpctl_k_custom_tlvs_clear,  /**< `(WO)` clear list of custom TLVs */
index 591b47d399d765cfef441d59233419713a91b74a..b858b3792d6f9175618d5978fe65ec25ecb9b6d8 100644 (file)
 #define LLDP_PORTID_SUBTYPE_LOCAL 7
 #define LLDP_PORTID_SUBTYPE_MAX LLDP_PORTID_SUBTYPE_LOCAL
 
+/* Port description source type */
+#define LLDP_PORTDESCR_SRC_AUTO     0
+#define LLDP_PORTDESCR_SRC_IFNAME   1
+#define LLDP_PORTDESCR_SRC_ALIAS    2
+#define LLDP_PORTDESCR_SRC_MAX      LLDP_PORTDESCR_SRC_ALIAS
+
 /* Operational MAU Type field. See:
  * https://www.iana.org/assignments/ianamau-mib/ianamau-mib */
 #define LLDP_DOT3_MAU_AUI 1
index a7ef70b62c51bc41241bacb8d111fdfa0cb63f3d..d1f7e9b350fe854d8af3bf23946cd7272c8d3561 100644 (file)
@@ -422,6 +422,7 @@ struct lldpd_config {
                                          slaves */
        int c_lldp_portid_type;        /* The PortID type */
        int c_lldp_agent_type;         /* The agent type */
+       int c_lldp_portdescr_type;            /* The port description source type */
 };
 MARSHAL_BEGIN(lldpd_config)
 MARSHAL_STR(lldpd_config, c_mgmt_pattern)