From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D44A1A00C2; Sat, 25 Apr 2020 01:37:22 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DACE21D41F; Sat, 25 Apr 2020 01:37:12 +0200 (CEST) Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by dpdk.org (Postfix) with ESMTP id B8A121D177 for ; Sat, 25 Apr 2020 01:37:09 +0200 (CEST) Received: by mail-pg1-f196.google.com with SMTP id n16so5372483pgb.7 for ; Fri, 24 Apr 2020 16:37:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7+kAs5aecFNDH+X6aZ7c7DUokpmwLQANU8MUvblf3Ws=; b=NwHAHgJB1ZIL5enwys1kFDm5BFVZgZnLfWLMHH2UKvO5W0wd67MYglH+ICTjxZ0XYf 8+Uh/ZR7msMQQmTOwLmt2NKw49IGVl81JKVdnlsaMm1kirbR0zgGbezdW4vPKAwU4KoH HoOt4bzaro6sLwvAK+y8DnsZGFq4fwIY7T6rnkodW8ZTi8QkYucCovNDuIXjehfnKZsa +RKLi3DEL3+aiY+FbJHE9Eta1CBg/Z1nE0M/UA86DNabP6QcZSCH10Cg+QEkttTYcqVQ +ABzO4OSeKM2XJcOSzsxRQT8+kkyQCdwvGw3ifNbtJc9yS09CoLZppnNsuT7Pbl2bi0N KuRw== 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=7+kAs5aecFNDH+X6aZ7c7DUokpmwLQANU8MUvblf3Ws=; b=EiC3pQHgu77B43kxEZtZIKfEtpnVx4JJNgBuEAOcvhm9HxtMvDxHWhlHSXIxn4QIUg 8X6vZ8x1JuQTvTKBS7lIaN6aIBsJuOLfsLaZx8n6xisei5HoXdZnGVeodf/GeBs3uWJj k7NpGAE2wcKg113iQmNnNxbFFF9xTMGSSlMaeyW53o7f3QAPLaLyex+l8FNguAufsEvx hUi6nVo1+lgDwN+kldAaXLHGPuoDRrQiLQsGCbgkG9+WqEbwD2uFkxkGgypP4Y+PWgLt LTbUqDf6GNPbVF0Q4akZnp3G3kJZxp77fOP5IbQqUPNehaIsztK8lM7wIaU2EPs8ofHL T2OQ== X-Gm-Message-State: AGi0PuZEsMtuu7Mm9Ud7jZkILznx2aWrLCHrxojX6k3Z+e+jykveFWzK n4WGbY6F6pgKE2bo/IyEY1RGGAOJtec= X-Google-Smtp-Source: APiQypLyGkm9HX8AtWJ1j/vWJYMg81OD0XtmVPYvB+3EqtnUxNzZazsP1/jn6dI35aOgwi0Q6vvb3A== X-Received: by 2002:a63:1160:: with SMTP id 32mr11381115pgr.441.1587771428430; Fri, 24 Apr 2020 16:37:08 -0700 (PDT) Received: from hermes.corp.microsoft.com (204-195-22-127.wavecable.com. [204.195.22.127]) by smtp.gmail.com with ESMTPSA id b5sm6826823pfb.190.2020.04.24.16.37.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Apr 2020 16:37:07 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org, keith.wiles@intel.com Cc: Stephen Hemminger Date: Fri, 24 Apr 2020 16:36:57 -0700 Message-Id: <20200424233657.12267-3-stephen@networkplumber.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200424233657.12267-1-stephen@networkplumber.org> References: <20200424233657.12267-1-stephen@networkplumber.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH 2/2] net/tap: use netlink extended ack support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" In recent Linux kernels, there is support for extended acknowledgement to netlink messages. This is quite useful for diagnosing errors in configuration in the kernel with TAP. Signed-off-by: Stephen Hemminger --- drivers/net/tap/tap_netlink.c | 78 +++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/drivers/net/tap/tap_netlink.c b/drivers/net/tap/tap_netlink.c index 64220178a6ba..2365678a9c13 100644 --- a/drivers/net/tap/tap_netlink.c +++ b/drivers/net/tap/tap_netlink.c @@ -9,10 +9,12 @@ #include #include #include +#include #include #include #include + #include "tap_log.h" /* Must be quite large to support dumping a huge list of QDISC or filters. */ @@ -43,6 +45,7 @@ tap_nl_init(uint32_t nl_groups) .nl_family = AF_NETLINK, .nl_groups = nl_groups, }; + int one = 1; fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); if (fd < 0) { @@ -59,6 +62,12 @@ tap_nl_init(uint32_t nl_groups) close(fd); return -1; } + +#ifdef NETLINK_EXT_ACK + /* Ask for extended ACK response. on older kernel will ignore request. */ + setsockopt(fd, SOL_NETLINK, NETLINK_EXT_ACK, &one, sizeof(one)); +#endif + if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0) { TAP_LOG(ERR, "Unable to bind to the netlink socket"); close(fd); @@ -119,6 +128,74 @@ tap_nl_send(int nlsk_fd, struct nlmsghdr *nh) return send_bytes; } +#ifdef NETLINK_EXT_ACK +static const struct nlattr * +tap_nl_attr_first(const struct nlmsghdr *nh, size_t offset) +{ + return (const struct nlattr *)((const char *)nh + NLMSG_SPACE(offset)); +} + +static const struct nlattr * +tap_nl_attr_next(const struct nlattr *attr) +{ + return (const struct nlattr *)((const char *)attr + + NLMSG_ALIGN(attr->nla_len)); +} + +static bool +tap_nl_attr_ok(const struct nlattr *attr, int len) +{ + if (len < (int)sizeof(struct nlattr)) + return false; /* missing header */ + if (attr->nla_len < sizeof(struct nlattr)) + return false; /* attribute length should include itself */ + if ((int)attr->nla_len > len) + return false; /* attribute is truncated */ + return true; +} + + +/* Decode extended errors from kernel */ +static void +tap_nl_dump_ext_ack(const struct nlmsghdr *nh, const struct nlmsgerr *err) +{ + const struct nlattr *attr; + const char *tail = (const char *)nh + NLMSG_ALIGN(nh->nlmsg_len); + size_t hlen = sizeof(*err); + + /* no TLVs, no extended response */ + if (!(nh->nlmsg_flags & NLM_F_ACK_TLVS)) + return; + + if (!(nh->nlmsg_flags & NLM_F_CAPPED)) + hlen += err->msg.nlmsg_len - NLMSG_HDRLEN; + + for (attr = tap_nl_attr_first(nh, hlen); + tap_nl_attr_ok(attr, tail - (const char *)attr); + attr = tap_nl_attr_next(attr)) { + uint16_t type = attr->nla_type & NLA_TYPE_MASK; + + if (type == NLMSGERR_ATTR_MSG) { + const char *msg = (const char *)attr + + NLMSG_ALIGN(sizeof(*attr)); + + if (err->error) + TAP_LOG(ERR, "%s", msg); + else + + TAP_LOG(WARNING, "%s", msg); + break; + } + } +} +#else +/* + * External ACK support was added in Linux kernel 4.17 + * on older kernels, just ignore that part of message + */ +#define tap_nl_dump_ext_ack(nh, err) do { } while(); +#endif + /** * Check that the kernel sends an appropriate ACK in response * to an tap_nl_send(). @@ -174,6 +251,7 @@ tap_nl_recv(int nlsk_fd, int (*cb)(struct nlmsghdr *, void *arg), void *arg) if (nh->nlmsg_type == NLMSG_ERROR) { struct nlmsgerr *err_data = NLMSG_DATA(nh); + tap_nl_dump_ext_ack(nh, err_data); if (err_data->error < 0) { errno = -err_data->error; return -1; -- 2.20.1