From: Vincent Bernat Date: Sat, 30 Dec 2017 12:24:46 +0000 (+0100) Subject: lib: ability to configure a local chassis ID X-Git-Tag: 1.0.0~21^2 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Flldpd.git;a=commitdiff_plain;h=8481f49050292ff9a4c0b20568ff05b7ecf85ef5;hp=e6f64ed93e6c223e7e7fab3ad994d85497d8e1e7 lib: ability to configure a local chassis ID Also, remove the `-c` flag for lldpd that was previously introduced. --- diff --git a/NEWS b/NEWS index c2f89ca4..48db878d 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,7 @@ lldpd (1.0.0) + * Changes: + + Chassis ID can be set to an arbitrary value with "configure system + chassisid". * Fix: + Ensure chassis-related changes are propagated immediately. diff --git a/src/client/conf-system.c b/src/client/conf-system.c index 3d6e5ffd..9958b1a5 100644 --- a/src/client/conf-system.c +++ b/src/client/conf-system.c @@ -109,6 +109,33 @@ cmd_system_description(struct lldpctl_conn_t *conn, struct writer *w, return 1; } +static int +cmd_system_chassisid(struct lldpctl_conn_t *conn, struct writer *w, + struct cmd_env *env, void *arg) +{ + const char *value; + value = cmdenv_get(env, "description"); + log_debug("lldpctl", "set chassis ID"); + 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; + } + if (lldpctl_atom_set_str(config, + lldpctl_k_config_cid_string, + value) == NULL) { + log_warnx("lldpctl", "unable to set chassis ID. %s", + lldpctl_last_strerror(conn)); + lldpctl_atom_dec_ref(config); + return 0; + } + log_info("lldpctl", "chassis ID set to new value %s", + value?value:"(none)"); + lldpctl_atom_dec_ref(config); + return 1; +} + static int cmd_management(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) @@ -337,6 +364,22 @@ register_commands_configure_system(struct cmd_node *configure, NEWLINE, "Don't override chassis description", NULL, cmd_system_description, "system"); + commands_new( + commands_new( + commands_new(configure_system, + "chassisid", "Override chassis ID", + NULL, NULL, NULL), + NULL, "Chassis ID", + NULL, cmd_store_env_value, "description"), + NEWLINE, "Override chassis ID", + NULL, cmd_system_chassisid, "system"); + commands_new( + commands_new(unconfigure_system, + "chassisid", "Don't override chassis ID", + NULL, NULL, NULL), + NEWLINE, "Don't override chassis ID", + NULL, cmd_system_chassisid, "system"); + commands_new( commands_new( commands_new(configure_system, diff --git a/src/client/lldpcli.8.in b/src/client/lldpcli.8.in index 300587fd..167c2604 100644 --- a/src/client/lldpcli.8.in +++ b/src/client/lldpcli.8.in @@ -239,6 +239,20 @@ 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 chassisid Ar description +.Bd -ragged -offset XXXXXX +Override chassis ID with the provided value instead of using MAC address +from one interface or host name. +.Ed + +.Cd unconfigure +.Cd system chassisid +.Bd -ragged -offset XXXXXX +Do not override chassis ID and use a value computed from one of the interface +MAC address (or host name if none is found). +.Ed + .Cd configure .Cd system platform Ar description .Bd -ragged -offset XXXXXX diff --git a/src/daemon/client.c b/src/daemon/client.c index 05d6ae65..c55288d5 100644 --- a/src/daemon/client.c +++ b/src/daemon/client.c @@ -137,6 +137,16 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, cfg->g_config.c_mgmt_pattern = xstrdup(config->c_mgmt_pattern); levent_update_now(cfg); } + if (CHANGED_STR(c_cid_string)) { + log_debug("rpc", "change chassis ID string to %s", + config->c_cid_string?config->c_cid_string:"(NULL)"); + free(cfg->g_config.c_cid_string); + cfg->g_config.c_cid_string = xstrdup(config->c_cid_string); + free(LOCAL_CHASSIS(cfg)->c_id); + LOCAL_CHASSIS(cfg)->c_id = NULL; + lldpd_update_localchassis(cfg); + levent_update_now(cfg); + } if (CHANGED_STR(c_description)) { log_debug("rpc", "change chassis description to %s", config->c_description?config->c_description:"(NULL)"); diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 83368425..b726882e 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -1201,20 +1201,20 @@ lldpd_update_localchassis(struct lldpd *cfg) has not been set previously (with the MAC address of an interface for example) */ + if (cfg->g_config.c_cid_string != NULL) { + log_debug("localchassis", "use specified chassis ID string"); + free(LOCAL_CHASSIS(cfg)->c_id); + if (!(LOCAL_CHASSIS(cfg)->c_id = strdup(cfg->g_config.c_cid_string))) + fatal("localchassis", NULL); + LOCAL_CHASSIS(cfg)->c_id_len = strlen(cfg->g_config.c_cid_string); + LOCAL_CHASSIS(cfg)->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL; + } if (LOCAL_CHASSIS(cfg)->c_id == NULL) { - if (cfg->g_config.c_cid_string != NULL) { - log_debug("localchassis", "no chassis ID is currently set, use chassis id string"); - if (!(LOCAL_CHASSIS(cfg)->c_id = strdup(cfg->g_config.c_cid_string))) + log_debug("localchassis", "no chassis ID is currently set, use chassis name"); + if (!(LOCAL_CHASSIS(cfg)->c_id = strdup(LOCAL_CHASSIS(cfg)->c_name))) fatal("localchassis", NULL); - LOCAL_CHASSIS(cfg)->c_id_len = strlen(cfg->g_config.c_cid_string); - LOCAL_CHASSIS(cfg)->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL; - } else { - log_debug("localchassis", "no chassis ID is currently set, use chassis name"); - if (!(LOCAL_CHASSIS(cfg)->c_id = strdup(LOCAL_CHASSIS(cfg)->c_name))) - fatal("localchassis", NULL); - LOCAL_CHASSIS(cfg)->c_id_len = strlen(LOCAL_CHASSIS(cfg)->c_name); - LOCAL_CHASSIS(cfg)->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL; - } + LOCAL_CHASSIS(cfg)->c_id_len = strlen(LOCAL_CHASSIS(cfg)->c_name); + LOCAL_CHASSIS(cfg)->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL; } } @@ -1483,13 +1483,13 @@ lldpd_main(int argc, char *argv[], char *envp[]) #endif const char *ctlname = NULL; char *mgmtp = NULL; - char *cidp = NULL, *cids = NULL; + char *cidp = NULL; char *interfaces = NULL; /* We do not want more options here. Please add them in lldpcli instead * unless there is a very good reason. Most command-line options will * get deprecated at some point. */ char *popt, opts[] = - "H:vhkrdD:p:xX:m:u:4:6:I:C:c:p:M:P:S:iL:O:@ "; + "H:vhkrdD:p:xX:m:u:4:6:I:C:p:M:P:S:iL:O:@ "; int i, found, advertise_version = 1; #ifdef ENABLE_LLDPMED int lldpmed = 0, noinventory = 0; @@ -1582,13 +1582,6 @@ lldpd_main(int argc, char *argv[], char *envp[]) } cidp = strdup(optarg); break; - case 'c': - if (cids) { - fprintf(stderr, "-c can only be used once\n"); - usage(); - } - cids = strdup(optarg); - break; case 'L': if (strlen(optarg)) lldpcli = optarg; else lldpcli = NULL; @@ -1818,7 +1811,6 @@ lldpd_main(int argc, char *argv[], char *envp[]) cfg->g_ctl = ctl; cfg->g_config.c_mgmt_pattern = mgmtp; cfg->g_config.c_cid_pattern = cidp; - cfg->g_config.c_cid_string = cids; cfg->g_config.c_iface_pattern = interfaces; cfg->g_config.c_smart = smart; if (lldpcli) diff --git a/src/lib/atoms/config.c b/src/lib/atoms/config.c index 7cd4f2ee..02836088 100644 --- a/src/lib/atoms/config.c +++ b/src/lib/atoms/config.c @@ -158,6 +158,12 @@ _lldpctl_atom_set_str_config(lldpctl_atom_t *atom, lldpctl_key_t key, value)) return NULL; break; + case lldpctl_k_config_cid_string: + if (!__lldpctl_atom_set_str_config(c, + &config.c_cid_string, &c->config->c_cid_string, + value)) + return NULL; + break; case lldpctl_k_config_description: if (!__lldpctl_atom_set_str_config(c, &config.c_description, &c->config->c_description, diff --git a/src/lib/lldpctl.h b/src/lib/lldpctl.h index f783f252..2a6e71ae 100644 --- a/src/lib/lldpctl.h +++ b/src/lib/lldpctl.h @@ -665,7 +665,7 @@ typedef enum { lldpctl_k_config_iface_promisc, /**< `(I,WO)` Enable or disable promiscuous mode on interfaces */ lldpctl_k_config_chassis_cap_advertise, /**< `(I,WO)` Enable or disable chassis capabilities advertisement */ lldpctl_k_config_chassis_mgmt_advertise, /**< `(I,WO)` Enable or disable management addresses advertisement */ - lldpctl_k_config_cid_string, /**< `(S)` User defined string for the chassis ID */ + lldpctl_k_config_cid_string, /**< `(S,WON)` User defined string for the chassis ID */ lldpctl_k_interface_name = 1000, /**< `(S)` The interface name. */ diff --git a/tests/integration/test_basic.py b/tests/integration/test_basic.py index 5c762c65..1ff7f4b7 100644 --- a/tests/integration/test_basic.py +++ b/tests/integration/test_basic.py @@ -104,6 +104,29 @@ def test_overrided_description2(lldpd1, lldpd, lldpcli, namespaces): assert out['lldp.eth0.chassis.descr'] == "Modified description" +def test_overrided_chassisid(lldpd1, lldpd, lldpcli, namespaces): + with namespaces(2): + lldpd() + lldpcli("configure", "system", "chassisid", "Modified chassis ID") + lldpcli("update") + time.sleep(1) + with namespaces(1): + out = lldpcli("-f", "keyvalue", "show", "neighbors") + assert out['lldp.eth0.chassis.local'] == "Modified chassis ID" + + +def test_overrided_chassisid_reverse(lldpd1, lldpd, lldpcli, namespaces): + with namespaces(2): + lldpd() + lldpcli("configure", "system", "chassisid", "Modified chassis ID") + lldpcli("unconfigure", "system", "chassisid") + lldpcli("update") + time.sleep(1) + with namespaces(1): + out = lldpcli("-f", "keyvalue", "show", "neighbors") + assert out['lldp.eth0.chassis.mac'] == "00:00:00:00:00:02" + + def test_hide_kernel(lldpd1, lldpd, lldpcli, namespaces): with namespaces(2): lldpd("-k")