]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpd: pause at start, unpause through lldpcli
authorVincent Bernat <bernat@luffy.cx>
Tue, 22 Jan 2013 08:46:01 +0000 (09:46 +0100)
committerVincent Bernat <bernat@luffy.cx>
Tue, 22 Jan 2013 08:51:30 +0000 (09:51 +0100)
lldpd will be paused at start. Nothing will run. lldpcli job is to
unpause it once the configuration has been read.

src/client/lldpcli.8
src/client/lldpcli.c
src/daemon/client.c
src/daemon/event.c
src/daemon/lldpd.c
src/lib/Makefile.am
src/lib/atom-private.c
src/lib/lldpctl.h
src/lldpd-structs.h

index 88bbd0e321081418c0dc40f8cdff1daaa4e33b57..1c726d7686e2c6a304b1c2d91863d4293c4c507d 100644 (file)
@@ -481,6 +481,30 @@ Here are two valid uses of this command:
 .D1 configure dot3 power pd supported enabled powerpairs spare class 3 type 1 source pse priority low requested 10000 allocated 15000
 .Ed
 
+.Cd pause
+.Bd -ragged -offset XXXXXX
+Pause
+.Nm lldpd
+operations.
+.Nm lldpd
+will not send any more frames or receive ones. This can be undone with
+.Cd resume
+command.
+.Ed
+
+.Cd resume
+.Bd -ragged -offset XXXXXX
+Resume
+.Nm lldpd
+operations.
+.Nm lldpd
+will start to send and receive frames. This command is issued
+internally after processing configuration but can be used at any time
+if a manual
+.Cd pause
+command is issued.
+.Ed
+
 .Ed
 .Sh FILES
 .Bl -tag -width "/var/run/lldpd.socketXX" -compact
index 5834d5e0dc2a250a6f93cf26bf73e2f57cf73684..95f66dab95444bdba126f768233f711e016c70f7 100644 (file)
@@ -135,6 +135,55 @@ cmd_update(struct lldpctl_conn_t *conn, struct writer *w,
        return 1;
 }
 
+/**
+ * Pause or resume execution of lldpd.
+ *
+ * @param conn    The connection to lldpd.
+ * @param pause   1 if we want to pause lldpd, 0 otherwise
+ * @return 1 on success, 0 on error
+ */
+static int
+cmd_pause_resume(lldpctl_conn_t *conn, int pause)
+{
+       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_get_int(config, lldpctl_k_config_paused) == pause) {
+               log_info("lldpctl", "lldpd is already %s",
+                   pause?"paused":"resumed");
+               lldpctl_atom_dec_ref(config);
+               return 0;
+       }
+       if (lldpctl_atom_set_int(config,
+               lldpctl_k_config_paused, pause) == NULL) {
+               log_warnx("lldpctl", "unable to ask lldpd to %s operations. %s",
+                   pause?"pause":"resume",
+                   lldpctl_last_strerror(conn));
+               lldpctl_atom_dec_ref(config);
+               return 0;
+       }
+       log_info("lldpctl", "lldpd should %s operations",
+           pause?"pause":"resume");
+       lldpctl_atom_dec_ref(config);
+       return 1;
+}
+static int
+cmd_pause(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, void *arg) {
+       (void)w; (void)env;
+       return cmd_pause_resume(conn, 1);
+}
+static int
+cmd_resume(struct lldpctl_conn_t *conn, struct writer *w,
+    struct cmd_env *env, void *arg) {
+       (void)w; (void)env;
+       return cmd_pause_resume(conn, 0);
+}
+
+
 #ifdef HAVE_LIBREADLINE
 static int
 _cmd_complete(int all)
@@ -277,6 +326,12 @@ register_commands()
        }
        commands_new(root, "help", "Get help on a possible command",
            NULL, cmd_store_env_and_pop, "help");
+       commands_new(
+               commands_new(root, "pause", "Pause lldpd operations", NULL, NULL, NULL),
+               NEWLINE, "Pause lldpd operations", NULL, cmd_pause, NULL);
+       commands_new(
+               commands_new(root, "resume", "Resume lldpd operations", NULL, NULL, NULL),
+               NEWLINE, "Resume lldpd operations", NULL, cmd_resume, NULL);
        commands_new(
                commands_new(root, "exit", "Exit interpreter", NULL, NULL, NULL),
                NEWLINE, "Exit interpreter", NULL, cmd_exit, NULL);
index dfe32ad5429effa8dcb3adf4aee49c7f591bdea9..dbf504c401729937e0d3e15ce74bbe9e530cbaa4 100644 (file)
@@ -57,8 +57,7 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type,
        }
        config = p;
 
