From: Sven Eckelmann <sven@narfation.org>
To: b.a.t.m.a.n@lists.open-mesh.org
Subject: [B.A.T.M.A.N.] [PATCH 38/38] batctl: Add command to monitor for netlink events
Date: Mon, 22 Oct 2018 00:55:24 +0200 [thread overview]
Message-ID: <20181021225524.8155-39-sven@narfation.org> (raw)
In-Reply-To: <20181021225524.8155-1-sven@narfation.org>
The netlink multicast groups of batman-adv are currently used to inform
userspace about finished throughputmeter runs. It will later also be used
to inform about changes of settings of a specific batadv interface.
The "event" will wait for these messages and print brief summaries about
the received data. This can be used during the development of new features
or to monitor running systems.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Makefile | 1 +
event.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++
man/batctl.8 | 4 +
3 files changed, 251 insertions(+)
create mode 100644 event.c
diff --git a/Makefile b/Makefile
index a6971d8..cf2b1c7 100755
--- a/Makefile
+++ b/Makefile
@@ -43,6 +43,7 @@ OBJ += dat_cache.o
OBJ += debugfs.o
OBJ += debug.o
OBJ += distributed_arp_table.o
+OBJ += event.o
OBJ += fragmentation.o
OBJ += functions.o
OBJ += gateways.o
diff --git a/event.c b/event.c
new file mode 100644
index 0000000..73c5a68
--- /dev/null
+++ b/event.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <mareklindner@neomailbox.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ * License-Filename: LICENSES/preferred/GPL-2.0
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+
+#include "batadv_packet.h"
+#include "batman_adv.h"
+#include "bat-hosts.h"
+#include "debug.h"
+#include "functions.h"
+#include "genl.h"
+#include "main.h"
+#include "netlink.h"
+
+enum event_time_mode {
+ EVENT_TIME_NO,
+ EVENT_TIME_LOCAL,
+ EVENT_TIME_RELATIVE,
+};
+
+struct event_args {
+ enum event_time_mode mode;
+ struct timeval tv;
+};
+
+static void event_usage(void)
+{
+ fprintf(stderr, "Usage: batctl [options] event [parameters]\n");
+ fprintf(stderr, "parameters:\n");
+ fprintf(stderr, " \t -h print this help\n");
+ fprintf(stderr, " \t -t print local timestamp\n");
+ fprintf(stderr, " \t -r print relative timestamp\n");
+}
+
+static int event_prepare(struct state *state)
+{
+ int ret;
+ int mcid;
+
+ if (!state->sock)
+ return -EOPNOTSUPP;
+
+ mcid = nl_get_multicast_id(state->sock, BATADV_NL_NAME,
+ BATADV_NL_MCAST_GROUP_TPMETER);
+ if (mcid < 0) {
+ fprintf(stderr, "Failed to resolve batadv tp_meter multicast group: %d\n",
+ mcid);
+ /* ignore error for now */
+ goto skip_tp_meter;
+ }
+
+ ret = nl_socket_add_membership(state->sock, mcid);
+ if (ret) {
+ fprintf(stderr, "Failed to join batadv tp_meter multicast group: %d\n",
+ ret);
+ /* ignore error for now */
+ goto skip_tp_meter;
+ }
+
+skip_tp_meter:
+
+ return 0;
+}
+
+static int no_seq_check(struct nl_msg *msg __maybe_unused,
+ void *arg __maybe_unused)
+{
+ return NL_OK;
+}
+
+static const int tp_meter_mandatory[] = {
+ BATADV_ATTR_TPMETER_COOKIE,
+ BATADV_ATTR_TPMETER_RESULT,
+};
+
+static void event_parse_tp_meter(struct nlattr **attrs)
+{
+ const char *result_str;
+ uint32_t cookie;
+ uint8_t result;
+
+ /* ignore entry when attributes are missing */
+ if (missing_mandatory_attrs(attrs, tp_meter_mandatory,
+ ARRAY_SIZE(tp_meter_mandatory)))
+ return;
+
+ cookie = nla_get_u32(attrs[BATADV_ATTR_TPMETER_COOKIE]);
+ result = nla_get_u8(attrs[BATADV_ATTR_TPMETER_RESULT]);
+
+ switch (result) {
+ case BATADV_TP_REASON_DST_UNREACHABLE:
+ result_str = "Destination unreachable";
+ break;
+ case BATADV_TP_REASON_RESEND_LIMIT:
+ result_str = "The number of retry for the same window exceeds the limit, test aborted";
+ break;
+ case BATADV_TP_REASON_ALREADY_ONGOING:
+ result_str = "Cannot run two test towards the same node";
+ break;
+ case BATADV_TP_REASON_MEMORY_ERROR:
+ result_str = "Kernel cannot allocate memory, aborted";
+ break;
+ case BATADV_TP_REASON_TOO_MANY:
+ result_str = "Too many ongoing sessions";
+ break;
+ case BATADV_TP_REASON_CANCEL:
+ result_str = "CANCEL received: test aborted";
+ break;
+ case BATADV_TP_REASON_COMPLETE:
+ result_str = "complete";
+ break;
+ default:
+ result_str = "unknown";
+ break;
+ }
+
+ printf("tp_meter 0x%08x: %s\n", cookie, result_str);
+}
+
+static unsigned long long get_timestamp(struct event_args *event_args)
+{
+ unsigned long long prevtime = 0;
+ unsigned long long now;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ now = 1000000ULL * tv.tv_sec + tv.tv_usec;
+
+ if (event_args->mode == EVENT_TIME_RELATIVE) {
+ prevtime = 1000000ULL * event_args->tv.tv_sec + event_args->tv.tv_usec;
+ event_args->tv = tv;
+ }
+
+ return now - prevtime;
+}
+
+static int event_parse(struct nl_msg *msg, void *arg)
+{
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
+ struct nlattr *attrs[NUM_BATADV_ATTR];
+ struct event_args *event_args = arg;
+ unsigned long long timestamp;
+ struct genlmsghdr *ghdr;
+
+ if (!genlmsg_valid_hdr(nlh, 0))
+ return NL_OK;
+
+ ghdr = nlmsg_data(nlh);
+
+ if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
+ genlmsg_len(ghdr), batadv_netlink_policy)) {
+ fputs("Received invalid data from kernel.\n", stderr);
+ return NL_OK;
+ }
+
+ if (event_args->mode != EVENT_TIME_NO) {
+ timestamp = get_timestamp(event_args);
+ printf("%llu.%06llu: ", timestamp / 1000000, timestamp % 1000000);
+ }
+
+ switch (ghdr->cmd) {
+ case BATADV_CMD_TP_METER:
+ event_parse_tp_meter(attrs);
+ break;
+ default:
+ printf("Received unknown event %u\n", ghdr->cmd);
+ break;
+ }
+
+ return NL_OK;
+}
+
+static int event(struct state *state, int argc __maybe_unused,
+ char **argv __maybe_unused)
+{
+ struct event_args event_args = {
+ .mode = EVENT_TIME_NO,
+ };
+ int opt;
+ int ret;
+
+ while ((opt = getopt(argc, argv, "htr")) != -1) {
+ switch (opt) {
+ case 'h':
+ event_usage();
+ return EXIT_SUCCESS;
+ case 't':
+ event_args.mode = EVENT_TIME_LOCAL;
+ break;
+ case 'r':
+ event_args.mode = EVENT_TIME_RELATIVE;
+ break;
+ default:
+ event_usage();
+ return EXIT_FAILURE;
+ }
+ }
+
+ ret = event_prepare(state);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to prepare event netlink: %s (%d)\n",
+ strerror(-ret), -ret);
+ return 1;
+ }
+
+ if (event_args.mode == EVENT_TIME_RELATIVE)
+ get_timestamp(&event_args);
+
+ nl_cb_set(state->cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
+ nl_cb_set(state->cb, NL_CB_VALID, NL_CB_CUSTOM, event_parse, &event_args);
+
+ while (1)
+ nl_recvmsgs(state->sock, state->cb);
+
+ return 0;
+}
+
+COMMAND(SUBCOMMAND, event, "e", COMMAND_FLAG_NETLINK, NULL,
+ " \tdisplay events from batman-adv");
diff --git a/man/batctl.8 b/man/batctl.8
index d5fc530..fe6cf93 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -89,6 +89,10 @@ OGM packet aggregation.
If no parameter is given the current bonding mode setting is displayed. Otherwise the parameter is used to enable or disable
the bonding mode.
.br
+.IP "\fBevent\fP|\fBe\fP [\fB\-t\fP|\fB\-r\fP]"
+batctl will monitor for events from the netlink kernel interface of batman-adv. The local timestamp of the event will be printed
+when parameter \fB\-t\fP is specified. Parameter \fB\-r\fP will do the same but with relative timestamps.
+.br
.IP "\fBfragmentation\fP|\fBf\fP [\fB0\fP|\fB1\fP]"
If no parameter is given the current fragmentation mode setting is displayed. Otherwise the parameter is used to enable or
disable fragmentation.
--
2.19.1
next prev parent reply other threads:[~2018-10-21 22:55 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-21 22:54 [B.A.T.M.A.N.] [PATCH 00/38] batctl: pre-netlink restructuring, part 1 Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 01/38] batctl: Drop unused define SOCKET_PATH_FMT Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 02/38] batctl: Use common code organization for statistics Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 03/38] batctl: Drop legacy vis_* related warning messages Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 04/38] batctl: Move loglevel command to separate file Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 05/38] batctl: Move log " Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 06/38] batctl: Move gw_mode " Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 07/38] batctl: Move routing_algo " Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 08/38] batctl: Rename tp_meter to throughputmeter Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 09/38] batctl: Introduce datastructure for subcommands Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 10/38] batctl: Add per command flags Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 11/38] batctl: Use command structure for remaining subcommands Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 12/38] batctl: Use getopt to parse main options Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 13/38] batctl: Store usage line next to command Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 14/38] batctl: Prepare command infrastructure for shared functions Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 15/38] batctl: Add type to command to structure usage output Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 16/38] batctl: Convert debug table to command infrastructure Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 17/38] batctl: Convert sysfs settings " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 18/38] batctl: Move backbonetable debug table to own file Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 19/38] batctl: Move claimtable " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 20/38] batctl: Move dat_cache " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 21/38] batctl: Move gateways " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 22/38] batctl: Move mcast_flags " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 23/38] batctl: Move nc_nodes " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 24/38] batctl: Move neighbors " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 25/38] batctl: Move originators " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 26/38] batctl: Move transglobal " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 27/38] batctl: Move translocal " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 28/38] batctl: Move aggregation setting " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 29/38] batctl: Move bonding " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 30/38] batctl: Move bridge_loop_avoidance " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 31/38] batctl: Move distributed_arp_table " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 32/38] batctl: Move fragmentation " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 33/38] batctl: Move isolation_mark " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 34/38] batctl: Move multicast_mode " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 35/38] batctl: Move network_coding " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 36/38] batctl: Move orig_interval " Sven Eckelmann
2018-10-21 23:02 ` [B.A.T.M.A.N.] [PATCH v2 " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 37/38] batctl: Use external netlink socket for debug tables Sven Eckelmann
2018-10-21 22:55 ` Sven Eckelmann [this message]
2018-10-22 16:42 ` [B.A.T.M.A.N.] [PATCH 00/38] batctl: pre-netlink restructuring, part 1 Sven Eckelmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181021225524.8155-39-sven@narfation.org \
--to=sven@narfation.org \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox