Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / net / ynl / lib / ynl-priv.h
blob3c09a7bbfba59ff743b9e0b2e2c087db1ee23fc9
1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 #ifndef __YNL_C_PRIV_H
3 #define __YNL_C_PRIV_H 1
5 #include <stdbool.h>
6 #include <stddef.h>
7 #include <linux/types.h>
9 struct ynl_parse_arg;
12 * YNL internals / low level stuff
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,
30 enum ynl_parse_result {
31 YNL_PARSE_CB_ERROR = -1,
32 YNL_PARSE_CB_STOP = 0,
33 YNL_PARSE_CB_OK = 1,
36 #define YNL_SOCKET_BUFFER_SIZE (1 << 17)
38 #define YNL_ARRAY_SIZE(array) (sizeof(array) ? \
39 sizeof(array) / sizeof(array[0]) : 0)
41 typedef int (*ynl_parse_cb_t)(const struct nlmsghdr *nlh,
42 struct ynl_parse_arg *yarg);
44 struct ynl_policy_attr {
45 enum ynl_policy_type type;
46 unsigned int len;
47 const char *name;
48 const struct ynl_policy_nest *nest;
51 struct ynl_policy_nest {
52 unsigned int max_attr;
53 const struct ynl_policy_attr *table;
56 struct ynl_parse_arg {
57 struct ynl_sock *ys;
58 const struct ynl_policy_nest *rsp_policy;
59 void *data;
62 struct ynl_dump_list_type {
63 struct ynl_dump_list_type *next;
64 unsigned char data[] __attribute__((aligned(8)));
66 extern struct ynl_dump_list_type *YNL_LIST_END;
68 static inline bool ynl_dump_obj_is_last(void *obj)
70 unsigned long uptr = (unsigned long)obj;
72 uptr -= offsetof(struct ynl_dump_list_type, data);
73 return uptr == (unsigned long)YNL_LIST_END;
76 static inline void *ynl_dump_obj_next(void *obj)
78 unsigned long uptr = (unsigned long)obj;
79 struct ynl_dump_list_type *list;
81 uptr -= offsetof(struct ynl_dump_list_type, data);
82 list = (struct ynl_dump_list_type *)uptr;
83 uptr = (unsigned long)list->next;
84 uptr += offsetof(struct ynl_dump_list_type, data);
86 return (void *)uptr;
89 struct ynl_ntf_base_type {
90 __u16 family;
91 __u8 cmd;
92 struct ynl_ntf_base_type *next;
93 void (*free)(struct ynl_ntf_base_type *ntf);
94 unsigned char data[] __attribute__((aligned(8)));
97 struct nlmsghdr *
98 ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version);
99 struct nlmsghdr *
100 ynl_gemsg_start_dump(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version);
102 int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr);
104 /* YNL specific helpers used by the auto-generated code */
106 struct ynl_req_state {
107 struct ynl_parse_arg yarg;
108 ynl_parse_cb_t cb;
109 __u32 rsp_cmd;
112 struct ynl_dump_state {
113 struct ynl_parse_arg yarg;
114 void *first;
115 struct ynl_dump_list_type *last;
116 size_t alloc_sz;
117 ynl_parse_cb_t cb;
118 __u32 rsp_cmd;
121 struct ynl_ntf_info {
122 const struct ynl_policy_nest *policy;
123 ynl_parse_cb_t cb;
124 size_t alloc_sz;
125 void (*free)(struct ynl_ntf_base_type *ntf);
128 int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
129 struct ynl_req_state *yrs);
130 int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
131 struct ynl_dump_state *yds);
133 void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd);
134 int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg);
136 /* Netlink message handling helpers */
138 #define YNL_MSG_OVERFLOW 1
140 static inline struct nlmsghdr *ynl_nlmsg_put_header(void *buf)
142 struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
144 memset(nlh, 0, sizeof(*nlh));
145 nlh->nlmsg_len = NLMSG_HDRLEN;
147 return nlh;
150 static inline unsigned int ynl_nlmsg_data_len(const struct nlmsghdr *nlh)
152 return nlh->nlmsg_len - NLMSG_HDRLEN;
155 static inline void *ynl_nlmsg_data(const struct nlmsghdr *nlh)
157 return (unsigned char *)nlh + NLMSG_HDRLEN;
160 static inline void *
161 ynl_nlmsg_data_offset(const struct nlmsghdr *nlh, unsigned int offset)
163 return (unsigned char *)nlh + NLMSG_HDRLEN + offset;
166 static inline void *ynl_nlmsg_end_addr(const struct nlmsghdr *nlh)
168 return (char *)nlh + nlh->nlmsg_len;
171 static inline void *
172 ynl_nlmsg_put_extra_header(struct nlmsghdr *nlh, unsigned int size)
174 void *tail = ynl_nlmsg_end_addr(nlh);
176 nlh->nlmsg_len += NLMSG_ALIGN(size);
177 return tail;
180 /* Netlink attribute helpers */
182 static inline unsigned int ynl_attr_type(const struct nlattr *attr)
184 return attr->nla_type & NLA_TYPE_MASK;
187 static inline unsigned int ynl_attr_data_len(const struct nlattr *attr)
189 return attr->nla_len - NLA_HDRLEN;
192 static inline void *ynl_attr_data(const struct nlattr *attr)
194 return (unsigned char *)attr + NLA_HDRLEN;
197 static inline void *ynl_attr_data_end(const struct nlattr *attr)
199 return (char *)ynl_attr_data(attr) + ynl_attr_data_len(attr);
202 #define ynl_attr_for_each(attr, nlh, fixed_hdr_sz) \
203 for ((attr) = ynl_attr_first(nlh, (nlh)->nlmsg_len, \
204 NLMSG_HDRLEN + fixed_hdr_sz); attr; \
205 (attr) = ynl_attr_next(ynl_nlmsg_end_addr(nlh), attr))
207 #define ynl_attr_for_each_nested(attr, outer) \
208 for ((attr) = ynl_attr_first(outer, outer->nla_len, \
209 sizeof(struct nlattr)); attr; \
210 (attr) = ynl_attr_next(ynl_attr_data_end(outer), attr))
212 #define ynl_attr_for_each_payload(start, len, attr) \
213 for ((attr) = ynl_attr_first(start, len, 0); attr; \
214 (attr) = ynl_attr_next(start + len, attr))
216 static inline struct nlattr *
217 ynl_attr_if_good(const void *end, struct nlattr *attr)
219 if (attr + 1 > (const struct nlattr *)end)
220 return NULL;
221 if (ynl_attr_data_end(attr) > end)
222 return NULL;
223 return attr;
226 static inline struct nlattr *
227 ynl_attr_next(const void *end, const struct nlattr *prev)
229 struct nlattr *attr;
231 attr = (struct nlattr *)((char *)prev + NLA_ALIGN(prev->nla_len));
232 return ynl_attr_if_good(end, attr);
235 static inline struct nlattr *
236 ynl_attr_first(const void *start, size_t len, size_t skip)
238 struct nlattr *attr;
240 attr = (struct nlattr *)((char *)start + NLMSG_ALIGN(skip));
241 return ynl_attr_if_good((char *)start + len, attr);
244 static inline bool
245 __ynl_attr_put_overflow(struct nlmsghdr *nlh, size_t size)
247 bool o;
249 /* ynl_msg_start() stashed buffer length in nlmsg_pid. */
250 o = nlh->nlmsg_len + NLA_HDRLEN + NLMSG_ALIGN(size) > nlh->nlmsg_pid;
251 if (o)
252 /* YNL_MSG_OVERFLOW is < NLMSG_HDRLEN, all subsequent checks
253 * are guaranteed to fail.
255 nlh->nlmsg_pid = YNL_MSG_OVERFLOW;
256 return o;
259 static inline struct nlattr *
260 ynl_attr_nest_start(struct nlmsghdr *nlh, unsigned int attr_type)
262 struct nlattr *attr;
264 if (__ynl_attr_put_overflow(nlh, 0))
265 return (struct nlattr *)ynl_nlmsg_end_addr(nlh) - 1;
267 attr = (struct nlattr *)ynl_nlmsg_end_addr(nlh);
268 attr->nla_type = attr_type | NLA_F_NESTED;
269 nlh->nlmsg_len += NLA_HDRLEN;
271 return attr;
274 static inline void
275 ynl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *attr)
277 attr->nla_len = (char *)ynl_nlmsg_end_addr(nlh) - (char *)attr;
280 static inline void
281 ynl_attr_put(struct nlmsghdr *nlh, unsigned int attr_type,
282 const void *value, size_t size)
284 struct nlattr *attr;
286 if (__ynl_attr_put_overflow(nlh, size))
287 return;
289 attr = (struct nlattr *)ynl_nlmsg_end_addr(nlh);
290 attr->nla_type = attr_type;
291 attr->nla_len = NLA_HDRLEN + size;
293 memcpy(ynl_attr_data(attr), value, size);
295 nlh->nlmsg_len += NLMSG_ALIGN(attr->nla_len);
298 static inline void
299 ynl_attr_put_str(struct nlmsghdr *nlh, unsigned int attr_type, const char *str)
301 struct nlattr *attr;
302 size_t len;
304 len = strlen(str);
305 if (__ynl_attr_put_overflow(nlh, len))
306 return;
308 attr = (struct nlattr *)ynl_nlmsg_end_addr(nlh);
309 attr->nla_type = attr_type;
311 strcpy((char *)ynl_attr_data(attr), str);
312 attr->nla_len = NLA_HDRLEN + NLA_ALIGN(len);
314 nlh->nlmsg_len += NLMSG_ALIGN(attr->nla_len);
317 static inline const char *ynl_attr_get_str(const struct nlattr *attr)
319 return (const char *)ynl_attr_data(attr);
322 static inline __s8 ynl_attr_get_s8(const struct nlattr *attr)
324 return *(__s8 *)ynl_attr_data(attr);
327 static inline __s16 ynl_attr_get_s16(const struct nlattr *attr)
329 return *(__s16 *)ynl_attr_data(attr);
332 static inline __s32 ynl_attr_get_s32(const struct nlattr *attr)
334 return *(__s32 *)ynl_attr_data(attr);
337 static inline __s64 ynl_attr_get_s64(const struct nlattr *attr)
339 __s64 tmp;
341 memcpy(&tmp, (unsigned char *)(attr + 1), sizeof(tmp));
342 return tmp;
345 static inline __u8 ynl_attr_get_u8(const struct nlattr *attr)
347 return *(__u8 *)ynl_attr_data(attr);
350 static inline __u16 ynl_attr_get_u16(const struct nlattr *attr)
352 return *(__u16 *)ynl_attr_data(attr);
355 static inline __u32 ynl_attr_get_u32(const struct nlattr *attr)
357 return *(__u32 *)ynl_attr_data(attr);
360 static inline __u64 ynl_attr_get_u64(const struct nlattr *attr)
362 __u64 tmp;
364 memcpy(&tmp, (unsigned char *)(attr + 1), sizeof(tmp));
365 return tmp;
368 static inline void
369 ynl_attr_put_s8(struct nlmsghdr *nlh, unsigned int attr_type, __s8 value)
371 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
374 static inline void
375 ynl_attr_put_s16(struct nlmsghdr *nlh, unsigned int attr_type, __s16 value)
377 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
380 static inline void
381 ynl_attr_put_s32(struct nlmsghdr *nlh, unsigned int attr_type, __s32 value)
383 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
386 static inline void
387 ynl_attr_put_s64(struct nlmsghdr *nlh, unsigned int attr_type, __s64 value)
389 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
392 static inline void
393 ynl_attr_put_u8(struct nlmsghdr *nlh, unsigned int attr_type, __u8 value)
395 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
398 static inline void
399 ynl_attr_put_u16(struct nlmsghdr *nlh, unsigned int attr_type, __u16 value)
401 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
404 static inline void
405 ynl_attr_put_u32(struct nlmsghdr *nlh, unsigned int attr_type, __u32 value)
407 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
410 static inline void
411 ynl_attr_put_u64(struct nlmsghdr *nlh, unsigned int attr_type, __u64 value)
413 ynl_attr_put(nlh, attr_type, &value, sizeof(value));
416 static inline __u64 ynl_attr_get_uint(const struct nlattr *attr)
418 switch (ynl_attr_data_len(attr)) {
419 case 4:
420 return ynl_attr_get_u32(attr);
421 case 8:
422 return ynl_attr_get_u64(attr);
423 default:
424 return 0;
428 static inline __s64 ynl_attr_get_sint(const struct nlattr *attr)
430 switch (ynl_attr_data_len(attr)) {
431 case 4:
432 return ynl_attr_get_s32(attr);
433 case 8:
434 return ynl_attr_get_s64(attr);
435 default:
436 return 0;
440 static inline void
441 ynl_attr_put_uint(struct nlmsghdr *nlh, __u16 type, __u64 data)
443 if ((__u32)data == (__u64)data)
444 ynl_attr_put_u32(nlh, type, data);
445 else
446 ynl_attr_put_u64(nlh, type, data);
449 static inline void
450 ynl_attr_put_sint(struct nlmsghdr *nlh, __u16 type, __s64 data)
452 if ((__s32)data == (__s64)data)
453 ynl_attr_put_s32(nlh, type, data);
454 else
455 ynl_attr_put_s64(nlh, type, data);
457 #endif