summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2024-02-23 18:16:45 -0800
committerJakub Kicinski <kuba@kernel.org>2024-02-23 18:16:46 -0800
commit6511743e01faa2220c758882d250a2217bde8d0b (patch)
treea57efa065dd9a76276dc4778746327aba5f9b93b
parent5c4e0f3ae45e82fa125c5a9c7c25e7df9a6b98ec (diff)
parente8a6c515ff5f52e1ee24397116a05cd4fc1bae99 (diff)
Merge branch 'tools-ynl-couple-of-cmdline-enhancements'
Jiri Pirko says: ==================== tools: ynl: couple of cmdline enhancements This is part of the original "netlink: specs: devlink: add the rest of missing attribute definitions" set which was rejected [1]. These three patches enhances the cmdline user comfort, allowing to pass flag attribute with bool values and enum names instead of scalars. [1] https://lore.kernel.org/all/20240220181004.639af931@kernel.org/ ==================== Link: https://lore.kernel.org/r/20240222134351.224704-1-jiri@resnulli.us Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--tools/net/ynl/lib/ynl.py43
1 files changed, 34 insertions, 9 deletions
diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py
index f45ee5f29bed..ac55aa5a3083 100644
--- a/tools/net/ynl/lib/ynl.py
+++ b/tools/net/ynl/lib/ynl.py
@@ -438,6 +438,26 @@ class YnlFamily(SpecFamily):
self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_ADD_MEMBERSHIP,
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):
try:
attr = self.attr_sets[space][name]
@@ -459,6 +479,9 @@ class YnlFamily(SpecFamily):
attr_payload += self._add_attr(attr['nested-attributes'],
subname, subvalue, sub_attrs)
elif attr["type"] == 'flag':
+ if not value:
+ # If value is absent or false then skip attribute creation.
+ return b''
attr_payload = b''
elif attr["type"] == 'string':
attr_payload = str(value).encode('ascii') + b'\x00'
@@ -471,16 +494,18 @@ class YnlFamily(SpecFamily):
attr_payload = self._encode_struct(attr.struct_name, value)
else:
raise Exception(f'Unknown type for binary attribute, value: {value}')
- elif attr.is_auto_scalar:
- scalar = int(value)
- real_type = attr["type"][0] + ('32' if scalar.bit_length() <= 32 else '64')
- format = NlAttr.get_format(real_type, attr.byte_order)
- attr_payload = format.pack(int(value))
- elif attr['type'] in NlAttr.type_formats:
- format = NlAttr.get_format(attr['type'], attr.byte_order)
- attr_payload = format.pack(int(value))
+ elif attr['type'] in NlAttr.type_formats or attr.is_auto_scalar:
+ scalar = self._get_scalar(attr, value)
+ if attr.is_auto_scalar:
+ attr_type = attr["type"][0] + ('32' if scalar.bit_length() <= 32 else '64')
+ else:
+ attr_type = attr["type"]
+ format = NlAttr.get_format(attr_type, attr.byte_order)
+ attr_payload = format.pack(scalar)
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':
msg_format = self._resolve_selector(attr, search_attrs)
attr_payload = b''