]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lib: ability to configure a local chassis ID 263/head
authorVincent Bernat <vincent@bernat.im>
Sat, 30 Dec 2017 12:24:46 +0000 (13:24 +0100)
committerVincent Bernat <vincent@bernat.im>
Sat, 30 Dec 2017 12:24:46 +0000 (13:24 +0100)
Also, remove the `-c` flag for lldpd that was previously introduced.

NEWS
src/client/conf-system.c
src/client/lldpcli.8.in
src/daemon/client.c
src/daemon/lldpd.c
src/lib/atoms/config.c
src/lib/lldpctl.h
tests/integration/test_basic.py

diff --git a/NEWS b/NEWS
index c2f89ca427d88b415732d8f468a1ea30352230ab..48db878dc1ea31a3f55f8685a06e41b4d2928cdc 100644 (file)
--- 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.
 
index 3d6e5ffdef393de98d62b5eaf6f6bfc5544462ed..9958b1a5f175bb3fd3b8b24859e441730c1a421f 100644 (file)
@@ -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,
index 300587fd781b342be29e9e16aace7f01b5dfe6b0..167c2604b747161f6dcd4ed5d39143e0096dbf8f 100644 (file)
@@ -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
index 05d6ae6521464186bd3959738aa953b0d064cf2b..c55288d577aec940590b92d0a73248cbe93271f8 100644 (file)
@@ -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)");
index 833684258ba02ba92f8b849473a69e912356140e..b726882eb7cc33767bef176ed2d35a22f25ee3c4 100644 (file)
@@ -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)
index 7cd4f2ee7d507de19da819a31816496eb1776864..02836088e3b802093a454e064dcf0fdc36e38d05 100644 (file)
@@ -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,
index f783f252feca486becf5aa746aa9ca2bbe91de3e..2a6e71ae675465c157709072ed27a301432b9265 100644 (file)
@@ -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. */
 
index 5c762c65cb6b0bdd6ab911bec4f8a44b3f14d407..1ff7f4b728f77ea5b6f75cd8c2e88e958216d189 100644 (file)
@@ -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")