From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
andrew+netdev@lunn.ch, horms@kernel.org, donald.hunter@gmail.com,
jacob.e.keller@intel.com, sdf@fomichev.me,
Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 2/3] tools: ynl-gen: split presence metadata
Date: Mon, 5 May 2025 09:52:06 -0700 [thread overview]
Message-ID: <20250505165208.248049-3-kuba@kernel.org> (raw)
In-Reply-To: <20250505165208.248049-1-kuba@kernel.org>
Each YNL struct contains the data and a sub-struct indicating which
fields are valid. Something like:
struct family_op_req {
struct {
u32 a:1;
u32 b:1;
u32 bin_len;
} _present;
u32 a;
u64 b;
const unsigned char *bin;
};
Note that the bin object 'bin' has a length stored, and that length
has a _len suffix added to the field name. This breaks if there
is a explicit field called bin_len, which is the case for some
TC actions. Move the length fields out of the _present struct,
create a new struct called _len:
struct family_op_req {
struct {
u32 a:1;
u32 b:1;
} _present;
struct {
u32 bin;
} _len;
u32 a;
u64 b;
const unsigned char *bin;
};
This should prevent name collisions and help with the packing
of the struct.
Unfortunately this is a breaking change, but hopefully the migration
isn't too painful.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
tools/net/ynl/samples/devlink.c | 2 +-
tools/net/ynl/samples/rt-addr.c | 4 +--
tools/net/ynl/samples/rt-route.c | 4 +--
tools/net/ynl/pyynl/ynl_gen_c.py | 46 ++++++++++++++++----------------
4 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/tools/net/ynl/samples/devlink.c b/tools/net/ynl/samples/devlink.c
index d2611d7ebab4..3d32a6335044 100644
--- a/tools/net/ynl/samples/devlink.c
+++ b/tools/net/ynl/samples/devlink.c
@@ -34,7 +34,7 @@ int main(int argc, char **argv)
if (!info_rsp)
goto err_free_devs;
- if (info_rsp->_present.info_driver_name_len)
+ if (info_rsp->_len.info_driver_name)
printf(" driver: %s\n", info_rsp->info_driver_name);
if (info_rsp->n_info_version_running)
printf(" running fw:\n");
diff --git a/tools/net/ynl/samples/rt-addr.c b/tools/net/ynl/samples/rt-addr.c
index 0f4851b4ec57..2edde5c36b18 100644
--- a/tools/net/ynl/samples/rt-addr.c
+++ b/tools/net/ynl/samples/rt-addr.c
@@ -20,7 +20,7 @@ static void rt_addr_print(struct rt_addr_getaddr_rsp *a)
if (name)
printf("%16s: ", name);
- switch (a->_present.address_len) {
+ switch (a->_len.address) {
case 4:
addr = inet_ntop(AF_INET, a->address,
addr_str, sizeof(addr_str));
@@ -36,7 +36,7 @@ static void rt_addr_print(struct rt_addr_getaddr_rsp *a)
if (addr)
printf("%s", addr);
else
- printf("[%d]", a->_present.address_len);
+ printf("[%d]", a->_len.address);
printf("\n");
}
diff --git a/tools/net/ynl/samples/rt-route.c b/tools/net/ynl/samples/rt-route.c
index 9d9c868f8873..7427104a96df 100644
--- a/tools/net/ynl/samples/rt-route.c
+++ b/tools/net/ynl/samples/rt-route.c
@@ -26,13 +26,13 @@ static void rt_route_print(struct rt_route_getroute_rsp *r)
printf("oif: %-16s ", name);
}
- if (r->_present.dst_len) {
+ if (r->_len.dst) {
route = inet_ntop(r->_hdr.rtm_family, r->dst,
route_str, sizeof(route_str));
printf("dst: %s/%d", route, r->_hdr.rtm_dst_len);
}
- if (r->_present.gateway_len) {
+ if (r->_len.gateway) {
route = inet_ntop(r->_hdr.rtm_family, r->gateway,
route_str, sizeof(route_str));
printf("gateway: %s ", route);
diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py
index f93e6e79312a..800710fe96c9 100755
--- a/tools/net/ynl/pyynl/ynl_gen_c.py
+++ b/tools/net/ynl/pyynl/ynl_gen_c.py
@@ -154,7 +154,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
if self.presence_type() == 'len':
pfx = '__' if space == 'user' else ''
- return f"{pfx}u32 {self.c_name}_len;"
+ return f"{pfx}u32 {self.c_name};"
def _complex_member_type(self, ri):
return None
@@ -217,10 +217,9 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
cw.p(f'[{self.enum_name}] = {"{"} .name = "{self.name}", {typol}{"}"},')
def _attr_put_line(self, ri, var, line):
- if self.presence_type() == 'present':
- ri.cw.p(f"if ({var}->_present.{self.c_name})")
- elif self.presence_type() == 'len':
- ri.cw.p(f"if ({var}->_present.{self.c_name}_len)")
+ presence = self.presence_type()
+ if presence in {'present', 'len'}:
+ ri.cw.p(f"if ({var}->_{presence}.{self.c_name})")
ri.cw.p(f"{line};")
def _attr_put_simple(self, ri, var, put_type):
@@ -282,6 +281,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
# Every layer below last is a nest, so we know it uses bit presence
# last layer is "self" and may be a complex type
if i == len(ref) - 1 and self.presence_type() != 'present':
+ presence = f"{var}->{'.'.join(ref[:i] + [''])}_{self.presence_type()}.{ref[i]}"
continue
code.append(presence + ' = 1;')
ref_path = '.'.join(ref[:-1])
@@ -496,7 +496,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
self._attr_put_simple(ri, var, 'str')
def _attr_get(self, ri, var):
- len_mem = var + '->_present.' + self.c_name + '_len'
+ len_mem = var + '->_len.' + self.c_name
return [f"{len_mem} = len;",
f"{var}->{self.c_name} = malloc(len + 1);",
f"memcpy({var}->{self.c_name}, ynl_attr_get_str(attr), len);",
@@ -505,10 +505,10 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
['unsigned int len;']
def _setter_lines(self, ri, member, presence):
- return [f"{presence}_len = strlen({self.c_name});",
- f"{member} = malloc({presence}_len + 1);",
- f'memcpy({member}, {self.c_name}, {presence}_len);',
- f'{member}[{presence}_len] = 0;']
+ return [f"{presence} = strlen({self.c_name});",
+ f"{member} = malloc({presence} + 1);",
+ f'memcpy({member}, {self.c_name}, {presence});',
+ f'{member}[{presence}] = 0;']
class TypeBinary(Type):
@@ -547,10 +547,10 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
def attr_put(self, ri, var):
self._attr_put_line(ri, var, f"ynl_attr_put(nlh, {self.enum_name}, " +
- f"{var}->{self.c_name}, {var}->_present.{self.c_name}_len)")
+ f"{var}->{self.c_name}, {var}->_len.{self.c_name})")
def _attr_get(self, ri, var):
- len_mem = var + '->_present.' + self.c_name + '_len'
+ len_mem = var + '->_len.' + self.c_name
return [f"{len_mem} = len;",
f"{var}->{self.c_name} = malloc(len);",
f"memcpy({var}->{self.c_name}, ynl_attr_data(attr), len);"], \
@@ -558,9 +558,9 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
['unsigned int len;']
def _setter_lines(self, ri, member, presence):
- return [f"{presence}_len = len;",
- f"{member} = malloc({presence}_len);",
- f'memcpy({member}, {self.c_name}, {presence}_len);']
+ return [f"{presence} = len;",
+ f"{member} = malloc({presence});",
+ f'memcpy({member}, {self.c_name}, {presence});']
class TypeBitfield32(Type):
@@ -716,7 +716,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
def _setter_lines(self, ri, member, presence):
# For multi-attr we have a count, not presence, hack up the presence
- presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name
+ presence = presence[:-(len('_count.') + len(self.c_name))] + "n_" + self.c_name
return [f"{member} = {self.c_name};",
f"{presence} = n_{self.c_name};"]
@@ -779,7 +779,7 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
def _setter_lines(self, ri, member, presence):
# For multi-attr we have a count, not presence, hack up the presence
- presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name
+ presence = presence[:-(len('_count.') + len(self.c_name))] + "n_" + self.c_name
return [f"{member} = {self.c_name};",
f"{presence} = n_{self.c_name};"]
@@ -2181,18 +2181,18 @@ _C_KW = {
ri.cw.p(ri.fixed_hdr + ' _hdr;')
ri.cw.nl()
- meta_started = False
- for _, attr in struct.member_list():
- for type_filter in ['len', 'present']:
+ for type_filter in ['present', 'len']:
+ meta_started = False
+ for _, attr in struct.member_list():
line = attr.presence_member(ri.ku_space, type_filter)
if line:
if not meta_started:
ri.cw.block_start(line=f"struct")
meta_started = True
ri.cw.p(line)
- if meta_started:
- ri.cw.block_end(line='_present;')
- ri.cw.nl()
+ if meta_started:
+ ri.cw.block_end(line=f'_{type_filter};')
+ ri.cw.nl()
for arg in struct.inherited:
ri.cw.p(f"__u32 {arg};")
--
2.49.0
next prev parent reply other threads:[~2025-05-05 16:52 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-05 16:52 [PATCH net-next 0/3] tools: ynl-gen: split presence metadata Jakub Kicinski
2025-05-05 16:52 ` [PATCH net-next 1/3] tools: ynl-gen: rename basic presence from 'bit' to 'present' Jakub Kicinski
2025-05-05 20:52 ` David Wei
2025-05-05 16:52 ` Jakub Kicinski [this message]
2025-05-05 21:06 ` [PATCH net-next 2/3] tools: ynl-gen: split presence metadata David Wei
2025-05-06 0:27 ` Jakub Kicinski
2025-05-05 16:52 ` [PATCH net-next 3/3] tools: ynl-gen: move the count into a presence struct too Jakub Kicinski
2025-05-08 1:40 ` [PATCH net-next 0/3] tools: ynl-gen: split presence metadata patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250505165208.248049-3-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jacob.e.keller@intel.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sdf@fomichev.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.