Skip to content

Commit

Permalink
Merge branch 'tools-ynl-couple-of-cmdline-enhancements'
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jakub Kicinski committed Feb 24, 2024
2 parents 5c4e0f3 + e8a6c51 commit 6511743
Showing 1 changed file with 34 additions and 9 deletions.
43 changes: 34 additions & 9 deletions tools/net/ynl/lib/ynl.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,26 @@ def ntf_subscribe(self, mcast_name):
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]
Expand All @@ -459,6 +479,9 @@ def _add_attr(self, space, name, value, search_attrs):
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'
Expand All @@ -471,16 +494,18 @@ def _add_attr(self, space, name, value, search_attrs):
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''
Expand Down

0 comments on commit 6511743

Please sign in to comment.