* [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types for binary attributes
@ 2025-05-09 15:42 Jakub Kicinski
2025-05-09 15:42 ` [PATCH net-next v2 1/3] tools: ynl-gen: support sub-type " Jakub Kicinski
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Jakub Kicinski @ 2025-05-09 15:42 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, donald.hunter,
jacob.e.keller, Jakub Kicinski
Binary attributes have sub-type annotations which either indicate
that the binary object should be interpreted as a raw / C array of
a simple type (e.g. u32), or that it's a struct.
Use this information in the C codegen instead of outputting void *
for all binary attrs. It doesn't make a huge difference in the genl
families, but in classic Netlink there is a lot more structs.
v2:
- use sub-classes
v1: https://lore.kernel.org/20250508022839.1256059-1-kuba@kernel.org
Jakub Kicinski (3):
tools: ynl-gen: support sub-type for binary attributes
tools: ynl-gen: auto-indent else
tools: ynl-gen: support struct for binary attributes
tools/net/ynl/pyynl/ynl_gen_c.py | 63 ++++++++++++++++++++++++++++++--
1 file changed, 60 insertions(+), 3 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH net-next v2 1/3] tools: ynl-gen: support sub-type for binary attributes 2025-05-09 15:42 [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types for binary attributes Jakub Kicinski @ 2025-05-09 15:42 ` Jakub Kicinski 2025-05-09 21:02 ` Donald Hunter 2025-05-09 15:42 ` [PATCH net-next v2 2/3] tools: ynl-gen: auto-indent else Jakub Kicinski ` (2 subsequent siblings) 3 siblings, 1 reply; 7+ messages in thread From: Jakub Kicinski @ 2025-05-09 15:42 UTC (permalink / raw) To: davem Cc: netdev, edumazet, pabeni, andrew+netdev, horms, donald.hunter, jacob.e.keller, Jakub Kicinski Sub-type annotation on binary attributes may indicate that the attribute carries an array of simple types (also referred to as "C array" in docs). Support rendering them as such in the C user code. For example for u32, instead of: struct { u32 arr; } _len; void *arr; render: struct { u32 arr; } _count; __u32 *arr; Note that count is the number of elements while len was the length in bytes. Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- v2: - create a separate class v1: https://lore.kernel.org/20250508022839.1256059-2-kuba@kernel.org/ --- tools/net/ynl/pyynl/ynl_gen_c.py | 43 +++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index 4a2d3cc07e14..4e2ae738c0aa 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -163,7 +163,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S return False def _free_lines(self, ri, var, ref): - if self.is_multi_val() or self.presence_type() == 'len': + if self.is_multi_val() or self.presence_type() in {'count', 'len'}: return [f'free({var}->{ref}{self.c_name});'] return [] @@ -566,6 +566,40 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S f'memcpy({member}, {self.c_name}, {presence});'] +class TypeBinaryScalarArray(TypeBinary): + def arg_member(self, ri): + return [f'__{self.get("sub-type")} *{self.c_name}', 'size_t count'] + + def presence_type(self): + return 'count' + + def struct_member(self, ri): + ri.cw.p(f'__{self.get("sub-type")} *{self.c_name};') + + def attr_put(self, ri, var): + presence = self.presence_type() + ri.cw.block_start(line=f"if ({var}->_{presence}.{self.c_name})") + ri.cw.p(f"i = {var}->_{presence}.{self.c_name} * sizeof(__{self.get('sub-type')});") + ri.cw.p(f"ynl_attr_put(nlh, {self.enum_name}, " + + f"{var}->{self.c_name}, i);") + ri.cw.block_end() + + def _attr_get(self, ri, var): + len_mem = var + '->_count.' + self.c_name + return [f"{len_mem} = len / sizeof(__{self.get('sub-type')});", + f"len = {len_mem} * sizeof(__{self.get('sub-type')});", + f"{var}->{self.c_name} = malloc(len);", + f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \ + ['len = ynl_attr_data_len(attr);'], \ + ['unsigned int len;'] + + def _setter_lines(self, ri, member, presence): + return [f"{presence} = count;", + f"count *= sizeof(__{self.get('sub-type')});", + f"{member} = malloc(count);", + f'memcpy({member}, {self.c_name}, count);'] + + class TypeBitfield32(Type): def _complex_member_type(self, ri): return "struct nla_bitfield32" @@ -672,7 +706,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S lines = [] if self.attr['type'] in scalars: lines += [f"free({var}->{ref}{self.c_name});"] - elif self.attr['type'] == 'binary' and 'struct' in self.attr: + elif self.attr['type'] == 'binary': lines += [f"free({var}->{ref}{self.c_name});"] elif self.attr['type'] == 'string': lines += [ @@ -976,7 +1010,10 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S elif elem['type'] == 'string': t = TypeString(self.family, self, elem, value) elif elem['type'] == 'binary': - t = TypeBinary(self.family, self, elem, value) + if elem.get('sub-type') in scalars: + t = TypeBinaryScalarArray(self.family, self, elem, value) + else: + t = TypeBinary(self.family, self, elem, value) elif elem['type'] == 'bitfield32': t = TypeBitfield32(self.family, self, elem, value) elif elem['type'] == 'nest': -- 2.49.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v2 1/3] tools: ynl-gen: support sub-type for binary attributes 2025-05-09 15:42 ` [PATCH net-next v2 1/3] tools: ynl-gen: support sub-type " Jakub Kicinski @ 2025-05-09 21:02 ` Donald Hunter 0 siblings, 0 replies; 7+ messages in thread From: Donald Hunter @ 2025-05-09 21:02 UTC (permalink / raw) To: Jakub Kicinski Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, jacob.e.keller Jakub Kicinski <kuba@kernel.org> writes: > Sub-type annotation on binary attributes may indicate that the attribute > carries an array of simple types (also referred to as "C array" in docs). > Support rendering them as such in the C user code. For example for u32, > instead of: > > struct { > u32 arr; > } _len; > > void *arr; > > render: > > struct { > u32 arr; > } _count; > > __u32 *arr; > > Note that count is the number of elements while len was the length in bytes. > > Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Donald Hunter <donald.hunter@gmail.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net-next v2 2/3] tools: ynl-gen: auto-indent else 2025-05-09 15:42 [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types for binary attributes Jakub Kicinski 2025-05-09 15:42 ` [PATCH net-next v2 1/3] tools: ynl-gen: support sub-type " Jakub Kicinski @ 2025-05-09 15:42 ` Jakub Kicinski 2025-05-09 15:42 ` [PATCH net-next v2 3/3] tools: ynl-gen: support struct for binary attributes Jakub Kicinski 2025-05-13 11:30 ` [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types " patchwork-bot+netdevbpf 3 siblings, 0 replies; 7+ messages in thread From: Jakub Kicinski @ 2025-05-09 15:42 UTC (permalink / raw) To: davem Cc: netdev, edumazet, pabeni, andrew+netdev, horms, donald.hunter, jacob.e.keller, Jakub Kicinski We auto-indent if statements (increase the indent of the subsequent line by 1), do the same thing for else branches without a block. There hasn't been any else branches before but we're about to add one. Reviewed-by: Donald Hunter <donald.hunter@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- tools/net/ynl/pyynl/ynl_gen_c.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index 4e2ae738c0aa..9a5c65966e9d 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -1458,6 +1458,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S if self._silent_block: ind += 1 self._silent_block = line.endswith(')') and CodeWriter._is_cond(line) + self._silent_block |= line.strip() == 'else' if line[0] == '#': ind = 0 if add_ind: -- 2.49.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next v2 3/3] tools: ynl-gen: support struct for binary attributes 2025-05-09 15:42 [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types for binary attributes Jakub Kicinski 2025-05-09 15:42 ` [PATCH net-next v2 1/3] tools: ynl-gen: support sub-type " Jakub Kicinski 2025-05-09 15:42 ` [PATCH net-next v2 2/3] tools: ynl-gen: auto-indent else Jakub Kicinski @ 2025-05-09 15:42 ` Jakub Kicinski 2025-05-09 21:03 ` Donald Hunter 2025-05-13 11:30 ` [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types " patchwork-bot+netdevbpf 3 siblings, 1 reply; 7+ messages in thread From: Jakub Kicinski @ 2025-05-09 15:42 UTC (permalink / raw) To: davem Cc: netdev, edumazet, pabeni, andrew+netdev, horms, donald.hunter, jacob.e.keller, Jakub Kicinski Support using a struct pointer for binary attrs. Len field is maintained because the structs may grow with newer kernel versions. Or, which matters more, be shorter if the binary is built against newer uAPI than kernel against which it's executed. Since we are storing a pointer to a struct type - always allocate at least the amount of memory needed by the struct per current uAPI headers (unused mem is zeroed). Technically users should check the length field but per modern ASAN checks storing a short object under a pointer seems like a bad idea. Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- v2: - create a separate class v1: https://lore.kernel.org/20250508022839.1256059-4-kuba@kernel.org --- tools/net/ynl/pyynl/ynl_gen_c.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py index 9a5c65966e9d..3b064c61a374 100755 --- a/tools/net/ynl/pyynl/ynl_gen_c.py +++ b/tools/net/ynl/pyynl/ynl_gen_c.py @@ -566,6 +566,23 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S f'memcpy({member}, {self.c_name}, {presence});'] +class TypeBinaryStruct(TypeBinary): + def struct_member(self, ri): + ri.cw.p(f'struct {c_lower(self.get("struct"))} *{self.c_name};') + + def _attr_get(self, ri, var): + struct_sz = 'sizeof(struct ' + c_lower(self.get("struct")) + ')' + len_mem = var + '->_' + self.presence_type() + '.' + self.c_name + return [f"{len_mem} = len;", + f"if (len < {struct_sz})", + f"{var}->{self.c_name} = calloc(1, {struct_sz});", + "else", + f"{var}->{self.c_name} = malloc(len);", + f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \ + ['len = ynl_attr_data_len(attr);'], \ + ['unsigned int len;'] + + class TypeBinaryScalarArray(TypeBinary): def arg_member(self, ri): return [f'__{self.get("sub-type")} *{self.c_name}', 'size_t count'] @@ -1010,7 +1027,9 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S elif elem['type'] == 'string': t = TypeString(self.family, self, elem, value) elif elem['type'] == 'binary': - if elem.get('sub-type') in scalars: + if 'struct' in elem: + t = TypeBinaryStruct(self.family, self, elem, value) + elif elem.get('sub-type') in scalars: t = TypeBinaryScalarArray(self.family, self, elem, value) else: t = TypeBinary(self.family, self, elem, value) -- 2.49.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v2 3/3] tools: ynl-gen: support struct for binary attributes 2025-05-09 15:42 ` [PATCH net-next v2 3/3] tools: ynl-gen: support struct for binary attributes Jakub Kicinski @ 2025-05-09 21:03 ` Donald Hunter 0 siblings, 0 replies; 7+ messages in thread From: Donald Hunter @ 2025-05-09 21:03 UTC (permalink / raw) To: Jakub Kicinski Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, jacob.e.keller Jakub Kicinski <kuba@kernel.org> writes: > Support using a struct pointer for binary attrs. Len field is maintained > because the structs may grow with newer kernel versions. Or, which matters > more, be shorter if the binary is built against newer uAPI than kernel > against which it's executed. Since we are storing a pointer to a struct > type - always allocate at least the amount of memory needed by the struct > per current uAPI headers (unused mem is zeroed). Technically users should > check the length field but per modern ASAN checks storing a short object > under a pointer seems like a bad idea. > > Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Donald Hunter <donald.hunter@gmail.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types for binary attributes 2025-05-09 15:42 [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types for binary attributes Jakub Kicinski ` (2 preceding siblings ...) 2025-05-09 15:42 ` [PATCH net-next v2 3/3] tools: ynl-gen: support struct for binary attributes Jakub Kicinski @ 2025-05-13 11:30 ` patchwork-bot+netdevbpf 3 siblings, 0 replies; 7+ messages in thread From: patchwork-bot+netdevbpf @ 2025-05-13 11:30 UTC (permalink / raw) To: Jakub Kicinski Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, donald.hunter, jacob.e.keller Hello: This series was applied to netdev/net-next.git (main) by Paolo Abeni <pabeni@redhat.com>: On Fri, 9 May 2025 08:42:10 -0700 you wrote: > Binary attributes have sub-type annotations which either indicate > that the binary object should be interpreted as a raw / C array of > a simple type (e.g. u32), or that it's a struct. > > Use this information in the C codegen instead of outputting void * > for all binary attrs. It doesn't make a huge difference in the genl > families, but in classic Netlink there is a lot more structs. > > [...] Here is the summary with links: - [net-next,v2,1/3] tools: ynl-gen: support sub-type for binary attributes https://git.kernel.org/netdev/net-next/c/02a562bb2b08 - [net-next,v2,2/3] tools: ynl-gen: auto-indent else https://git.kernel.org/netdev/net-next/c/9ba8e351efd4 - [net-next,v2,3/3] tools: ynl-gen: support struct for binary attributes https://git.kernel.org/netdev/net-next/c/25e37418c872 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-05-13 11:30 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-05-09 15:42 [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types for binary attributes Jakub Kicinski 2025-05-09 15:42 ` [PATCH net-next v2 1/3] tools: ynl-gen: support sub-type " Jakub Kicinski 2025-05-09 21:02 ` Donald Hunter 2025-05-09 15:42 ` [PATCH net-next v2 2/3] tools: ynl-gen: auto-indent else Jakub Kicinski 2025-05-09 15:42 ` [PATCH net-next v2 3/3] tools: ynl-gen: support struct for binary attributes Jakub Kicinski 2025-05-09 21:03 ` Donald Hunter 2025-05-13 11:30 ` [PATCH net-next v2 0/3] tools: ynl-gen: support sub-types " patchwork-bot+netdevbpf
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).