Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp1219010ybt; Tue, 7 Jul 2020 10:16:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwJ6FieLi3u9g15JOjiKcbd5SnpwIkr/SWi8BkuK2BzG/uRdYKVpinJX18DEhdQtyw2KtmQ X-Received: by 2002:a05:6402:1c86:: with SMTP id cy6mr48427317edb.30.1594142186655; Tue, 07 Jul 2020 10:16:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594142186; cv=none; d=google.com; s=arc-20160816; b=ohBExhd2lNdUTtf4koRLGcab3X3kJ0uk2VV7y+YyvuxusZRskKhXIKNtj/BXks9V1O 5SULLXM6Qzh7ncaB83KWoUdRA1yN88/7eafUuE0qrAWW715tvbafl8zuEjhsr0TAco4y N4HkNBQdlXSgEP6BW6/Yxdz5sudUnDTy0iBq4/XAoim1/lX06j3H9nv+BcuJfV52Fa01 gwCDrebg6KK8oEP3Uu3xCgGE6LacsxlKOP3UQR7rg5oVWw0B00cdROyIb/xI/ZgsPt4R /I9SFQA6j/m34upzwUx6oYf1GNdY+fmHUq1fWfijdBjbqVmb3b5+zl4xSj05IrQxvGXe AJug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=zPaFNN0CwRIrxgMT/Hx12rk1w2uEgsV43cWtsFNawmA=; b=YJceFgs6Zor2N0BH9afHt9jIeya3dUKw+X9oA3pJMcPHtnKYX3hmKkmPPRUSBCyAyC rR3W09Me7ncrrKgw3rR+zSWjLe+3pa6+pcoYg0Vpq5gsDjvQy9Lc4UsJoQLtPKA/1MdB d6ECXU6jpxNGP+TXw8UOC2xs5O4e9it5a9/FhqiBRiQHAavheXtPG1vPvtTwFZ0mqak2 orf+QhZ00nkjGATnss02tEj69OnuW7aanoVVuOXD/pc37A+VbT3ZtUNT5+WP0YybfTbT 5DoqMloz+0GReli1hOAQ2a3r+UfrS/Zyvb4zw2ckxbAxpM4QV2Zto4GxIzGRTYqlnvyQ 7ChA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=OoD5s6Eq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e26si15413364edv.66.2020.07.07.10.16.04; Tue, 07 Jul 2020 10:16:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=OoD5s6Eq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728447AbgGGRPT (ORCPT + 99 others); Tue, 7 Jul 2020 13:15:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727834AbgGGRPT (ORCPT ); Tue, 7 Jul 2020 13:15:19 -0400 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA663C061755; Tue, 7 Jul 2020 10:15:18 -0700 (PDT) Received: by mail-wr1-x443.google.com with SMTP id f18so37969193wrs.0; Tue, 07 Jul 2020 10:15:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=zPaFNN0CwRIrxgMT/Hx12rk1w2uEgsV43cWtsFNawmA=; b=OoD5s6EqQZLxfIp3I7A669VifnUn9Ibnc7LYMSzZ0tIPUiA9Tp+buHQWel8bB9NGk2 EGangoBXq+izJzkRL1SnU8OAXuEDSdrGvKiTIwg3pdycFDevybGoENDig+Lin5AzfxWn rV61Zirbp/gFLfE4XdvxvCOlOODfeXWxT96BQOHVqZkX/J+llXtaJhvzMN3duDyx1vmF UtnFxZDDLSvOdsxVgUzYyobE4n4F/ZgGwV+CqNdRYZAjF1GmtCkfutynvWYnuKPjn1wm ymW3Rw/ZTEaVMH6waJzp/4nd8HMM7k76LkNaYVpT4umj4p1Z6H3JkI3G8/Hg1SfAn7v2 IxdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=zPaFNN0CwRIrxgMT/Hx12rk1w2uEgsV43cWtsFNawmA=; b=bBrUUUf2JVcBAHcp8P7U/l62YvlsVWBC4yA6G1YXFjf6RDy85RgK/ngcdPpsVUDluo h3RcpreFKki1YTjUd2DiEMGhkr45E41Q1FJdzNTN8c1OBVAt+wkkNHkIIXshXQZbohPW V1kpaa0w5zCh9RyX7ISKFZp3tU+5ms1r4laEs541Ny10MWIrUQsHHqLmpgBa0YCITRdi ArK810IAF/RtcOP3T5WXsHvXbqF6nfHDBIcC35Q2rK1PbJDyTRGMvlemxXBJPKApR05Y 3P2EgZy7TcvtKIxCYyOgtU+K4u8ZnIcbByHTPGLN1h0Nlpfbee3ZrXjLO8Rcr0f4FvmX rXLA== X-Gm-Message-State: AOAM531138zjzglc/zRSHI2yYLJ/zYv+Bfw/4D4XwOXW3Ohy7B8Jvm+9 qxhZaSponVLGhLKb6up4oag= X-Received: by 2002:a5d:6683:: with SMTP id l3mr7880261wru.288.1594142117582; Tue, 07 Jul 2020 10:15:17 -0700 (PDT) Received: from localhost.localdomain ([185.200.214.168]) by smtp.gmail.com with ESMTPSA id d132sm1872742wmd.35.2020.07.07.10.15.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jul 2020 10:15:16 -0700 (PDT) From: izabela.bakollari@gmail.com To: nhorman@tuxdriver.com, davem@davemloft.net, kuba@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kernel-mentees@lists.linuxfoundation.org, izabela.bakollari@gmail.com Subject: [PATCH net-next] dropwatch: Support monitoring of dropped frames Date: Tue, 7 Jul 2020 19:15:15 +0200 Message-Id: <20200707171515.110818-1-izabela.bakollari@gmail.com> X-Mailer: git-send-email 2.18.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Izabela Bakollari Dropwatch is a utility that monitors dropped frames by having userspace record them over the dropwatch protocol over a file. This augument allows live monitoring of dropped frames using tools like tcpdump. With this feature, dropwatch allows two additional commands (start and stop interface) which allows the assignment of a net_device to the dropwatch protocol. When assinged, dropwatch will clone dropped frames, and receive them on the assigned interface, allowing tools like tcpdump to monitor for them. With this feature, create a dummy ethernet interface (ip link add dev dummy0 type dummy), assign it to the dropwatch kernel subsystem, by using these new commands, and then monitor dropped frames in real time by running tcpdump -i dummy0. Signed-off-by: Izabela Bakollari --- include/uapi/linux/net_dropmon.h | 3 ++ net/core/drop_monitor.c | 79 +++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/net_dropmon.h b/include/uapi/linux/net_dropmon.h index 67e31f329190..e8e861e03a8a 100644 --- a/include/uapi/linux/net_dropmon.h +++ b/include/uapi/linux/net_dropmon.h @@ -58,6 +58,8 @@ enum { NET_DM_CMD_CONFIG_NEW, NET_DM_CMD_STATS_GET, NET_DM_CMD_STATS_NEW, + NET_DM_CMD_START_IFC, + NET_DM_CMD_STOP_IFC, _NET_DM_CMD_MAX, }; @@ -93,6 +95,7 @@ enum net_dm_attr { NET_DM_ATTR_SW_DROPS, /* flag */ NET_DM_ATTR_HW_DROPS, /* flag */ NET_DM_ATTR_FLOW_ACTION_COOKIE, /* binary */ + NET_DM_ATTR_IFNAME, /* string */ __NET_DM_ATTR_MAX, NET_DM_ATTR_MAX = __NET_DM_ATTR_MAX - 1 diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 8e33cec9fc4e..8049bff05abd 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ */ static int trace_state = TRACE_OFF; static bool monitor_hw; +struct net_device *interface; /* net_dm_mutex * @@ -220,9 +222,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location) struct per_cpu_dm_data *data; unsigned long flags; - local_irq_save(flags); + spin_lock_irqsave(&data->lock, flags); data = this_cpu_ptr(&dm_cpu_data); - spin_lock(&data->lock); dskb = data->skb; if (!dskb) @@ -255,6 +256,12 @@ static void trace_drop_common(struct sk_buff *skb, void *location) out: spin_unlock_irqrestore(&data->lock, flags); + + if (interface && interface != skb->dev) { + skb = skb_clone(skb, GFP_ATOMIC); + skb->dev = interface; + netif_receive_skb(skb); + } } static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, void *location) @@ -1315,6 +1322,63 @@ static int net_dm_cmd_trace(struct sk_buff *skb, return -EOPNOTSUPP; } +static int net_dm_interface_start(struct net *net, const char *ifname) +{ + struct net_device *nd; + + nd = dev_get_by_name(net, ifname); + + if (nd) { + interface = nd; + dev_hold(interface); + } else { + return -ENODEV; + } + return 0; +} + +static int net_dm_interface_stop(struct net *net, const char *ifname) +{ + struct net_device *nd; + + nd = dev_get_by_name(net, ifname); + + if (nd) { + interface = nd; + dev_put(interface); + } else { + return -ENODEV; + } + return 0; +} + +static int net_dm_cmd_ifc_trace(struct sk_buff *skb, struct genl_info *info) +{ + struct net *net = sock_net(skb->sk); + char ifname[IFNAMSIZ]; + int rc; + + memset(ifname, 0, IFNAMSIZ); + nla_strlcpy(ifname, info->attrs[NET_DM_ATTR_IFNAME], IFNAMSIZ - 1); + + switch (info->genlhdr->cmd) { + case NET_DM_CMD_START_IFC: + rc = net_dm_interface_start(net, ifname); + if (rc) + return rc; + break; + case NET_DM_CMD_STOP_IFC: + if (interface) { + rc = net_dm_interface_stop(net, interface->ifname); + return rc; + } else { + return -ENODEV; + } + } + + return 0; +} + static int net_dm_config_fill(struct sk_buff *msg, struct genl_info *info) { void *hdr; @@ -1543,6 +1607,7 @@ static const struct nla_policy net_dm_nl_policy[NET_DM_ATTR_MAX + 1] = { [NET_DM_ATTR_QUEUE_LEN] = { .type = NLA_U32 }, [NET_DM_ATTR_SW_DROPS] = {. type = NLA_FLAG }, [NET_DM_ATTR_HW_DROPS] = {. type = NLA_FLAG }, + [NET_DM_ATTR_IFNAME] = {. type = NLA_STRING, .len = IFNAMSIZ }, }; static const struct genl_ops dropmon_ops[] = { @@ -1570,6 +1635,16 @@ static const struct genl_ops dropmon_ops[] = { .cmd = NET_DM_CMD_STATS_GET, .doit = net_dm_cmd_stats_get, }, + { + .cmd = NET_DM_CMD_START_IFC, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = net_dm_cmd_ifc_trace, + }, + { + .cmd = NET_DM_CMD_STOP_IFC, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = net_dm_cmd_ifc_trace, + }, }; static int net_dm_nl_pre_doit(const struct genl_ops *ops, -- 2.18.4