From: Vincent Bernat Date: Tue, 22 Jan 2013 08:46:01 +0000 (+0100) Subject: lldpd: pause at start, unpause through lldpcli X-Git-Tag: 0.7.2~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e4ff3ed5cec2dcad6236e5ad7bb8cbec562f6ff2;p=thirdparty%2Flldpd.git lldpd: pause at start, unpause through lldpcli lldpd will be paused at start. Nothing will run. lldpcli job is to unpause it once the configuration has been read. --- diff --git a/src/client/lldpcli.8 b/src/client/lldpcli.8 index 88bbd0e3..1c726d76 100644 --- a/src/client/lldpcli.8 +++ b/src/client/lldpcli.8 @@ -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 diff --git a/src/client/lldpcli.c b/src/client/lldpcli.c index 5834d5e0..95f66dab 100644 --- a/src/client/lldpcli.c +++ b/src/client/lldpcli.c @@ -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); diff --git a/src/daemon/client.c b/src/daemon/client.c index dfe32ad5..dbf504c4 100644 --- a/src/daemon/client.c +++ b/src/daemon/client.c @@ -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); diff --git a/src/daemon/event.c b/src/daemon/event.c index 8b05ff3f..31903ee5 100644 --- a/src/daemon/event.c +++ b/src/daemon/event.c @@ -476,6 +476,7 @@ void levent_loop(struct lldpd *cfg) { levent_init(cfg); + lldpd_loop(cfg); /* libevent loop */ do { diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 855034d4..025c8f44 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -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) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index f56133fc..90c1afcd 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -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 diff --git a/src/lib/atom-private.c b/src/lib/atom-private.c index e3a19356..a754896b 100644 --- a/src/lib/atom-private.c +++ b/src/lib/atom-private.c @@ -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; diff --git a/src/lib/lldpctl.h b/src/lib/lldpctl.h index f6761ef4..2c19228b 100644 --- a/src/lib/lldpctl.h +++ b/src/lib/lldpctl.h @@ -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. */ diff --git a/src/lldpd-structs.h b/src/lldpd-structs.h index 8a1ec5d9..34e536a0 100644 --- a/src/lldpd-structs.h +++ b/src/lldpd-structs.h @@ -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 */