diff --git a/src/client/conf-system.c b/src/client/conf-system.c index a262d364..3ae0e508 100644 --- a/src/client/conf-system.c +++ b/src/client/conf-system.c @@ -76,6 +76,32 @@ cmd_system_description(struct lldpctl_conn_t *conn, struct writer *w, return 1; } +static int +cmd_hostname(struct lldpctl_conn_t *conn, struct writer *w, + struct cmd_env *env, void *arg) +{ + log_debug("lldpctl", "set system name"); + + 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; + } + const char *value = cmdenv_get(env, "hostname"); + + if (lldpctl_atom_set_str(config, + lldpctl_k_config_hostname, cmdenv_get(env, "hostname")) == NULL) { + log_warnx("lldpctl", "unable to set system name. %s", + lldpctl_last_strerror(conn)); + lldpctl_atom_dec_ref(config); + return 0; + } + log_info("lldpctl", "system name set to new value %s", cmdenv_get(env, "hostname")); + lldpctl_atom_dec_ref(config); + return 1; +} + static int cmd_update_descriptions(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) @@ -246,6 +272,16 @@ register_commands_configure_system(struct cmd_node *configure, NEWLINE, "Override platform description", NULL, cmd_system_description, NULL); + commands_new( + commands_new( + commands_new(configure_system, + "hostname", "Override system name", + NULL, NULL, NULL), + NULL, "System name", + NULL, cmd_store_env_value, "hostname"), + NEWLINE, "Override system name", + NULL, cmd_hostname, NULL); + commands_new( commands_new( commands_new(configure_interface, diff --git a/src/client/display.c b/src/client/display.c index ec57fe5f..28d4c397 100644 --- a/src/client/display.c +++ b/src/client/display.c @@ -723,6 +723,8 @@ display_configuration(lldpctl_conn_t *conn, struct writer *w) N(lldpctl_atom_get_str(configuration, lldpctl_k_config_description))); tag_datatag(w, "platform", "Override platform with", N(lldpctl_atom_get_str(configuration, lldpctl_k_config_platform))); + tag_datatag(w, "hostname", "Override system name with", + N(lldpctl_atom_get_str(configuration, lldpctl_k_config_hostname))); tag_datatag(w, "advertise-version", "Advertise version", lldpctl_atom_get_int(configuration, lldpctl_k_config_advertise_version)? "yes":"no"); diff --git a/src/daemon/client.c b/src/daemon/client.c index 00247c00..674b854f 100644 --- a/src/daemon/client.c +++ b/src/daemon/client.c @@ -112,6 +112,12 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, cfg->g_config.c_platform = strdup(config->c_platform); levent_update_now(cfg); } + if (config->c_hostname) { + log_debug("rpc", "change system name to %s", config->c_hostname); + free(cfg->g_config.c_hostname); + cfg->g_config.c_hostname = strdup(config->c_hostname); + levent_update_now(cfg); + } if (config->c_set_ifdescr != cfg->g_config.c_set_ifdescr) { log_debug("rpc", "%s setting of interface description based on discovered neighbors", config->c_set_ifdescr?"enable":"disable"); diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 76951c19..2fe8383d 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -987,8 +987,13 @@ lldpd_update_localchassis(struct lldpd *cfg) /* Set system name and description */ if (uname(&un) < 0) fatal("localchassis", "failed to get system information"); - if ((hp = priv_gethostbyname()) == NULL) - fatal("localchassis", "failed to get system name"); + if (cfg->g_config.c_hostname) { + log_debug("localchassis", "use overridden system name `%s`", cfg->g_config.c_hostname); + hp = cfg->g_config.c_hostname; + } else { + if ((hp = priv_gethostbyname()) == NULL) + fatal("localchassis", "failed to get system name"); + } free(LOCAL_CHASSIS(cfg)->c_name); free(LOCAL_CHASSIS(cfg)->c_descr); if ((LOCAL_CHASSIS(cfg)->c_name = strdup(hp)) == NULL) diff --git a/src/lib/atom-private.c b/src/lib/atom-private.c index 0d1a2a29..313ec5d2 100644 --- a/src/lib/atom-private.c +++ b/src/lib/atom-private.c @@ -367,6 +367,8 @@ _lldpctl_atom_get_str_config(lldpctl_atom_t *atom, lldpctl_key_t key) res = c->config->c_description; break; case lldpctl_k_config_platform: res = c->config->c_platform; break; + case lldpctl_k_config_hostname: + res = c->config->c_hostname; break; case lldpctl_k_config_bond_slave_src_mac_type: return map_lookup(bond_slave_src_mac_map, c->config->c_bond_slave_src_mac_type); @@ -418,6 +420,15 @@ _lldpctl_atom_set_str_config(lldpctl_atom_t *atom, lldpctl_key_t key, free(c->config->c_platform); c->config->c_description = strdup(description); break; + case lldpctl_k_config_hostname: + description = _lldpctl_alloc_in_atom(atom, strlen(value) + 1); + if (!description) + return NULL; + memcpy(description, value, len); + config.c_hostname = description; + free(c->config->c_hostname); + c->config->c_hostname = strdup(description); + break; default: SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); return NULL; diff --git a/src/lib/lldpctl.h b/src/lib/lldpctl.h index a3f5bb75..306bb5ba 100644 --- a/src/lib/lldpctl.h +++ b/src/lib/lldpctl.h @@ -589,6 +589,7 @@ typedef enum { lldpctl_k_config_cid_pattern, /**< `(S)` Interface pattern to choose the chassis ID */ lldpctl_k_config_description, /**< `(S,WO)` Chassis description overridden */ lldpctl_k_config_platform, /**< `(S,WO)` Platform description overridden (CDP) */ + lldpctl_k_config_hostname, /**< `(S,WO)` System name overridden */ lldpctl_k_config_advertise_version, /**< `(I)` Advertise version */ lldpctl_k_config_lldpmed_noinventory, /**< `(I)` Disable LLDP-MED inventory */ lldpctl_k_config_paused, /**< `(I)` lldpd is paused */ diff --git a/src/lldpd-structs.c b/src/lldpd-structs.c index 12fe3b81..71d28087 100644 --- a/src/lldpd-structs.c +++ b/src/lldpd-structs.c @@ -177,6 +177,7 @@ lldpd_config_cleanup(struct lldpd_config *config) free(config->c_mgmt_pattern); free(config->c_cid_pattern); free(config->c_iface_pattern); + free(config->c_hostname); free(config->c_platform); free(config->c_description); } diff --git a/src/lldpd-structs.h b/src/lldpd-structs.h index ca34ae26..245dd8cc 100644 --- a/src/lldpd-structs.h +++ b/src/lldpd-structs.h @@ -323,6 +323,7 @@ struct lldpd_config { char *c_platform; /* Override platform description (for CDP) */ char *c_description; /* Override chassis description */ + char *c_hostname; /* Override system name */ int c_advertise_version; /* Should the precise version be advertised? */ int c_set_ifdescr; /* Set interface description */ @@ -340,6 +341,7 @@ MARSHAL_BEGIN(lldpd_config) MARSHAL_STR(lldpd_config, c_mgmt_pattern) MARSHAL_STR(lldpd_config, c_cid_pattern) MARSHAL_STR(lldpd_config, c_iface_pattern) +MARSHAL_STR(lldpd_config, c_hostname) MARSHAL_STR(lldpd_config, c_platform) MARSHAL_STR(lldpd_config, c_description) MARSHAL_END(lldpd_config);