tools: ynl: create local for_each helpers
authorJakub Kicinski <kuba@kernel.org>
Tue, 27 Feb 2024 22:30:20 +0000 (14:30 -0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 28 Feb 2024 23:25:42 +0000 (15:25 -0800)
Create ynl_attr_for_each*() iteration helpers.
Use them instead of the mnl ones.

Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Link: https://lore.kernel.org/r/20240227223032.1835527-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/net/ynl/lib/ynl-priv.h
tools/net/ynl/lib/ynl.c
tools/net/ynl/ynl-gen-c.py

index d42d44a77dcbd399abd08ff4b1d4fbfc0bf1574e..a339732450c3926e499b9093facc1f84f969dd5b 100644 (file)
@@ -147,6 +147,53 @@ static inline void *ynl_attr_data(const struct nlattr *attr)
        return (unsigned char *)attr + NLA_HDRLEN;
 }
 
+static inline void *ynl_attr_data_end(const struct nlattr *attr)
+{
+       return ynl_attr_data(attr) + ynl_attr_data_len(attr);
+}
+
+#define ynl_attr_for_each(attr, nlh, fixed_hdr_sz)                     \
+       for ((attr) = ynl_attr_first(nlh, (nlh)->nlmsg_len,             \
+                                    NLMSG_HDRLEN + fixed_hdr_sz); attr; \
+            (attr) = ynl_attr_next(ynl_nlmsg_end_addr(nlh), attr))
+
+#define ynl_attr_for_each_nested(attr, outer)                          \
+       for ((attr) = ynl_attr_first(outer, outer->nla_len,             \
+                                    sizeof(struct nlattr)); attr;      \
+            (attr) = ynl_attr_next(ynl_attr_data_end(outer), attr))
+
+#define ynl_attr_for_each_payload(start, len, attr)                    \
+       for ((attr) = ynl_attr_first(start, len, 0); attr;              \
+            (attr) = ynl_attr_next(start + len, attr))
+
+static inline struct nlattr *
+ynl_attr_if_good(const void *end, struct nlattr *attr)
+{
+       if (attr + 1 > (const struct nlattr *)end)
+               return NULL;
+       if (ynl_attr_data_end(attr) > end)
+               return NULL;
+       return attr;
+}
+
+static inline struct nlattr *
+ynl_attr_next(const void *end, const struct nlattr *prev)
+{
+       struct nlattr *attr;
+
+       attr = (void *)((char *)prev + NLA_ALIGN(prev->nla_len));
+       return ynl_attr_if_good(end, attr);
+}
+
+static inline struct nlattr *
+ynl_attr_first(const void *start, size_t len, size_t skip)
+{
+       struct nlattr *attr;
+
+       attr = (void *)((char *)start + NLMSG_ALIGN(skip));
+       return ynl_attr_if_good(start + len, attr);
+}
+
 static inline struct nlattr *
 ynl_attr_nest_start(struct nlmsghdr *nlh, unsigned int attr_type)
 {
index b9ed587af676b12001921c0ea290b5b6e313b724..0f71e69b70c07c7e62b5140b42e45fc9ad32430f 100644 (file)
@@ -92,7 +92,7 @@ ynl_err_walk(struct ynl_sock *ys, void *start, void *end, unsigned int off,
 
        data_len = end - start;
 
-       mnl_attr_for_each_payload(start, data_len) {
+       ynl_attr_for_each_payload(start, data_len, attr) {
                astart_off = (char *)attr - (char *)start;
                aend_off = astart_off + ynl_attr_data_len(attr);
                if (aend_off <= off)
@@ -150,7 +150,7 @@ ynl_ext_ack_check(struct ynl_sock *ys, const struct nlmsghdr *nlh,
                return MNL_CB_OK;
        }
 
-       mnl_attr_for_each(attr, nlh, hlen) {
+       ynl_attr_for_each(attr, nlh, hlen) {
                unsigned int len, type;
 
                len = ynl_attr_data_len(attr);
@@ -500,7 +500,7 @@ ynl_get_family_info_mcast(struct ynl_sock *ys, const struct nlattr *mcasts)
        const struct nlattr *entry, *attr;
        unsigned int i;
 
-       mnl_attr_for_each_nested(attr, mcasts)
+       ynl_attr_for_each_nested(attr, mcasts)
                ys->n_mcast_groups++;
 
        if (!ys->n_mcast_groups)
@@ -512,8 +512,8 @@ ynl_get_family_info_mcast(struct ynl_sock *ys, const struct nlattr *mcasts)
                return MNL_CB_ERROR;
 
        i = 0;
-       mnl_attr_for_each_nested(entry, mcasts) {
-               mnl_attr_for_each_nested(attr, entry) {
+       ynl_attr_for_each_nested(entry, mcasts) {
+               ynl_attr_for_each_nested(attr, entry) {
                        if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GRP_ID)
                                ys->mcast_groups[i].id = ynl_attr_get_u32(attr);
                        if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GRP_NAME) {
@@ -535,7 +535,7 @@ static int ynl_get_family_info_cb(const struct nlmsghdr *nlh, void *data)
        const struct nlattr *attr;
        bool found_id = true;
 
-       mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+       ynl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
                if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GROUPS)
                        if (ynl_get_family_info_mcast(ys, attr))
                                return MNL_CB_ERROR;
index 99a3eb7b158b20b950ee6c35299e52f501194fc9..eabce06f03d933a42cf532da021037a7ce2a282d 100755 (executable)
@@ -650,7 +650,7 @@ class TypeArrayNest(Type):
     def _attr_get(self, ri, var):
         local_vars = ['const struct nlattr *attr2;']
         get_lines = [f'attr_{self.c_name} = attr;',
-                     'mnl_attr_for_each_nested(attr2, attr)',
+                     'ynl_attr_for_each_nested(attr2, attr)',
                      f'\t{var}->n_{self.c_name}++;']
         return get_lines, None, local_vars
 
@@ -1612,11 +1612,11 @@ def put_req_nested(ri, struct):
 
 def _multi_parse(ri, struct, init_lines, local_vars):
     if struct.nested:
-        iter_line = "mnl_attr_for_each_nested(attr, nested)"
+        iter_line = "ynl_attr_for_each_nested(attr, nested)"
     else:
         if ri.fixed_hdr:
             local_vars += ['void *hdr;']
-        iter_line = "mnl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len)"
+        iter_line = "ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len)"
 
     array_nests = set()
     multi_attrs = set()
@@ -1679,7 +1679,7 @@ def _multi_parse(ri, struct, init_lines, local_vars):
         ri.cw.p(f"dst->n_{aspec.c_name} = n_{aspec.c_name};")
         ri.cw.p('i = 0;')
         ri.cw.p(f"parg.rsp_policy = &{aspec.nested_render_name}_nest;")
-        ri.cw.block_start(line=f"mnl_attr_for_each_nested(attr, attr_{aspec.c_name})")
+        ri.cw.block_start(line=f"ynl_attr_for_each_nested(attr, attr_{aspec.c_name})")
         ri.cw.p(f"parg.data = &dst->{aspec.c_name}[i];")
         ri.cw.p(f"if ({aspec.nested_render_name}_parse(&parg, attr, ynl_attr_type(attr)))")
         ri.cw.p('return MNL_CB_ERROR;')