* [PATCH net-next 0/4] ynl: fill in some gaps of ethtool spec
@ 2023-03-18 0:23 Stanislav Fomichev
2023-03-18 0:23 ` [PATCH net-next 1/4] ynl: support be16 in schemas Stanislav Fomichev
` (3 more replies)
0 siblings, 4 replies; 16+ messages in thread
From: Stanislav Fomichev @ 2023-03-18 0:23 UTC (permalink / raw)
To: netdev; +Cc: davem, edumazet, kuba, pabeni, Stanislav Fomichev
I was trying to fill in the spec while exploring ethtool API for some
related work. I don't think I'll have the patience to fill in the rest,
so decided to share whatever I currently have.
Patches 1-2 add the be16 + spec.
Patches 3-4 implement an ethtool-like python tool to test the spec.
Patches 3-4 are there because it felt more fun do the tool instead
of writing the actual tests; feel free to drop it; sharing mostly
to show that the spec is not a complete nonsense.
The spec is not 100% complete, see patch 2 for what's missing.
I was hoping to finish the stats-get message, but I'm too dump
to implement bitmask marshaling (multi-attr).
Stanislav Fomichev (4):
ynl: support be16 in schemas
ynl: populate most of the ethtool spec
ynl: replace print with NlError
ynl: ethtool testing tool
Documentation/netlink/genetlink-c.yaml | 2 +-
Documentation/netlink/genetlink-legacy.yaml | 4 +-
Documentation/netlink/genetlink.yaml | 2 +-
Documentation/netlink/specs/ethtool.yaml | 1473 +++++++++++++++++--
tools/net/ynl/ethtool | 424 ++++++
tools/net/ynl/lib/nlspec.py | 9 +
tools/net/ynl/lib/ynl.py | 31 +-
7 files changed, 1827 insertions(+), 118 deletions(-)
create mode 100755 tools/net/ynl/ethtool
--
2.40.0.rc1.284.g88254d51c5-goog
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH net-next 1/4] ynl: support be16 in schemas 2023-03-18 0:23 [PATCH net-next 0/4] ynl: fill in some gaps of ethtool spec Stanislav Fomichev @ 2023-03-18 0:23 ` Stanislav Fomichev 2023-03-18 4:18 ` Jakub Kicinski 2023-03-18 0:23 ` [PATCH net-next 2/4] ynl: populate most of the ethtool spec Stanislav Fomichev ` (2 subsequent siblings) 3 siblings, 1 reply; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-18 0:23 UTC (permalink / raw) To: netdev; +Cc: davem, edumazet, kuba, pabeni, Stanislav Fomichev Used by ethtool spec. Signed-off-by: Stanislav Fomichev <sdf@google.com> --- 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': -- 2.40.0.rc1.284.g88254d51c5-goog ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 1/4] ynl: support be16 in schemas 2023-03-18 0:23 ` [PATCH net-next 1/4] ynl: support be16 in schemas Stanislav Fomichev @ 2023-03-18 4:18 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 0 siblings, 1 reply; 16+ messages in thread From: Jakub Kicinski @ 2023-03-18 4:18 UTC (permalink / raw) To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, pabeni On Fri, 17 Mar 2023 17:23:37 -0700 Stanislav Fomichev wrote: > ynl: support be16 in schemas https://docs.kernel.org/next/userspace-api/netlink/specs.html#byte-order byte-order: big-endian Looks like it's slightly supported in ynl-gen-c but indeed the CLI lib doesn't have the parsing, yet. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 1/4] ynl: support be16 in schemas 2023-03-18 4:18 ` Jakub Kicinski @ 2023-03-20 18:03 ` Stanislav Fomichev 0 siblings, 0 replies; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-20 18:03 UTC (permalink / raw) To: Jakub Kicinski; +Cc: netdev, davem, edumazet, pabeni On Fri, Mar 17, 2023 at 9:18 PM Jakub Kicinski <kuba@kernel.org> wrote: > > On Fri, 17 Mar 2023 17:23:37 -0700 Stanislav Fomichev wrote: > > ynl: support be16 in schemas > > https://docs.kernel.org/next/userspace-api/netlink/specs.html#byte-order > > byte-order: big-endian > > Looks like it's slightly supported in ynl-gen-c but indeed the CLI > lib doesn't have the parsing, yet. Didn't know about this, will try to convert. ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net-next 2/4] ynl: populate most of the ethtool spec 2023-03-18 0:23 [PATCH net-next 0/4] ynl: fill in some gaps of ethtool spec Stanislav Fomichev 2023-03-18 0:23 ` [PATCH net-next 1/4] ynl: support be16 in schemas Stanislav Fomichev @ 2023-03-18 0:23 ` Stanislav Fomichev 2023-03-18 4:33 ` Jakub Kicinski 2023-03-18 0:23 ` [PATCH net-next 3/4] ynl: replace print with NlError Stanislav Fomichev 2023-03-18 0:23 ` [PATCH net-next 4/4] ynl: ethtool testing tool Stanislav Fomichev 3 siblings, 1 reply; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-18 0:23 UTC (permalink / raw) To: netdev; +Cc: davem, edumazet, kuba, pabeni, Stanislav Fomichev 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 <sdf@google.com> --- 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 -- 2.40.0.rc1.284.g88254d51c5-goog ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/4] ynl: populate most of the ethtool spec 2023-03-18 0:23 ` [PATCH net-next 2/4] ynl: populate most of the ethtool spec Stanislav Fomichev @ 2023-03-18 4:33 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 0 siblings, 1 reply; 16+ messages in thread From: Jakub Kicinski @ 2023-03-18 4:33 UTC (permalink / raw) To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, pabeni On Fri, 17 Mar 2023 17:23:38 -0700 Stanislav Fomichev wrote: > 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 Hm. What kind of nonsense? > - notifications are not tested > - features-nft has hard-coded value:13, not sure why it skews ETHTOOL_MSG_FEATURES_SET_REPLY exists but there is no reply: section in the spec. > Signed-off-by: Stanislav Fomichev <sdf@google.com> > --- > 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 ] s/_/-/ everywhere > + > 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 missing - before this line? the u64-array and s32-array should be separate? > + attributes: > + - > + name: s32 > + type: nest > + multi-attr: true > + nested-attributes: s32 > - > name: string > attributes: > + - > + 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 reply: here. Not sure if it needs an empty attributes: or not. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/4] ynl: populate most of the ethtool spec 2023-03-18 4:33 ` Jakub Kicinski @ 2023-03-20 18:03 ` Stanislav Fomichev 2023-03-20 18:59 ` Jakub Kicinski 0 siblings, 1 reply; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-20 18:03 UTC (permalink / raw) To: Jakub Kicinski; +Cc: netdev, davem, edumazet, pabeni " On Fri, Mar 17, 2023 at 9:33 PM Jakub Kicinski <kuba@kernel.org> wrote: > > On Fri, 17 Mar 2023 17:23:38 -0700 Stanislav Fomichev wrote: > > 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 > > Hm. What kind of nonsense? {'grp': {'id': 1, 'ss-id': 18}} But I guess that's because I'm not passing the group bitmask correctly? > > - notifications are not tested > > - features-nft has hard-coded value:13, not sure why it skews > > ETHTOOL_MSG_FEATURES_SET_REPLY exists but there is no reply: > section in the spec. Ah, good catch, I guess something like this would do? It doesn't have to be a new empty msg? reply: attributes: *feature > > Signed-off-by: Stanislav Fomichev <sdf@google.com> > > --- > > 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 ] > > s/_/-/ everywhere > > > + > > 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 > > missing > > - > > before this line? the u64-array and s32-array should be separate? Right. I guess the fact that I've never exercised "phc-vclocks-get" shows :-/ > > + attributes: > > + - > > + name: s32 > > + type: nest > > + multi-attr: true > > + nested-attributes: s32 > > - > > name: string > > attributes: > > > + - > > + 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 > > reply: > > here. Not sure if it needs an empty attributes: or not. > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 2/4] ynl: populate most of the ethtool spec 2023-03-20 18:03 ` Stanislav Fomichev @ 2023-03-20 18:59 ` Jakub Kicinski 0 siblings, 0 replies; 16+ messages in thread From: Jakub Kicinski @ 2023-03-20 18:59 UTC (permalink / raw) To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, pabeni On Mon, 20 Mar 2023 11:03:33 -0700 Stanislav Fomichev wrote: > On Fri, Mar 17, 2023 at 9:33 PM Jakub Kicinski <kuba@kernel.org> wrote: > > On Fri, 17 Mar 2023 17:23:38 -0700 Stanislav Fomichev wrote: > > > 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 > > > > Hm. What kind of nonsense? > > {'grp': {'id': 1, 'ss-id': 18}} > > But I guess that's because I'm not passing the group bitmask correctly? Hm, or the driver you're trying does not have any _structured_ stats? Does ethtool -S \* --all-groups show anything? Note that these are not all the old ethtool -S stats. > > > - notifications are not tested > > > - features-nft has hard-coded value:13, not sure why it skews > > > > ETHTOOL_MSG_FEATURES_SET_REPLY exists but there is no reply: > > section in the spec. > > Ah, good catch, I guess something like this would do? It doesn't have > to be a new empty msg? > reply: > attributes: *feature Oh right, there's an actual reply to features. I thought it was just reserved but we need to return to the user space what we managed to set and what we didn't. Makes sense. ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net-next 3/4] ynl: replace print with NlError 2023-03-18 0:23 [PATCH net-next 0/4] ynl: fill in some gaps of ethtool spec Stanislav Fomichev 2023-03-18 0:23 ` [PATCH net-next 1/4] ynl: support be16 in schemas Stanislav Fomichev 2023-03-18 0:23 ` [PATCH net-next 2/4] ynl: populate most of the ethtool spec Stanislav Fomichev @ 2023-03-18 0:23 ` Stanislav Fomichev 2023-03-18 4:21 ` Jakub Kicinski 2023-03-18 0:23 ` [PATCH net-next 4/4] ynl: ethtool testing tool Stanislav Fomichev 3 siblings, 1 reply; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-18 0:23 UTC (permalink / raw) To: netdev; +Cc: davem, edumazet, kuba, pabeni, Stanislav Fomichev 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 <sdf@google.com> --- 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:") -- 2.40.0.rc1.284.g88254d51c5-goog ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 3/4] ynl: replace print with NlError 2023-03-18 0:23 ` [PATCH net-next 3/4] ynl: replace print with NlError Stanislav Fomichev @ 2023-03-18 4:21 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 0 siblings, 1 reply; 16+ messages in thread From: Jakub Kicinski @ 2023-03-18 4:21 UTC (permalink / raw) To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, pabeni On Fri, 17 Mar 2023 17:23:39 -0700 Stanislav Fomichev wrote: > 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. > 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): Why not __repr__ ? > + return f"Netlink error: {os.strerror(-self.nl_msg.error)}\n{self.nl_msg}" > + nit: double new line here > 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:") ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 3/4] ynl: replace print with NlError 2023-03-18 4:21 ` Jakub Kicinski @ 2023-03-20 18:03 ` Stanislav Fomichev 2023-03-20 18:53 ` Jakub Kicinski 0 siblings, 1 reply; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-20 18:03 UTC (permalink / raw) To: Jakub Kicinski; +Cc: netdev, davem, edumazet, pabeni On Fri, Mar 17, 2023 at 9:21 PM Jakub Kicinski <kuba@kernel.org> wrote: > > On Fri, 17 Mar 2023 17:23:39 -0700 Stanislav Fomichev wrote: > > 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. > > > 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): > > Why not __repr__ ? The following: class A(Exception): def __repr__(self): return "{{{A}}}" def __str__(self): return "{{{B}}}" raise A Gets me this: $ python3 tmp.py Traceback (most recent call last): File "/usr/local/google/home/sdf/tmp/tmp.py", line 9, in <module> raise A __main__.A: {{{B}}} And for this: class A(Exception): def __repr__(self): return "{{{A}}}" raise A I see: $ python3 tmp.py Traceback (most recent call last): File "/usr/local/google/home/sdf/tmp/tmp.py", line 7, in <module> raise A __main__.A It seems that __repr__ is mostly for repr()? And the rest is using __str__? My pythonic powers are weak, can convert to __repr__ if you prefer (or understand the difference). > > + return f"Netlink error: {os.strerror(-self.nl_msg.error)}\n{self.nl_msg}" > > + > > nit: double new line here > > > 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:") > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 3/4] ynl: replace print with NlError 2023-03-20 18:03 ` Stanislav Fomichev @ 2023-03-20 18:53 ` Jakub Kicinski 0 siblings, 0 replies; 16+ messages in thread From: Jakub Kicinski @ 2023-03-20 18:53 UTC (permalink / raw) To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, pabeni On Mon, 20 Mar 2023 11:03:24 -0700 Stanislav Fomichev wrote: > It seems that __repr__ is mostly for repr()? And the rest is using > __str__? My pythonic powers are weak, can convert to __repr__ if you > prefer (or understand the difference). I used to know but I forgot. Let's leave it be unless someone chimes in and tells us.. ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net-next 4/4] ynl: ethtool testing tool 2023-03-18 0:23 [PATCH net-next 0/4] ynl: fill in some gaps of ethtool spec Stanislav Fomichev ` (2 preceding siblings ...) 2023-03-18 0:23 ` [PATCH net-next 3/4] ynl: replace print with NlError Stanislav Fomichev @ 2023-03-18 0:23 ` Stanislav Fomichev 2023-03-18 4:23 ` Jakub Kicinski 2023-03-18 4:24 ` Jakub Kicinski 3 siblings, 2 replies; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-18 0:23 UTC (permalink / raw) To: netdev; +Cc: davem, edumazet, kuba, pabeni, Stanislav Fomichev 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 <sdf@google.com> --- 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] -- 2.40.0.rc1.284.g88254d51c5-goog ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 4/4] ynl: ethtool testing tool 2023-03-18 0:23 ` [PATCH net-next 4/4] ynl: ethtool testing tool Stanislav Fomichev @ 2023-03-18 4:23 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 2023-03-18 4:24 ` Jakub Kicinski 1 sibling, 1 reply; 16+ messages in thread From: Jakub Kicinski @ 2023-03-18 4:23 UTC (permalink / raw) To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, pabeni On Fri, 17 Mar 2023 17:23:40 -0700 Stanislav Fomichev wrote: > 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 'header' is ethtool specific tho, right? > + return attrs ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 4/4] ynl: ethtool testing tool 2023-03-18 4:23 ` Jakub Kicinski @ 2023-03-20 18:03 ` Stanislav Fomichev 0 siblings, 0 replies; 16+ messages in thread From: Stanislav Fomichev @ 2023-03-20 18:03 UTC (permalink / raw) To: Jakub Kicinski; +Cc: netdev, davem, edumazet, pabeni On Fri, Mar 17, 2023 at 9:23 PM Jakub Kicinski <kuba@kernel.org> wrote: > > On Fri, 17 Mar 2023 17:23:40 -0700 Stanislav Fomichev wrote: > > 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 > > 'header' is ethtool specific tho, right? Good point, will move to the binary. (but as I mentioned in the cover letter, not sure we need to really put that into the repo, up to you). > > + return attrs ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 4/4] ynl: ethtool testing tool 2023-03-18 0:23 ` [PATCH net-next 4/4] ynl: ethtool testing tool Stanislav Fomichev 2023-03-18 4:23 ` Jakub Kicinski @ 2023-03-18 4:24 ` Jakub Kicinski 1 sibling, 0 replies; 16+ messages in thread From: Jakub Kicinski @ 2023-03-18 4:24 UTC (permalink / raw) To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, pabeni On Fri, 17 Mar 2023 17:23:40 -0700 Stanislav Fomichev wrote: > $ 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 Quite impressive BTW :) ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2023-03-20 19:08 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-03-18 0:23 [PATCH net-next 0/4] ynl: fill in some gaps of ethtool spec Stanislav Fomichev 2023-03-18 0:23 ` [PATCH net-next 1/4] ynl: support be16 in schemas Stanislav Fomichev 2023-03-18 4:18 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 2023-03-18 0:23 ` [PATCH net-next 2/4] ynl: populate most of the ethtool spec Stanislav Fomichev 2023-03-18 4:33 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 2023-03-20 18:59 ` Jakub Kicinski 2023-03-18 0:23 ` [PATCH net-next 3/4] ynl: replace print with NlError Stanislav Fomichev 2023-03-18 4:21 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 2023-03-20 18:53 ` Jakub Kicinski 2023-03-18 0:23 ` [PATCH net-next 4/4] ynl: ethtool testing tool Stanislav Fomichev 2023-03-18 4:23 ` Jakub Kicinski 2023-03-20 18:03 ` Stanislav Fomichev 2023-03-18 4:24 ` Jakub Kicinski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).