]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Allow configuring tx-interval in milliseconds
authorJean-Pierre Tosoni <jp.tosoni@acksys.fr>
Wed, 15 Jan 2020 17:56:08 +0000 (18:56 +0100)
committerJean-Pierre Tosoni <jp.tosoni@acksys.fr>
Thu, 16 Jan 2020 08:36:09 +0000 (09:36 +0100)
This is a prerequisite for TTDP support.

Usage: add "ms" suffix to the delay value to force interpretation as a
milliseconds value:

 lldpcli configure lldp tx-interval 200ms

When computing a TTL (TTL = tx-interval * tx-hold), the result is rounded
up to the next second, as LLDP frames need a value in seconds.

A new tx-interval-ms item is added to the json output. The old tx-interval
is kept in seconds (rounded up) for compatibility.

src/client/conf-lldp.c
src/client/display.c
src/daemon/agent.c
src/daemon/client.c
src/daemon/event.c
src/daemon/lldpd.c
src/daemon/protocols/edp.c
src/daemon/protocols/sonmp.c
src/lib/atoms/config.c
src/lib/lldpctl.h
src/lldpd-structs.h

index 8523f3cc5a405193edb5d95f2f56fb559bc0423b..f82f2ec7c1046f6bb454bde9d16ffde708e0cd95 100644 (file)
@@ -26,6 +26,11 @@ static int
 cmd_txdelay(struct lldpctl_conn_t *conn, struct writer *w,
     struct cmd_env *env, void *arg)
 {
+       const char *interval;
+       char interval_ms[8]; /* less than 2.5 hours */
+       lldpctl_key_t key;
+       int arglen;
+
        log_debug("lldpctl", "set transmit delay");
 
        lldpctl_atom_t *config = lldpctl_get_configuration(conn);
@@ -34,8 +39,23 @@ cmd_txdelay(struct lldpctl_conn_t *conn, struct writer *w,
                    lldpctl_last_strerror(conn));
                return 0;
        }
-       if (lldpctl_atom_set_str(config,
-               lldpctl_k_config_tx_interval, cmdenv_get(env, "tx-interval")) == NULL) {
+       interval = cmdenv_get(env, "tx-interval");
+       key = lldpctl_k_config_tx_interval;
+       /* interval is either <number> for seconds or <number>ms for milliseconds */
+       if (interval) {
+               arglen = strlen(interval);
+               /* room for "ms" in interval, room for interval in interval_ms */
+               if (arglen >= 2 && arglen-2 < sizeof(interval_ms) &&
+                               strcmp("ms", interval+arglen-2) == 0) {
+                       /* remove "ms" suffix */
+                       memcpy(interval_ms, interval, arglen-2);
+                       interval_ms[arglen-2] = '\0';
+                       /* substitute key and value */
+                       key = lldpctl_k_config_tx_interval_ms;
+                       interval = interval_ms;
+               }
+       }
+       if (lldpctl_atom_set_str(config, key, interval) == NULL) {
                log_warnx("lldpctl", "unable to set transmit delay. %s",
                    lldpctl_last_strerror(conn));
                lldpctl_atom_dec_ref(config);
@@ -521,7 +541,7 @@ register_commands_configure_lldp(struct cmd_node *configure,
                        commands_new(configure_lldp,
                            "tx-interval", "Set LLDP transmit delay",
                            cmd_check_no_env, NULL, "ports"),
-                       NULL, "LLDP transmit delay in seconds",
+                       NULL, "LLDP transmit <delay> in seconds or <delay>ms in milliseconds",
                        NULL, cmd_store_env_value, "tx-interval"),
                NEWLINE, "Set LLDP transmit delay",
                NULL, cmd_txdelay, NULL);
index 396478efc785fcd6eadb4c3ebe25bf21ad0b07de..faaa8b15afb5dbdb5e7cad765f97633e3dff5371 100644 (file)
@@ -553,9 +553,11 @@ display_local_ttl(struct writer *w, lldpctl_conn_t *conn, int details)
        }
 
        tx_hold = lldpctl_atom_get_int(configuration, lldpctl_k_config_tx_hold);
-       tx_interval = lldpctl_atom_get_int(configuration, lldpctl_k_config_tx_interval);
+       tx_interval = lldpctl_atom_get_int(configuration, lldpctl_k_config_tx_interval_ms);
 
