From 6dd83015cb744d6846463b4bfd66c62a1bfc45c2 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Tue, 4 Nov 2014 20:35:10 +0100 Subject: [PATCH] lldpcli: allow to unset patterns and system description/hostname --- NEWS | 4 +++ src/client/conf-system.c | 71 ++++++++++++++++++++++++++++++++-------- src/client/lldpcli.8.in | 41 +++++++++++++++++++++++ src/daemon/client.c | 35 +++++++++++++------- src/lib/atom-private.c | 21 +++++++----- src/lib/atom.c | 10 +++--- 6 files changed, 146 insertions(+), 36 deletions(-) diff --git a/NEWS b/NEWS index 4f27a4b8..465d125c 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,8 @@ lldpd (0.7.12) + * Features: + + Interface pattern, management pattern, system description, + system platform and system hostname can be unconfigured to their + default values. * Fix: + Don't complain when parsing a commented line. + Correctly persist configuration changes for "system interface diff --git a/src/client/conf-system.c b/src/client/conf-system.c index 31e60662..b403d466 100644 --- a/src/client/conf-system.c +++ b/src/client/conf-system.c @@ -33,14 +33,18 @@ cmd_iface_pattern(struct lldpctl_conn_t *conn, struct writer *w, lldpctl_last_strerror(conn)); return 0; } + + const char *value = cmdenv_get(env, "iface-pattern"); if (lldpctl_atom_set_str(config, - lldpctl_k_config_iface_pattern, cmdenv_get(env, "iface-pattern")) == NULL) { + lldpctl_k_config_iface_pattern, + value) == NULL) { log_warnx("lldpctl", "unable to set iface-pattern. %s", lldpctl_last_strerror(conn)); lldpctl_atom_dec_ref(config); return 0; } - log_info("lldpctl", "iface-pattern set to new value %s", cmdenv_get(env, "iface-pattern")); + log_info("lldpctl", "iface-pattern set to new value %s", + value?value:"(none)"); lldpctl_atom_dec_ref(config); return 1; } @@ -75,12 +79,15 @@ cmd_system_description(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) { int platform = 0; - const char *value = cmdenv_get(env, "description"); - if (!value) { - platform = 1; + const char *what = arg; + const char *value; + if (!strcmp(what, "system")) { + value = cmdenv_get(env, "description"); + } else { value = cmdenv_get(env, "platform"); + platform = 1; } - log_debug("lldpctl", "set %s description", platform?"platform":"system"); + log_debug("lldpctl", "set %s description", what); lldpctl_atom_t *config = lldpctl_get_configuration(conn); if (config == NULL) { log_warnx("lldpctl", "unable to get configuration from lldpd. %s", @@ -96,7 +103,7 @@ cmd_system_description(struct lldpctl_conn_t *conn, struct writer *w, return 0; } log_info("lldpctl", "description set to new value %s", - value); + value?value:"(none)"); lldpctl_atom_dec_ref(config); return 1; } @@ -113,8 +120,8 @@ cmd_management(struct lldpctl_conn_t *conn, struct writer *w, lldpctl_last_strerror(conn)); return 0; } - const char *value = cmdenv_get(env, "management-pattern"); + const char *value = cmdenv_get(env, "management-pattern"); if (lldpctl_atom_set_str(config, lldpctl_k_config_mgmt_pattern, value) == NULL) { log_warnx("lldpctl", "unable to set management pattern. %s", @@ -122,7 +129,8 @@ cmd_management(struct lldpctl_conn_t *conn, struct writer *w, lldpctl_atom_dec_ref(config); return 0; } - log_info("lldpctl", "management pattaren set to new value %s", value); + log_info("lldpctl", "management pattaren set to new value %s", + value?value:"(none)"); lldpctl_atom_dec_ref(config); return 1; } @@ -139,8 +147,8 @@ cmd_hostname(struct lldpctl_conn_t *conn, struct writer *w, lldpctl_last_strerror(conn)); return 0; } - const char *value = cmdenv_get(env, "hostname"); + const char *value = cmdenv_get(env, "hostname"); if (lldpctl_atom_set_str(config, lldpctl_k_config_hostname, value) == NULL) { log_warnx("lldpctl", "unable to set system name. %s", @@ -148,7 +156,8 @@ cmd_hostname(struct lldpctl_conn_t *conn, struct writer *w, lldpctl_atom_dec_ref(config); return 0; } - log_info("lldpctl", "system name set to new value %s", value); + log_info("lldpctl", "system name set to new value %s", + value?value:"(none)"); lldpctl_atom_dec_ref(config); return 1; } @@ -311,7 +320,13 @@ register_commands_configure_system(struct cmd_node *configure, NULL, "Chassis description", NULL, cmd_store_env_value, "description"), NEWLINE, "Override chassis description", - NULL, cmd_system_description, NULL); + NULL, cmd_system_description, "system"); + commands_new( + commands_new(unconfigure_system, + "description", "Don't override chassis description", + NULL, NULL, NULL), + NEWLINE, "Don't override chassis description", + NULL, cmd_system_description, "system"); commands_new( commands_new( @@ -321,7 +336,13 @@ register_commands_configure_system(struct cmd_node *configure, NULL, "Platform description (CDP)", NULL, cmd_store_env_value, "platform"), NEWLINE, "Override platform description", - NULL, cmd_system_description, NULL); + NULL, cmd_system_description, "platform"); + commands_new( + commands_new(unconfigure_system, + "platform", "Don't override platform description", + NULL, NULL, NULL), + NEWLINE, "Don't override platform description", + NULL, cmd_system_description, "platform"); commands_new( commands_new( @@ -332,6 +353,12 @@ register_commands_configure_system(struct cmd_node *configure, NULL, cmd_store_env_value, "hostname"), NEWLINE, "Override system name", NULL, cmd_hostname, NULL); + commands_new( + commands_new(unconfigure_system, + "hostname", "Don't override system name", + NULL, NULL, NULL), + NEWLINE, "Don't override system name", + NULL, cmd_hostname, NULL); commands_new( commands_new( @@ -348,6 +375,18 @@ register_commands_configure_system(struct cmd_node *configure, NULL, cmd_store_env_value, "management-pattern"), NEWLINE, "Set IP management pattern", NULL, cmd_management, NULL); + commands_new( + commands_new( + commands_new( + commands_new(unconfigure_system, + "ip", "IP related options", + NULL, NULL, NULL), + "management", "IP management related options", + NULL, NULL, NULL), + "pattern", "Delete any IP management pattern", + NULL, NULL, NULL), + NEWLINE, "Delete any IP management pattern", + NULL, cmd_management, NULL); commands_new( commands_new( @@ -358,6 +397,12 @@ register_commands_configure_system(struct cmd_node *configure, NULL, cmd_store_env_value, "iface-pattern"), NEWLINE, "Set active interface pattern", NULL, cmd_iface_pattern, NULL); + commands_new( + commands_new(unconfigure_interface, + "pattern", "Delete any interface pattern", + NULL, NULL, NULL), + NEWLINE, "Delete any interface pattern", + NULL, cmd_iface_pattern, NULL); commands_new( commands_new(configure_interface, diff --git a/src/client/lldpcli.8.in b/src/client/lldpcli.8.in index c67c5573..0f323442 100644 --- a/src/client/lldpcli.8.in +++ b/src/client/lldpcli.8.in @@ -174,6 +174,12 @@ system name is found from the resolved value of .Ic uname -n . .Ed +.Cd unconfigure +.Cd system hostname +.Bd -ragged -offset XXXXXX +Do not override system hostname and restore the use of the node name. +.Ed + .Cd configure .Cd system description Ar description .Bd -ragged -offset XXXXXX @@ -181,6 +187,13 @@ Override chassis description with the provided value instead of using kernel name, node name, kernel version, build date and architecture. .Ed +.Cd unconfigure +.Cd system description +.Bd -ragged -offset XXXXXX +Do not override chassis description and use a value computed from node +name, kernel name, kernel version, build date and architecture instead. +.Ed + .Cd configure .Cd system platform Ar description .Bd -ragged -offset XXXXXX @@ -188,6 +201,13 @@ Override platform description with the provided value instead of using kernel name. This value is currently only used for CDP. .Ed +.Cd unconfigure +.Cd system platform +.Bd -ragged -offset XXXXXX +Do not override platform description and use the kernel name. This +option undoes the previous one. +.Ed + .Cd configure .Cd system interface pattern Ar pattern .Bd -ragged -offset XXXXXX @@ -220,6 +240,13 @@ When an exact match is found, it will circumvent some tests. For example, if is specified, it will be accepted even if this is a VLAN interface. .Ed +.Cd unconfigure +.Cd system interface pattern +.Bd -ragged -offset XXXXXX +Remove any previously configured interface pattern and listen to all +physical interafces. This option undoes the previous one. +.Ed + .Cd configure .Cd system interface description .Bd -ragged -offset XXXXXX @@ -230,6 +257,13 @@ to override this description with the name of the peer neighbor if one is found or with the number of neighbors found. .Ed +.Cd unconfigure +.Cd system interface descripton +.Bd -ragged -offset XXXXXX +Do not update interface description with the name of the peer +neighbor. This option undoes the previous one. +.Ed + .Cd configure .Cd system interface promiscuous .Bd -ragged -offset XXXXXX @@ -273,6 +307,13 @@ want to blacklist IPv6 addresses, you can use .Em !*:* . .Ed +.Cd unconfigure +.Cd system ip management pattern +.Bd -ragged -offset XXXXXX +Unset any specific pattern for matching management addresses. This +option undoes the previous one. +.Ed + .Cd configure .Cd portidsubtype ifname .Cd ifname | macaddress diff --git a/src/daemon/client.c b/src/daemon/client.c index 8603ffd8..2ac762fc 100644 --- a/src/daemon/client.c +++ b/src/daemon/client.c @@ -42,6 +42,13 @@ client_handle_get_configuration(struct lldpd *cfg, enum hmsg_type *type, return output_len; } +static char* +xstrdup(const char *str) +{ + if (!str) return NULL; + return strdup(str); +} + /* Change the global configuration */ static int client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, @@ -57,7 +64,8 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, } #define CHANGED(w) (config->w != cfg->g_config.w) -#define CHANGED_STR(w) (config->w && (!cfg->g_config.w || strcmp(config->w, cfg->g_config.w))) +#define CHANGED_STR(w) (!(config->w == cfg->g_config.w || \ + (config->w && cfg->g_config.w && !strcmp(config->w, cfg->g_config.w)))) /* What needs to be done? Transmit delay? */ if (CHANGED(c_tx_interval) && config->c_tx_interval > 0) { @@ -108,33 +116,38 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, } #endif if (CHANGED_STR(c_iface_pattern)) { - log_debug("rpc", "change interface pattern to %s", config->c_iface_pattern); + log_debug("rpc", "change interface pattern to %s", + config->c_iface_pattern?config->c_iface_pattern:"(NULL)"); free(cfg->g_config.c_iface_pattern); - cfg->g_config.c_iface_pattern = strdup(config->c_iface_pattern); + cfg->g_config.c_iface_pattern = xstrdup(config->c_iface_pattern); levent_update_now(cfg); } if (CHANGED_STR(c_mgmt_pattern)) { - log_debug("rpc", "change management pattern to %s", config->c_mgmt_pattern); + log_debug("rpc", "change management pattern to %s", + config->c_mgmt_pattern?config->c_mgmt_pattern:"(NULL)"); free(cfg->g_config.c_mgmt_pattern); - cfg->g_config.c_mgmt_pattern = strdup(config->c_mgmt_pattern); + cfg->g_config.c_mgmt_pattern = xstrdup(config->c_mgmt_pattern); levent_update_now(cfg); } if (CHANGED_STR(c_description)) { - log_debug("rpc", "change chassis description to %s", config->c_description); + log_debug("rpc", "change chassis description to %s", + config->c_description?config->c_description:"(NULL)"); free(cfg->g_config.c_description); - cfg->g_config.c_description = strdup(config->c_description); + cfg->g_config.c_description = xstrdup(config->c_description); levent_update_now(cfg); } if (CHANGED_STR(c_platform)) { - log_debug("rpc", "change platform description to %s", config->c_platform); + log_debug("rpc", "change platform description to %s", + config->c_platform?config->c_platform:"(NULL)"); free(cfg->g_config.c_platform); - cfg->g_config.c_platform = strdup(config->c_platform); + cfg->g_config.c_platform = xstrdup(config->c_platform); levent_update_now(cfg); } if (CHANGED_STR(c_hostname)) { - log_debug("rpc", "change system name to %s", config->c_hostname); + log_debug("rpc", "change system name to %s", + config->c_hostname?config->c_hostname:"(NULL"); free(cfg->g_config.c_hostname); - cfg->g_config.c_hostname = strdup(config->c_hostname); + cfg->g_config.c_hostname = xstrdup(config->c_hostname); levent_update_now(cfg); } if (CHANGED(c_set_ifdescr)) { diff --git a/src/lib/atom-private.c b/src/lib/atom-private.c index 8a0bc0e7..113c9dbc 100644 --- a/src/lib/atom-private.c +++ b/src/lib/atom-private.c @@ -396,13 +396,18 @@ static struct _lldpctl_atom_config_t* __lldpctl_atom_set_str_config(struct _lldpctl_atom_config_t *c, char **local, char **global, const char *value) { - char *aval = NULL; - size_t len = strlen(value) + 1; - aval = _lldpctl_alloc_in_atom((lldpctl_atom_t *)c, len); - if (!aval) return NULL; - memcpy(aval, value, len); - *local = aval; - free(*global); *global = strdup(aval); + if (value) { + char *aval = NULL; + size_t len = strlen(value) + 1; + aval = _lldpctl_alloc_in_atom((lldpctl_atom_t *)c, len); + if (!aval) return NULL; + memcpy(aval, value, len); + *local = aval; + free(*global); *global = strdup(aval); + } else { + free(*global); + *local = *global = NULL; + } return c; } @@ -453,7 +458,7 @@ _lldpctl_atom_set_str_config(lldpctl_atom_t *atom, lldpctl_key_t key, return NULL; } - if (asprintf(&canary, "%d%s", key, value) == -1) { + if (asprintf(&canary, "%d%s", key, value?value:"(NULL)") == -1) { SET_ERROR(atom->conn, LLDPCTL_ERR_NOMEM); return NULL; } diff --git a/src/lib/atom.c b/src/lib/atom.c index c592ff92..4909be00 100644 --- a/src/lib/atom.c +++ b/src/lib/atom.c @@ -137,7 +137,7 @@ lldpctl_atom_set_str(lldpctl_atom_t *atom, lldpctl_key_t key, lldpctl_atom_t *result = NULL; char *end; long int converted; - int isint; + int isint = 0; int bad = 0; if (atom == NULL) return NULL; @@ -152,8 +152,10 @@ lldpctl_atom_set_str(lldpctl_atom_t *atom, lldpctl_key_t key, bad = bad || (lldpctl_last_error(atom->conn) == LLDPCTL_ERR_BAD_VALUE); } - converted = strtol(value, &end, 0); - isint = (end != value && *end == '\0'); + if (value) { + converted = strtol(value, &end, 0); + isint = (end != value && *end == '\0'); + } RESET_ERROR(atom->conn); if (atom->set_int != NULL && isint) { @@ -167,7 +169,7 @@ lldpctl_atom_set_str(lldpctl_atom_t *atom, lldpctl_key_t key, RESET_ERROR(atom->conn); if (atom->set_buffer != NULL) { - result = atom->set_buffer(atom, key, (u_int8_t*)value, strlen(value)); + result = atom->set_buffer(atom, key, (u_int8_t*)value, value?strlen(value):0); if (result) return result; if (lldpctl_last_error(atom->conn) != LLDPCTL_ERR_NOT_EXIST && lldpctl_last_error(atom->conn) != LLDPCTL_ERR_BAD_VALUE) -- 2.39.5