From patchwork Fri Mar 16 19:23:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Ricardo Leitner X-Patchwork-Id: 887109 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Tp0ypuSH"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 402wNm4xmZz9sPx for ; Sat, 17 Mar 2018 06:23:36 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752683AbeCPTXe (ORCPT ); Fri, 16 Mar 2018 15:23:34 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:39838 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752302AbeCPTXa (ORCPT ); Fri, 16 Mar 2018 15:23:30 -0400 Received: by mail-qt0-f195.google.com with SMTP id v11so4093268qtj.6 for ; Fri, 16 Mar 2018 12:23:30 -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:in-reply-to:references; bh=y0AjWYT/NvNfyIaXpR57SNbacF/ES8iSxPHl7ZUiYe8=; b=Tp0ypuSHP4Sd7fbS9LLAI8hy5/t8AbOKiA7B7sVR9z1Kly6djKAvt1RLCeEyw/eQa2 naJA57Ets9gj8mj74hiat2g6AVpLifPMB2LE3HIl+KQZFN/M6JEySUCbRkomOsUlU8lP 5stiA8Hmantn9akT2eCtX9MYCzTqKowXZqr67WITjeAq9r/U93Trz2spm8V0P85/3SyB Fh6KN0y45mKCzZkC0lpJLRFmqX3D8oLK0MWx2+qGcLWpBK7VB6AUwVfTT04mXj4p/VJ+ 4saOrwn3n8y5hQprXmTKmlJFxLQCcoMVBfFaJeCi92F7S3Q4Ykv2Y7vivT+T5Y86Xicy Y6uQ== 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; bh=y0AjWYT/NvNfyIaXpR57SNbacF/ES8iSxPHl7ZUiYe8=; b=UCt5c6zFFpJBBkELJE0R68Yow8E/4hU/DOysOjWVjvWKHwmaxPVSdZUalq7pzKrq30 A1UHrJhLL+YfDPD1cQ8CPYPtyH+BdSh/an0yaPchzlSvDDtTNmqVfiF1jXtJO65KviTU bs7weLDqOeqyNoapGnIWV6wGPjyrBr55lATYaRp9yrzYgBw/QVADfLzCBDzQZzXE+PNV d87FWHkyILZXTGd2Gq9hdjvFecr6TR/x7T/3Ncf/hHgIHY9Y8YnMHte3ESKq37G/QZgw cLPU/LssXFLGghKw7wHc3/xmmRjTAVRZUJEkvW31SW6X73jM4xy00WPEjg8ttmmJZIWJ krrA== X-Gm-Message-State: AElRT7HF1JUHysZynUVVLt8+E5uDMSDWdDUHheDX0jQdy9AknzpVL3ti v/rfajHHrImDp5XbX6pEKeElxw== X-Google-Smtp-Source: AG47ELuciac+ojK4Wln1kuramLJVQxnCCDS8Hb1mMVlKcG5GJdl/kzHynXB9+3qwFG/xM3Brtv800A== X-Received: by 10.200.6.6 with SMTP id d6mr4379077qth.112.1521228209283; Fri, 16 Mar 2018 12:23:29 -0700 (PDT) Received: from localhost.localdomain.com ([177.10.56.96]) by smtp.gmail.com with ESMTPSA id n88sm5964835qte.66.2018.03.16.12.23.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 16 Mar 2018 12:23:28 -0700 (PDT) From: Marcelo Ricardo Leitner To: netdev@vger.kernel.org Cc: marcelo.leitner@gmail.com, Alexander Aring , Jiri Pirko , Jakub Kicinski Subject: [PATCH RFC iproute2] libnetlink: allow reading more than one message from extack Date: Fri, 16 Mar 2018 16:23:09 -0300 Message-Id: <0e68f6e4a4fc68fd3f5f164b8d50a95fde6a1f50.1521227930.git.mleitner@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch introduces support for reading more than one message from extack's and to adjust their level (warning/error) accordingly. Yes, there is a FIXME tag in the callback call for now. Signed-off-by: Marcelo Ricardo Leitner --- lib/libnetlink.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 928de1dd16d84b7802c06d0a659f5d73e1bbcb4b..7c4c81e11e02ea857888190eb5e7a9e99d159bb3 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -43,9 +43,16 @@ static const enum mnl_attr_data_type extack_policy[NLMSGERR_ATTR_MAX + 1] = { [NLMSGERR_ATTR_OFFS] = MNL_TYPE_U32, }; +#define NETLINK_MAX_EXTACK_MSGS 8 +struct extack_args { + const struct nlattr *msg[NETLINK_MAX_EXTACK_MSGS]; + const struct nlattr *offs; + int msg_count; +}; + static int err_attr_cb(const struct nlattr *attr, void *data) { - const struct nlattr **tb = data; + struct extack_args *tb = data; uint16_t type; if (mnl_attr_type_valid(attr, NLMSGERR_ATTR_MAX) < 0) { @@ -60,19 +67,23 @@ static int err_attr_cb(const struct nlattr *attr, void *data) return MNL_CB_ERROR; } - tb[type] = attr; + if (type == NLMSGERR_ATTR_OFFS) + tb->offs = attr; + else if (tb->msg_count < NETLINK_MAX_EXTACK_MSGS) + tb->msg[tb->msg_count++] = attr; return MNL_CB_OK; } /* dump netlink extended ack error message */ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) { - struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; + struct extack_args tb = {}; const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh); const struct nlmsghdr *err_nlh = NULL; unsigned int hlen = sizeof(*err); - const char *msg = NULL; + const char *msg[NETLINK_MAX_EXTACK_MSGS] = {}; uint32_t off = 0; + int ret, i; /* no TLVs, nothing to do here */ if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS)) @@ -82,14 +93,14 @@ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) if (!(nlh->nlmsg_flags & NLM_F_CAPPED)) hlen += mnl_nlmsg_get_payload_len(&err->msg); - if (mnl_attr_parse(nlh, hlen, err_attr_cb, tb) != MNL_CB_OK) + if (mnl_attr_parse(nlh, hlen, err_attr_cb, &tb) != MNL_CB_OK) return 0; - if (tb[NLMSGERR_ATTR_MSG]) - msg = mnl_attr_get_str(tb[NLMSGERR_ATTR_MSG]); + for (i = 0; i < NETLINK_MAX_EXTACK_MSGS && tb.msg[i]; i++) + msg[i] = mnl_attr_get_str(tb.msg[i]); - if (tb[NLMSGERR_ATTR_OFFS]) { - off = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); + if (tb.offs) { + off = mnl_attr_get_u32(tb.offs); if (off > nlh->nlmsg_len) { fprintf(stderr, @@ -100,21 +111,35 @@ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) } if (errfn) - return errfn(msg, off, err_nlh); + return errfn(*msg, off, err_nlh); /* FIXME */ - if (msg && *msg != '\0') { + ret = 0; + for (i = 0; i < NETLINK_MAX_EXTACK_MSGS && msg[i]; i++) { bool is_err = !!err->error; + const char *_msg = msg[i]; + + /* Message tagging has precedence. + * KERN_WARNING = ASCII Start Of Header ('\001') + '4' + */ + if (!strncmp(_msg, "\0014", 2)) { + is_err = false; + _msg += 2; + } + /* But we can't have Error if it didn't fail. */ + if (is_err && !err->error) + is_err = 0; fprintf(stderr, "%s: %s", - is_err ? "Error" : "Warning", msg); - if (msg[strlen(msg) - 1] != '.') + is_err ? "Error" : "Warning", _msg); + if (_msg[strlen(_msg) - 1] != '.') fprintf(stderr, "."); fprintf(stderr, "\n"); - return is_err ? 1 : 0; + if (is_err) + ret = 1; } - return 0; + return ret; } #else #warning "libmnl required for error support"