-       /* What needs to be done? Currently, we only support setting the
-        * transmit delay. */
+       /* What needs to be done? Transmit delay? */
        if (config->c_tx_interval > 0) {
                log_debug("rpc", "client change transmit interval to %d",
                        config->c_tx_interval);
@@ -68,6 +67,13 @@ client_handle_set_configuration(struct lldpd *cfg, enum hmsg_type *type,
                log_debug("rpc", "client asked for immediate retransmission");
                levent_send_now(cfg);
        }
+       /* Pause/resume */
+       if (config->c_paused != cfg->g_config.c_paused) {
+               log_debug("rpc", "client asked to %s lldpd",
+                   config->c_paused?"pause":"resume");
+               cfg->g_config.c_paused = config->c_paused;
+               levent_send_now(cfg);
+       }
 
        lldpd_config_cleanup(config);
 
index 8b05ff3fad6d3565633ac3dfdcfd6d5b52839e50..31903ee5601e569d5d52158a96f8a11c6d5f6928 100644 (file)
@@ -476,6 +476,7 @@ void
 levent_loop(struct lldpd *cfg)
 {
        levent_init(cfg);
+       lldpd_loop(cfg);
 
        /* libevent loop */
        do {
index 855034d4fe1060f7221b9a96922038f9e4903d21..025c8f44539f10965f7b400c435e9b63676e6a2c 100644 (file)
@@ -758,6 +758,12 @@ lldpd_recv(struct lldpd *cfg, struct lldpd_hardware *hardware, int fd)
                free(buffer);
                return;
        }
+       if (cfg->g_config.c_paused) {
+               log_debug("receive", "paused, ignore the frame on %s",
+                       hardware->h_ifname);
+               free(buffer);
+               return;
+       }
        hardware->h_rx_cnt++;
        log_debug("receive", "decode received frame on %s",
            hardware->h_ifname);
@@ -773,7 +779,7 @@ lldpd_send(struct lldpd_hardware *hardware)
        struct lldpd_port *port;
        int i, sent;
 
-       if (cfg->g_config.c_receiveonly) return;
+       if (cfg->g_config.c_receiveonly || cfg->g_config.c_paused) return;
        if ((hardware->h_flags & IFF_RUNNING) == 0)
                return;
 
@@ -1022,6 +1028,7 @@ lldpd_configure(int debug, const char *path)
                        if (execl(path, "lldpcli", sdebug,
                                "-c", SYSCONFDIR "/lldpd.conf",
                                "-c", SYSCONFDIR "/lldpd.d",
+                               "resume",
                                NULL) == -1) {
                                log_warn("main", "unable to execute %s", path);
                                log_warnx("main", "configuration may be incomplete");
@@ -1382,7 +1389,9 @@ lldpd_main(int argc, char *argv[])
        cfg->g_config.c_cid_pattern = cidp;
        cfg->g_config.c_iface_pattern = interfaces;
        cfg->g_config.c_smart = smart;
+       cfg->g_config.c_paused = 1;
        cfg->g_config.c_receiveonly = receiveonly;
+       cfg->g_config.c_tx_interval = LLDPD_TX_INTERVAL;
 #ifdef USE_SNMP
        cfg->g_snmp = snmp;
        cfg->g_snmp_agentx = agentx;
@@ -1392,7 +1401,6 @@ lldpd_main(int argc, char *argv[])
        log_debug("main", "get an ioctl socket");
        if ((cfg->g_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
                fatal("main", "failed to get ioctl socket");
-       cfg->g_config.c_tx_interval = LLDPD_TX_INTERVAL;
 
        /* Description */
        if (!(cfg->g_config.c_advertise_version = advertise_version) && lsb_release)
index f56133fc613446d659dcf6c2942d1e415cf8ee78..90c1afcd36c2a413138cd88ba56f7d294adae19a 100644 (file)
@@ -3,7 +3,7 @@ include_HEADERS = lldpctl.h
 
 liblldpctl_la_SOURCES = lldpctl.h private.h errors.c connection.c atom.c atom-private.c
 liblldpctl_la_LIBADD  = $(top_builddir)/src/libcommon-daemon-lib.la
-liblldpctl_la_LDFLAGS = -export-symbols-regex '^lldpctl_' -version-info 1:0:1
+liblldpctl_la_LDFLAGS = -export-symbols-regex '^lldpctl_' -version-info 2:0:2
 
 # -version-info format is `current`:`revision`:`age`. For more details, see:
 #   http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91
index e3a19356c382a8adedb6fe0ebf5839edf50ae5e1..a754896bc086d145292a7267d22825cb6f68d1aa 100644 (file)
@@ -373,6 +373,8 @@ _lldpctl_atom_get_int_config(lldpctl_atom_t *atom, lldpctl_key_t key)
        struct _lldpctl_atom_config_t *c =
            (struct _lldpctl_atom_config_t *)atom;
        switch (key) {
+       case lldpctl_k_config_paused:
+               return c->config->c_paused;
        case lldpctl_k_config_tx_interval:
                return c->config->c_tx_interval;
        case lldpctl_k_config_receiveonly:
@@ -399,6 +401,9 @@ _lldpctl_atom_set_int_config(lldpctl_atom_t *atom, lldpctl_key_t key,
        memset(&config, 0, sizeof(struct lldpd_config));
 
        switch (key) {
+       case lldpctl_k_config_paused:
+               config.c_paused = c->config->c_paused = value;
+               break;
        case lldpctl_k_config_tx_interval:
                config.c_tx_interval = value;
                if (value > 0) c->config->c_tx_interval = value;
index f6761ef482c46d025cc75000853b2e38e2d85f36..2c19228b29066eb14f93c74f0d493e8e1fbe5da8 100644 (file)
@@ -573,6 +573,7 @@ typedef enum {
        lldpctl_k_config_platform,      /**< `(S)` Platform description overridden (CDP) */
        lldpctl_k_config_advertise_version, /**< `(I)` Advertise version */
        lldpctl_k_config_lldpmed_noinventory, /**< `(I)` Disable LLDP-MED inventory */
+       lldpctl_k_config_paused,              /**< `(I)` lldpd is paused */
 
        lldpctl_k_interface_name, /**< `(S)` The interface name. */
 
index 8a1ec5d9066cd4ef34ba292dca9ca1b759f4cf0d..34e536a05415553f60be32be2985927dc9af8dda 100644 (file)
@@ -311,6 +311,7 @@ MARSHAL_END;
                        SMART_OUTGOING_ONE_NEIGH)
 
 struct lldpd_config {
+       int c_paused;           /* lldpd is paused */
        int c_tx_interval;      /* Transmit interval */
        int c_smart;            /* Bitmask for smart configuration (see SMART_*) */
        int c_receiveonly;      /* Receive only mode */