From: Ignacio Sanchez Navarro Date: Mon, 1 Aug 2022 17:22:40 +0000 (-0400) Subject: client: Added support to override system capabilities X-Git-Tag: 1.0.15~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4c8e6e37142b2d92dc4879ef502cca9e8b02ddd9;p=thirdparty%2Flldpd.git client: Added support to override system capabilities 1) configure system capabilities enabled Override system capabilities with the provided value instead of using kernel information. Several capabilities can be specified separated by commas. Only available capabilities can be enabled. Valid capabilities are: other repeater bridge wlan router telephone docsis station Here is an example of use: lldpcli configure system capabilities enabled bridge,router 2) unconfigure system capabilities enabled Do not override capabilities and use the kernel information. This option undoes the previous one. Ignacio Sanchez Navarro (Ignacio.Sanchez@uws.ac.uk) - University of the West of Scotland - Supported by H2020-ICT-2020-2/101017226 6G-BRAINS ------------------------------------------------------------------------------- Modified files lldpd-structs.h - Added new attribute "c_cap_override" to "lldpd_config" struct conf-system.c - Added new function "cmd_capability" for new command to override the chassis capabilities - Added new function "register_commands_capabilities" to registers new commands to override the chassis capabilities - Added call to "register_commands_capabilities" in "register_commands_configure_system" chassis.c - Added new function "_lldpctl_atom_st_int_chassis" to set "int" type vars in chassis - Added assignation of ".set_int" function in "chassis" var build config.c - Added case for "lldpctl_k_config_chassis_cap_override" to get value of "c_cap_override" in "_lldpctl_atom_get_int_config" function - Added case for "lldpctl_k_config_chassis_cap_override" to set value of "c_cap_override" in "_lldpctl_atom_set_int_config" function client.c - Added changes check for "c_cap_override" var in "client_handle_set_configuration" function - Added changes check for "c_cap_enabled" var in "client_handle_set_local_chassis" function lldpctl.h - Added new enum values un "lldpctl_key_t" enum : "lldpctl_k_chassis_cap_enabled" and "lldpctl_k_config_chassis_cap_override" - Corrected some typos in previous comments lldpd.c - Added check of capabilities override before setting new values in "lldpd_update_localchassis" function - Added check of capabilities override before setting initial value of "c_cap_enabled" to 0 in "lldpd_loop" function - Added initial set of "cfg->g_config.c_cap_override" to 0 in "lldpd_main" function interfaces.c - Added check of capabilities override before setting new values in "interfaces_helper_chassis" function display.c - Added new line to display the status of capabilities override in "show configration" command lldpcli.8.in - Added new commands and descriptions to man file --- diff --git a/NEWS b/NEWS index 1380b0c4..ff529f46 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ lldpd (1.0.15) + * Changes + + Add configure command to override system capabilities (#526) * Fix: + Really don't send VLANs when there are too many (#520) + Ignore temporary IPv6 addresses (#521) diff --git a/src/client/conf-system.c b/src/client/conf-system.c index 9524d0db..b91e95d3 100644 --- a/src/client/conf-system.c +++ b/src/client/conf-system.c @@ -227,6 +227,87 @@ cmd_hostname(struct lldpctl_conn_t *conn, struct writer *w, return 1; } +static int +cmd_capability(struct lldpctl_conn_t *conn, struct writer *w, + struct cmd_env *env, void *arg) +{ + log_debug("lldpctl", "set capabilities"); + + int ret = 0; + lldpctl_atom_t *config = lldpctl_get_configuration(conn); + lldpctl_atom_t *chassis = NULL; + if (config == NULL) { + log_warnx("lldpctl", "unable to get configuration from lldpd. %s", + lldpctl_last_strerror(conn)); + goto cmd_capability_end; + } + + if (!strcmp(arg, "configure")) { + + const char *s = cmdenv_get(env, "capabilities"); + if (s) { + chassis = lldpctl_get_local_chassis(conn); + if (chassis == NULL) { + log_warnx("lldpctl", "unable to get local chassis from lldpd. %s", + lldpctl_last_strerror(conn)); + goto cmd_capability_end; + } + u_int16_t value = 0; + const char delim[] = ","; + char *s_copy = strdup(s); + char *token = strtok(s_copy, delim); + while (token != NULL) { + if (!strcmp(token, "other")) { + value |= LLDP_CAP_OTHER; + } else if (!strcmp(token, "repeater")) { + value |= LLDP_CAP_REPEATER; + } else if (!strcmp(token, "bridge")) { + value |= LLDP_CAP_BRIDGE; + } else if (!strcmp(token, "wlan")) { + value |= LLDP_CAP_WLAN; + } else if (!strcmp(token, "router")) { + value |= LLDP_CAP_ROUTER; + } else if (!strcmp(token, "telephone")) { + value |= LLDP_CAP_TELEPHONE; + } else if (!strcmp(token, "docsis")) { + value |= LLDP_CAP_DOCSIS; + } else if (!strcmp(token, "station")) { + value |= LLDP_CAP_STATION; + } else { + log_warnx("lldpctl", "capability %s not found", token); + } + token = strtok(NULL, delim); + } + free(s_copy); + + if (lldpctl_atom_set_int(chassis, lldpctl_k_chassis_cap_enabled, value) == NULL) { + log_warnx("lldpctl", "unable to set system capabilities. %s", + lldpctl_last_strerror(conn)); + goto cmd_capability_end; + } + if (lldpctl_atom_set_int(config, lldpctl_k_config_chassis_cap_override, 1) == NULL) { + log_warnx("lldpctl", "unable to set system capabilities override. %s", + lldpctl_last_strerror(conn)); + goto cmd_capability_end; + } + log_debug("lldpctl", "system capabilities set to new value %d", + value); + } + } else { + if (lldpctl_atom_set_int(config, lldpctl_k_config_chassis_cap_override, 0) == NULL) { + log_warnx("lldpctl", "unable to set system capabilities to not override. %s", + lldpctl_last_strerror(conn)); + goto cmd_capability_end; + } + } + + ret = 1; + cmd_capability_end: + lldpctl_atom_dec_ref(chassis); + lldpctl_atom_dec_ref(config); + return ret; +} + static int cmd_update_descriptions(struct lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env, void *arg) @@ -376,6 +457,38 @@ register_commands_srcmac_type(struct cmd_node *configure) } } +static void +register_commands_capabilities(struct cmd_node *configure, struct cmd_node *unconfigure) +{ + struct cmd_node *configure_capability = commands_new( + configure, + "capabilities", "Capabilities configuration", + cmd_check_no_env, NULL, "ports"); + struct cmd_node *unconfigure_capability = commands_new( + unconfigure, + "capabilities", "Capabilities configuration", + cmd_check_no_env, NULL, "ports"); + + /* Override */ + commands_new( + commands_new( + commands_new(configure_capability, + "enabled", "Override capabilities", + NULL, NULL, NULL), + NULL, " Set of capabilities separated by commas", + NULL, cmd_store_env_value, "capabilities"), + NEWLINE, "Override capabilities", + NULL, cmd_capability, "configure"); + + /* Do not override */ + commands_new( + commands_new(unconfigure_capability, + "enabled", "Do not override capabilities", + NULL, NULL, NULL), + NEWLINE, "Do not override capabilities", + NULL, cmd_capability, "unconfigure"); +} + /** * Register `configure system` commands. * @@ -562,6 +675,7 @@ register_commands_configure_system(struct cmd_node *configure, NEWLINE, "Don't enable promiscuous mode on managed interfaces", NULL, cmd_iface_promisc, NULL); + register_commands_capabilities(configure_system, unconfigure_system); register_commands_srcmac_type(configure_system); } diff --git a/src/client/display.c b/src/client/display.c index b21ff028..8465d2db 100644 --- a/src/client/display.c +++ b/src/client/display.c @@ -992,6 +992,9 @@ display_configuration(lldpctl_conn_t *conn, struct writer *w) 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, "capabilities", "Override system capabilities", + lldpctl_atom_get_int(configuration, lldpctl_k_config_chassis_cap_override)? + "yes":"no"); tag_datatag(w, "advertise-version", "Advertise version", lldpctl_atom_get_int(configuration, lldpctl_k_config_advertise_version)? "yes":"no"); diff --git a/src/client/lldpcli.8.in b/src/client/lldpcli.8.in index dd458d16..1dc75a0e 100644 --- a/src/client/lldpcli.8.in +++ b/src/client/lldpcli.8.in @@ -267,6 +267,34 @@ Do not override platform description and use the kernel name. This option undoes the previous one. .Ed +.Cd configure +.Cd system capabilities enabled Ar capabilities +.Bd -ragged -offset XXXXXX +Override system capabilities with the provided value instead of using +kernel information. Several capabilities can be specified separated by +commas. Only available capabilities can be enabled. Valid capabilities are: +.Bl -tag -width "XXX." -compact -offset XX +.It Sy other +.It Sy repeater +.It Sy bridge +.It Sy wlan +.It Sy router +.It Sy telephone +.It Sy docsis +.It Sy station +.El +Here is an example of use: +.D1 configure system capabilities enabled bridge,router +.Pp +.Ed + +.Cd unconfigure +.Cd system capabilities enabled +.Bd -ragged -offset XXXXXX +Do not override capabilities and use the kernel information. This option +undoes the previous one. +.Ed + .Cd configure .Cd system interface pattern Ar pattern .Bd -ragged -offset XXXXXX diff --git a/src/daemon/client.c b/src/daemon/client.c index 56e57590..654dbefd 100644 --- a/src/daemon/client.c +++ b/src/daemon/client.c @@ -18,9 +18,7 @@ #include "lldpd.h" #include "trace.h" -#ifdef ENABLE_LLDPMED #include -#endif static ssize_t client_handle_none(struct lldpd *cfg, enum hmsg_type *type, @@ -207,6 +205,12 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type, cfg->g_config.c_cap_advertise = config->c_cap_advertise; levent_update_now(cfg); } + if (CHANGED(c_cap_override)) { + log_debug("rpc", "%s chassis capabilities override", + config->c_cap_override?"enable":"disable"); + cfg->g_config.c_cap_override = config->c_cap_override; + levent_update_now(cfg); + } if (CHANGED(c_mgmt_advertise)) { log_debug("rpc", "%s management addresses advertisement", config->c_mgmt_advertise?"enable":"disable"); @@ -277,9 +281,8 @@ client_handle_get_interfaces(struct lldpd *cfg, enum hmsg_type *type, return output_len; } -#ifdef ENABLE_LLDPMED /** - * Set local chassis inventory info + * Set local chassis info * Input: chassis object * Output: updated chassis object */ @@ -289,7 +292,9 @@ client_handle_set_local_chassis(struct lldpd *cfg, enum hmsg_type *type, { struct lldpd_chassis *chassis = NULL; struct lldpd_chassis *local_chassis = NULL; +#ifdef ENABLE_LLDPMED struct utsname un; +#endif log_debug("rpc", "client request a change in chassis configuration"); if (lldpd_chassis_unserialize(input, input_len, &chassis) <= 0) { @@ -299,6 +304,7 @@ client_handle_set_local_chassis(struct lldpd *cfg, enum hmsg_type *type, local_chassis = LOCAL_CHASSIS(cfg); +#ifdef ENABLE_LLDPMED free(local_chassis->c_med_hw); local_chassis->c_med_hw = (!chassis->c_med_hw) ? dmi_hw() : strdup(chassis->c_med_hw); @@ -332,7 +338,14 @@ client_handle_set_local_chassis(struct lldpd *cfg, enum hmsg_type *type, free(local_chassis->c_med_asset); local_chassis->c_med_asset = (!chassis->c_med_asset) ? dmi_asset() : strdup(chassis->c_med_asset); +#endif + + if(chassis->c_cap_enabled != local_chassis->c_cap_enabled){ + local_chassis->c_cap_enabled = chassis->c_cap_enabled; + log_debug("rpc", "change capabilities enabled to: %d", local_chassis->c_cap_enabled); + } +#ifdef ENABLE_LLDPMED log_debug("rpc", "change hardware-revision to: %s", local_chassis->c_med_hw); log_debug("rpc", "change software-revision to: %s", local_chassis->c_med_sw); log_debug("rpc", "change firmware-revision to: %s", local_chassis->c_med_fw); @@ -340,6 +353,7 @@ client_handle_set_local_chassis(struct lldpd *cfg, enum hmsg_type *type, log_debug("rpc", "change manufacturer to: %s", local_chassis->c_med_manuf); log_debug("rpc", "change model to: %s", local_chassis->c_med_model); log_debug("rpc", "change asset to: %s", local_chassis->c_med_asset); +#endif lldpd_chassis_cleanup(chassis, 1); @@ -351,7 +365,6 @@ client_handle_set_local_chassis(struct lldpd *cfg, enum hmsg_type *type, return output_len; } -#endif /* ENABLE_LLDPMED */ /* Return the local chassis. Input: nothing. @@ -652,9 +665,7 @@ static struct client_handle client_handles[] = { { GET_INTERFACES, "Get interfaces", client_handle_get_interfaces }, { GET_INTERFACE, "Get interface", client_handle_get_interface }, { GET_DEFAULT_PORT, "Get default port", client_handle_get_default_port }, -#ifdef ENABLE_LLDPMED { SET_CHASSIS, "Set local chassis", client_handle_set_local_chassis }, -#endif { GET_CHASSIS, "Get local chassis", client_handle_get_local_chassis }, { SET_PORT, "Set port", client_handle_set_port }, { SUBSCRIBE, "Subscribe", client_handle_subscribe }, diff --git a/src/daemon/interfaces.c b/src/daemon/interfaces.c index 4cd600df..a59b6afd 100644 --- a/src/daemon/interfaces.c +++ b/src/daemon/interfaces.c @@ -351,17 +351,19 @@ interfaces_helper_chassis(struct lldpd *cfg, struct lldpd_hardware *hardware; char *name = NULL; - LOCAL_CHASSIS(cfg)->c_cap_enabled &= - ~(LLDP_CAP_BRIDGE | LLDP_CAP_WLAN | LLDP_CAP_STATION); - TAILQ_FOREACH(iface, interfaces, next) { - if (iface->type & IFACE_BRIDGE_T) - LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_BRIDGE; - if (iface->type & IFACE_WIRELESS_T) - LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_WLAN; + if (!cfg->g_config.c_cap_override) { + LOCAL_CHASSIS(cfg)->c_cap_enabled &= + ~(LLDP_CAP_BRIDGE | LLDP_CAP_WLAN | LLDP_CAP_STATION); + TAILQ_FOREACH(iface, interfaces, next) { + if (iface->type & IFACE_BRIDGE_T) + LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_BRIDGE; + if (iface->type & IFACE_WIRELESS_T) + LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_WLAN; + } + if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_STATION) && + (LOCAL_CHASSIS(cfg)->c_cap_enabled == 0)) + LOCAL_CHASSIS(cfg)->c_cap_enabled = LLDP_CAP_STATION; } - if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_STATION) && - (LOCAL_CHASSIS(cfg)->c_cap_enabled == 0)) - LOCAL_CHASSIS(cfg)->c_cap_enabled = LLDP_CAP_STATION; /* Do not modify the chassis if it's already set to a MAC address or if * it's set to a local address equal to the user-provided diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 6d885347..2d53fbad 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -1241,23 +1241,25 @@ lldpd_update_localchassis(struct lldpd *cfg) if (cfg->g_config.c_platform == NULL) cfg->g_config.c_platform = strdup(un.sysname); - /* Check routing */ - if (lldpd_routing_enabled(cfg)) { - log_debug("localchassis", "routing is enabled, enable router capability"); - LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_ROUTER; - } else - LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_ROUTER; + if (!cfg->g_config.c_cap_override) { + /* Check routing */ + if (lldpd_routing_enabled(cfg)) { + log_debug("localchassis", "routing is enabled, enable router capability"); + LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_ROUTER; + } else + LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_ROUTER; #ifdef ENABLE_LLDPMED - if (LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_TELEPHONE) - LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_TELEPHONE; - lldpd_med(cfg, &un); + if (LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_TELEPHONE) + LOCAL_CHASSIS(cfg)->c_cap_enabled |= LLDP_CAP_TELEPHONE; + lldpd_med(cfg, &un); #endif - if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_STATION) && - (LOCAL_CHASSIS(cfg)->c_cap_enabled == 0)) - LOCAL_CHASSIS(cfg)->c_cap_enabled = LLDP_CAP_STATION; - else if (LOCAL_CHASSIS(cfg)->c_cap_enabled != LLDP_CAP_STATION) - LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_STATION; + if ((LOCAL_CHASSIS(cfg)->c_cap_available & LLDP_CAP_STATION) && + (LOCAL_CHASSIS(cfg)->c_cap_enabled == 0)) + LOCAL_CHASSIS(cfg)->c_cap_enabled = LLDP_CAP_STATION; + else if (LOCAL_CHASSIS(cfg)->c_cap_enabled != LLDP_CAP_STATION) + LOCAL_CHASSIS(cfg)->c_cap_enabled &= ~LLDP_CAP_STATION; + } /* Set chassis ID if needed. This is only done if chassis ID has not been set previously (with the MAC address of an @@ -1307,7 +1309,8 @@ lldpd_loop(struct lldpd *cfg) 2. Update local chassis information */ log_debug("loop", "start new loop"); - LOCAL_CHASSIS(cfg)->c_cap_enabled = 0; + if(!cfg->g_config.c_cap_override) + LOCAL_CHASSIS(cfg)->c_cap_enabled = 0; /* Information for local ports is triggered even when it is possible to * update them on some other event because we want to refresh them if we * missed something. */ @@ -1941,6 +1944,7 @@ lldpd_main(int argc, char *argv[], char *envp[]) calloc(1, sizeof(struct lldpd_chassis))) == NULL) fatal("localchassis", NULL); cfg->g_config.c_cap_advertise = 1; + cfg->g_config.c_cap_override = 0; lchassis->c_cap_available = LLDP_CAP_BRIDGE | LLDP_CAP_WLAN | LLDP_CAP_ROUTER | LLDP_CAP_STATION; cfg->g_config.c_mgmt_advertise = 1; diff --git a/src/lib/atoms/chassis.c b/src/lib/atoms/chassis.c index 1d2ed27b..4ef72a51 100644 --- a/src/lib/atoms/chassis.c +++ b/src/lib/atoms/chassis.c @@ -234,6 +234,42 @@ _lldpctl_atom_get_str_chassis(lldpctl_atom_t *atom, lldpctl_key_t key) } } +static lldpctl_atom_t* +_lldpctl_atom_set_int_chassis(lldpctl_atom_t *atom, lldpctl_key_t key, + long int value) +{ + int rc; + char *canary = NULL; + struct _lldpctl_atom_chassis_t *c = + (struct _lldpctl_atom_chassis_t *) atom; + struct lldpd_chassis chassis; + memcpy(&chassis, c->chassis, sizeof(struct lldpd_chassis)); + + switch (key) { + case lldpctl_k_chassis_cap_enabled: + chassis.c_cap_enabled = c->chassis->c_cap_enabled = chassis.c_cap_available & value; + break; + default: + SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); + return NULL; + } + + if (asprintf(&canary, "%d%ld", key, value) == -1) { + SET_ERROR(atom->conn, LLDPCTL_ERR_NOMEM); + return NULL; + } + + rc = _lldpctl_do_something(atom->conn, + CONN_STATE_SET_CHASSIS_SEND, CONN_STATE_SET_CHASSIS_RECV, + canary, + SET_CHASSIS, &chassis, &MARSHAL_INFO(lldpd_chassis), + NULL, NULL); + + free(canary); + if (rc == 0) return atom; + return NULL; +} + static long int _lldpctl_atom_get_int_chassis(lldpctl_atom_t *atom, lldpctl_key_t key) { @@ -287,6 +323,7 @@ static struct atom_builder chassis = .get = _lldpctl_atom_get_atom_chassis, .get_str = _lldpctl_atom_get_str_chassis, .get_int = _lldpctl_atom_get_int_chassis, + .set_int = _lldpctl_atom_set_int_chassis, .get_buffer = _lldpctl_atom_get_buf_chassis, #ifdef ENABLE_LLDPMED .set_str = _lldpctl_atom_set_str_chassis, diff --git a/src/lib/atoms/config.c b/src/lib/atoms/config.c index ebe8a36a..675e6f62 100644 --- a/src/lib/atoms/config.c +++ b/src/lib/atoms/config.c @@ -234,6 +234,8 @@ _lldpctl_atom_get_int_config(lldpctl_atom_t *atom, lldpctl_key_t key) return c->config->c_promisc; case lldpctl_k_config_chassis_cap_advertise: return c->config->c_cap_advertise; + case lldpctl_k_config_chassis_cap_override: + return c->config->c_cap_override; case lldpctl_k_config_chassis_mgmt_advertise: return c->config->c_mgmt_advertise; #ifdef ENABLE_LLDPMED @@ -285,6 +287,9 @@ _lldpctl_atom_set_int_config(lldpctl_atom_t *atom, lldpctl_key_t key, case lldpctl_k_config_chassis_cap_advertise: config.c_cap_advertise = c->config->c_cap_advertise = value; break; + case lldpctl_k_config_chassis_cap_override: + config.c_cap_override = c->config->c_cap_override = value; + break; case lldpctl_k_config_chassis_mgmt_advertise: config.c_mgmt_advertise = c->config->c_mgmt_advertise = value; break; diff --git a/src/lib/lldpctl.h b/src/lib/lldpctl.h index 56b3bf48..6774ed1e 100644 --- a/src/lib/lldpctl.h +++ b/src/lib/lldpctl.h @@ -718,6 +718,7 @@ typedef enum { lldpctl_k_config_cid_string, /**< `(S,WON)` User defined string for the chassis ID */ lldpctl_k_config_perm_iface_pattern, /**< `(S,WON)` Pattern of permanent interfaces */ lldpctl_k_config_tx_interval_ms, /**< `(I,WO)` Transmit interval in milliseconds. Set to -1 to transmit now. */ + lldpctl_k_config_chassis_cap_override, /**< `(I,WO)` Override chassis capabilities */ lldpctl_k_interface_name = 1000, /**< `(S)` The interface name. */ @@ -793,13 +794,13 @@ typedef enum { lldpctl_k_chassis_id, /**< `(BS)` The ID of this chassis. */ lldpctl_k_chassis_name, /**< `(S)` The name of this chassis. */ lldpctl_k_chassis_descr, /**< `(S)` The description of this chassis. */ - lldpctl_k_chassis_cap_available, /**< `(I)` Available capabalities (see `LLDP_CAP_*`) */ + lldpctl_k_chassis_cap_available, /**< `(I)` Available capabilities (see `LLDP_CAP_*`) */ lldpctl_k_chassis_cap_enabled, /**< `(I)` Enabled capabilities (see `LLDP_CAP_*`) */ lldpctl_k_chassis_mgmt, /**< `(AL)` List of management addresses */ lldpctl_k_chassis_ttl, /**< Deprecated */ lldpctl_k_chassis_med_type = 1900, /**< `(IS)` Chassis MED type. See `LLDP_MED_CLASS_*` */ - lldpctl_k_chassis_med_cap, /**< `(I)` Available MED capabilitied. See `LLDP_MED_CAP_*` */ + lldpctl_k_chassis_med_cap, /**< `(I)` Available MED capabilities. See `LLDP_MED_CAP_*` */ lldpctl_k_chassis_med_inventory_hw, /**< `(S,W)` LLDP MED inventory "Hardware Revision" */ lldpctl_k_chassis_med_inventory_sw, /**< `(S,W)` LLDP MED inventory "Software Revision" */ lldpctl_k_chassis_med_inventory_fw, /**< `(S,W)` LLDP MED inventory "Firmware Revision" */ diff --git a/src/lldpd-structs.h b/src/lldpd-structs.h index e98a0551..5a7d4538 100644 --- a/src/lldpd-structs.h +++ b/src/lldpd-structs.h @@ -411,6 +411,7 @@ struct lldpd_config { int c_set_ifdescr; /* Set interface description */ int c_promisc; /* Interfaces should be in promiscuous mode */ int c_cap_advertise; /* Chassis capabilities advertisement */ + int c_cap_override; /* Override chassis capabilities enabled */ int c_mgmt_advertise; /* Management addresses advertisement */ #ifdef ENABLE_LLDPMED diff --git a/tests/integration/test_lldpcli.py b/tests/integration/test_lldpcli.py index 6cef96a1..098d2d26 100644 --- a/tests/integration/test_lldpcli.py +++ b/tests/integration/test_lldpcli.py @@ -625,3 +625,44 @@ def test_config_change(lldpd1, lldpcli, namespaces, command, name, expected): assert result.returncode == 0 out = lldpcli("-f", "keyvalue", "show", "configuration") assert out['configuration.config.{}'.format(name)] == str(expected) + + +def test_config_capabilities(lldpd1, lldpcli, namespaces): + with namespaces(1): + out = lldpcli("-f", "keyvalue", "show", "chassis") + + # Save values to check after unconfigure + bridge = out['local-chassis.chassis.Bridge.enabled'] + router = out['local-chassis.chassis.Router.enabled'] + wlan = out['local-chassis.chassis.Wlan.enabled'] + station = out['local-chassis.chassis.Station.enabled'] + + # Configure only bridge capability + lldpcli("configure", "system", "capabilities", "enabled", "bridge") + + # Check only bridge capability on + out = lldpcli("-f", "keyvalue", "show", "chassis") + assert out['local-chassis.chassis.Bridge.enabled'] == "on" + assert out['local-chassis.chassis.Router.enabled'] == "off" + assert out['local-chassis.chassis.Wlan.enabled'] == "off" + assert out['local-chassis.chassis.Station.enabled'] == "off" + + # Configure router and wlan capabilities. + lldpcli("configure", "system", "capabilities", "enabled", "router,wlan") + + # This shoud enable only router and wlan and set to off the bridge capability again + out = lldpcli("-f", "keyvalue", "show", "chassis") + assert out['local-chassis.chassis.Bridge.enabled'] == "off" + assert out['local-chassis.chassis.Router.enabled'] == "on" + assert out['local-chassis.chassis.Wlan.enabled'] == "on" + assert out['local-chassis.chassis.Station.enabled'] == "off" + + # Unconfigure system capabilities and use again the kernel information to enable capabilities + lldpcli("unconfigure", "system", "capabilities", "enabled") + + # Check if the capabilities have the same values as before start the configurations + out = lldpcli("-f", "keyvalue", "show", "chassis") + assert out['local-chassis.chassis.Bridge.enabled'] == bridge + assert out['local-chassis.chassis.Router.enabled'] == router + assert out['local-chassis.chassis.Wlan.enabled'] == wlan + assert out['local-chassis.chassis.Station.enabled'] == station