From patchwork Sat Mar 18 00:23:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13179635 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 210D0C7618E for ; Sat, 18 Mar 2023 00:23:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229967AbjCRAXq (ORCPT ); Fri, 17 Mar 2023 20:23:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229940AbjCRAXo (ORCPT ); Fri, 17 Mar 2023 20:23:44 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2066DCF6D for ; Fri, 17 Mar 2023 17:23:43 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id i7-20020a626d07000000b005d29737db06so3389533pfc.15 for ; Fri, 17 Mar 2023 17:23:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679099023; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Zc4RhVmVpU1pXWFLdUvbx968KFQg4fwNWqu5jwdXsws=; b=eRHkh6Na26C1NimSM4I09lHWFLe2KPqePy9k8F89aIHeJ66dm0w925X7wNdPFjgi7k 1Jn6pzJCD4RK13WkmgLOHsu/X/OoI5BoHsMrgbHY9hV5jusAvtaAXRkvrk65prIWahKX UHhdzxFzhE9kYHY6Glgf9IY3rk3nVwK7vltuP7JjZUofGVJjuzuMuvD6x5Q6FtcK73ZA q7uCqz5nsftNs5it5VnSfPkeWzxsB+Ki1p1kpbK/dkaekt/BcKUdiDXjzmxyJYgHxXim YjYK9gwqZcAwaLJ/yrSVS8/OTr4I++jOv+DHlNjADTlaFLva+YCbnq5EfnX3iK2aV4S1 LQ1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679099023; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Zc4RhVmVpU1pXWFLdUvbx968KFQg4fwNWqu5jwdXsws=; b=mqbL1YtHSCzNXGPruRCSpSJQXfMKXVmJzNoaF7Q/d7iaLBnx88wmKlVcGyydTvESiL yJR5wdGy3o1UIkPMp3eU/fDrG8k8Zm7+gvabo8cG7LuJ+ydhzMI11xqA6xJtNevzgy4t bSasXSoXrRC02Z+/JjI0wxvtK9X3Klc1B/6ByizeNmwTHhw952/96lqgWgVwxIVBTdbk 8uha4OlNzLkcXm50rWPjfVEl/tiLjVpC92EBwYkUtGiFW8Rr+DyDFPClCJ8zNS7V37nZ PxSDnEyv0wrpuB31Ebe352S/KM0wfPsFGgvrFkhMzxbu5r8XmZjoWEm/1TYPKUVh6fYM fx2g== X-Gm-Message-State: AO0yUKXpjUj92yizDofgo2dBGoHfpIrINQ6wKZ/2ViV6QNP0/zZoVy/X 0I0IQKhIu0tFWcT4UDIYclS4sVpSoUtm2VNsPhseYjGB6lH1H9OzNAyeC1XB46XltCL4MR6TYfj whcFet9JfPnoKfxPj0aFbhs3HWTIRfql8WO89I2KrgO4svRyTPOdEgQ== X-Google-Smtp-Source: AK7set94sqXkq+v7Fogh8NjA0NGPkoaIu1pcAYTNyvu71b+cH1nDpUljWUyedif862ShAsVEzr/ORoQ= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a65:5248:0:b0:503:72c5:dd77 with SMTP id q8-20020a655248000000b0050372c5dd77mr37540pgp.6.1679099023315; Fri, 17 Mar 2023 17:23:43 -0700 (PDT) Date: Fri, 17 Mar 2023 17:23:37 -0700 In-Reply-To: <20230318002340.1306356-1-sdf@google.com> Mime-Version: 1.0 References: <20230318002340.1306356-1-sdf@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Message-ID: <20230318002340.1306356-2-sdf@google.com> Subject: [PATCH net-next 1/4] ynl: support be16 in schemas From: Stanislav Fomichev To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, Stanislav Fomichev Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Used by ethtool spec. Signed-off-by: Stanislav Fomichev --- Documentation/netlink/genetlink-c.yaml | 2 +- Documentation/netlink/genetlink-legacy.yaml | 4 ++-- Documentation/netlink/genetlink.yaml | 2 +- tools/net/ynl/lib/ynl.py | 7 +++++++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Documentation/netlink/genetlink-c.yaml b/Documentation/netlink/genetlink-c.yaml index 8e8c17b0a6c6..1b057fc9326c 100644 --- a/Documentation/netlink/genetlink-c.yaml +++ b/Documentation/netlink/genetlink-c.yaml @@ -148,7 +148,7 @@ additionalProperties: False name: type: string type: &attr-type - enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64, + enum: [ unused, pad, flag, binary, u8, u16, be16, u32, u64, s32, s64, string, nest, array-nest, nest-type-value ] doc: description: Documentation of the attribute. diff --git a/Documentation/netlink/genetlink-legacy.yaml b/Documentation/netlink/genetlink-legacy.yaml index 5dc6f1c07a97..3796d8be9045 100644 --- a/Documentation/netlink/genetlink-legacy.yaml +++ b/Documentation/netlink/genetlink-legacy.yaml @@ -119,7 +119,7 @@ additionalProperties: False name: type: string type: - enum: [ u8, u16, u32, u64, s8, s16, s32, s64, string ] + enum: [ u8, u16, be16, u32, u64, s8, s16, s32, s64, string ] len: $ref: '#/$defs/len-or-define' # End genetlink-legacy @@ -171,7 +171,7 @@ additionalProperties: False name: type: string type: &attr-type - enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64, + enum: [ unused, pad, flag, binary, u8, u16, be16, u32, u64, s32, s64, string, nest, array-nest, nest-type-value ] doc: description: Documentation of the attribute. diff --git a/Documentation/netlink/genetlink.yaml b/Documentation/netlink/genetlink.yaml index d8b2cdeba058..a143221c3d2e 100644 --- a/Documentation/netlink/genetlink.yaml +++ b/Documentation/netlink/genetlink.yaml @@ -121,7 +121,7 @@ additionalProperties: False name: type: string type: &attr-type - enum: [ unused, pad, flag, binary, u8, u16, u32, u64, s32, s64, + enum: [ unused, pad, flag, binary, u8, u16, be16, u32, u64, s32, s64, string, nest, array-nest, nest-type-value ] doc: description: Documentation of the attribute. diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py index 90764a83c646..21c015911803 100644 --- a/tools/net/ynl/lib/ynl.py +++ b/tools/net/ynl/lib/ynl.py @@ -81,6 +81,9 @@ from .nlspec import SpecFamily def as_u16(self): return struct.unpack("H", self.raw)[0] + def as_be16(self): + return struct.unpack(">H", self.raw)[0] + def as_u32(self): return struct.unpack("I", self.raw)[0] @@ -334,6 +337,8 @@ genl_family_name_to_id = None attr_payload += self._add_attr(attr['nested-attributes'], subname, subvalue) elif attr["type"] == 'flag': attr_payload = b'' + elif attr["type"] == 'be16': + attr_payload = struct.pack(">H", int(value)) elif attr["type"] == 'u32': attr_payload = struct.pack("I", int(value)) elif attr["type"] == 'string': @@ -371,6 +376,8 @@ genl_family_name_to_id = None decoded = subdict elif attr_spec['type'] == 'u8': decoded = attr.as_u8() + elif attr_spec['type'] == 'be16': + decoded = attr.as_be16() elif attr_spec['type'] == 'u32': decoded = attr.as_u32() elif attr_spec['type'] == 'u64': From patchwork Sat Mar 18 00:23:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13179637 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2F38C6FD1D for ; Sat, 18 Mar 2023 00:23:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229981AbjCRAXy (ORCPT ); Fri, 17 Mar 2023 20:23:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229986AbjCRAXt (ORCPT ); Fri, 17 Mar 2023 20:23:49 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 39FAEE20F4 for ; Fri, 17 Mar 2023 17:23:46 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id e129-20020a251e87000000b00b56598237f5so6833510ybe.16 for ; Fri, 17 Mar 2023 17:23:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679099025; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=wwVxbuKRzpmq9elonGFMqhO58CjCEoFcP0XIkRK2Lfk=; b=GWZczzulQt1Opf6u5D89emOZOAVH/n2k/9gCAhsvHpEL9nfQY0yOfMRCstQ56xvzXR 9ct5CQpNc4sPreKaLaoWALHdT8DCrtVU4IyDP9iSQwAD0Mt96yokkGPJKqljhyBI8pgZ d3vRhxAHqJtcZHoLQYy8j13UEeT1cZlF95RtlfscMkyInYztTPRHGWBJ4nrnZqSASKHj zJA5Bbi2Od9iTlpZFWGX3nf40ssMssLxlugingTnEZ2lgH8Nj7s59eD6YxHRyCSHNhTV GnKMKLGNLO/jmXJY8GQRMfCImcvz1aMsI6KBcQrNM1I2ES6PrGcSCsx51AzcZ/Rq3Fja 0g+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679099025; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wwVxbuKRzpmq9elonGFMqhO58CjCEoFcP0XIkRK2Lfk=; b=GFY7H+Fu0xg9EHmY5squMMBVfvWjAOW5SnHEv32stOKyVe3stexJLZqmdrRQ7eTV2u YK+nMb+Xqpmk/YdGf5D18mZuTnVkR64EwnAyhy9TwFhOiQkYWaLDWnY+psYtRyGndYa9 uF7ooUsSRoK0X74NgehrOQvawRd78dRULFLKrS9HNo0A5nFHtMx6MhdTxRvKlXiVXx4Y exUTlAsNp9uIBQGDrzgKk3IXAE4PwjicqPmBOknAKA8U15vKSBrJWR6eFTrYCvh0MnTk TFN3MmOVgOBPprbjZvJY01o1TR9WL+mz4Zrk4ZITfgajQbZAMziog+JnipO+QQpy96LY YDAw== X-Gm-Message-State: AO0yUKWDdWymndqFMVLFm3ue+kRYhQVlCxr105IgGv8lVfZHWB9nZg7D ncp1f2bTjP0JgCb4BeifqIUYfxaybR2eu5Ws+F6Rj3FEPIUdNEV+xODz+1eUAD1s/PAzjR76drS 4SHZG+PAigZq/ZSNRYK2tZZr46b+gk2PqyUPSb/KbZvRLzhtpMh48Rg== X-Google-Smtp-Source: AK7set9HQb37KnpJ/udVVgNbA8nYfVt9viu2a/qnn/Ya4/VlbHryjpFJXLYiz5+fF6bHc3BRVgFCBMo= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a5b:9d0:0:b0:b46:4a5e:365f with SMTP id y16-20020a5b09d0000000b00b464a5e365fmr245199ybq.8.1679099025267; Fri, 17 Mar 2023 17:23:45 -0700 (PDT) Date: Fri, 17 Mar 2023 17:23:38 -0700 In-Reply-To: <20230318002340.1306356-1-sdf@google.com> Mime-Version: 1.0 References: <20230318002340.1306356-1-sdf@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Message-ID: <20230318002340.1306356-3-sdf@google.com> Subject: [PATCH net-next 2/4] ynl: populate most of the ethtool spec From: Stanislav Fomichev To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, Stanislav Fomichev Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Things that are not implemented: - cable tests - bitmaks in the requests don't work (needs multi-attr support in ynl.py) - stats-get seems to return nonsense - notifications are not tested - features-nft has hard-coded value:13, not sure why it skews Signed-off-by: Stanislav Fomichev --- Documentation/netlink/specs/ethtool.yaml | 1473 ++++++++++++++++++++-- 1 file changed, 1362 insertions(+), 111 deletions(-) diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml index 4727c067e2ba..ba9ee9b6e5ad 100644 --- a/Documentation/netlink/specs/ethtool.yaml +++ b/Documentation/netlink/specs/ethtool.yaml @@ -6,6 +6,12 @@ protocol: genetlink-legacy doc: Partial family for Ethtool Netlink. +definitions: + - + name: udp-tunnel-type + type: enum + entries: [ vxlan, geneve, vxlan_gpe ] + attribute-sets: - name: header @@ -38,6 +44,7 @@ doc: Partial family for Ethtool Netlink. - name: bit type: nest + multi-attr: true nested-attributes: bitset-bit - name: bitset @@ -53,6 +60,21 @@ doc: Partial family for Ethtool Netlink. type: nest nested-attributes: bitset-bits + - + name: u64-array + attributes: + - + name: u64 + type: nest + multi-attr: true + nested-attributes: u64 + name: s32-array + attributes: + - + name: s32 + type: nest + multi-attr: true + nested-attributes: s32 - name: string attributes: @@ -228,116 +250,1347 @@ doc: Partial family for Ethtool Netlink. name: stats type: nest nested-attributes: mm-stat + - + name: linkinfo + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: port + type: u8 + - + name: phyaddr + type: u8 + - + name: tp_mdix + type: u8 + - + name: tp_mdix_ctrl + type: u8 + - + name: transceiver + type: u8 + - + name: linkmodes + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: autoneg + type: u8 + - + name: ours + type: nest + nested-attributes: bitset + - + name: peer + type: nest + nested-attributes: bitset + - + name: speed + type: u32 + - + name: duplex + type: u8 + - + name: master_slave_cfg + type: u8 + - + name: master_slave_state + type: u8 + - + name: master_slave_lanes + type: u32 + - + name: rate_matching + type: u8 + - + name: linkstate + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: link + type: u8 + - + name: sqi + type: u32 + - + name: sqi_max + type: u32 + - + name: ext_state + type: u8 + - + name: ext_substate + type: u8 + - + name: down_cnt + type: u32 + - + name: debug + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: msgmask + type: nest + nested-attributes: bitset + - + name: wol + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: modes + type: nest + nested-attributes: bitset + - + name: sopass + type: binary + - + name: features + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: hw + type: nest + nested-attributes: bitset + - + name: wanted + type: nest + nested-attributes: bitset + - + name: active + type: nest + nested-attributes: bitset + - + name: nochange + type: nest + nested-attributes: bitset + - + name: channels + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: rx-max + type: u32 + - + name: tx-max + type: u32 + - + name: other-max + type: u32 + - + name: combined-max + type: u32 + - + name: rx-count + type: u32 + - + name: tx-count + type: u32 + - + name: other-count + type: u32 + - + name: combined-count + type: u32 -operations: - enum-model: directional - list: - - - name: strset-get - doc: Get string set from the kernel. - - attribute-set: strset - - do: &strset-get-op - request: - attributes: - - header - - stringsets - - counts-only - reply: - attributes: - - header - - stringsets - dump: *strset-get-op - - # TODO: fill in the requests in between - - - - name: privflags-get - doc: Get device private flags. - - attribute-set: privflags - - do: &privflag-get-op - request: - value: 13 - attributes: - - header - reply: - value: 14 - attributes: - - header - - flags - dump: *privflag-get-op - - - name: privflags-set - doc: Set device private flags. - - attribute-set: privflags - - do: - request: - attributes: - - header - - flags - - - name: privflags-ntf - doc: Notification for change in device private flags. - notify: privflags-get - - - - name: rings-get - doc: Get ring params. - - attribute-set: rings - - do: &ring-get-op - request: - attributes: - - header - reply: - attributes: - - header - - rx-max - - rx-mini-max - - rx-jumbo-max - - tx-max - - rx - - rx-mini - - rx-jumbo - - tx - - rx-buf-len - - tcp-data-split - - cqe-size - - tx-push - - rx-push - dump: *ring-get-op - - - name: rings-set - doc: Set ring params. - - attribute-set: rings - - do: - request: - attributes: - - header - - rx - - rx-mini - - rx-jumbo - - tx - - rx-buf-len - - tcp-data-split - - cqe-size - - tx-push - - rx-push - - - name: rings-ntf - doc: Notification for change in ring params. - notify: rings-get - - # TODO: fill in the requests in between - + - + name: coalesce + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: rx-usecs + type: u32 + - + name: rx-max-frames + type: u32 + - + name: rx-usecs-irq + type: u32 + - + name: rx-max-frames-irq + type: u32 + - + name: tx-usecs + type: u32 + - + name: tx-max-frames + type: u32 + - + name: tx-usecs-irq + type: u32 + - + name: tx-max-frames-irq + type: u32 + - + name: stats-block-usecs + type: u32 + - + name: use-adaptive-rx + type: u8 + - + name: use-adaptive-tx + type: u8 + - + name: pkt-rate-low + type: u32 + - + name: rx-usecs-low + type: u32 + - + name: rx-max-frames-low + type: u32 + - + name: tx-usecs-low + type: u32 + - + name: tx-max-frames-low + type: u32 + - + name: pkt-rate-high + type: u32 + - + name: rx-usecs-high + type: u32 + - + name: rx-max-frames-high + type: u32 + - + name: tx-usecs-high + type: u32 + - + name: tx-max-frames-high + type: u32 + - + name: rate-sample-interval + type: u32 + - + name: use-cqe-mode-tx + type: u8 + - + name: use-cqe-mode-rx + type: u8 + - + name: tx-aggr-max-bytes + type: u32 + - + name: tx-aggr-max-frames + type: u32 + - + name: tx-aggr-time-usecs + type: u32 + - + name: pause-stat + attributes: + - + name: pad + type: u32 + - + name: tx-frames + type: u64 + - + name: rx-frames + type: u64 + - + name: pause + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: autoneg + type: u8 + - + name: rx + type: u8 + - + name: tx + type: u8 + - + name: stats + type: nest + nested-attributes: pause-stat + - + name: stats-src + type: u32 + - + name: eee + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: modes-ours + type: nest + nested-attributes: bitset + - + name: modes-peer + type: nest + nested-attributes: bitset + - + name: active + type: u8 + - + name: enabled + type: u8 + - + name: tx-lpi-enabled + type: u8 + - + name: tx-lpi-timer + type: u32 + - + name: tsinfo + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: timestamping + type: nest + nested-attributes: bitset + - + name: tx-types + type: nest + nested-attributes: bitset + - + name: rx-filters + type: nest + nested-attributes: bitset + - + name: phc-index + type: u32 + - + name: cable-test-nft-nest-result + attributes: + - + name: pair + type: u8 + - + name: code + type: u8 + - + name: cable-test-nft-nest-fault-length + attributes: + - + name: pair + type: u8 + - + name: cm + type: u32 + - + name: cable-test-nft-nest + attributes: + - + name: result + type: nest + nested-attributes: cable-test-nft-nest-result + - + name: fault-length + type: nest + nested-attributes: cable-test-nft-nest-fault-length + - + name: cable-test + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: status + type: u8 + - + name: nest + type: nest + nested-attributes: cable-test-nft-nest + - + name: cable-test-tdr-cfg + attributes: + - + name: first + type: u32 + - + name: last + type: u32 + - + name: step + type: u32 + - + name: pari + type: u8 + - + name: cable-test-tdr + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: cfg + type: nest + nested-attributes: cable-test-tdr-cfg + - + name: tunnel-info-udp-entry + attributes: + - + name: port + type: be16 + - + name: type + type: u32 + enum: udp-tunnel-type + - + name: tunnel-info-udp-table + attributes: + - + name: size + type: u32 + - + name: types + type: nest + nested-attributes: bitset + - + name: udp-ports + type: nest + nested-attributes: tunnel-info-udp-entry + - + name: tunnel-info + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: udp-ports + type: nest + nested-attributes: tunnel-info-udp-table + - + name: fec-stat + attributes: + - + name: pad + type: u8 + - + name: corrected + type: nest + nested-attributes: u64-array + - + name: uncorr + type: nest + nested-attributes: u64-array + - + name: corr-bits + type: nest + nested-attributes: u64-array + - + name: fec + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: modes + type: nest + nested-attributes: bitset + - + name: auto + type: u8 + - + name: active + type: u32 + - + name: stats + type: nest + nested-attributes: fec-stat + - + name: module-eeprom + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: offset + type: u32 + - + name: length + type: u32 + - + name: page + type: u8 + - + name: bank + type: u8 + - + name: i2c-address + type: u8 + - + name: data + type: binary + - + name: stats-grp + attributes: + - + name: pad + type: u32 + - + name: id + type: u32 + - + name: ss-id + type: u32 + - + name: stat + type: nest + nested-attributes: u64 + - + name: hist-rx + type: nest + nested-attributes: u64 + - + name: hist-tx + type: nest + nested-attributes: u64 + - + name: hist-bkt-low + type: u32 + - + name: hist-bkt-hi + type: u32 + - + name: hist-bkt-val + type: u64 + - + name: stats + attributes: + - + name: pad + type: u32 + - + name: header + type: nest + nested-attributes: header + - + name: groups + type: nest + nested-attributes: bitset + - + name: grp + type: nest + nested-attributes: stats-grp + - + name: src + type: u32 + - + name: phc-vclocks + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: num + type: u32 + - + name: index + type: nest + nested-attributes: s32-array + - + name: module + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: power-mode-policy + type: u8 + - + name: power-mode + type: u8 + - + name: pse + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: admin-state + type: u32 + - + name: admin-control + type: u32 + - + name: pw-d-status + type: u32 + - + name: rss + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: context + type: u32 + - + name: hfunc + type: u32 + - + name: indir + type: binary + - + name: hkey + type: binary + - + name: plca + attributes: + - + name: header + type: nest + nested-attributes: header + - + name: version + type: u16 + - + name: enabled + type: u8 + - + name: status + type: u8 + - + name: node-cnt + type: u32 + - + name: node-id + type: u32 + - + name: to-tmr + type: u32 + - + name: burst-cnt + type: u32 + - + name: burst-tmr + type: u32 + +operations: + enum-model: directional + list: + - + name: strset-get + doc: Get string set from the kernel. + + attribute-set: strset + + do: &strset-get-op + request: + attributes: + - header + - stringsets + - counts-only + reply: + attributes: + - header + - stringsets + dump: *strset-get-op + - + name: linkinfo-get + doc: Get link info. + + attribute-set: linkinfo + + do: &linkinfo-get-op + request: + attributes: + - header + reply: + attributes: &linkinfo + - header + - port + - phyaddr + - tp_mdix + - tp_mdix_ctrl + - transceiver + dump: *linkinfo-get-op + - + name: linkinfo-set + doc: Set link info. + + attribute-set: linkinfo + + do: + request: + attributes: *linkinfo + - + name: linkinfo-ntf + doc: Notification for change in link info. + notify: linkinfo-get + - + name: linkmodes-get + doc: Get link modes. + + attribute-set: linkmodes + + do: &linkmodes-get-op + request: + attributes: + - header + reply: + attributes: &linkmodes + - header + - autoneg + - ours + - peer + - speed + - duplex + - master_slave_cfg + - master_slave_state + - master_slave_lanes + - rate_matching + dump: *linkmodes-get-op + - + name: linkmodes-set + doc: Set link modes. + + attribute-set: linkmodes + + do: + request: + attributes: *linkmodes + - + name: linkmodes-ntf + doc: Notification for change in link modes. + notify: linkmodes-get + - + name: linkstate-get + doc: Get link state. + + attribute-set: linkstate + + do: &linkstate-get-op + request: + attributes: + - header + reply: + attributes: + - header + - link + - sqi + - sqi_max + - ext_state + - ext_substate + - down_cnt + dump: *linkstate-get-op + - + name: debug-get + doc: Get debug message mask. + + attribute-set: debug + + do: &debug-get-op + request: + attributes: + - header + reply: + attributes: &debug + - header + - msgmask + dump: *debug-get-op + - + name: debug-set + doc: Set debug message mask. + + attribute-set: debug + + do: + request: + attributes: *debug + - + name: debug-ntf + doc: Notification for change in debug message mask. + notify: debug-get + - + name: wol-get + doc: Get WOL params. + + attribute-set: wol + + do: &wol-get-op + request: + attributes: + - header + reply: + attributes: &wol + - header + - modes + - sopass + dump: *wol-get-op + - + name: wol-set + doc: Set WOL params. + + attribute-set: wol + + do: + request: + attributes: *wol + - + name: wol-ntf + doc: Notification for change in WOL params. + notify: wol-get + - + name: features-get + doc: Get features. + + attribute-set: features + + do: &feature-get-op + request: + attributes: + - header + reply: + attributes: &feature + - header + # User-changeable features. + - hw + # User-requested features. + - wanted + # Currently active features. + - active + # Unchangeable features. + - nochange + dump: *feature-get-op + - + name: features-set + doc: Set features. + + attribute-set: features + + do: + request: + attributes: *feature + - + name: features-ntf + doc: Notification for change in features. + notify: features-get + value: 13 # TODO: WHY? + - + name: privflags-get + doc: Get device private flags. + + attribute-set: privflags + + do: &privflag-get-op + request: + attributes: + - header + reply: + attributes: &privflag + - header + - flags + dump: *privflag-get-op + - + name: privflags-set + doc: Set device private flags. + + attribute-set: privflags + + do: + request: + attributes: *privflag + - + name: privflags-ntf + doc: Notification for change in device private flags. + notify: privflags-get + + - + name: rings-get + doc: Get ring params. + + attribute-set: rings + + do: &ring-get-op + request: + attributes: + - header + reply: + attributes: &ring + - header + - rx-max + - rx-mini-max + - rx-jumbo-max + - tx-max + - rx + - rx-mini + - rx-jumbo + - tx + - rx-buf-len + - tcp-data-split + - cqe-size + - tx-push + - rx-push + dump: *ring-get-op + - + name: rings-set + doc: Set ring params. + + attribute-set: rings + + do: + request: + attributes: *ring + - + name: rings-ntf + doc: Notification for change in ring params. + notify: rings-get + - + name: channels-get + doc: Get channel params. + + attribute-set: channels + + do: &channel-get-op + request: + attributes: + - header + reply: + attributes: &channel + - header + - rx-max + - tx-max + - other-max + - combined-max + - rx-count + - tx-count + - other-count + - combined-count + dump: *channel-get-op + - + name: channels-set + doc: Set channel params. + + attribute-set: channels + + do: + request: + attributes: *channel + - + name: channels-ntf + doc: Notification for change in channel params. + notify: channels-get + - + name: coalesce-get + doc: Get coalesce params. + + attribute-set: coalesce + + do: &coalesce-get-op + request: + attributes: + - header + reply: + attributes: &coalesce + - header + - rx-usecs + - rx-max-frames + - rx-usecs-irq + - rx-max-frames-irq + - tx-usecs + - tx-max-frames + - tx-usecs-irq + - tx-max-frames-irq + - stats-block-usecs + - use-adaptive-rx + - use-adaptive-tx + - pkt-rate-low + - rx-usecs-low + - rx-max-frames-low + - tx-usecs-low + - tx-max-frames-low + - pkt-rate-high + - rx-usecs-high + - rx-max-frames-high + - tx-usecs-high + - tx-max-frames-high + - rate-sample-interval + - use-cqe-mode-tx + - use-cqe-mode-rx + - tx-aggr-max-bytes + - tx-aggr-max-frames + - tx-aggr-time-usecs + dump: *coalesce-get-op + - + name: coalesce-set + doc: Set coalesce params. + + attribute-set: coalesce + + do: + request: + attributes: *coalesce + - + name: coalesce-ntf + doc: Notification for change in coalesce params. + notify: coalesce-get + - + name: pause-get + doc: Get pause params. + + attribute-set: pause + + do: &pause-get-op + request: + attributes: + - header + reply: + attributes: &pause + - header + - autoneg + - rx + - tx + - stats + - stats-src + dump: *pause-get-op + - + name: pause-set + doc: Set pause params. + + attribute-set: pause + + do: + request: + attributes: *pause + - + name: pause-ntf + doc: Notification for change in pause params. + notify: pause-get + - + name: eee-get + doc: Get eee params. + + attribute-set: eee + + do: &eee-get-op + request: + attributes: + - header + reply: + attributes: &eee + - header + - modes-ours + - modes-peer + - active + - enabled + - tx-lpi-enabled + - tx-lpi-timer + dump: *eee-get-op + - + name: eee-set + doc: Set eee params. + + attribute-set: eee + + do: + request: + attributes: *eee + - + name: eee-ntf + doc: Notification for change in eee params. + notify: eee-get + - + name: tsinfo-get + doc: Get tsinfo params. + + attribute-set: tsinfo + + do: &tsinfo-get-op + request: + attributes: + - header + reply: + attributes: + - header + - timestamping + - tx-types + - rx-filters + - phc-index + dump: *tsinfo-get-op + - + name: cable-test-act + doc: Cable test. + + attribute-set: cable-test + + do: + request: + attributes: + - header + reply: + attributes: + - header + - cable-test-nft-nest + - + name: cable-test-tdr-act + doc: Cable test TDR. + + attribute-set: cable-test-tdr + + do: + request: + attributes: + - header + reply: + attributes: + - header + - cable-test-tdr-cfg + - + name: tunnel-info-get + doc: Get tsinfo params. + + attribute-set: tunnel-info + + do: &tunnel-info-get-op + request: + attributes: + - header + reply: + attributes: + - header + - udp-ports + dump: *tunnel-info-get-op + - + name: fec-get + doc: Get FEC params. + + attribute-set: fec + + do: &fec-get-op + request: + attributes: + - header + reply: + attributes: &fec + - header + - modes + - auto + - active + - stats + dump: *fec-get-op + - + name: fec-set + doc: Set FEC params. + + attribute-set: fec + + do: + request: + attributes: *fec + - + name: fec-ntf + doc: Notification for change in FEC params. + notify: fec-get + - + name: module-eeprom-get + doc: Get module EEPROM params. + + attribute-set: module-eeprom + + do: &module-eeprom-get-op + request: + attributes: + - header + reply: + attributes: + - header + - offset + - length + - page + - bank + - i2c-address + - data + dump: *module-eeprom-get-op + - + name: stats-get + doc: Get statistics. + + attribute-set: stats + + do: &stats-get-op + request: + attributes: + - header + - groups + reply: + attributes: + - header + - groups + - grp + - src + dump: *stats-get-op + - + name: phc-vclocks-get + doc: Get PHC VCLOCKs. + + attribute-set: phc-vclocks + + do: &phc-vclocks-get-op + request: + attributes: + - header + reply: + attributes: + - header + - num + dump: *phc-vclocks-get-op + - + name: module-get + doc: Get module params. + + attribute-set: module + + do: &module-get-op + request: + attributes: + - header + reply: + attributes: &module + - header + - power-mode-policy + - power-mode + dump: *module-get-op + - + name: module-set + doc: Set module params. + + attribute-set: module + + do: + request: + attributes: *module + - + name: module-ntf + doc: Notification for change in module params. + notify: module-get + - + name: pse-get + doc: Get Power Sourcing Equipment params. + + attribute-set: pse + + do: &pse-get-op + request: + attributes: + - header + reply: + attributes: &pse + - header + - admin-state + - admin-control + - pw-d-status + dump: *pse-get-op + - + name: pse-set + doc: Set Power Sourcing Equipment params. + + attribute-set: pse + + do: + request: + attributes: *pse + - + name: rss-get + doc: Get RSS params. + + attribute-set: rss + + do: &rss-get-op + request: + attributes: + - header + reply: + attributes: + - header + - context + - hfunc + - indir + - hkey + dump: *rss-get-op + - + name: plca-get + doc: Get PLCA params. + + attribute-set: plca + + do: &plca-get-op + request: + attributes: + - header + reply: + attributes: &plca + - header + - version + - enabled + - status + - node-cnt + - node-id + - to-tmr + - burst-cnt + - burst-tmr + dump: *plca-get-op + - + name: plca-set + doc: Set PLCA params. + + attribute-set: plca + + do: + request: + attributes: *plca + - + name: plca-get-status + doc: Get PLCA status params. + + attribute-set: plca + + do: &plca-get-status-op + request: + attributes: + - header + reply: + attributes: *plca + dump: *plca-get-status-op + - + name: plca-ntf + doc: Notification for change in PLCA params. + notify: plca-get - name: mm-get doc: Get MAC Merge configuration and state @@ -346,11 +1599,9 @@ doc: Partial family for Ethtool Netlink. do: &mm-get-op request: - value: 42 attributes: - header reply: - value: 42 attributes: - header - pmac-enabled From patchwork Sat Mar 18 00:23:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13179636 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B26DC74A5B for ; Sat, 18 Mar 2023 00:23:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229978AbjCRAXw (ORCPT ); Fri, 17 Mar 2023 20:23:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229981AbjCRAXt (ORCPT ); Fri, 17 Mar 2023 20:23:49 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D184519C54 for ; Fri, 17 Mar 2023 17:23:47 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id 16-20020a056a00073000b006260bbaa3a4so2437092pfm.16 for ; Fri, 17 Mar 2023 17:23:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679099027; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=qXWQq7pZNb2Qr91BMJaQI2TVkAr5dxBPMbErA++ZpiQ=; b=SPdzF7ivLePZIgv4AoletMKSNrj7akdvi+lbyvjavEEipFcxXPNgJiURl07I/PT11J n/gxz0vyi78oAexwWxJVH1/oNjWFxe/Y5hEK2tPVzOpTCSXDzUDYGv0phrwR6OPSt2QF jSKB+VNOfUXwMmgceRtp1UC9mjpk73huVS/N+3wen5YZDvwxGqccDiVDi858HYF2jQVt ukvB7mBFsuBtmx+ztDvPlFqAwhOzWCF+y0ID2Kzz5maHYf9pQEu6xPrB8sZ8hnWISPla UPgzWiyf5QW/Z1fcarZhC8GRHzSo9Q2pZTK7+zbJCBFPemWYGD2RKbWoG4QYvRhylJCs ZpAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679099027; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=qXWQq7pZNb2Qr91BMJaQI2TVkAr5dxBPMbErA++ZpiQ=; b=kbtCm5nLEFe6+ypDi8p14Dtwr/Y4ctLEWLXq2Xnox265hLBbrMd51WlI/JVd/HRokl i8q4zKp70GrwX1LjDVFfsiCHOMAVVkHlp+Kxts2fI78pGjMBN0qFb3fdhE88PfaA8MxQ fq9goCvI/P7T79pbkZPSRISuLElxkp0iXd1eW3I1oyczj7oPPKN55/9a1ICllr1zgu5p t5y7AEDKhv/B8/bGum1Q/0HCNpHLHy1CzVEiGGqxEJx+BRVzOeYJXPlk2dfySWqlU2Tj EXOZGVa+W5kh7FGVzBuPgZ8vxXC0ObMG9SSWSriOH2jfqWiRp+JB51earprbehG/mATb aqwQ== X-Gm-Message-State: AO0yUKVUdxnJgp4o9cgCJF8pUnkU5OIxKa6BqWQF8x9h8d68mdoPYgmm a68klQhBQPjIWyoSr8fG8FoQXz4f0dj2U2KLAkh0FTcWWtqWc7DO2eMj3Qx/fRPeUfOVGwq9rdt inELu6UKCNl8ie4ctnToVIvajtoeuWjUkBiNwK5l4LW9J7S7JD+BszA== X-Google-Smtp-Source: AK7set9daD/UTdoiY36srGAEoCh/G9GbxZfRMDc4PLs5bYPJZ3AQ2mhOpF7S6VzkCI5uTZ2aAO8IWG8= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a05:6a00:1a8e:b0:61c:67d2:a332 with SMTP id e14-20020a056a001a8e00b0061c67d2a332mr2165833pfv.3.1679099027250; Fri, 17 Mar 2023 17:23:47 -0700 (PDT) Date: Fri, 17 Mar 2023 17:23:39 -0700 In-Reply-To: <20230318002340.1306356-1-sdf@google.com> Mime-Version: 1.0 References: <20230318002340.1306356-1-sdf@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Message-ID: <20230318002340.1306356-4-sdf@google.com> Subject: [PATCH net-next 3/4] ynl: replace print with NlError From: Stanislav Fomichev To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, Stanislav Fomichev Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Instead of dumping the error on the stdout, make the callee and opportunity to decide what to do with it. This is mostly for the ethtool testing. Signed-off-by: Stanislav Fomichev --- tools/net/ynl/lib/ynl.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py index 21c015911803..6c1a59cef957 100644 --- a/tools/net/ynl/lib/ynl.py +++ b/tools/net/ynl/lib/ynl.py @@ -67,6 +67,13 @@ from .nlspec import SpecFamily NLMSGERR_ATTR_MISS_NEST = 6 +class NlError(Exception): + def __init__(self, nl_msg): + self.nl_msg = nl_msg + + def __str__(self): + return f"Netlink error: {os.strerror(-self.nl_msg.error)}\n{self.nl_msg}" + class NlAttr: def __init__(self, raw, offset): self._len, self._type = struct.unpack("HH", raw[offset:offset + 4]) @@ -495,9 +502,7 @@ genl_family_name_to_id = None self._decode_extack(msg, op.attr_set, nl_msg.extack) if nl_msg.error: - print("Netlink error:", os.strerror(-nl_msg.error)) - print(nl_msg) - return + raise NlError(nl_msg) if nl_msg.done: if nl_msg.extack: print("Netlink warning:") From patchwork Sat Mar 18 00:23:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Fomichev X-Patchwork-Id: 13179638 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 280A2C74A5B for ; Sat, 18 Mar 2023 00:23:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229970AbjCRAXz (ORCPT ); Fri, 17 Mar 2023 20:23:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51152 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229987AbjCRAXw (ORCPT ); Fri, 17 Mar 2023 20:23:52 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0867FE2761 for ; Fri, 17 Mar 2023 17:23:49 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id d5-20020a17090a7bc500b0023d3366e005so2908848pjl.6 for ; Fri, 17 Mar 2023 17:23:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679099029; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=hg8RNxe/1g875izj8dZ3PN99hAkP2LB4x/c6P39U0ho=; b=sZ4OQN7F6Rv/Nu7UdFl8iLQxXhh6hUPOxHXyiUTFLtgRXjZeT28gR2H/wneGLSpfF4 nbUN/9VMJFVWnnw465yAtawBc6kWA2CSM2KRl0FpOugaoMANqQIFgfvSGmh4IWw8vNd4 gxnZK4sqzVN/u2jA6DUgJ+oux79pbLvUe4Juq/oxtL8uRe5RhlISllu4Hn8hljKFyXhd SkZkHe+hmtmg4maiqqtP7eRmqalIP92hcnuy1FdTfxl1239dbVD4h9Xf3EoN5eFZIwQb r2r9FvSpBP+EXT6esRfaJDbmvOKWbBFyE6XLNWl36KzGqwq3UX61+Wy8FgW2GMtH0kYm CdfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679099029; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=hg8RNxe/1g875izj8dZ3PN99hAkP2LB4x/c6P39U0ho=; b=KmUXwNYNLfURNs29sAaYX6dES1TAQ4aVbwKedk2ZiPqPSOFp2V4f0DWTEnzv15bRgb oaPkjHiZt7qZSCW90xcAA5vwSF9E/h0OdJzJlhaXHbJ8SaxvhUlOpg6FJH17YXYKMvVZ +9kXaCkxZbZMf2s+BbIVs5aKabKS9UWDje0ZdRdd4xqd4UQqiP1m5Fgz68L28GiUQ7/l 8quMqKsRIdknKjBC6qRcHaPwTG0ZMfVwi5p6uaWqM2gZYC9LU5nn5Fz0fz/AB1ICpRzJ egal6gmKfMSBl4wN8gi/ns4rjRl4tOZJ3qpYTj6u3AtL52YdWMirdrJlpQTn+oR9iYQE i6OQ== X-Gm-Message-State: AO0yUKVkVDL2R1Q8l+kv/mSCPpmt2EiwQVGlMRomQbJrYQhLfYhsPca6 OFf1BQ1jKAMUvhlEJIY/1/q2qcao+9QV+zwk1DdXqrjXAOG1kU9jLiv9fKdSjGBtiy1Ou/Fn32F EWD7VhboiAlOjXDiPspgHBQRkE4TlpJpboC55QOhqrAGl3FOsagnmQA== X-Google-Smtp-Source: AK7set+BbilQ4ms0qn0FgXaaDJLX6+fYFxTb9kY34rM383gnv/4U4hNXzghghS9XBfroD6yMekw07iU= X-Received: from sdf.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5935]) (user=sdf job=sendgmr) by 2002:a65:52c8:0:b0:503:7bcd:89e9 with SMTP id z8-20020a6552c8000000b005037bcd89e9mr50910pgp.1.1679099029124; Fri, 17 Mar 2023 17:23:49 -0700 (PDT) Date: Fri, 17 Mar 2023 17:23:40 -0700 In-Reply-To: <20230318002340.1306356-1-sdf@google.com> Mime-Version: 1.0 References: <20230318002340.1306356-1-sdf@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Message-ID: <20230318002340.1306356-5-sdf@google.com> Subject: [PATCH net-next 4/4] ynl: ethtool testing tool From: Stanislav Fomichev To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, Stanislav Fomichev Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This is what I've been using to see whether the spec makes sense. A small subset of getters (mostly the unprivileged ones) is implemented. Some setters (channels) also work. Setters for messages with bitmasks are not implemented. Initially I was trying to make this tool look 1:1 like real ethtool, but eventually gave up :-) Sample output: $ ethtool enp0s31f6 Settings for enp0s31f6: Supported ports: [ TP ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Supported pause frame use: No Supports auto-negotiation: Yes Supported FEC modes: Not reported Advertised link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Advertised pause frame use: No Advertised auto-negotiation: Yes Advertised FEC modes: Not reported Speed: Unknown! Duplex: Unknown! (255) Auto-negotiation: on Port: Twisted Pair PHYAD: 2 Transceiver: internal MDI-X: Unknown (auto) netlink error: Operation not permitted Current message level: 0x00000007 (7) drv probe link Link detected: no Signed-off-by: Stanislav Fomichev --- tools/net/ynl/ethtool | 424 ++++++++++++++++++++++++++++++++++++ tools/net/ynl/lib/nlspec.py | 9 + tools/net/ynl/lib/ynl.py | 13 ++ 3 files changed, 446 insertions(+) create mode 100755 tools/net/ynl/ethtool diff --git a/tools/net/ynl/ethtool b/tools/net/ynl/ethtool new file mode 100755 index 000000000000..7454fd3653e5 --- /dev/null +++ b/tools/net/ynl/ethtool @@ -0,0 +1,424 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +import argparse +import json +import pprint +import sys +import re + +from lib import YnlFamily + +def args_to_req(ynl, op_name, args, req): + """ + Verify and convert command-line arguments to the ynl-compatible request. + """ + valid_attrs = ynl.operation_do_attributes(op_name) + + if len(args) == 0: + print(f'no attributes, expected: {valid_attrs}') + sys.exit(1) + + i = 0 + while i < len(args): + attr = args[i] + if i + 1 >= len(args): + print(f'expected value for \'{attr}\'') + sys.exit(1) + + if attr not in valid_attrs: + print(f'invalid attribute \'{attr}\', expected: {valid_attrs}') + sys.exit(1) + + val = args[i+1] + i += 2 + + req[attr] = val + +def print_field(reply, *desc): + """ + Pretty-print a set of fields from the reply. desc specifies the + fields and the optional type (bool/yn). + """ + if len(desc) == 0: + return print_field(reply, *zip(reply.keys(), reply.keys())) + + for spec in desc: + try: + field, name, tp = spec + except: + field, name = spec + tp = 'int' + + value = reply.get(field, None) + if tp == 'yn': + value = 'yes' if value else 'no' + elif tp == 'bool' or isinstance(value, bool): + value = 'on' if value else 'off' + else: + value = 'n/a' if value is None else value + + print(f'{name}: {value}') + +def print_speed(name, value): + """ + Print out the speed-like strings from the value dict. + """ + speed_re = re.compile(r'[0-9]+base[^/]+/.+') + speed = [ k for k, v in value.items() if v and speed_re.match(k) ] + print(f'{name}: {" ".join(speed)}') + +def doit(ynl, args, op_name): + """ + Prepare request header, parse arguments and doit. + """ + req = { + 'header': { + 'dev-name': args.device, + }, + } + + args_to_req(ynl, op_name, args.args, req) + ynl.do(op_name, req) + +def dumpit(ynl, args, op_name, extra = {}): + """ + Prepare request header, parse arguments and dumpit (filtering out the + devices we're not interested in). + """ + reply = ynl.dump(op_name, { 'header': {} } | extra) + if not reply: + return {} + + for msg in reply: + if msg['header']['dev-name'] == args.device: + if args.json: + pprint.PrettyPrinter().pprint(msg) + sys.exit(1) + msg.pop('header', None) + return msg + + print(f"Not supported for device {args.device}") + sys.exit(1) + +def bits_to_dict(attr): + """ + Convert ynl-formatted bitmask to a dict of bit=value. + """ + ret = {} + if 'bits' not in attr: + return dict() + if 'bit' not in attr['bits']: + return dict() + for bit in attr['bits']['bit']: + if bit['name'] == '': + continue + name = bit['name'] + value = bit.get('value', False) + ret[name] = value + return ret + +def main(): + parser = argparse.ArgumentParser(description='ethtool wannabe') + parser.add_argument('--json', action=argparse.BooleanOptionalAction) + parser.add_argument('--show-priv-flags', action=argparse.BooleanOptionalAction) + parser.add_argument('--set-priv-flags', action=argparse.BooleanOptionalAction) + parser.add_argument('--show-eee', action=argparse.BooleanOptionalAction) + parser.add_argument('--set-eee', action=argparse.BooleanOptionalAction) + parser.add_argument('-a', '--show-pause', action=argparse.BooleanOptionalAction) + parser.add_argument('-A', '--set-pause', action=argparse.BooleanOptionalAction) + parser.add_argument('-c', '--show-coalesce', action=argparse.BooleanOptionalAction) + parser.add_argument('-C', '--set-coalesce', action=argparse.BooleanOptionalAction) + parser.add_argument('-g', '--show-ring', action=argparse.BooleanOptionalAction) + parser.add_argument('-G', '--set-ring', action=argparse.BooleanOptionalAction) + parser.add_argument('-k', '--show-features', action=argparse.BooleanOptionalAction) + parser.add_argument('-K', '--set-features', action=argparse.BooleanOptionalAction) + parser.add_argument('-l', '--show-channels', action=argparse.BooleanOptionalAction) + parser.add_argument('-L', '--set-channels', action=argparse.BooleanOptionalAction) + parser.add_argument('-T', '--show-time-stamping', action=argparse.BooleanOptionalAction) + parser.add_argument('-S', '--statistics', action=argparse.BooleanOptionalAction) + # TODO: --show-tunnels tunnel-info-get + # TODO: --show-module module-get + # TODO: --get-plca-cfg plca-get + # TODO: --get-plca-status plca-get-status + # TODO: --show-mm mm-get + # TODO: --show-fec fec-get + # TODO: --dump-module-eerpom module-eeprom-get + # TODO: pse-get + # TODO: rss-get + parser.add_argument('device', metavar='device', type=str) + parser.add_argument('args', metavar='args', type=str, nargs='*') + global args + args = parser.parse_args() + + spec = '/usr/local/google/home/sdf/src/linux/Documentation/netlink/specs/ethtool.yaml' + schema = '/usr/local/google/home/sdf/src/linux/Documentation/netlink/genetlink-legacy.yaml' + + ynl = YnlFamily(spec, schema) + + if args.set_priv_flags: + # TODO: parse the bitmask + print("not implemented") + return + + if args.set_eee: + return doit(ynl, args, 'eee-set') + + if args.set_pause: + return doit(ynl, args, 'pause-set') + + if args.set_coalesce: + return doit(ynl, args, 'coalesce-set') + + if args.set_features: + # TODO: parse the bitmask + print("not implemented") + return + + if args.set_channels: + return doit(ynl, args, 'channels-set') + + if args.set_ring: + return doit(ynl, args, 'rings-set') + + if args.show_priv_flags: + flags = bits_to_dict(dumpit(ynl, args, 'privflags-get')['flags']) + print_field(flags) + return + + if args.show_eee: + eee = dumpit(ynl, args, 'eee-get') + ours = bits_to_dict(eee['modes-ours']) + peer = bits_to_dict(eee['modes-peer']) + + if 'enabled' in eee: + status = 'enabled' if eee['enabled'] else 'disabled' + if 'active' in eee and eee['active']: + status = status + ' - active' + else: + status = status + ' - inactive' + else: + status = 'not supported' + + print(f'EEE status: {status}') + print_field(eee, ('tx-lpi-timer', 'Tx LPI')) + print_speed('Advertised EEE link modes', ours) + print_speed('Link partner advertised EEE link modes', peer) + + return + + if args.show_pause: + print_field(dumpit(ynl, args, 'pause-get'), + ('autoneg', 'Autonegotiate', 'bool'), + ('rx', 'RX', 'bool'), + ('tx', 'TX', 'bool')) + return + + if args.show_coalesce: + print_field(dumpit(ynl, args, 'coalesce-get')) + return + + if args.show_features: + reply = dumpit(ynl, args, 'features-get') + available = bits_to_dict(reply['hw']) + requested = bits_to_dict(reply['wanted']).keys() + active = bits_to_dict(reply['active']).keys() + never_changed = bits_to_dict(reply['nochange']).keys() + pprint.PrettyPrinter().pprint(reply) + + for f in sorted(available): + value = "off" + if f in active: + value = "on" + + fixed = "" + if f not in available or f in never_changed: + fixed = " [fixed]" + + req = "" + if f in requested: + if f in active: + req = " [requested on]" + else: + req = " [requested off]" + + print(f'{f}: {value}{fixed}{req}') + + return + + if args.show_channels: + reply = dumpit(ynl, args, 'channels-get') + print(f'Channel parameters for {args.device}:') + + print(f'Pre-set maximums:') + print_field(reply, + ('rx-max', 'RX'), + ('tx-max', 'TX'), + ('other-max', 'Other'), + ('combined-max', 'Combined')) + + print(f'Current hardware settings:') + print_field(reply, + ('rx-count', 'RX'), + ('tx-count', 'TX'), + ('other-count', 'Other'), + ('combined-count', 'Combined')) + + return + + if args.show_ring: + reply = dumpit(ynl, args, 'channels-get') + + print(f'Ring parameters for {args.device}:') + + print(f'Pre-set maximums:') + print_field(reply, + ('rx-max', 'RX'), + ('rx-mini-max', 'RX Mini'), + ('rx-jumbo-max', 'RX Jumbo'), + ('tx-max', 'TX')) + + print(f'Current hardware settings:') + print_field(reply, + ('rx', 'RX'), + ('rx-mini', 'RX Mini'), + ('rx-jumbo', 'RX Jumbo'), + ('tx', 'TX')) + + print_field(reply, + ('rx-buf-len', 'RX Buf Len'), + ('cqe-size', 'CQE Size'), + ('tx-push', 'TX Push', 'bool')) + + return + + if args.statistics: + print(f'NIC statistics:') + + # TODO: pass id? + strset = dumpit(ynl, args, 'strset-get') + pprint.PrettyPrinter().pprint(strset) + + req = { + 'groups': { + 'size': 1, + 'bits': { + 'bit': + # TODO: support passing the bitmask + #[ + #{ 'name': 'eth-phy', 'value': True }, + { 'name': 'eth-mac', 'value': True }, + #{ 'name': 'eth-ctrl', 'value': True }, + #{ 'name': 'rmon', 'value': True }, + #], + }, + }, + } + + rsp = dumpit(ynl, args, 'stats-get', req) + pprint.PrettyPrinter().pprint(rsp) + return + + if args.show_time_stamping: + tsinfo = dumpit(ynl, args, 'tsinfo-get') + + print(f'Time stamping parameters for {args.device}:') + + print('Capabilities:') + [print(f'\t{v}') for v in bits_to_dict(tsinfo['timestamping'])] + + print(f'PTP Hardware Clock: {tsinfo["phc-index"]}') + + print('Hardware Transmit Timestamp Modes:') + [print(f'\t{v}') for v in bits_to_dict(tsinfo['tx-types'])] + + print('Hardware Receive Filter Modes:') + [print(f'\t{v}') for v in bits_to_dict(tsinfo['rx-filters'])] + return + + print(f'Settings for {args.device}:') + linkmodes = dumpit(ynl, args, 'linkmodes-get') + ours = bits_to_dict(linkmodes['ours']) + + supported_ports = ('TP', 'AUI', 'BNC', 'MII', 'FIBRE', 'Backplane') + ports = [ p for p in supported_ports if ours.get(p, False)] + print(f'Supported ports: [ {" ".join(ports)} ]') + + print_speed('Supported link modes', ours) + + print_field(ours, ('Pause', 'Supported pause frame use', 'yn')) + print_field(ours, ('Autoneg', 'Supports auto-negotiation', 'yn')) + + supported_fec = ('None', 'PS', 'BASER', 'LLRS') + fec = [ p for p in supported_fec if ours.get(p, False)] + fec_str = " ".join(fec) + if len(fec) == 0: + fec_str = "Not reported" + + print(f'Supported FEC modes: {fec_str}') + + speed = 'Unknown!' + if linkmodes['speed'] > 0 and linkmodes['speed'] < 0xffffffff: + speed = f'{linkmodes["speed"]}Mb/s' + print(f'Speed: {speed}') + + duplex_modes = { + 0: 'Half', + 1: 'Full', + } + duplex = duplex_modes.get(linkmodes["duplex"], None) + if not duplex: + duplex = f'Unknown! ({linkmodes["duplex"]})' + print(f'Duplex: {duplex}') + + autoneg = "off" + if linkmodes.get("autoneg", 0) != 0: + autoneg = "on" + print(f'Auto-negotiation: {autoneg}') + + ports = { + 0: 'Twisted Pair', + 1: 'AUI', + 2: 'MII', + 3: 'FIBRE', + 4: 'BNC', + 5: 'Directly Attached Copper', + 0xef: 'None', + } + linkinfo = dumpit(ynl, args, 'linkinfo-get') + print(f'Port: {ports.get(linkinfo["port"], "Other")}') + + print_field(linkinfo, ('phyaddr', 'PHYAD')) + + transceiver = { + 0: 'Internal', + 1: 'External', + } + print(f'Transceiver: {transceiver.get(linkinfo["transceiver"], "Unknown")}') + + mdix_ctrl = { + 1: 'off', + 2: 'on', + } + mdix = mdix_ctrl.get(linkinfo['tp_mdix_ctrl'], None) + if mdix: + mdix = mdix + ' (forced)' + else: + mdix = mdix_ctrl.get(linkinfo['tp_mdix'], 'Unknown (auto)') + print(f'MDI-X: {mdix}') + + debug = dumpit(ynl, args, 'debug-get') + msgmask = bits_to_dict(debug.get("msgmask", [])).keys() + print(f'Current message level: {" ".join(msgmask)}') + + linkstate = dumpit(ynl, args, 'linkstate-get') + detected_states = { + 0: 'no', + 1: 'yes', + } + # TODO: wol-get + detected = detected_states.get(linkstate['link'], 'unknown') + print(f'Link detected: {detected}') + +if __name__ == '__main__': + main() diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py index d04450c2a44a..174690fccfcd 100644 --- a/tools/net/ynl/lib/nlspec.py +++ b/tools/net/ynl/lib/nlspec.py @@ -392,6 +392,15 @@ jsonschema = None self.msgs[op.name] = op + def find_operation(self, name): + """ + For a given operation name, find and return operation spec. + """ + for op in self.yaml['operations']['list']: + if name == op['name']: + return op + return None + def resolve(self): self.resolve_up(super()) diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py index 6c1a59cef957..2562e2cd4768 100644 --- a/tools/net/ynl/lib/ynl.py +++ b/tools/net/ynl/lib/ynl.py @@ -477,6 +477,19 @@ genl_family_name_to_id = None self.handle_ntf(nl_msg, gm) + def operation_do_attributes(self, name): + """ + For a given operation name, find and return a supported + set of attributes (as a dict). + """ + op = self.find_operation(name) + if not op: + return None + + attrs = op['do']['request']['attributes'].copy() + attrs.remove('header') # not user-provided + return attrs + def _op(self, method, vals, dump=False): op = self.ops[method]