xref: /linux/tools/net/ynl/lib/ynl-priv.h (revision 021bc4b9)
1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 #ifndef __YNL_C_PRIV_H
3 #define __YNL_C_PRIV_H 1
4 
5 #include <stddef.h>
6 #include <libmnl/libmnl.h>
7 #include <linux/types.h>
8 
9 /*
10  * YNL internals / low level stuff
11  */
12 
13 /* Generic mnl helper code */
14 
15 enum ynl_policy_type {
16 	YNL_PT_REJECT = 1,
17 	YNL_PT_IGNORE,
18 	YNL_PT_NEST,
19 	YNL_PT_FLAG,
20 	YNL_PT_BINARY,
21 	YNL_PT_U8,
22 	YNL_PT_U16,
23 	YNL_PT_U32,
24 	YNL_PT_U64,
25 	YNL_PT_UINT,
26 	YNL_PT_NUL_STR,
27 	YNL_PT_BITFIELD32,
28 };
29 
30 struct ynl_policy_attr {
31 	enum ynl_policy_type type;
32 	unsigned int len;
33 	const char *name;
34 	struct ynl_policy_nest *nest;
35 };
36 
37 struct ynl_policy_nest {
38 	unsigned int max_attr;
39 	struct ynl_policy_attr *table;
40 };
41 
42 struct ynl_parse_arg {
43 	struct ynl_sock *ys;
44 	struct ynl_policy_nest *rsp_policy;
45 	void *data;
46 };
47 
48 struct ynl_dump_list_type {
49 	struct ynl_dump_list_type *next;
50 	unsigned char data[] __attribute__((aligned(8)));
51 };
52 extern struct ynl_dump_list_type *YNL_LIST_END;
53 
54 static inline bool ynl_dump_obj_is_last(void *obj)
55 {
56 	unsigned long uptr = (unsigned long)obj;
57 
58 	uptr -= offsetof(struct ynl_dump_list_type, data);
59 	return uptr == (unsigned long)YNL_LIST_END;
60 }
61 
62 static inline void *ynl_dump_obj_next(void *obj)
63 {
64 	unsigned long uptr = (unsigned long)obj;
65 	struct ynl_dump_list_type *list;
66 
67 	uptr -= offsetof(struct ynl_dump_list_type, data);
68 	list = (void *)uptr;
69 	uptr = (unsigned long)list->next;
70 	uptr += offsetof(struct ynl_dump_list_type, data);
71 
72 	return (void *)uptr;
73 }
74 
75 struct ynl_ntf_base_type {
76 	__u16 family;
77 	__u8 cmd;
78 	struct ynl_ntf_base_type *next;
79 	void (*free)(struct ynl_ntf_base_type *ntf);
80 	unsigned char data[] __attribute__((aligned(8)));
81 };
82 
83 extern mnl_cb_t ynl_cb_array[NLMSG_MIN_TYPE];
84 
85 struct nlmsghdr *
86 ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version);
87 struct nlmsghdr *
88 ynl_gemsg_start_dump(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version);
89 
90 int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr);
91 
92 int ynl_recv_ack(struct ynl_sock *ys, int ret);
93 int ynl_cb_null(const struct nlmsghdr *nlh, void *data);
94 
95 /* YNL specific helpers used by the auto-generated code */
96 
97 struct ynl_req_state {
98 	struct ynl_parse_arg yarg;
99 	mnl_cb_t cb;
100 	__u32 rsp_cmd;
101 };
102 
103 struct ynl_dump_state {
104 	struct ynl_sock *ys;
105 	struct ynl_policy_nest *rsp_policy;
106 	void *first;
107 	struct ynl_dump_list_type *last;
108 	size_t alloc_sz;
109 	mnl_cb_t cb;
110 	__u32 rsp_cmd;
111 };
112 
113 struct ynl_ntf_info {
114 	struct ynl_policy_nest *policy;
115 	mnl_cb_t cb;
116 	size_t alloc_sz;
117 	void (*free)(struct ynl_ntf_base_type *ntf);
118 };
119 
120 int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
121 	     struct ynl_req_state *yrs);
122 int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
123 		  struct ynl_dump_state *yds);
124 
125 void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd);
126 int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg);
127 
128 #ifndef MNL_HAS_AUTO_SCALARS
129 static inline uint64_t mnl_attr_get_uint(const struct nlattr *attr)
130 {
131 	if (mnl_attr_get_payload_len(attr) == 4)
132 		return mnl_attr_get_u32(attr);
133 	return mnl_attr_get_u64(attr);
134 }
135 
136 static inline void
137 mnl_attr_put_uint(struct nlmsghdr *nlh, uint16_t type, uint64_t data)
138 {
139 	if ((uint32_t)data == (uint64_t)data)
140 		return mnl_attr_put_u32(nlh, type, data);
141 	return mnl_attr_put_u64(nlh, type, data);
142 }
143 #endif
144 #endif
145