Commit e8a6c515 authored by Jiri Pirko's avatar Jiri Pirko Committed by Jakub Kicinski

tools: ynl: allow user to pass enum string instead of scalar value

During decoding of messages coming from kernel, attribute values are
converted to enum names in case the attribute type is enum of bitfield32.

However, when user constructs json message, he has to pass plain scalar
values. See "state" "selector" and "value" attributes in following
examples:

$ sudo ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/dpll.yaml --do pin-set --json '{"id": 0, "parent-device": {"parent-id": 0, "state": 1}}'
$ sudo ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/devlink.yaml --do port-set --json '{"bus-name": "pci", "dev-name": "0000:08:00.1", "port-index": 98304, "port-function": {"caps": {"selector": 1, "value": 1 }}}'

Allow user to pass strings containing enum names, convert them to scalar
values to be encoded into Netlink message:

$ sudo ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/dpll.yaml --do pin-set --json '{"id": 0, "parent-device": {"parent-id": 0, "state": "connected"}}'
$ sudo ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/devlink.yaml --do port-set --json '{"bus-name": "pci", "dev-name": "0000:08:00.1", "port-index": 98304, "port-function": {"caps": {"selector": ["roce-bit"], "value": ["roce-bit"] }}}'
Signed-off-by: default avatarJiri Pirko <jiri@nvidia.com>
Reviewed-by: default avatarDonald Hunter <donald.hunter@gmail.com>
Link: https://lore.kernel.org/r/20240222134351.224704-4-jiri@resnulli.usSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ffe10a45
...@@ -438,6 +438,26 @@ class YnlFamily(SpecFamily): ...@@ -438,6 +438,26 @@ class YnlFamily(SpecFamily):
self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_ADD_MEMBERSHIP, self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_ADD_MEMBERSHIP,
mcast_id) mcast_id)
def _encode_enum(self, attr_spec, value):
enum = self.consts[attr_spec['enum']]
if enum.type == 'flags' or attr_spec.get('enum-as-flags', False):
scalar = 0
if isinstance(value, str):
value = [value]
for single_value in value:
scalar += enum.entries[single_value].user_value(as_flags = True)
return scalar
else:
return enum.entries[value].user_value()
def _get_scalar(self, attr_spec, value):
try:
return int(value)
except (ValueError, TypeError) as e:
if 'enum' not in attr_spec:
raise e
return self._encode_enum(attr_spec, value);
def _add_attr(self, space, name, value, search_attrs): def _add_attr(self, space, name, value, search_attrs):
try: try:
attr = self.attr_sets[space][name] attr = self.attr_sets[space][name]
...@@ -475,7 +495,7 @@ class YnlFamily(SpecFamily): ...@@ -475,7 +495,7 @@ class YnlFamily(SpecFamily):
else: else:
raise Exception(f'Unknown type for binary attribute, value: {value}') raise Exception(f'Unknown type for binary attribute, value: {value}')
elif attr['type'] in NlAttr.type_formats or attr.is_auto_scalar: elif attr['type'] in NlAttr.type_formats or attr.is_auto_scalar:
scalar = int(value) scalar = self._get_scalar(attr, value)
if attr.is_auto_scalar: if attr.is_auto_scalar:
attr_type = attr["type"][0] + ('32' if scalar.bit_length() <= 32 else '64') attr_type = attr["type"][0] + ('32' if scalar.bit_length() <= 32 else '64')
else: else:
...@@ -483,7 +503,9 @@ class YnlFamily(SpecFamily): ...@@ -483,7 +503,9 @@ class YnlFamily(SpecFamily):
format = NlAttr.get_format(attr_type, attr.byte_order) format = NlAttr.get_format(attr_type, attr.byte_order)
attr_payload = format.pack(scalar) attr_payload = format.pack(scalar)
elif attr['type'] in "bitfield32": elif attr['type'] in "bitfield32":
attr_payload = struct.pack("II", int(value["value"]), int(value["selector"])) scalar_value = self._get_scalar(attr, value["value"])
scalar_selector = self._get_scalar(attr, value["selector"])
attr_payload = struct.pack("II", scalar_value, scalar_selector)
elif attr['type'] == 'sub-message': elif attr['type'] == 'sub-message':
msg_format = self._resolve_selector(attr, search_attrs) msg_format = self._resolve_selector(attr, search_attrs)
attr_payload = b'' attr_payload = b''
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment