lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun,  7 Jul 2019 11:01:58 +0300
From:   Ido Schimmel <idosch@...sch.org>
To:     netdev@...r.kernel.org
Cc:     davem@...emloft.net, jiri@...lanox.com, mlxsw@...lanox.com,
        dsahern@...il.com, roopa@...ulusnetworks.com,
        nikolay@...ulusnetworks.com, andy@...yhouse.net,
        pablo@...filter.org, jakub.kicinski@...ronome.com,
        pieter.jansenvanvuuren@...ronome.com, andrew@...n.ch,
        f.fainelli@...il.com, vivien.didelot@...il.com,
        Ido Schimmel <idosch@...lanox.com>
Subject: [PATCH iproute2-next 5/7] devlink: Set NETLINK_NO_ENOBUFS when monitoring events

From: Ido Schimmel <idosch@...lanox.com>

If we lost an event, there is nothing we can do in order to recover it.
Set above mentioned socket option on the netlink socket when monitoring
devlink events, so that `devlink monitor` will not abort in case we are
not draining the receive buffer fast enough.

The number of events we lost can be retrieved using:

# cat /proc/net/netlink | grep `pidof devlink` | awk '{ print $9 }'

Signed-off-by: Ido Schimmel <idosch@...lanox.com>
Acked-by: Jiri Pirko <jiri@...lanox.com>
---
 devlink/devlink.c | 22 +++++++++++++++++++++-
 devlink/mnlg.c    | 12 ++++++++++++
 devlink/mnlg.h    |  2 ++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index b9fce850ee00..817b74259ec3 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -140,6 +140,19 @@ static int _mnlg_socket_group_add(struct mnlg_socket *nlg,
 	return 0;
 }
 
+static int _mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type,
+				   void *buf, socklen_t len)
+{
+	int err;
+
+	err = mnlg_socket_setsockopt(nlg, type, buf, len);
+	if (err < 0) {
+		pr_err("Failed to call mnlg_socket_setsockopt\n");
+		return -errno;
+	}
+	return 0;
+}
+
 struct ifname_map {
 	struct list_head list;
 	char *bus_name;
@@ -4020,7 +4033,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
 
 static int cmd_mon_show(struct dl *dl)
 {
-	int err;
+	int err, one = 1;
 	unsigned int index = 0;
 	const char *cur_obj;
 
@@ -4035,6 +4048,13 @@ static int cmd_mon_show(struct dl *dl)
 			return -EINVAL;
 		}
 	}
+	/* It is possible to lose some events if we are not draining the socket
+	 * receive buffer fast enough. Keep processing events and do not abort.
+	 */
+	err = _mnlg_socket_setsockopt(dl->nlg, NETLINK_NO_ENOBUFS, &one,
+				      sizeof(one));
+	if (err)
+		return err;
 	err = _mnlg_socket_group_add(dl->nlg, DEVLINK_GENL_MCGRP_CONFIG_NAME);
 	if (err)
 		return err;
diff --git a/devlink/mnlg.c b/devlink/mnlg.c
index ee125df042f0..23e6e794b508 100644
--- a/devlink/mnlg.c
+++ b/devlink/mnlg.c
@@ -231,6 +231,18 @@ int mnlg_socket_group_add(struct mnlg_socket *nlg, const char *group_name)
 	return 0;
 }
 
+int mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type, void *buf,
+			   socklen_t len)
+{
+	int err;
+
+	err = mnl_socket_setsockopt(nlg->nl, type, buf, len);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 static int get_family_id_attr_cb(const struct nlattr *attr, void *data)
 {
 	const struct nlattr **tb = data;
diff --git a/devlink/mnlg.h b/devlink/mnlg.h
index 4d1babf3b4c2..49154215729e 100644
--- a/devlink/mnlg.h
+++ b/devlink/mnlg.h
@@ -21,6 +21,8 @@ struct nlmsghdr *mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd,
 int mnlg_socket_send(struct mnlg_socket *nlg, const struct nlmsghdr *nlh);
 int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void *data);
 int mnlg_socket_group_add(struct mnlg_socket *nlg, const char *group_name);
+int mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type, void *buf,
+			   socklen_t len);
 struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version);
 void mnlg_socket_close(struct mnlg_socket *nlg);
 
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