From 30b5c720e1a90c9709187871c9f2152192078519 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:49 -0700 Subject: [PATCH 01/12] tools: ynl-gen: cleanup user space header includes Bots started screaming that we're including stdlib.h twice. While at it move string.h into a common spot and drop stdio.h which we don't need. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=5464 Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=5466 Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=5467 Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index 251c5bfffd8da..e1b86b1fba66f 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -2323,8 +2323,8 @@ def main(): headers = ['uapi/' + parsed.uapi_header] else: cw.p('#include ') + cw.p('#include ') if args.header: - cw.p('#include ') cw.p('#include ') else: cw.p(f'#include "{parsed.name}-user.h"') @@ -2339,9 +2339,6 @@ def main(): if args.mode == "user": if not args.header: - cw.p("#include ") - cw.p("#include ") - cw.p("#include ") cw.p("#include ") cw.p("#include ") cw.nl() From 9b52fd4b630526aa78bde8f9c6217954c71dc6a5 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:50 -0700 Subject: [PATCH 02/12] tools: ynl: regen: cleanup user space header includes Remove unnecessary includes. Signed-off-by: Jakub Kicinski --- tools/net/ynl/generated/devlink-user.c | 4 +--- tools/net/ynl/generated/fou-user.c | 4 +--- tools/net/ynl/generated/handshake-user.c | 4 +--- tools/net/ynl/generated/netdev-user.c | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/tools/net/ynl/generated/devlink-user.c b/tools/net/ynl/generated/devlink-user.c index c3204e20b9717..4604b6829fd07 100644 --- a/tools/net/ynl/generated/devlink-user.c +++ b/tools/net/ynl/generated/devlink-user.c @@ -4,13 +4,11 @@ /* YNL-GEN user source */ #include +#include #include "devlink-user.h" #include "ynl.h" #include -#include -#include -#include #include #include diff --git a/tools/net/ynl/generated/fou-user.c b/tools/net/ynl/generated/fou-user.c index c08c85a6b6c47..23c8f347547ef 100644 --- a/tools/net/ynl/generated/fou-user.c +++ b/tools/net/ynl/generated/fou-user.c @@ -4,13 +4,11 @@ /* YNL-GEN user source */ #include +#include #include "fou-user.h" #include "ynl.h" #include -#include -#include -#include #include #include diff --git a/tools/net/ynl/generated/handshake-user.c b/tools/net/ynl/generated/handshake-user.c index 72eb1c52a8fc9..7c204bf4c7cb6 100644 --- a/tools/net/ynl/generated/handshake-user.c +++ b/tools/net/ynl/generated/handshake-user.c @@ -4,13 +4,11 @@ /* YNL-GEN user source */ #include +#include #include "handshake-user.h" #include "ynl.h" #include -#include -#include -#include #include #include diff --git a/tools/net/ynl/generated/netdev-user.c b/tools/net/ynl/generated/netdev-user.c index 3db6921b9fabe..fe0da71f653c2 100644 --- a/tools/net/ynl/generated/netdev-user.c +++ b/tools/net/ynl/generated/netdev-user.c @@ -4,13 +4,11 @@ /* YNL-GEN user source */ #include +#include #include "netdev-user.h" #include "ynl.h" #include -#include -#include -#include #include #include From 820343ccbb2e11a6579a33a856dcc2a10bb3c7a6 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:51 -0700 Subject: [PATCH 03/12] tools: ynl-gen: complete the C keyword list C keywords need to be avoided when naming things. Complete the list (ethtool has at least one thing called "auto"). Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index e1b86b1fba66f..9b6ff256f80e8 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -1172,7 +1172,40 @@ def write_struct_init(self, members): } _C_KW = { - 'do' + 'auto', + 'bool', + 'break', + 'case', + 'char', + 'const', + 'continue', + 'default', + 'do', + 'double', + 'else', + 'enum', + 'extern', + 'float', + 'for', + 'goto', + 'if', + 'inline', + 'int', + 'long', + 'register', + 'return', + 'short', + 'signed', + 'sizeof', + 'static', + 'struct', + 'switch', + 'typedef', + 'union', + 'unsigned', + 'void', + 'volatile', + 'while' } From 2c0f1466867c8405224b97d978b67f35d76b1dc1 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:52 -0700 Subject: [PATCH 04/12] tools: ynl-gen: combine else with closing bracket Code gen currently prints: } else if (... This is really ugly. Fix it by delaying printing of closing brackets in anticipation of else coming along. Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index 9b6ff256f80e8..d2edded5f747d 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -1017,6 +1017,7 @@ def __init__(self, nlib, out_file): self.nlib = nlib self._nl = False + self._block_end = False self._silent_block = False self._ind = 0 self._out = out_file @@ -1025,11 +1026,18 @@ def __init__(self, nlib, out_file): def _is_cond(cls, line): return line.startswith('if') or line.startswith('while') or line.startswith('for') - def p(self, line, add_ind=0, eat_nl=False): + def p(self, line, add_ind=0): + if self._block_end: + self._block_end = False + if line.startswith('else'): + line = '} ' + line + else: + self._out.write('\t' * self._ind + '}\n') + if self._nl: - if not eat_nl: - self._out.write('\n') + self._out.write('\n') self._nl = False + ind = self._ind if line[-1] == ':': ind -= 1 @@ -1053,7 +1061,14 @@ def block_end(self, line=''): if line and line[0] not in {';', ','}: line = ' ' + line self._ind -= 1 - self.p('}' + line, eat_nl=True) + self._nl = False + if not line: + # Delay printing closing bracket in case "else" comes next + if self._block_end: + self._out.write('\t' * (self._ind + 1) + '}\n') + self._block_end = True + else: + self.p('}' + line) def write_doc_line(self, doc, indent=True): words = doc.split() From e4ea3cc68472b1cc0b68a1adf145ee39fb90a506 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:53 -0700 Subject: [PATCH 05/12] tools: ynl-gen: get attr type outside of if() Reading attr type with mnl_attr_get_type() for each condition leads to most conditions being longer than 80 chars. Avoid this by reading the type to a variable on the stack. Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index d2edded5f747d..ecd8beba7e0d6 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -153,7 +153,7 @@ def attr_get(self, ri, var, first): init_lines = [init_lines] kw = 'if' if first else 'else if' - ri.cw.block_start(line=f"{kw} (mnl_attr_get_type(attr) == {self.enum_name})") + ri.cw.block_start(line=f"{kw} (type == {self.enum_name})") if local_vars: for local in local_vars: ri.cw.p(local) @@ -1418,6 +1418,8 @@ def _multi_parse(ri, struct, init_lines, local_vars): ri.cw.nl() ri.cw.block_start(line=iter_line) + ri.cw.p('unsigned int type = mnl_attr_get_type(attr);') + ri.cw.nl() first = True for _, arg in struct.member_list(): From 7234415b8f86c496fec2d62a48f136cde530ad95 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:54 -0700 Subject: [PATCH 06/12] tools: ynl: regen: regenerate the if ladders Renegate the code to combine } and else and use tmp variable to store type. Signed-off-by: Jakub Kicinski --- tools/net/ynl/generated/devlink-user.c | 74 ++++++++++++------------ tools/net/ynl/generated/fou-user.c | 31 ++++------ tools/net/ynl/generated/handshake-user.c | 29 +++++----- tools/net/ynl/generated/netdev-user.c | 7 ++- 4 files changed, 67 insertions(+), 74 deletions(-) diff --git a/tools/net/ynl/generated/devlink-user.c b/tools/net/ynl/generated/devlink-user.c index 4604b6829fd07..939bd45feacad 100644 --- a/tools/net/ynl/generated/devlink-user.c +++ b/tools/net/ynl/generated/devlink-user.c @@ -126,7 +126,9 @@ int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg, const struct nlattr *attr; mnl_attr_for_each_nested(attr, nested) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_NAME) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_INFO_VERSION_NAME) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -137,8 +139,7 @@ int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg, dst->info_version_name = malloc(len + 1); memcpy(dst->info_version_name, mnl_attr_get_str(attr), len); dst->info_version_name[len] = 0; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_VALUE) { + } else if (type == DEVLINK_ATTR_INFO_VERSION_VALUE) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -167,13 +168,14 @@ int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg, const struct nlattr *attr; mnl_attr_for_each_nested(attr, nested) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_LIMIT) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_STATS_LIMIT) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.reload_stats_limit = 1; dst->reload_stats_limit = mnl_attr_get_u8(attr); - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_VALUE) { + } else if (type == DEVLINK_ATTR_RELOAD_STATS_VALUE) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.reload_stats_value = 1; @@ -208,7 +210,9 @@ int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg, return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)"); mnl_attr_for_each_nested(attr, nested) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { n_reload_stats_entry++; } } @@ -255,13 +259,14 @@ int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg, return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)"); mnl_attr_for_each_nested(attr, nested) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_ACTION) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.reload_action = 1; dst->reload_action = mnl_attr_get_u8(attr); - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) { + } else if (type == DEVLINK_ATTR_RELOAD_ACTION_STATS) { n_reload_action_stats++; } } @@ -308,7 +313,9 @@ int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg, return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)"); mnl_attr_for_each_nested(attr, nested) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_ACTION_INFO) { n_reload_action_info++; } } @@ -347,7 +354,9 @@ int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg, parg.ys = yarg->ys; mnl_attr_for_each_nested(attr, nested) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_STATS) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_STATS) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.reload_stats = 1; @@ -356,8 +365,7 @@ int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg, parg.data = &dst->reload_stats; if (devlink_dl_reload_stats_parse(&parg, attr)) return MNL_CB_ERROR; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_REMOTE_RELOAD_STATS) { + } else if (type == DEVLINK_ATTR_REMOTE_RELOAD_STATS) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.remote_reload_stats = 1; @@ -400,7 +408,9 @@ int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data) parg.ys = yarg->ys; mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_BUS_NAME) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -411,8 +421,7 @@ int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->bus_name = malloc(len + 1); memcpy(dst->bus_name, mnl_attr_get_str(attr), len); dst->bus_name[len] = 0; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_NAME) { + } else if (type == DEVLINK_ATTR_DEV_NAME) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -423,20 +432,17 @@ int devlink_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->dev_name = malloc(len + 1); memcpy(dst->dev_name, mnl_attr_get_str(attr), len); dst->dev_name[len] = 0; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_FAILED) { + } else if (type == DEVLINK_ATTR_RELOAD_FAILED) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.reload_failed = 1; dst->reload_failed = mnl_attr_get_u8(attr); - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_RELOAD_ACTION) { + } else if (type == DEVLINK_ATTR_RELOAD_ACTION) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.reload_action = 1; dst->reload_action = mnl_attr_get_u8(attr); - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_STATS) { + } else if (type == DEVLINK_ATTR_DEV_STATS) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.dev_stats = 1; @@ -576,7 +582,9 @@ int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data) return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)"); mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { - if (mnl_attr_get_type(attr) == DEVLINK_ATTR_BUS_NAME) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -587,8 +595,7 @@ int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->bus_name = malloc(len + 1); memcpy(dst->bus_name, mnl_attr_get_str(attr), len); dst->bus_name[len] = 0; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_DEV_NAME) { + } else if (type == DEVLINK_ATTR_DEV_NAME) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -599,8 +606,7 @@ int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->dev_name = malloc(len + 1); memcpy(dst->dev_name, mnl_attr_get_str(attr), len); dst->dev_name[len] = 0; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_DRIVER_NAME) { + } else if (type == DEVLINK_ATTR_INFO_DRIVER_NAME) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -611,8 +617,7 @@ int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->info_driver_name = malloc(len + 1); memcpy(dst->info_driver_name, mnl_attr_get_str(attr), len); dst->info_driver_name[len] = 0; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_SERIAL_NUMBER) { + } else if (type == DEVLINK_ATTR_INFO_SERIAL_NUMBER) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -623,14 +628,11 @@ int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->info_serial_number = malloc(len + 1); memcpy(dst->info_serial_number, mnl_attr_get_str(attr), len); dst->info_serial_number[len] = 0; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) { + } else if (type == DEVLINK_ATTR_INFO_VERSION_FIXED) { n_info_version_fixed++; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) { + } else if (type == DEVLINK_ATTR_INFO_VERSION_RUNNING) { n_info_version_running++; - } - else if (mnl_attr_get_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) { + } else if (type == DEVLINK_ATTR_INFO_VERSION_STORED) { n_info_version_stored++; } } diff --git a/tools/net/ynl/generated/fou-user.c b/tools/net/ynl/generated/fou-user.c index 23c8f347547ef..4271b5d43c586 100644 --- a/tools/net/ynl/generated/fou-user.c +++ b/tools/net/ynl/generated/fou-user.c @@ -172,42 +172,38 @@ int fou_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst = yarg->data; mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { - if (mnl_attr_get_type(attr) == FOU_ATTR_PORT) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == FOU_ATTR_PORT) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.port = 1; dst->port = mnl_attr_get_u16(attr); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_IPPROTO) { + } else if (type == FOU_ATTR_IPPROTO) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.ipproto = 1; dst->ipproto = mnl_attr_get_u8(attr); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_TYPE) { + } else if (type == FOU_ATTR_TYPE) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.type = 1; dst->type = mnl_attr_get_u8(attr); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_REMCSUM_NOPARTIAL) { + } else if (type == FOU_ATTR_REMCSUM_NOPARTIAL) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.remcsum_nopartial = 1; - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_LOCAL_V4) { + } else if (type == FOU_ATTR_LOCAL_V4) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.local_v4 = 1; dst->local_v4 = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_PEER_V4) { + } else if (type == FOU_ATTR_PEER_V4) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.peer_v4 = 1; dst->peer_v4 = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_LOCAL_V6) { + } else if (type == FOU_ATTR_LOCAL_V6) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -217,8 +213,7 @@ int fou_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->_present.local_v6_len = len; dst->local_v6 = malloc(len); memcpy(dst->local_v6, mnl_attr_get_payload(attr), len); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_PEER_V6) { + } else if (type == FOU_ATTR_PEER_V6) { unsigned int len; if (ynl_attr_validate(yarg, attr)) @@ -228,14 +223,12 @@ int fou_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst->_present.peer_v6_len = len; dst->peer_v6 = malloc(len); memcpy(dst->peer_v6, mnl_attr_get_payload(attr), len); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_PEER_PORT) { + } else if (type == FOU_ATTR_PEER_PORT) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.peer_port = 1; dst->peer_port = mnl_attr_get_u16(attr); - } - else if (mnl_attr_get_type(attr) == FOU_ATTR_IFINDEX) { + } else if (type == FOU_ATTR_IFINDEX) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.ifindex = 1; diff --git a/tools/net/ynl/generated/handshake-user.c b/tools/net/ynl/generated/handshake-user.c index 7c204bf4c7cb6..3a0392b3355e2 100644 --- a/tools/net/ynl/generated/handshake-user.c +++ b/tools/net/ynl/generated/handshake-user.c @@ -116,13 +116,14 @@ int handshake_x509_parse(struct ynl_parse_arg *yarg, const struct nlattr *attr; mnl_attr_for_each_nested(attr, nested) { - if (mnl_attr_get_type(attr) == HANDSHAKE_A_X509_CERT) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == HANDSHAKE_A_X509_CERT) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.cert = 1; dst->cert = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == HANDSHAKE_A_X509_PRIVKEY) { + } else if (type == HANDSHAKE_A_X509_PRIVKEY) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.privkey = 1; @@ -171,37 +172,33 @@ int handshake_accept_rsp_parse(const struct nlmsghdr *nlh, void *data) return ynl_error_parse(yarg, "attribute already present (accept.peer-identity)"); mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { - if (mnl_attr_get_type(attr) == HANDSHAKE_A_ACCEPT_SOCKFD) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == HANDSHAKE_A_ACCEPT_SOCKFD) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.sockfd = 1; dst->sockfd = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == HANDSHAKE_A_ACCEPT_MESSAGE_TYPE) { + } else if (type == HANDSHAKE_A_ACCEPT_MESSAGE_TYPE) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.message_type = 1; dst->message_type = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == HANDSHAKE_A_ACCEPT_TIMEOUT) { + } else if (type == HANDSHAKE_A_ACCEPT_TIMEOUT) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.timeout = 1; dst->timeout = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == HANDSHAKE_A_ACCEPT_AUTH_MODE) { + } else if (type == HANDSHAKE_A_ACCEPT_AUTH_MODE) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.auth_mode = 1; dst->auth_mode = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == HANDSHAKE_A_ACCEPT_PEER_IDENTITY) { + } else if (type == HANDSHAKE_A_ACCEPT_PEER_IDENTITY) { n_peer_identity++; - } - else if (mnl_attr_get_type(attr) == HANDSHAKE_A_ACCEPT_CERTIFICATE) { + } else if (type == HANDSHAKE_A_ACCEPT_CERTIFICATE) { n_certificate++; - } - else if (mnl_attr_get_type(attr) == HANDSHAKE_A_ACCEPT_PEERNAME) { + } else if (type == HANDSHAKE_A_ACCEPT_PEERNAME) { unsigned int len; if (ynl_attr_validate(yarg, attr)) diff --git a/tools/net/ynl/generated/netdev-user.c b/tools/net/ynl/generated/netdev-user.c index fe0da71f653c2..12069784637eb 100644 --- a/tools/net/ynl/generated/netdev-user.c +++ b/tools/net/ynl/generated/netdev-user.c @@ -79,13 +79,14 @@ int netdev_dev_get_rsp_parse(const struct nlmsghdr *nlh, void *data) dst = yarg->data; mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { - if (mnl_attr_get_type(attr) == NETDEV_A_DEV_IFINDEX) { + unsigned int type = mnl_attr_get_type(attr); + + if (type == NETDEV_A_DEV_IFINDEX) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.ifindex = 1; dst->ifindex = mnl_attr_get_u32(attr); - } - else if (mnl_attr_get_type(attr) == NETDEV_A_DEV_XDP_FEATURES) { + } else if (type == NETDEV_A_DEV_XDP_FEATURES) { if (ynl_attr_validate(yarg, attr)) return MNL_CB_ERROR; dst->_present.xdp_features = 1; From f2ba1e5e22081e3279fd248677f53ce719fdc23d Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:55 -0700 Subject: [PATCH 07/12] tools: ynl-gen: stop generating common notification handlers Common notification handler was supposed to be a way for the user to parse the notifications from a socket synchronously. I don't think we'll end up using it, ynl_ntf_check() works for all known use cases. Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 73 -------------------------------------- 1 file changed, 73 deletions(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index ecd8beba7e0d6..f88417947e60e 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -1810,70 +1810,6 @@ def print_ntf_type_free(ri): ri.cw.nl() -def print_ntf_parse_prototype(family, cw, suffix=';'): - cw.write_func_prot('struct ynl_ntf_base_type *', f"{family['name']}_ntf_parse", - ['struct ynl_sock *ys'], suffix=suffix) - - -def print_ntf_type_parse(family, cw, ku_mode): - print_ntf_parse_prototype(family, cw, suffix='') - cw.block_start() - cw.write_func_lvar(['struct genlmsghdr *genlh;', - 'struct nlmsghdr *nlh;', - 'struct ynl_parse_arg yarg = { .ys = ys, };', - 'struct ynl_ntf_base_type *rsp;', - 'int len, err;', - 'mnl_cb_t parse;']) - cw.p('len = mnl_socket_recvfrom(ys->sock, ys->rx_buf, MNL_SOCKET_BUFFER_SIZE);') - cw.p('if (len < (ssize_t)(sizeof(*nlh) + sizeof(*genlh)))') - cw.p('return NULL;') - cw.nl() - cw.p('nlh = (struct nlmsghdr *)ys->rx_buf;') - cw.p('genlh = mnl_nlmsg_get_payload(nlh);') - cw.nl() - cw.block_start(line='switch (genlh->cmd)') - for ntf_op in sorted(family.all_notify.keys()): - op = family.ops[ntf_op] - ri = RenderInfo(cw, family, ku_mode, op, ntf_op, "notify") - for ntf in op['notify']['cmds']: - cw.p(f"case {ntf.enum_name}:") - cw.p(f"rsp = calloc(1, sizeof({type_name(ri, 'notify')}));") - cw.p(f"parse = {op_prefix(ri, 'reply', deref=True)}_parse;") - cw.p(f"yarg.rsp_policy = &{ri.struct['reply'].render_name}_nest;") - cw.p(f"rsp->free = (void *){op_prefix(ri, 'notify')}_free;") - cw.p('break;') - for op_name, op in family.ops.items(): - if 'event' not in op: - continue - ri = RenderInfo(cw, family, ku_mode, op, op_name, "event") - cw.p(f"case {op.enum_name}:") - cw.p(f"rsp = calloc(1, sizeof({type_name(ri, 'event')}));") - cw.p(f"parse = {op_prefix(ri, 'reply', deref=True)}_parse;") - cw.p(f"yarg.rsp_policy = &{ri.struct['reply'].render_name}_nest;") - cw.p(f"rsp->free = (void *){op_prefix(ri, 'notify')}_free;") - cw.p('break;') - cw.p('default:') - cw.p('ynl_error_unknown_notification(ys, genlh->cmd);') - cw.p('return NULL;') - cw.block_end() - cw.nl() - cw.p('yarg.data = rsp->data;') - cw.nl() - cw.p(f"err = {cw.nlib.parse_cb_run('parse', '&yarg', True)};") - cw.p('if (err < 0)') - cw.p('goto err_free;') - cw.nl() - cw.p('rsp->family = nlh->nlmsg_type;') - cw.p('rsp->cmd = genlh->cmd;') - cw.p('return rsp;') - cw.nl() - cw.p('err_free:') - cw.p('free(rsp);') - cw.p('return NULL;') - cw.block_end() - cw.nl() - - def print_req_policy_fwd(cw, struct, ri=None, terminate=True): if terminate and ri and kernel_can_gen_family_struct(struct.family): return @@ -2513,10 +2449,6 @@ def main(): print_rsp_type(ri) cw.nl() print_wrapped_type(ri) - - if parsed.has_notifications(): - cw.p('/* --------------- Common notification parsing --------------- */') - print_ntf_parse_prototype(parsed, cw) cw.nl() else: cw.p('/* Enums */') @@ -2580,11 +2512,6 @@ def main(): ri = RenderInfo(cw, parsed, args.mode, op, op_name, "event") print_ntf_type_free(ri) - - if parsed.has_notifications(): - cw.p('/* --------------- Common notification parsing --------------- */') - print_ntf_type_parse(parsed, cw, args.mode) - cw.nl() render_user_family(parsed, cw, False) From d0915d64c3a636f73065dbb7e5aab78eb7e75f0d Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:56 -0700 Subject: [PATCH 08/12] tools: ynl: regen: stop generating common notification handlers Remove unused notification handlers. Signed-off-by: Jakub Kicinski --- tools/net/ynl/generated/handshake-user.c | 45 ----------------------- tools/net/ynl/generated/handshake-user.h | 3 -- tools/net/ynl/generated/netdev-user.c | 47 ------------------------ tools/net/ynl/generated/netdev-user.h | 3 -- 4 files changed, 98 deletions(-) diff --git a/tools/net/ynl/generated/handshake-user.c b/tools/net/ynl/generated/handshake-user.c index 3a0392b3355e2..7c67765daf902 100644 --- a/tools/net/ynl/generated/handshake-user.c +++ b/tools/net/ynl/generated/handshake-user.c @@ -315,51 +315,6 @@ int handshake_done(struct ynl_sock *ys, struct handshake_done_req *req) return 0; } -/* --------------- Common notification parsing --------------- */ -struct ynl_ntf_base_type *handshake_ntf_parse(struct ynl_sock *ys) -{ - struct ynl_parse_arg yarg = { .ys = ys, }; - struct ynl_ntf_base_type *rsp; - struct genlmsghdr *genlh; - struct nlmsghdr *nlh; - mnl_cb_t parse; - int len, err; - - len = mnl_socket_recvfrom(ys->sock, ys->rx_buf, MNL_SOCKET_BUFFER_SIZE); - if (len < (ssize_t)(sizeof(*nlh) + sizeof(*genlh))) - return NULL; - - nlh = (struct nlmsghdr *)ys->rx_buf; - genlh = mnl_nlmsg_get_payload(nlh); - - switch (genlh->cmd) { - case HANDSHAKE_CMD_READY: - rsp = calloc(1, sizeof(struct handshake_accept_ntf)); - parse = handshake_accept_rsp_parse; - yarg.rsp_policy = &handshake_accept_nest; - rsp->free = (void *)handshake_accept_ntf_free; - break; - default: - ynl_error_unknown_notification(ys, genlh->cmd); - return NULL; - } - - yarg.data = rsp->data; - - err = mnl_cb_run2(ys->rx_buf, len, 0, 0, parse, &yarg, - ynl_cb_array, NLMSG_MIN_TYPE); - if (err < 0) - goto err_free; - - rsp->family = nlh->nlmsg_type; - rsp->cmd = genlh->cmd; - return rsp; - -err_free: - free(rsp); - return NULL; -} - static const struct ynl_ntf_info handshake_ntf_info[] = { [HANDSHAKE_CMD_READY] = { .alloc_sz = sizeof(struct handshake_accept_ntf), diff --git a/tools/net/ynl/generated/handshake-user.h b/tools/net/ynl/generated/handshake-user.h index 38e0844f2efd8..47646bb91cea6 100644 --- a/tools/net/ynl/generated/handshake-user.h +++ b/tools/net/ynl/generated/handshake-user.h @@ -142,7 +142,4 @@ __handshake_done_req_set_remote_auth(struct handshake_done_req *req, */ int handshake_done(struct ynl_sock *ys, struct handshake_done_req *req); -/* --------------- Common notification parsing --------------- */ -struct ynl_ntf_base_type *handshake_ntf_parse(struct ynl_sock *ys); - #endif /* _LINUX_HANDSHAKE_GEN_H */ diff --git a/tools/net/ynl/generated/netdev-user.c b/tools/net/ynl/generated/netdev-user.c index 12069784637eb..4eb8aefef0cd2 100644 --- a/tools/net/ynl/generated/netdev-user.c +++ b/tools/net/ynl/generated/netdev-user.c @@ -172,53 +172,6 @@ void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp) free(rsp); } -/* --------------- Common notification parsing --------------- */ -struct ynl_ntf_base_type *netdev_ntf_parse(struct ynl_sock *ys) -{ - struct ynl_parse_arg yarg = { .ys = ys, }; - struct ynl_ntf_base_type *rsp; - struct genlmsghdr *genlh; - struct nlmsghdr *nlh; - mnl_cb_t parse; - int len, err; - - len = mnl_socket_recvfrom(ys->sock, ys->rx_buf, MNL_SOCKET_BUFFER_SIZE); - if (len < (ssize_t)(sizeof(*nlh) + sizeof(*genlh))) - return NULL; - - nlh = (struct nlmsghdr *)ys->rx_buf; - genlh = mnl_nlmsg_get_payload(nlh); - - switch (genlh->cmd) { - case NETDEV_CMD_DEV_ADD_NTF: - case NETDEV_CMD_DEV_DEL_NTF: - case NETDEV_CMD_DEV_CHANGE_NTF: - rsp = calloc(1, sizeof(struct netdev_dev_get_ntf)); - parse = netdev_dev_get_rsp_parse; - yarg.rsp_policy = &netdev_dev_nest; - rsp->free = (void *)netdev_dev_get_ntf_free; - break; - default: - ynl_error_unknown_notification(ys, genlh->cmd); - return NULL; - } - - yarg.data = rsp->data; - - err = mnl_cb_run2(ys->rx_buf, len, 0, 0, parse, &yarg, - ynl_cb_array, NLMSG_MIN_TYPE); - if (err < 0) - goto err_free; - - rsp->family = nlh->nlmsg_type; - rsp->cmd = genlh->cmd; - return rsp; - -err_free: - free(rsp); - return NULL; -} - static const struct ynl_ntf_info netdev_ntf_info[] = { [NETDEV_CMD_DEV_ADD_NTF] = { .alloc_sz = sizeof(struct netdev_dev_get_ntf), diff --git a/tools/net/ynl/generated/netdev-user.h b/tools/net/ynl/generated/netdev-user.h index d146bc4b21122..5554dc69bb9c8 100644 --- a/tools/net/ynl/generated/netdev-user.h +++ b/tools/net/ynl/generated/netdev-user.h @@ -82,7 +82,4 @@ struct netdev_dev_get_ntf { void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp); -/* --------------- Common notification parsing --------------- */ -struct ynl_ntf_base_type *netdev_ntf_parse(struct ynl_sock *ys); - #endif /* _LINUX_NETDEV_GEN_H */ From ced1568862bdb985eb4e5ca854cc7734a4ad3543 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:57 -0700 Subject: [PATCH 09/12] tools: ynl-gen: sanitize notification tracking Don't modify the raw dicts (as loaded from YAML) to pretend that the notify attributes also exist on the ops. This makes the code easier to follow. Signed-off-by: Jakub Kicinski --- tools/net/ynl/lib/nlspec.py | 5 ++- tools/net/ynl/ynl-gen-c.py | 65 +++++++++++++------------------------ 2 files changed, 27 insertions(+), 43 deletions(-) diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py index 9f7ad87d69af0..623c5702bd10c 100644 --- a/tools/net/ynl/lib/nlspec.py +++ b/tools/net/ynl/lib/nlspec.py @@ -329,8 +329,8 @@ class SpecFamily(SpecElement): attr_sets dict of attribute sets msgs dict of all messages (index by name) - msgs_by_value dict of all messages (indexed by name) ops dict of all valid requests / responses + ntfs dict of all async events consts dict of all constants/enums fixed_header string, optional name of family default fixed header struct """ @@ -370,6 +370,7 @@ def __init__(self, spec_path, schema_path=None): self.req_by_value = collections.OrderedDict() self.rsp_by_value = collections.OrderedDict() self.ops = collections.OrderedDict() + self.ntfs = collections.OrderedDict() self.consts = collections.OrderedDict() last_exception = None @@ -491,3 +492,5 @@ def resolve(self): self.rsp_by_value[op.rsp_value] = op if not op.is_async and 'attribute-set' in op: self.ops[op.name] = op + elif op.is_async: + self.ntfs[op.name] = op diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index f88417947e60e..a230598d216f5 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -714,6 +714,8 @@ def __init__(self, family, yaml, req_value, rsp_value): self.dual_policy = ('do' in yaml and 'request' in yaml['do']) and \ ('dump' in yaml and 'request' in yaml['dump']) + self.has_ntf = False + # Added by resolve: self.enum_name = None delattr(self, "enum_name") @@ -726,12 +728,8 @@ def resolve(self): else: self.enum_name = self.family.async_op_prefix + c_upper(self.name) - def add_notification(self, op): - if 'notify' not in self.yaml: - self.yaml['notify'] = dict() - self.yaml['notify']['reply'] = self.yaml['do']['reply'] - self.yaml['notify']['cmds'] = [] - self.yaml['notify']['cmds'].append(op) + def mark_has_ntf(self): + self.has_ntf = True class Family(SpecFamily): @@ -793,14 +791,12 @@ def resolve(self): self.root_sets = dict() # dict space-name -> set('request', 'reply') self.pure_nested_structs = dict() - self.all_notify = dict() + self._mark_notify() self._mock_up_events() - self._dictify() self._load_root_sets() self._load_nested_sets() - self._load_all_notify() self._load_hooks() self.kernel_policy = self.yaml.get('kernel-policy', 'split') @@ -816,6 +812,11 @@ def new_attr_set(self, elem): def new_operation(self, elem, req_value, rsp_value): return Operation(self, elem, req_value, rsp_value) + def _mark_notify(self): + for op in self.msgs.values(): + if 'notify' in op: + self.ops[op['notify']].mark_has_ntf() + # Fake a 'do' equivalent of all events, so that we can render their response parsing def _mock_up_events(self): for op in self.yaml['operations']['list']: @@ -826,14 +827,6 @@ def _mock_up_events(self): } } - def _dictify(self): - ntf = [] - for msg in self.msgs.values(): - if 'notify' in msg: - ntf.append(msg) - for n in ntf: - self.ops[n['notify']].add_notification(n) - def _load_root_sets(self): for op_name, op in self.ops.items(): if 'attribute-set' not in op: @@ -922,14 +915,6 @@ def _load_nested_sets(self): child.request |= struct.request child.reply |= struct.reply - def _load_all_notify(self): - for op_name, op in self.ops.items(): - if not op: - continue - - if 'notify' in op: - self.all_notify[op_name] = op['notify']['cmds'] - def _load_global_policy(self): global_set = set() attr_set_name = None @@ -968,21 +953,15 @@ def _load_hooks(self): self.hooks[when][op_mode]['set'].add(name) self.hooks[when][op_mode]['list'].append(name) - def has_notifications(self): - for op in self.ops.values(): - if 'notify' in op or 'event' in op: - return True - return False - class RenderInfo: def __init__(self, cw, family, ku_space, op, op_name, op_mode, attr_set=None): self.family = family self.nl = cw.nlib self.ku_space = ku_space + self.op_mode = op_mode self.op = op self.op_name = op_name - self.op_mode = op_mode # 'do' and 'dump' response parsing is identical self.type_consistent = True @@ -1004,6 +983,8 @@ def __init__(self, cw, family, ku_space, op, op_name, op_mode, attr_set=None): self.cw = cw self.struct = dict() + if op_mode == 'notify': + op_mode = 'do' for op_dir in ['request', 'reply']: if op and op_dir in op[op_mode]: self.struct[op_dir] = Struct(family, self.attr_set, @@ -2209,14 +2190,14 @@ def render_user_family(family, cw, prototype): cw.p(f'extern {symbol};') return - ntf = family.has_notifications() - if ntf: + if family.ntfs: cw.block_start(line=f"static const struct ynl_ntf_info {family['name']}_ntf_info[] = ") - for ntf_op in sorted(family.all_notify.keys()): - op = family.ops[ntf_op] - ri = RenderInfo(cw, family, "user", op, ntf_op, "notify") - for ntf in op['notify']['cmds']: - _render_user_ntf_entry(ri, ntf) + for ntf_op_name, ntf_op in family.ntfs.items(): + if 'notify' not in ntf_op: + continue + op = family.ops[ntf_op['notify']] + ri = RenderInfo(cw, family, "user", op, op.name, "notify") + _render_user_ntf_entry(ri, ntf_op) for op_name, op in family.ops.items(): if 'event' not in op: continue @@ -2227,7 +2208,7 @@ def render_user_family(family, cw, prototype): cw.block_start(f'{symbol} = ') cw.p(f'.name\t\t= "{family.name}",') - if ntf: + if family.ntfs: cw.p(f".ntf_info\t= {family['name']}_ntf_info,") cw.p(f".ntf_info_size\t= MNL_ARRAY_SIZE({family['name']}_ntf_info),") cw.block_end(line=';') @@ -2436,7 +2417,7 @@ def main(): print_dump_prototype(ri) cw.nl() - if 'notify' in op: + if op.has_ntf: cw.p(f"/* {op.enum_name} - notify */") ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify') if not ri.type_consistent: @@ -2497,7 +2478,7 @@ def main(): print_dump(ri) cw.nl() - if 'notify' in op: + if op.has_ntf: cw.p(f"/* {op.enum_name} - notify */") ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify') if not ri.type_consistent: From 6da3424fd629570b5e3b5e9484ffc752a325f9f5 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:58 -0700 Subject: [PATCH 10/12] tools: ynl-gen: support code gen for events Netlink specs support both events and notifications (former can define their own message contents). Plug in missing code to generate types, parsers and include events into notification tables. Signed-off-by: Jakub Kicinski --- tools/net/ynl/lib/nlspec.py | 2 +- tools/net/ynl/ynl-gen-c.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/lib/nlspec.py index 623c5702bd10c..c5d4a6d476a0c 100644 --- a/tools/net/ynl/lib/nlspec.py +++ b/tools/net/ynl/lib/nlspec.py @@ -423,7 +423,7 @@ def _dictify_ops_directional(self): self.fixed_header = self.yaml['operations'].get('fixed-header') req_val = rsp_val = 1 for elem in self.yaml['operations']['list']: - if 'notify' in elem: + if 'notify' in elem or 'event' in elem: if 'value' in elem: rsp_val = elem['value'] req_val_next = req_val diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index a230598d216f5..ccd73f10384c9 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -828,7 +828,7 @@ def _mock_up_events(self): } def _load_root_sets(self): - for op_name, op in self.ops.items(): + for op_name, op in self.msgs.items(): if 'attribute-set' not in op: continue @@ -839,6 +839,8 @@ def _load_root_sets(self): req_attrs.update(set(op[op_mode]['request']['attributes'])) if op_mode in op and 'reply' in op[op_mode]: rsp_attrs.update(set(op[op_mode]['reply']['attributes'])) + if 'event' in op: + rsp_attrs.update(set(op['event']['attributes'])) if op['attribute-set'] not in self.root_sets: self.root_sets[op['attribute-set']] = {'request': req_attrs, 'reply': rsp_attrs} @@ -2193,10 +2195,13 @@ def render_user_family(family, cw, prototype): if family.ntfs: cw.block_start(line=f"static const struct ynl_ntf_info {family['name']}_ntf_info[] = ") for ntf_op_name, ntf_op in family.ntfs.items(): - if 'notify' not in ntf_op: - continue - op = family.ops[ntf_op['notify']] - ri = RenderInfo(cw, family, "user", op, op.name, "notify") + if 'notify' in ntf_op: + op = family.ops[ntf_op['notify']] + ri = RenderInfo(cw, family, "user", op, op.name, "notify") + elif 'event' in ntf_op: + ri = RenderInfo(cw, family, "user", ntf_op, ntf_op_name, "event") + else: + raise Exception('Invalid notification ' + ntf_op_name) _render_user_ntf_entry(ri, ntf_op) for op_name, op in family.ops.items(): if 'event' not in op: @@ -2424,6 +2429,7 @@ def main(): raise Exception(f'Only notifications with consistent types supported ({op.name})') print_wrapped_type(ri) + for op_name, op in parsed.ntfs.items(): if 'event' in op: ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'event') cw.p(f"/* {op.enum_name} - event */") @@ -2485,6 +2491,7 @@ def main(): raise Exception(f'Only notifications with consistent types supported ({op.name})') print_ntf_type_free(ri) + for op_name, op in parsed.ntfs.items(): if 'event' in op: cw.p(f"/* {op.enum_name} - event */") From 6f96ec73cb5a87f438fa20c585e72b2918885df3 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:11:59 -0700 Subject: [PATCH 11/12] tools: ynl-gen: don't pass op_name to RenderInfo The op_name argument is barely used and identical to op.name in all cases. Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index ccd73f10384c9..be860dee72395 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -957,13 +957,12 @@ def _load_hooks(self): class RenderInfo: - def __init__(self, cw, family, ku_space, op, op_name, op_mode, attr_set=None): + def __init__(self, cw, family, ku_space, op, op_mode, attr_set=None): self.family = family self.nl = cw.nlib self.ku_space = ku_space self.op_mode = op_mode self.op = op - self.op_name = op_name # 'do' and 'dump' response parsing is identical self.type_consistent = True @@ -978,7 +977,7 @@ def __init__(self, cw, family, ku_space, op, op_name, op_mode, attr_set=None): self.attr_set = op['attribute-set'] if op: - self.type_name = c_lower(op_name) + self.type_name = c_lower(op.name) else: self.type_name = c_lower(attr_set) @@ -2197,16 +2196,16 @@ def render_user_family(family, cw, prototype): for ntf_op_name, ntf_op in family.ntfs.items(): if 'notify' in ntf_op: op = family.ops[ntf_op['notify']] - ri = RenderInfo(cw, family, "user", op, op.name, "notify") + ri = RenderInfo(cw, family, "user", op, "notify") elif 'event' in ntf_op: - ri = RenderInfo(cw, family, "user", ntf_op, ntf_op_name, "event") + ri = RenderInfo(cw, family, "user", ntf_op, "event") else: raise Exception('Invalid notification ' + ntf_op_name) _render_user_ntf_entry(ri, ntf_op) for op_name, op in family.ops.items(): if 'event' not in op: continue - ri = RenderInfo(cw, family, "user", op, op_name, "event") + ri = RenderInfo(cw, family, "user", op, "event") _render_user_ntf_entry(ri, op) cw.block_end(line=";") cw.nl() @@ -2343,7 +2342,7 @@ def main(): if parsed.kernel_policy in {'per-op', 'split'}: for op_name, op in parsed.ops.items(): if 'do' in op and 'event' not in op: - ri = RenderInfo(cw, parsed, args.mode, op, op_name, "do") + ri = RenderInfo(cw, parsed, args.mode, op, "do") print_req_policy_fwd(cw, ri.struct['request'], ri=ri) cw.nl() @@ -2372,7 +2371,7 @@ def main(): for op_mode in ['do', 'dump']: if op_mode in op and 'request' in op[op_mode]: cw.p(f"/* {op.enum_name} - {op_mode} */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, op_mode) + ri = RenderInfo(cw, parsed, args.mode, op, op_mode) print_req_policy(cw, ri.struct['request'], ri=ri) cw.nl() @@ -2392,7 +2391,7 @@ def main(): cw.p('/* Common nested types */') for attr_set, struct in parsed.pure_nested_structs.items(): - ri = RenderInfo(cw, parsed, args.mode, "", "", "", attr_set) + ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set) print_type_full(ri, struct) for op_name, op in parsed.ops.items(): @@ -2400,7 +2399,7 @@ def main(): if 'do' in op and 'event' not in op: cw.p(f"/* {op.enum_name} - do */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, "do") + ri = RenderInfo(cw, parsed, args.mode, op, "do") print_req_type(ri) print_req_type_helpers(ri) cw.nl() @@ -2412,7 +2411,7 @@ def main(): if 'dump' in op: cw.p(f"/* {op.enum_name} - dump */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'dump') + ri = RenderInfo(cw, parsed, args.mode, op, 'dump') if 'request' in op['dump']: print_req_type(ri) print_req_type_helpers(ri) @@ -2424,14 +2423,14 @@ def main(): if op.has_ntf: cw.p(f"/* {op.enum_name} - notify */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify') + ri = RenderInfo(cw, parsed, args.mode, op, 'notify') if not ri.type_consistent: raise Exception(f'Only notifications with consistent types supported ({op.name})') print_wrapped_type(ri) for op_name, op in parsed.ntfs.items(): if 'event' in op: - ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'event') + ri = RenderInfo(cw, parsed, args.mode, op, 'event') cw.p(f"/* {op.enum_name} - event */") print_rsp_type(ri) cw.nl() @@ -2456,7 +2455,7 @@ def main(): cw.p('/* Common nested types */') for attr_set, struct in parsed.pure_nested_structs.items(): - ri = RenderInfo(cw, parsed, args.mode, "", "", "", attr_set) + ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set) free_rsp_nested(ri, struct) if struct.request: @@ -2468,7 +2467,7 @@ def main(): cw.p(f"/* ============== {op.enum_name} ============== */") if 'do' in op and 'event' not in op: cw.p(f"/* {op.enum_name} - do */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, "do") + ri = RenderInfo(cw, parsed, args.mode, op, "do") print_req_free(ri) print_rsp_free(ri) parse_rsp_msg(ri) @@ -2477,7 +2476,7 @@ def main(): if 'dump' in op: cw.p(f"/* {op.enum_name} - dump */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, "dump") + ri = RenderInfo(cw, parsed, args.mode, op, "dump") if not ri.type_consistent: parse_rsp_msg(ri, deref=True) print_dump_type_free(ri) @@ -2486,7 +2485,7 @@ def main(): if op.has_ntf: cw.p(f"/* {op.enum_name} - notify */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, 'notify') + ri = RenderInfo(cw, parsed, args.mode, op, 'notify') if not ri.type_consistent: raise Exception(f'Only notifications with consistent types supported ({op.name})') print_ntf_type_free(ri) @@ -2495,10 +2494,10 @@ def main(): if 'event' in op: cw.p(f"/* {op.enum_name} - event */") - ri = RenderInfo(cw, parsed, args.mode, op, op_name, "do") + ri = RenderInfo(cw, parsed, args.mode, op, "do") parse_rsp_msg(ri) - ri = RenderInfo(cw, parsed, args.mode, op, op_name, "event") + ri = RenderInfo(cw, parsed, args.mode, op, "event") print_ntf_type_free(ri) cw.nl() render_user_family(parsed, cw, False) From 76abff37f0d70066503747a76deb40b752fb23be Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 8 Jun 2023 14:12:00 -0700 Subject: [PATCH 12/12] tools: ynl-gen: support / skip pads on the way to kernel Kernel does not have padding requirements for 64b attrs. We can ignore pad attrs. Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index be860dee72395..7b051c00cfc30 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -227,12 +227,18 @@ def arg_member(self, ri): def _attr_typol(self): return '.type = YNL_PT_IGNORE, ' + def attr_put(self, ri, var): + pass + def attr_get(self, ri, var, first): pass def attr_policy(self, cw): pass + def setter(self, ri, space, direction, deref=False, ref=None): + pass + class TypeScalar(Type): def __init__(self, family, attr_set, attr, value):