-       if (asprintf(&ttl, "%lu", tx_hold*tx_interval) == -1) {
+       tx_interval = (tx_interval * tx_hold + 999) / 1000;
+
+       if (asprintf(&ttl, "%lu", tx_interval) == -1) {
                log_warnx("lldpctl", "not enough memory to build TTL.");
                goto end;
        }
@@ -949,6 +951,8 @@ display_configuration(lldpctl_conn_t *conn, struct writer *w)
 
        tag_datatag(w, "tx-delay", "Transmit delay",
            lldpctl_atom_get_str(configuration, lldpctl_k_config_tx_interval));
+       tag_datatag(w, "tx-delay-ms", "Transmit delay in milliseconds",
+           lldpctl_atom_get_str(configuration, lldpctl_k_config_tx_interval_ms));
        tag_datatag(w, "tx-hold", "Transmit hold",
            lldpctl_atom_get_str(configuration, lldpctl_k_config_tx_hold));
        tag_datatag(w, "max-neighbors", "Maximum number of neighbors",
index cd33c78ec2bf89fcedcc56842a523691a589941d..39560c26124ff5626e8e7320024658d57cf2a974 100644 (file)
@@ -639,10 +639,10 @@ agent_h_scalars(struct variable *vp, oid *name, size_t *length,
 
        switch (vp->magic) {
        case LLDP_SNMP_TXINTERVAL:
-                long_ret = scfg->g_config.c_tx_interval;
+                long_ret = (scfg->g_config.c_tx_interval+999) / 1000;
                return (u_char *)&long_ret;
        case LLDP_SNMP_TXMULTIPLIER:
-               long_ret = scfg->g_config.c_ttl / scfg->g_config.c_tx_interval;
+               long_ret = scfg->g_config.c_tx_hold;
                return (u_char *)&long_ret;
        case LLDP_SNMP_REINITDELAY:
                long_ret = 1;
index a95de9c10fc60f847964358171b45261c2891e73..c5aa1ceeca0161cd4536b012f55302c3bf2390f1 100644 (file)
@@ -72,11 +72,12 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type,
                if (config->c_tx_interval < 0) {
                        log_debug("rpc", "client asked for immediate retransmission");
                } else {
-                       log_debug("rpc", "client change transmit interval to %d",
+                       log_debug("rpc", "client change transmit interval to %d ms",
                            config->c_tx_interval);
                        cfg->g_config.c_tx_interval = config->c_tx_interval;
                        cfg->g_config.c_ttl = cfg->g_config.c_tx_interval *
                            cfg->g_config.c_tx_hold;
+                       cfg->g_config.c_ttl = (cfg->g_config.c_ttl + 999) / 1000;
                }
                levent_send_now(cfg);
        }
@@ -86,6 +87,7 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type,
                cfg->g_config.c_tx_hold = config->c_tx_hold;
                cfg->g_config.c_ttl = cfg->g_config.c_tx_interval *
                    cfg->g_config.c_tx_hold;
+               cfg->g_config.c_ttl = (cfg->g_config.c_ttl + 999) / 1000;
        }
        if (CHANGED(c_max_neighbors) && config->c_max_neighbors > 0) {
                log_debug("rpc", "client change maximum neighbors to %d",
index c42bc3fab9edc21fd8a9e2ec35d7d6a9626ad05e..c9bf04ab742dd239ac6cb6dbfff1c56f6c0d98e8 100644 (file)
@@ -476,11 +476,15 @@ static void
 levent_update_and_send(evutil_socket_t fd, short what, void *arg)
 {
        struct lldpd *cfg = arg;
-       struct timeval tv = { cfg->g_config.c_tx_interval, 0 };
+       struct timeval tv;
+       long interval_ms = cfg->g_config.c_tx_interval;
+
        (void)fd; (void)what;
        lldpd_loop(cfg);
        if (cfg->g_iface_event != NULL)
-               tv.tv_sec *= 20;
+               interval_ms *= 20;
+       tv.tv_sec = interval_ms / 1000;
+       tv.tv_usec = (interval_ms % 1000) * 1000;
        event_add(cfg->g_main_loop, &tv);
 }
 
@@ -844,10 +848,12 @@ levent_send_pdu(evutil_socket_t fd, short what, void *arg)
                hardware->h_tx_fast--;
 
        if (hardware->h_tx_fast > 0)
-               tx_interval = hardware->h_cfg->g_config.c_tx_fast_interval;
+               tx_interval = hardware->h_cfg->g_config.c_tx_fast_interval * 1000;
 #endif
 
-       struct timeval tv = { tx_interval, 0 };
+       struct timeval tv;
+       tv.tv_sec = tx_interval / 1000;
+       tv.tv_usec = (tx_interval % 1000) * 1000;
        if (event_add(hardware->h_timer, &tv) == -1) {
                log_warnx("event", "unable to re-register timer event for port %s",
                    hardware->h_ifname);
index dfe71523784b1895e7d9a211243e6f13e6d858e9..db4e24a5f1a601cb457053efe392fd82b1df3f13 100644 (file)
@@ -1862,9 +1862,10 @@ lldpd_main(int argc, char *argv[], char *envp[])
        if (lldpcli)
                cfg->g_config.c_paused = 1;
        cfg->g_config.c_receiveonly = receiveonly;
-       cfg->g_config.c_tx_interval = LLDPD_TX_INTERVAL;
+       cfg->g_config.c_tx_interval = LLDPD_TX_INTERVAL * 1000;
        cfg->g_config.c_tx_hold = LLDPD_TX_HOLD;
        cfg->g_config.c_ttl = cfg->g_config.c_tx_interval * cfg->g_config.c_tx_hold;
+       cfg->g_config.c_ttl = (cfg->g_config.c_ttl + 999) / 1000;
        cfg->g_config.c_max_neighbors = LLDPD_MAX_NEIGHBORS;
 #ifdef ENABLE_LLDPMED
        cfg->g_config.c_enable_fast_start = enable_fast_start;
index 9cd55f6a8933e2e478b25bf9ecd8a498a7d4bc7a..bda77786ebbeb097c08492fcec616e8ce73d1598 100644 (file)
@@ -308,6 +308,7 @@ edp_decode(struct lldpd *cfg, char *frame, int s,
                goto malformed;
        }
        port->p_ttl = cfg?cfg->g_config.c_tx_interval * cfg->g_config.c_tx_hold:0;
+       port->p_ttl = (port->p_ttl + 999) / 1000;
        chassis->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
        chassis->c_id_len = ETHER_ADDR_LEN;
        if ((chassis->c_id = (char *)malloc(ETHER_ADDR_LEN)) == NULL) {
index faa00208d3153c8fc74525faf6a80d9d49ec060b..d2eed157063d3c6d9cfe2cf1a2313b801456f0a7 100644 (file)
@@ -367,6 +367,7 @@ sonmp_decode(struct lldpd *cfg, char *frame, int s,
        TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);
        port->p_ttl = cfg?(cfg->g_config.c_tx_interval * cfg->g_config.c_tx_hold):
            LLDPD_TTL;
+       port->p_ttl = (port->p_ttl + 999) / 1000;
 
        port->p_id_subtype = LLDP_PORTID_SUBTYPE_LOCAL;
        if (asprintf(&port->p_id, "%02x-%02x-%02x",
index 66374c695ee90472e2e986b3accf1e59eb8c7f12..f82166489df05661a3dddbdcb6b2c391b3c79919 100644 (file)
@@ -221,7 +221,9 @@ _lldpctl_atom_get_int_config(lldpctl_atom_t *atom, lldpctl_key_t key)
        case lldpctl_k_config_paused:
                return c->config->c_paused;
        case lldpctl_k_config_tx_interval:
-               return c->config->c_tx_interval;
+               return (c->config->c_tx_interval+999)/1000; /* s units */
+       case lldpctl_k_config_tx_interval_ms:
+               return c->config->c_tx_interval; /* ms units */
        case lldpctl_k_config_receiveonly:
                return c->config->c_receiveonly;
        case lldpctl_k_config_advertise_version:
@@ -267,6 +269,10 @@ _lldpctl_atom_set_int_config(lldpctl_atom_t *atom, lldpctl_key_t key,
                config.c_paused = c->config->c_paused = value;
                break;
        case lldpctl_k_config_tx_interval:
+               config.c_tx_interval = value * 1000;
+               if (value > 0) c->config->c_tx_interval = value * 1000;
+               break;
+       case lldpctl_k_config_tx_interval_ms:
                config.c_tx_interval = value;
                if (value > 0) c->config->c_tx_interval = value;
                break;
index 9d656f16c49e149a1b6cf34d5d12e54d2b274271..4c46a904adb9ac6715a371ed8ab3f92847f0f741 100644 (file)
@@ -652,6 +652,7 @@ lldpctl_atom_t *lldpctl_get_default_port(lldpctl_conn_t *conn);
  */
 typedef enum {
        lldpctl_k_config_tx_interval, /**< `(I,WO)` Transmit interval. When set to -1, it is meant to transmit now. */
+       lldpctl_k_config_tx_interval_ms, /**< `(I,WO)` Transmit interval in milliseconds. Set to -1 to transmit now. */
        lldpctl_k_config_receiveonly, /**< `(I)` Receive only mode */
        lldpctl_k_config_mgmt_pattern, /**< `(S,WON)` Pattern to choose the management address */
        lldpctl_k_config_iface_pattern, /**< `(S,WON)` Pattern of enabled interfaces */
index 93cde0312a3960e9541339c383fb50aee8359a9d..31daef1368832a4f746a4e8fed6e543329006616 100644 (file)
@@ -388,7 +388,7 @@ MARSHAL_END(lldpd_port_set);
 
 struct lldpd_config {
        int c_paused;           /* lldpd is paused */
-       int c_tx_interval;      /* Transmit interval */
+       int c_tx_interval;      /* Transmit interval (in ms) */
        int c_ttl;              /* TTL */
        int c_smart;            /* Bitmask for smart configuration (see SMART_*) */
        int c_receiveonly;      /* Receive only mode */