diff options
Diffstat (limited to 'tools/net/ynl/pyynl')
| -rwxr-xr-x | tools/net/ynl/pyynl/ethtool.py | 14 | ||||
| -rw-r--r-- | tools/net/ynl/pyynl/lib/__init__.py | 2 | ||||
| -rw-r--r-- | tools/net/ynl/pyynl/lib/doc_generator.py | 4 | ||||
| -rw-r--r-- | tools/net/ynl/pyynl/lib/nlspec.py | 2 | ||||
| -rw-r--r-- | tools/net/ynl/pyynl/lib/ynl.py | 45 | ||||
| -rwxr-xr-x | tools/net/ynl/pyynl/ynl_gen_c.py | 137 |
6 files changed, 125 insertions, 79 deletions
diff --git a/tools/net/ynl/pyynl/ethtool.py b/tools/net/ynl/pyynl/ethtool.py index cab6b576c876..9b523cbb3568 100755 --- a/tools/net/ynl/pyynl/ethtool.py +++ b/tools/net/ynl/pyynl/ethtool.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause import argparse -import json import pathlib import pprint import sys @@ -51,7 +50,7 @@ def print_field(reply, *desc): for spec in desc: try: field, name, tp = spec - except: + except ValueError: field, name = spec tp = 'int' @@ -156,7 +155,6 @@ def main(): global args args = parser.parse_args() - script_abs_dir = os.path.dirname(os.path.abspath(sys.argv[0])) spec = os.path.join(spec_dir(), 'ethtool.yaml') schema = os.path.join(schema_dir(), 'genetlink-legacy.yaml') @@ -255,14 +253,14 @@ def main(): reply = dumpit(ynl, args, 'channels-get') print(f'Channel parameters for {args.device}:') - print(f'Pre-set maximums:') + print('Pre-set maximums:') print_field(reply, ('rx-max', 'RX'), ('tx-max', 'TX'), ('other-max', 'Other'), ('combined-max', 'Combined')) - print(f'Current hardware settings:') + print('Current hardware settings:') print_field(reply, ('rx-count', 'RX'), ('tx-count', 'TX'), @@ -276,14 +274,14 @@ def main(): print(f'Ring parameters for {args.device}:') - print(f'Pre-set maximums:') + print('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('Current hardware settings:') print_field(reply, ('rx', 'RX'), ('rx-mini', 'RX Mini'), @@ -298,7 +296,7 @@ def main(): return if args.statistics: - print(f'NIC statistics:') + print('NIC statistics:') # TODO: pass id? strset = dumpit(ynl, args, 'strset-get') diff --git a/tools/net/ynl/pyynl/lib/__init__.py b/tools/net/ynl/pyynl/lib/__init__.py index 5f266ebe4526..ec9ea00071be 100644 --- a/tools/net/ynl/pyynl/lib/__init__.py +++ b/tools/net/ynl/pyynl/lib/__init__.py @@ -8,4 +8,4 @@ from .doc_generator import YnlDocGenerator __all__ = ["SpecAttr", "SpecAttrSet", "SpecEnumEntry", "SpecEnumSet", "SpecFamily", "SpecOperation", "SpecSubMessage", "SpecSubMessageFormat", - "YnlFamily", "Netlink", "NlError"] + "YnlFamily", "Netlink", "NlError", "YnlDocGenerator"] diff --git a/tools/net/ynl/pyynl/lib/doc_generator.py b/tools/net/ynl/pyynl/lib/doc_generator.py index 403abf1a2eda..3a16b8eb01ca 100644 --- a/tools/net/ynl/pyynl/lib/doc_generator.py +++ b/tools/net/ynl/pyynl/lib/doc_generator.py @@ -289,6 +289,10 @@ class YnlDocGenerator: for entry in entries: lines.append(self.fmt.rst_section(namespace, 'attribute-set', entry["name"])) + + if "doc" in entry: + lines.append(self.fmt.rst_paragraph(entry["doc"], 0) + "\n") + for attr in entry["attributes"]: if LINE_STR in attr: lines.append(self.fmt.rst_lineno(attr[LINE_STR])) diff --git a/tools/net/ynl/pyynl/lib/nlspec.py b/tools/net/ynl/pyynl/lib/nlspec.py index 314ec8007496..85c17fe01e35 100644 --- a/tools/net/ynl/pyynl/lib/nlspec.py +++ b/tools/net/ynl/pyynl/lib/nlspec.py @@ -501,7 +501,7 @@ class SpecFamily(SpecElement): return SpecStruct(self, elem) def new_sub_message(self, elem): - return SpecSubMessage(self, elem); + return SpecSubMessage(self, elem) def new_operation(self, elem, req_val, rsp_val): return SpecOperation(self, elem, req_val, rsp_val) diff --git a/tools/net/ynl/pyynl/lib/ynl.py b/tools/net/ynl/pyynl/lib/ynl.py index 8244a5f440b2..62383c70ebb9 100644 --- a/tools/net/ynl/pyynl/lib/ynl.py +++ b/tools/net/ynl/pyynl/lib/ynl.py @@ -9,7 +9,6 @@ import socket import struct from struct import Struct import sys -import yaml import ipaddress import uuid import queue @@ -562,11 +561,13 @@ class YnlFamily(SpecFamily): if attr["type"] == 'nest': nl_type |= Netlink.NLA_F_NESTED - attr_payload = b'' sub_space = attr['nested-attributes'] - sub_attrs = SpaceAttrs(self.attr_sets[sub_space], value, search_attrs) - for subname, subvalue in value.items(): - attr_payload += self._add_attr(sub_space, subname, subvalue, sub_attrs) + attr_payload = self._add_nest_attrs(value, sub_space, search_attrs) + elif attr['type'] == 'indexed-array' and attr['sub-type'] == 'nest': + nl_type |= Netlink.NLA_F_NESTED + sub_space = attr['nested-attributes'] + attr_payload = self._encode_indexed_array(value, sub_space, + search_attrs) elif attr["type"] == 'flag': if not value: # If value is absent or false then skip attribute creation. @@ -620,9 +621,28 @@ class YnlFamily(SpecFamily): else: raise Exception(f'Unknown type at {space} {name} {value} {attr["type"]}') + return self._add_attr_raw(nl_type, attr_payload) + + def _add_attr_raw(self, nl_type, attr_payload): pad = b'\x00' * ((4 - len(attr_payload) % 4) % 4) return struct.pack('HH', len(attr_payload) + 4, nl_type) + attr_payload + pad + def _add_nest_attrs(self, value, sub_space, search_attrs): + sub_attrs = SpaceAttrs(self.attr_sets[sub_space], value, search_attrs) + attr_payload = b'' + for subname, subvalue in value.items(): + attr_payload += self._add_attr(sub_space, subname, subvalue, + sub_attrs) + return attr_payload + + def _encode_indexed_array(self, vals, sub_space, search_attrs): + attr_payload = b'' + for i, val in enumerate(vals): + idx = i | Netlink.NLA_F_NESTED + val_payload = self._add_nest_attrs(val, sub_space, search_attrs) + attr_payload += self._add_attr_raw(idx, val_payload) + return attr_payload + def _get_enum_or_unknown(self, enum, raw): try: name = enum.entries_by_val[raw].name @@ -706,7 +726,7 @@ class YnlFamily(SpecFamily): return attr.as_bin() def _rsp_add(self, rsp, name, is_multi, decoded): - if is_multi == None: + if is_multi is None: if name in rsp and type(rsp[name]) is not list: rsp[name] = [rsp[name]] is_multi = True @@ -739,14 +759,14 @@ class YnlFamily(SpecFamily): decoded = {} offset = 0 if msg_format.fixed_header: - decoded.update(self._decode_struct(attr.raw, msg_format.fixed_header)); + decoded.update(self._decode_struct(attr.raw, msg_format.fixed_header)) offset = self._struct_size(msg_format.fixed_header) if msg_format.attr_set: if msg_format.attr_set in self.attr_sets: subdict = self._decode(NlAttrs(attr.raw, offset), msg_format.attr_set) decoded.update(subdict) else: - raise Exception(f"Unknown attribute-set '{attr_space}' when decoding '{attr_spec.name}'") + raise Exception(f"Unknown attribute-set '{msg_format.attr_set}' when decoding '{attr_spec.name}'") return decoded def _decode(self, attrs, space, outer_attrs = None): @@ -936,7 +956,7 @@ class YnlFamily(SpecFamily): formatted = hex(raw) else: formatted = bytes.hex(raw, ' ') - elif display_hint in [ 'ipv4', 'ipv6' ]: + elif display_hint in [ 'ipv4', 'ipv6', 'ipv4-or-v6' ]: formatted = format(ipaddress.ip_address(raw)) elif display_hint == 'uuid': formatted = str(uuid.UUID(bytes=raw)) @@ -945,12 +965,17 @@ class YnlFamily(SpecFamily): return formatted def _from_string(self, string, attr_spec): - if attr_spec.display_hint in ['ipv4', 'ipv6']: + if attr_spec.display_hint in ['ipv4', 'ipv6', 'ipv4-or-v6']: ip = ipaddress.ip_address(string) if attr_spec['type'] == 'binary': raw = ip.packed else: raw = int(ip) + elif attr_spec.display_hint == 'hex': + if attr_spec['type'] == 'binary': + raw = bytes.fromhex(string) + else: + raw = int(string, 16) else: raise Exception(f"Display hint '{attr_spec.display_hint}' not implemented" f" when parsing '{attr_spec['name']}'") diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index ef032e17fec4..58086b101057 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) import argparse -import collections import filecmp import pathlib import os @@ -14,7 +13,7 @@ import yaml sys.path.append(pathlib.Path(__file__).resolve().parent.as_posix()) from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, SpecEnumEntry -from lib import SpecSubMessage, SpecSubMessageFormat +from lib import SpecSubMessage def c_upper(name): @@ -243,7 +242,7 @@ class Type(SpecAttr): raise Exception(f"Attr get not implemented for class type {self.type}") def attr_get(self, ri, var, first): - lines, init_lines, local_vars = self._attr_get(ri, var) + lines, init_lines, _ = self._attr_get(ri, var) if type(lines) is str: lines = [lines] if type(init_lines) is str: @@ -251,10 +250,6 @@ class Type(SpecAttr): kw = 'if' if first else 'else if' ri.cw.block_start(line=f"{kw} (type == {self.enum_name})") - if local_vars: - for local in local_vars: - ri.cw.p(local) - ri.cw.nl() if not self.is_multi_val(): ri.cw.p("if (ynl_attr_validate(yarg, attr))") @@ -398,7 +393,7 @@ class TypeScalar(Type): if 'enum' in self.attr: enum = self.family.consts[self.attr['enum']] low, high = enum.value_range() - if low == None and high == None: + if low is None and high is None: self.checks['sparse'] = True else: if 'min' not in self.checks: @@ -485,7 +480,7 @@ class TypeString(Type): ri.cw.p(f"char *{self.c_name};") def _attr_typol(self): - typol = f'.type = YNL_PT_NUL_STR, ' + typol = '.type = YNL_PT_NUL_STR, ' if self.is_selector: typol += '.is_selector = 1, ' return typol @@ -539,7 +534,7 @@ class TypeBinary(Type): ri.cw.p(f"void *{self.c_name};") def _attr_typol(self): - return f'.type = YNL_PT_BINARY,' + return '.type = YNL_PT_BINARY,' def _attr_policy(self, policy): if len(self.checks) == 0: @@ -556,7 +551,7 @@ class TypeBinary(Type): elif 'exact-len' in self.checks: mem = 'NLA_POLICY_EXACT_LEN(' + self.get_limit_str('exact-len') + ')' elif 'min-len' in self.checks: - mem = '{ .len = ' + self.get_limit_str('min-len') + ', }' + mem = 'NLA_POLICY_MIN_LEN(' + self.get_limit_str('min-len') + ')' elif 'max-len' in self.checks: mem = 'NLA_POLICY_MAX_LEN(' + self.get_limit_str('max-len') + ')' @@ -636,10 +631,10 @@ class TypeBitfield32(Type): return "struct nla_bitfield32" def _attr_typol(self): - return f'.type = YNL_PT_BITFIELD32, ' + return '.type = YNL_PT_BITFIELD32, ' def _attr_policy(self, policy): - if not 'enum' in self.attr: + if 'enum' not in self.attr: raise Exception('Enum required for bitfield32 attr') enum = self.family.consts[self.attr['enum']] mask = enum.get_mask(as_flags=True) @@ -725,7 +720,11 @@ class TypeMultiAttr(Type): return 'struct ynl_string *' elif self.attr['type'] in scalars: scalar_pfx = '__' if ri.ku_space == 'user' else '' - return scalar_pfx + self.attr['type'] + if self.is_auto_scalar: + name = self.type[0] + '64' + else: + name = self.attr['type'] + return scalar_pfx + name else: raise Exception(f"Sub-type {self.attr['type']} not supported yet") @@ -792,7 +791,7 @@ class TypeMultiAttr(Type): f"{presence} = n_{self.c_name};"] -class TypeArrayNest(Type): +class TypeIndexedArray(Type): def is_multi_val(self): return True @@ -816,21 +815,28 @@ class TypeArrayNest(Type): f'unsigned int n_{self.c_name}'] return super().arg_member(ri) + def _attr_policy(self, policy): + if self.attr['sub-type'] == 'nest': + return f'NLA_POLICY_NESTED_ARRAY({self.nested_render_name}_nl_policy)' + return super()._attr_policy(policy) + def _attr_typol(self): if self.attr['sub-type'] in scalars: return f'.type = YNL_PT_U{c_upper(self.sub_type[1:])}, ' elif self.attr['sub-type'] == 'binary' and 'exact-len' in self.checks: return f'.type = YNL_PT_BINARY, .len = {self.checks["exact-len"]}, ' - else: + elif self.attr['sub-type'] == 'nest': return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, ' + else: + raise Exception(f"Typol for IndexedArray sub-type {self.attr['sub-type']} not supported, yet") def _attr_get(self, ri, var): local_vars = ['const struct nlattr *attr2;'] get_lines = [f'attr_{self.c_name} = attr;', 'ynl_attr_for_each_nested(attr2, attr) {', - '\tif (ynl_attr_validate(yarg, attr2))', + '\tif (__ynl_attr_validate(yarg, attr2, type))', '\t\treturn YNL_PARSE_CB_ERROR;', - f'\t{var}->_count.{self.c_name}++;', + f'\tn_{self.c_name}++;', '}'] return get_lines, None, local_vars @@ -848,7 +854,7 @@ class TypeArrayNest(Type): ri.cw.p(f'for (i = 0; i < {var}->_count.{self.c_name}; i++)') ri.cw.p(f"{self.nested_render_name}_put(nlh, i, &{var}->{self.c_name}[i]);") else: - raise Exception(f"Put for ArrayNest sub-type {self.attr['sub-type']} not supported, yet") + raise Exception(f"Put for IndexedArray sub-type {self.attr['sub-type']} not supported, yet") ri.cw.p('ynl_attr_nest_end(nlh, array);') def _setter_lines(self, ri, member, presence): @@ -909,7 +915,7 @@ class TypeSubMessage(TypeNest): else: sel_var = f"{var}->{sel}" get_lines = [f'if (!{sel_var})', - f'return ynl_submsg_failed(yarg, "%s", "%s");' % + 'return ynl_submsg_failed(yarg, "%s", "%s");' % (self.name, self['selector']), f"if ({self.nested_render_name}_parse(&parg, {sel_var}, attr))", "return YNL_PARSE_CB_ERROR;"] @@ -1125,7 +1131,7 @@ class AttrSet(SpecAttrSet): t = TypeNest(self.family, self, elem, value) elif elem['type'] == 'indexed-array' and 'sub-type' in elem: if elem["sub-type"] in ['binary', 'nest', 'u32']: - t = TypeArrayNest(self.family, self, elem, value) + t = TypeIndexedArray(self.family, self, elem, value) else: raise Exception(f'new_attr: unsupported sub-type {elem["sub-type"]}') elif elem['type'] == 'nest-type-value': @@ -1563,7 +1569,7 @@ class RenderInfo: if family.is_classic(): self.fixed_hdr_len = f"sizeof(struct {c_lower(fixed_hdr)})" else: - raise Exception(f"Per-op fixed header not supported, yet") + raise Exception("Per-op fixed header not supported, yet") # 'do' and 'dump' response parsing is identical @@ -2034,6 +2040,20 @@ def put_enum_to_str(family, cw, enum): _put_enum_to_str_helper(cw, enum.render_name, map_name, 'value', enum=enum) +def put_local_vars(struct): + local_vars = [] + has_array = False + has_count = False + for _, arg in struct.member_list(): + has_array |= arg.type == 'indexed-array' + has_count |= arg.presence_type() == 'count' + if has_array: + local_vars.append('struct nlattr *array;') + if has_count: + local_vars.append('unsigned int i;') + return local_vars + + def put_req_nested_prototype(ri, struct, suffix=';'): func_args = ['struct nlmsghdr *nlh', 'unsigned int attr_type', @@ -2056,15 +2076,7 @@ def put_req_nested(ri, struct): init_lines.append(f"hdr = ynl_nlmsg_put_extra_header(nlh, {struct_sz});") init_lines.append(f"memcpy(hdr, &obj->_hdr, {struct_sz});") - has_anest = False - has_count = False - for _, arg in struct.member_list(): - has_anest |= arg.type == 'indexed-array' - has_count |= arg.presence_type() == 'count' - if has_anest: - local_vars.append('struct nlattr *array;') - if has_count: - local_vars.append('unsigned int i;') + local_vars += put_local_vars(struct) put_req_nested_prototype(ri, struct, suffix='') ri.cw.block_start() @@ -2099,35 +2111,43 @@ def _multi_parse(ri, struct, init_lines, local_vars): if ri.family.is_classic(): iter_line = f"ynl_attr_for_each(attr, nlh, sizeof({struct.fixed_header}))" else: - raise Exception(f"Per-op fixed header not supported, yet") + raise Exception("Per-op fixed header not supported, yet") - array_nests = set() + indexed_arrays = set() multi_attrs = set() needs_parg = False + var_set = set() for arg, aspec in struct.member_list(): if aspec['type'] == 'indexed-array' and 'sub-type' in aspec: if aspec["sub-type"] in {'binary', 'nest'}: - local_vars.append(f'const struct nlattr *attr_{aspec.c_name};') - array_nests.add(arg) + local_vars.append(f'const struct nlattr *attr_{aspec.c_name} = NULL;') + indexed_arrays.add(arg) elif aspec['sub-type'] in scalars: - local_vars.append(f'const struct nlattr *attr_{aspec.c_name};') - array_nests.add(arg) + local_vars.append(f'const struct nlattr *attr_{aspec.c_name} = NULL;') + indexed_arrays.add(arg) else: raise Exception(f'Not supported sub-type {aspec["sub-type"]}') if 'multi-attr' in aspec: multi_attrs.add(arg) needs_parg |= 'nested-attributes' in aspec needs_parg |= 'sub-message' in aspec - if array_nests or multi_attrs: + + try: + _, _, l_vars = aspec._attr_get(ri, '') + var_set |= set(l_vars) if l_vars else set() + except Exception: + pass # _attr_get() not implemented by simple types, ignore + local_vars += list(var_set) + if indexed_arrays or multi_attrs: local_vars.append('int i;') if needs_parg: local_vars.append('struct ynl_parse_arg parg;') init_lines.append('parg.ys = yarg->ys;') - all_multi = array_nests | multi_attrs + all_multi = indexed_arrays | multi_attrs - for anest in sorted(all_multi): - local_vars.append(f"unsigned int n_{struct[anest].c_name} = 0;") + for arg in sorted(all_multi): + local_vars.append(f"unsigned int n_{struct[arg].c_name} = 0;") ri.cw.block_start() ri.cw.write_func_lvar(local_vars) @@ -2147,8 +2167,8 @@ def _multi_parse(ri, struct, init_lines, local_vars): else: ri.cw.p('hdr = ynl_nlmsg_data_offset(nlh, sizeof(struct genlmsghdr));') ri.cw.p(f"memcpy(&dst->_hdr, hdr, sizeof({struct.fixed_header}));") - for anest in sorted(all_multi): - aspec = struct[anest] + for arg in sorted(all_multi): + aspec = struct[arg] ri.cw.p(f"if (dst->{aspec.c_name})") ri.cw.p(f'return ynl_error_parse(yarg, "attribute already present ({struct.attr_set.name}.{aspec.name})");') @@ -2166,8 +2186,8 @@ def _multi_parse(ri, struct, init_lines, local_vars): ri.cw.block_end() ri.cw.nl() - for anest in sorted(array_nests): - aspec = struct[anest] + for arg in sorted(indexed_arrays): + aspec = struct[arg] ri.cw.block_start(line=f"if (n_{aspec.c_name})") ri.cw.p(f"dst->{aspec.c_name} = calloc(n_{aspec.c_name}, sizeof(*dst->{aspec.c_name}));") @@ -2192,8 +2212,8 @@ def _multi_parse(ri, struct, init_lines, local_vars): ri.cw.block_end() ri.cw.nl() - for anest in sorted(multi_attrs): - aspec = struct[anest] + for arg in sorted(multi_attrs): + aspec = struct[arg] ri.cw.block_start(line=f"if (n_{aspec.c_name})") ri.cw.p(f"dst->{aspec.c_name} = calloc(n_{aspec.c_name}, sizeof(*dst->{aspec.c_name}));") ri.cw.p(f"dst->_count.{aspec.c_name} = n_{aspec.c_name};") @@ -2348,10 +2368,7 @@ def print_req(ri): local_vars += ['size_t hdr_len;', 'void *hdr;'] - for _, attr in ri.struct["request"].member_list(): - if attr.presence_type() == 'count': - local_vars += ['unsigned int i;'] - break + local_vars += put_local_vars(ri.struct['request']) print_prototype(ri, direction, terminate=False) ri.cw.block_start() @@ -2418,6 +2435,9 @@ def print_dump(ri): local_vars += ['size_t hdr_len;', 'void *hdr;'] + if 'request' in ri.op[ri.op_mode]: + local_vars += put_local_vars(ri.struct['request']) + ri.cw.write_func_lvar(local_vars) ri.cw.p('yds.yarg.ys = ys;') @@ -2502,7 +2522,7 @@ def print_free_prototype(ri, direction, suffix=';'): def print_nlflags_set(ri, direction): name = op_prefix(ri, direction) - ri.cw.write_func_prot(f'static inline void', f"{name}_set_nlflags", + ri.cw.write_func_prot('static inline void', f"{name}_set_nlflags", [f"struct {name} *req", "__u16 nl_flags"]) ri.cw.block_start() ri.cw.p('req->_nlmsg_flags = nl_flags;') @@ -2533,7 +2553,7 @@ def _print_type(ri, direction, struct): line = attr.presence_member(ri.ku_space, type_filter) if line: if not meta_started: - ri.cw.block_start(line=f"struct") + ri.cw.block_start(line="struct") meta_started = True ri.cw.p(line) if meta_started: @@ -2697,7 +2717,7 @@ def print_dump_type_free(ri): ri.cw.nl() _free_type_members(ri, 'rsp', ri.struct['reply'], ref='obj.') - ri.cw.p(f'free(rsp);') + ri.cw.p('free(rsp);') ri.cw.block_end() ri.cw.block_end() ri.cw.nl() @@ -2708,7 +2728,7 @@ def print_ntf_type_free(ri): ri.cw.block_start() _free_type_members_iter(ri, ri.struct['reply']) _free_type_members(ri, 'rsp', ri.struct['reply'], ref='obj.') - ri.cw.p(f'free(rsp);') + ri.cw.p('free(rsp);') ri.cw.block_end() ri.cw.nl() @@ -2803,8 +2823,6 @@ def print_kernel_policy_sparse_enum_validates(family, cw): cw.p('/* Sparse enums validation callbacks */') first = False - sign = '' if attr.type[0] == 'u' else '_signed' - suffix = 'ULL' if attr.type[0] == 'u' else 'LL' cw.write_func_prot('static int', f'{c_lower(attr.enum_name)}_validate', ['const struct nlattr *attr', 'struct netlink_ext_ack *extack']) cw.block_start() @@ -3211,8 +3229,9 @@ def render_uapi(family, cw): cw.block_end(line=';') cw.nl() elif const['type'] == 'const': + name_pfx = const.get('name-prefix', f"{family.ident_name}-") defines.append([c_upper(family.get('c-define-name', - f"{family.ident_name}-{const['name']}")), + f"{name_pfx}{const['name']}")), const['value']]) if defines: @@ -3324,7 +3343,7 @@ def render_user_family(family, cw, prototype): cw.block_start(f'{symbol} = ') cw.p(f'.name\t\t= "{family.c_name}",') if family.is_classic(): - cw.p(f'.is_classic\t= true,') + cw.p('.is_classic\t= true,') cw.p(f'.classic_id\t= {family.get("protonum")},') if family.is_classic(): if family.fixed_header: |
