Commit fe7d57e0 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Paolo Abeni
Browse files

tools: ynl: let classic netlink requests specify extra nlflags



Classic netlink makes extensive use of flags. Support specifying
them the same way as attributes are specified (using a helper),
for example:

     rt_link_newlink_req_set_nlflags(req, NLM_F_CREATE | NLM_F_ECHO);

Wrap the code up in a RenderInfo predicate. I think that some
genetlink families may want this, too. It should be easy to
add a spec property later.

Reviewed-by: default avatarDonald Hunter <donald.hunter@gmail.com>
Reviewed-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20250429154704.2613851-5-kuba@kernel.org


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent d12a7be0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ struct ynl_ntf_base_type {
	unsigned char data[] __attribute__((aligned(8)));
};

struct nlmsghdr *ynl_msg_start_req(struct ynl_sock *ys, __u32 id);
struct nlmsghdr *ynl_msg_start_req(struct ynl_sock *ys, __u32 id, __u16 flags);
struct nlmsghdr *ynl_msg_start_dump(struct ynl_sock *ys, __u32 id);

struct nlmsghdr *
+2 −2
Original line number Diff line number Diff line
@@ -451,9 +451,9 @@ ynl_gemsg_start(struct ynl_sock *ys, __u32 id, __u16 flags,
	return nlh;
}

struct nlmsghdr *ynl_msg_start_req(struct ynl_sock *ys, __u32 id)
struct nlmsghdr *ynl_msg_start_req(struct ynl_sock *ys, __u32 id, __u16 flags)
{
	return ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK);
	return ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK | flags);
}

struct nlmsghdr *ynl_msg_start_dump(struct ynl_sock *ys, __u32 id)
+20 −1
Original line number Diff line number Diff line
@@ -1294,6 +1294,9 @@ class RenderInfo:
    def type_empty(self, key):
        return len(self.struct[key].attr_list) == 0 and self.fixed_hdr is None

    def needs_nlflags(self, direction):
        return self.op_mode == 'do' and direction == 'request' and self.family.is_classic()


class CodeWriter:
    def __init__(self, nlib, out_file=None, overwrite=True):
@@ -1924,7 +1927,7 @@ def print_req(ri):
    ri.cw.write_func_lvar(local_vars)

    if ri.family.is_classic():
        ri.cw.p(f"nlh = ynl_msg_start_req(ys, {ri.op.enum_name});")
        ri.cw.p(f"nlh = ynl_msg_start_req(ys, {ri.op.enum_name}, req->_nlmsg_flags);")
    else:
        ri.cw.p(f"nlh = ynl_gemsg_start_req(ys, {ri.nl.get_family_id()}, {ri.op.enum_name}, 1);")

@@ -2053,6 +2056,16 @@ def print_free_prototype(ri, direction, suffix=';'):
    ri.cw.write_func_prot('void', f"{name}_free", [f"struct {struct_name} *{arg}"], suffix=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",
                          [f"struct {name} *req", "__u16 nl_flags"])
    ri.cw.block_start()
    ri.cw.p('req->_nlmsg_flags = nl_flags;')
    ri.cw.block_end()
    ri.cw.nl()


def _print_type(ri, direction, struct):
    suffix = f'_{ri.type_name}{direction_to_suffix[direction]}'
    if not direction and ri.type_name_conflict:
@@ -2063,6 +2076,9 @@ def _print_type(ri, direction, struct):

    ri.cw.block_start(line=f"struct {ri.family.c_name}{suffix}")

    if ri.needs_nlflags(direction):
        ri.cw.p('__u16 _nlmsg_flags;')
        ri.cw.nl()
    if ri.fixed_hdr:
        ri.cw.p(ri.fixed_hdr + ' _hdr;')
        ri.cw.nl()
@@ -2102,6 +2118,9 @@ def print_type_helpers(ri, direction, deref=False):
    print_free_prototype(ri, direction)
    ri.cw.nl()

    if ri.needs_nlflags(direction):
        print_nlflags_set(ri, direction)

    if ri.ku_space == 'user' and direction == 'request':
        for _, attr in ri.struct[direction].member_list():
            attr.setter(ri, ri.attr_set, direction, deref=deref)