This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Max gerrit-no-reply at lists.osmocom.orgMax has submitted this change and it was merged. ( https://gerrit.osmocom.org/12710 ) Change subject: Add ping probe support ...................................................................... Add ping probe support Use liboping (new dependency) to add 'ping XXX' entries support in .cfg file, where XXX can be either IP address or FQDN. Sample output: ... ping ya.ru IP: 2a02:6b8::2:242 dropped: 3/3 8.8.8.8 IP: 8.8.8.8 dropped: 0/3 latency: 20.4 ms TTL: 120 ... N. B: to gather actual ping statistic we have to be able to send ICMP requests (have enough privileges to work with RAW sockets). Related: SYS#2655 Change-Id: Ife32540b532fb54368f63c78fb7837b84d4e8c76 --- M configure.ac M src/Makefile.am M src/osysmon.h M src/osysmon_main.c A src/osysmon_ping.c 5 files changed, 281 insertions(+), 2 deletions(-) Approvals: Jenkins Builder: Verified osmith: Looks good to me, approved diff --git a/configure.ac b/configure.ac index 734ac99..d98de89 100644 --- a/configure.ac +++ b/configure.ac @@ -43,6 +43,8 @@ PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 0.11.0) PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.11.0) PKG_CHECK_MODULES(LIBMNL, libmnl) +dnl FIXME: bump to 1.10.0 once it's available on build slaves and remove workaround from osysmon_ping.c +PKG_CHECK_MODULES(LIBOPING, liboping >= 1.9.0) dnl checks for header files AC_HEADER_STDC diff --git a/src/Makefile.am b/src/Makefile.am index cb85da2..d0d6a22 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,11 +24,12 @@ libintern_la_SOURCES = simple_ctrl.c libintern_la_LIBADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -osmo_sysmon_CFLAGS = $(LIBMNL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(AM_CFLAGS) +osmo_sysmon_CFLAGS = $(LIBMNL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOPING_CFLAGS) $(AM_CFLAGS) osmo_sysmon_LDADD = $(LDADD) \ $(LIBOSMOVTY_LIBS) \ $(LIBMNL_LIBS) \ + $(LIBOPING_LIBS) \ $(NULL) osmo_sysmon_SOURCES = \ @@ -37,6 +38,7 @@ osysmon_sysinfo.c \ osysmon_rtnl.c \ osysmon_file.c \ + osysmon_ping.c \ osysmon_main.c \ $(NULL) diff --git a/src/osysmon.h b/src/osysmon.h index 735b11e..df8bf8d 100644 --- a/src/osysmon.h +++ b/src/osysmon.h @@ -9,6 +9,7 @@ #include "value_node.h" struct rtnl_client_state; +struct ping_state; struct osysmon_state { struct rtnl_client_state *rcs; @@ -18,6 +19,7 @@ struct llist_head netdevs; /* list of 'struct osysmon_file' */ struct llist_head files; + struct ping_state *pings; }; extern struct osysmon_state *g_oss; @@ -28,6 +30,7 @@ CTRL_CLIENT_NODE = _LAST_OSMOVTY_NODE + 1, CTRL_CLIENT_GETVAR_NODE, NETDEV_NODE, + PING_NODE, }; @@ -42,5 +45,8 @@ int osysmon_sysinfo_init(); int osysmon_sysinfo_poll(struct value_node *parent); +int osysmon_ping_init(); +int osysmon_ping_poll(struct value_node *parent); + int osysmon_file_init(); int osysmon_file_poll(struct value_node *parent); diff --git a/src/osysmon_main.c b/src/osysmon_main.c index 82df61f..eb4f50b 100644 --- a/src/osysmon_main.c +++ b/src/osysmon_main.c @@ -193,7 +193,7 @@ int main(int argc, char **argv) { - int rc; + int rc, ping_init; osmo_init_logging2(NULL, &log_info); @@ -207,6 +207,7 @@ osysmon_sysinfo_init(); osysmon_ctrl_init(); osysmon_rtnl_init(); + ping_init = osysmon_ping_init(); osysmon_file_init(); rc = vty_read_config_file(cmdline_opts.config_file, NULL); @@ -233,6 +234,10 @@ osysmon_sysinfo_poll(root); osysmon_ctrl_poll(root); osysmon_rtnl_poll(root); + + if (ping_init == 0) + osysmon_ping_poll(root); + osysmon_file_poll(root); display_update(root); diff --git a/src/osysmon_ping.c b/src/osysmon_ping.c new file mode 100644 index 0000000..f736798 --- /dev/null +++ b/src/osysmon_ping.c @@ -0,0 +1,264 @@ +/* Simple Osmocom System Monitor (osysmon): Support for ping probe */ + +/* (C) 2018 by sysmocom - s.f.m.c. GmbH. + * Author: Max Suraev + * All Rights Reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include <stdbool.h> +#include <errno.h> + +#include <oping.h> + +#include <osmocom/core/utils.h> +#include <osmocom/vty/vty.h> +#include <osmocom/vty/command.h> + +#include "osysmon.h" +#include "value_node.h" + +/*********************************************************************** + * Data model + ***********************************************************************/ + +#define BUFLEN 128 + +struct ping_state { + pingobj_t *ping_handle; +}; + +/* FIXME: replace with ping_iterator_count() once we bump requirements to liboping 1.10.0+ */ +static unsigned iterator_count(pingobj_t *p) +{ + unsigned count = 0; + pingobj_iter_t *iter; + for (iter = ping_iterator_get(p); iter; iter = ping_iterator_next(iter)) + count++; + return count; +} + +/* Workaround for liboping issue https://github.com/octo/liboping/issues/43 */ +static int add_host(pingobj_t *pinger, const char *host) +{ + int num_host = iterator_count(pinger), + rc = ping_host_add(pinger, host); + + if (rc < 0) { + if (num_host != iterator_count(pinger)) + ping_host_remove(pinger, host); + } + + return rc; +} + + +static bool add_drop(pingobj_iter_t *iter, struct value_node *vn_host) +{ + char *s = NULL; + uint32_t drop, seq; + size_t len = sizeof(drop); + int rc = ping_iterator_get_info(iter, PING_INFO_DROPPED, &drop, &len); + if (rc) + return false; + + len = sizeof(seq); + rc = ping_iterator_get_info(iter, PING_INFO_SEQUENCE, &seq, &len); + if (rc) + return false; + + osmo_talloc_asprintf(vn_host, s, "%u/%u", drop, seq); + value_node_add(vn_host, "dropped", s); + + return true; +} + +static bool add_ttl(pingobj_iter_t *iter, struct value_node *vn_host) +{ + int ttl, rc; + size_t len = sizeof(ttl); + + rc = ping_iterator_get_info(iter, PING_INFO_RECV_TTL, &ttl, &len); + if (rc) + return false; + + if (ttl > -1) { + char *s = NULL; + osmo_talloc_asprintf(vn_host, s, "%d", ttl); + value_node_add(vn_host, "TTL", s); + } + + return true; +} + +static bool add_latency(pingobj_iter_t *iter, struct value_node *vn_host) +{ + double latency; + size_t len = sizeof(latency); + int rc = ping_iterator_get_info(iter, PING_INFO_LATENCY, &latency, &len); + if (rc) + return false; + + if (latency > -1) { + char *s = NULL; + osmo_talloc_asprintf(vn_host, s, "%.1lf ms", latency); + value_node_add(vn_host, "latency", s); + } + + return true; +} + + +/*********************************************************************** + * VTY + ***********************************************************************/ + +static struct cmd_node ping_node = { + PING_NODE, + "%s(config-ping)# ", + 1, +}; + +int osysmon_ping_go_parent(struct vty *vty) +{ + switch (vty->node) { + case PING_NODE: + vty->node = CONFIG_NODE; + vty->index = NULL; + break; + default: + break; + } + return vty->node; +} + +#define PING_STR "Configure a host to be monitored/pinged\n" + +DEFUN(cfg_ping, cfg_ping_cmd, + "ping HOST", + PING_STR "Name of the host to ping\n") +{ + int rc = add_host(g_oss->pings->ping_handle, argv[0]); + if (rc < 0) { + vty_out(vty, "[%d] Couldn't add pinger for %s: %s%s", + iterator_count(g_oss->pings->ping_handle), argv[0], + ping_get_error(g_oss->pings->ping_handle), VTY_NEWLINE); + + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN(cfg_no_ping, cfg_no_ping_cmd, + "no ping HOST", + NO_STR PING_STR "Name of the host to ping\n") +{ + int rc = ping_host_remove(g_oss->pings->ping_handle, argv[0]); + if (rc < 0) { + vty_out(vty, "[%d] Couldn't remove %s pinger: %s%s", + iterator_count(g_oss->pings->ping_handle), argv[0], + ping_get_error(g_oss->pings->ping_handle), VTY_NEWLINE); + + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +static int config_write_ping(struct vty *vty) +{ + char buf[BUFLEN]; + pingobj_iter_t *iter; + for (iter = ping_iterator_get(g_oss->pings->ping_handle); iter; iter = ping_iterator_next(iter)) { + size_t len = BUFLEN; + /* hostname as it was supplied via vty 'ping' entry */ + if (ping_iterator_get_info(iter, PING_INFO_USERNAME, buf, &len)) + return CMD_WARNING; + + vty_out(vty, "ping %s%s", buf, VTY_NEWLINE); + } + + return CMD_SUCCESS; +} + + +/*********************************************************************** + * Runtime Code + ***********************************************************************/ + +/* called once on startup before config file parsing */ +int osysmon_ping_init() +{ + install_element(CONFIG_NODE, &cfg_ping_cmd); + install_element(CONFIG_NODE, &cfg_no_ping_cmd); + install_node(&ping_node, config_write_ping); + + g_oss->pings = talloc_zero(NULL, struct ping_state); + if (!g_oss->pings) + return -ENOMEM; + + g_oss->pings->ping_handle = ping_construct(); + + if (g_oss->pings->ping_handle) + return 0; + + return -EINVAL; +} + +/* called periodically */ +int osysmon_ping_poll(struct value_node *parent) +{ + char buf[BUFLEN]; + struct value_node *vn_host; + int num_host = iterator_count(g_oss->pings->ping_handle); + pingobj_iter_t *iter; + struct value_node *vn_ping = value_node_add(parent, "ping", NULL); + if (!vn_ping) + return -ENOMEM; + + for (iter = ping_iterator_get(g_oss->pings->ping_handle); iter; iter = ping_iterator_next(iter)) { + size_t len = BUFLEN; + int rc = ping_iterator_get_info(iter, PING_INFO_USERNAME, buf, &len); + if (rc) + return -EINVAL; + + vn_host = value_node_find_or_add(vn_ping, talloc_strdup(vn_ping, buf)); + if (!vn_host) + return -ENOMEM; + + len = BUFLEN; /* IP address is looked up on-call, even 40 bytes should be enough */ + rc = ping_iterator_get_info(iter, PING_INFO_ADDRESS, buf, &len); + if (rc) + return -EINVAL; + + value_node_add(vn_host, "IP", buf); + + add_drop(iter, vn_host); + + /* Parameters below might be absent from output depending on the host reachability: */ + add_latency(iter, vn_host); + add_ttl(iter, vn_host); + } + + if (num_host) + return ping_send(g_oss->pings->ping_handle); + + return 0; +} -- To view, visit https://gerrit.osmocom.org/12710 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-sysmon Gerrit-Branch: master Gerrit-MessageType: merged Gerrit-Change-Id: Ife32540b532fb54368f63c78fb7837b84d4e8c76 Gerrit-Change-Number: 12710 Gerrit-PatchSet: 10 Gerrit-Owner: Max <msuraev at sysmocom.de> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder (1000002) Gerrit-Reviewer: Max <msuraev at sysmocom.de> Gerrit-Reviewer: Pau Espin Pedrol <pespin at sysmocom.de> Gerrit-Reviewer: daniel <dwillmann at sysmocom.de> Gerrit-Reviewer: osmith <osmith at sysmocom.de> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190131/f156a91f/attachment.htm>