From: Alexandru Ardelean Date: Tue, 24 Mar 2015 07:08:33 +0000 (+0200) Subject: lldpd: implement basic support to override port IDs via lldpcli X-Git-Tag: 0.7.14~8^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e46010cf12f3b7c629744345022ef590ab1c8cc;p=thirdparty%2Flldpd.git lldpd: implement basic support to override port IDs via lldpcli Signed-off-by: Alexandru Ardelean --- diff --git a/src/client/conf-lldp.c b/src/client/conf-lldp.c index 64553c80..962ce360 100644 --- a/src/client/conf-lldp.c +++ b/src/client/conf-lldp.c @@ -69,6 +69,30 @@ cmd_txhold(struct lldpctl_conn_t *conn, struct writer *w, return 1; } +static int +cmd_portid_type_local(struct lldpctl_conn_t *conn, struct writer *w, + struct cmd_env *env, void *arg) +{ + lldpctl_atom_t *iface; + const char *id = cmdenv_get(env, "port-id"); + + if (!id || !strlen(id)) { + log_warnx("lldpctl", "no id speficied"); + return 0; + } + + while ((iface = cmd_iterate_on_interfaces(conn, env))) { + lldpctl_atom_t *port = lldpctl_get_port(iface); + if (lldpctl_atom_set_str(port, lldpctl_k_port_id, id) == NULL) { + log_warnx("lldpctl", "unable to set LLDP PortID." + " %s", lldpctl_last_strerror(conn)); + } + lldpctl_atom_dec_ref(port); + } + + return 1; +} + static int cmd_portid_type(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) @@ -167,6 +191,17 @@ register_commands_configure_lldp(struct cmd_node *configure) NEWLINE, NULL, NULL, cmd_portid_type, b_map->string); + } else if (!strcmp(b_map->string, "local")) { + commands_new( + commands_new( + commands_new(configure_lldp_portid_type, + b_map->string, "Local", + NULL, NULL, NULL), + NULL, "PortID", + NULL, cmd_store_env_value, "port-id"), + NEWLINE, NULL, + NULL, cmd_portid_type_local, + b_map->string); } else if (!strcmp(b_map->string, "macaddress")) { commands_new( commands_new(configure_lldp_portid_type, diff --git a/src/daemon/client.c b/src/daemon/client.c index 6e8fdca6..7f4b4658 100644 --- a/src/daemon/client.c +++ b/src/daemon/client.c @@ -293,7 +293,13 @@ client_handle_set_port(struct lldpd *cfg, enum hmsg_type *type, TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) if (!strcmp(hardware->h_ifname, set->ifname)) { struct lldpd_port *port = &hardware->h_lport; - (void)port; + if (set->local_id) { + log_debug("rpc", "requested change to Port ID"); + free(port->p_id); + port->p_id = strdup(set->local_id); + port->p_id_len = strlen(set->local_id); + port->p_id_subtype = LLDP_PORTID_SUBTYPE_LOCAL; + } #ifdef ENABLE_LLDPMED if (set->med_policy && set->med_policy->type > 0) { log_debug("rpc", "requested change to MED policy"); @@ -356,6 +362,7 @@ client_handle_set_port(struct lldpd *cfg, enum hmsg_type *type, set_port_finished: if (!ret) *type = NONE; free(set->ifname); + free(set->local_id); #ifdef ENABLE_LLDPMED free(set->med_policy); if (set->med_location) free(set->med_location->data); diff --git a/src/daemon/interfaces.c b/src/daemon/interfaces.c index 849ed285..c43614e7 100644 --- a/src/daemon/interfaces.c +++ b/src/daemon/interfaces.c @@ -465,6 +465,9 @@ interfaces_helper_port_name_desc(struct lldpd *cfg, { struct lldpd_port *port = &hardware->h_lport; + if (port->p_id_subtype == LLDP_PORTID_SUBTYPE_LOCAL) + goto description; + /* We need to set the portid to what the client configured. This can be done from the CLI. */ @@ -492,6 +495,7 @@ interfaces_helper_port_name_desc(struct lldpd *cfg, port->p_id_len = ETHER_ADDR_LEN; } +description: if (iface->alias != NULL && strlen(iface->alias) != 0) { /* use the actual alias in the port description */ log_debug("interfaces", "using alias in description for %s", diff --git a/src/lib/atom-private.c b/src/lib/atom-private.c index 7b43a03a..ad725211 100644 --- a/src/lib/atom-private.c +++ b/src/lib/atom-private.c @@ -273,6 +273,7 @@ static lldpctl_map_t bond_slave_src_mac_map[] = { static lldpctl_map_t lldp_portid_map[] = { { LLDP_PORTID_SUBTYPE_IFNAME, "ifname"}, { LLDP_PORTID_SUBTYPE_LLADDR, "macaddress"}, + { LLDP_PORTID_SUBTYPE_LOCAL, "local"}, { LLDP_PORTID_SUBTYPE_UNKNOWN, NULL}, }; @@ -844,6 +845,9 @@ _lldpctl_atom_set_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key, lldpctl_ato } switch (key) { + case lldpctl_k_port_id: + set.local_id = p->port->p_id; + break; #ifdef ENABLE_DOT3 case lldpctl_k_port_dot3_power: if (value->type != atom_dot3_power) { @@ -1025,6 +1029,31 @@ _lldpctl_atom_get_str_port(lldpctl_atom_t *atom, lldpctl_key_t key) } } +static lldpctl_atom_t* +_lldpctl_atom_set_str_port(lldpctl_atom_t *atom, lldpctl_key_t key, + const char *value) +{ + struct _lldpctl_atom_port_t *p = + (struct _lldpctl_atom_port_t *)atom; + struct lldpd_port *port = p->port; + + if (!value || !strlen(value)) + return NULL; + + switch (key) { + case lldpctl_k_port_id: + free(port->p_id); + port->p_id = strdup(value); + port->p_id_len = strlen(value); + break; + default: + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } + + return _lldpctl_atom_set_atom_port(atom, key, NULL); +} + static long int _lldpctl_atom_get_int_port(lldpctl_atom_t *atom, lldpctl_key_t key) { @@ -2593,6 +2622,7 @@ struct atom_builder builders[] = { .get = _lldpctl_atom_get_atom_port, .set = _lldpctl_atom_set_atom_port, .get_str = _lldpctl_atom_get_str_port, + .set_str = _lldpctl_atom_set_str_port, .get_int = _lldpctl_atom_get_int_port, .get_buffer = _lldpctl_atom_get_buf_port }, { atom_mgmts_list, sizeof(struct _lldpctl_atom_mgmts_list_t), diff --git a/src/lib/lldpctl.h b/src/lib/lldpctl.h index e6263be5..d42d5efb 100644 --- a/src/lib/lldpctl.h +++ b/src/lib/lldpctl.h @@ -626,7 +626,7 @@ typedef enum { lldpctl_k_port_protocol, /**< `(IS)` The protocol that was used to retrieve this information. */ lldpctl_k_port_age, /**< `(I)` Age of information, seconds from epoch. */ lldpctl_k_port_id_subtype, /**< `(IS)` The subtype ID of this port. */ - lldpctl_k_port_id, /**< `(BS)` The ID of this port. */ + lldpctl_k_port_id, /**< `(BS,WO)` The ID of this port. */ lldpctl_k_port_descr, /**< `(S)` The description of this port. */ lldpctl_k_port_hidden, /**< `(I)` Is this port hidden (or should it be displayed?)? */ diff --git a/src/lldpd-structs.c b/src/lldpd-structs.c index 094325d7..d24f4bf5 100644 --- a/src/lldpd-structs.c +++ b/src/lldpd-structs.c @@ -161,11 +161,11 @@ lldpd_port_cleanup(struct lldpd_port *port, int all) #endif /* will set these to NULL so we don't free wrong memory */ - free(port->p_id); - port->p_id = NULL; free(port->p_descr); port->p_descr = NULL; if (all) { + free(port->p_id); + port->p_id = NULL; free(port->p_lastframe); if (port->p_chassis) { /* chassis may not have been attributed, yet */ port->p_chassis->c_refcount--; diff --git a/src/lldpd-structs.h b/src/lldpd-structs.h index c2b69d26..52557073 100644 --- a/src/lldpd-structs.h +++ b/src/lldpd-structs.h @@ -275,6 +275,7 @@ MARSHAL_END(lldpd_port); /* Used to modify some port related settings */ struct lldpd_port_set { char *ifname; + char *local_id; #ifdef ENABLE_LLDPMED struct lldpd_med_policy *med_policy; struct lldpd_med_loc *med_location; @@ -286,6 +287,7 @@ struct lldpd_port_set { }; MARSHAL_BEGIN(lldpd_port_set) MARSHAL_STR(lldpd_port_set, ifname) +MARSHAL_STR(lldpd_port_set, local_id) #ifdef ENABLE_LLDPMED MARSHAL_POINTER(lldpd_port_set, lldpd_med_policy, med_policy) MARSHAL_POINTER(lldpd_port_set, lldpd_med_loc, med_location)