xref: /linux/tools/net/ynl/lib/ynl.h (revision 9112fc0109fc0037ac3b8b633a169e78b4e23ca1)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 #ifndef __YNL_C_H
3 #define __YNL_C_H 1
4 
5 #include <stddef.h>
6 #include <linux/genetlink.h>
7 #include <linux/types.h>
8 
9 #include "ynl-priv.h"
10 
11 enum ynl_error_code {
12 	YNL_ERROR_NONE = 0,
13 	__YNL_ERRNO_END = 4096,
14 	YNL_ERROR_INTERNAL,
15 	YNL_ERROR_DUMP_INTER,
16 	YNL_ERROR_EXPECT_ACK,
17 	YNL_ERROR_EXPECT_MSG,
18 	YNL_ERROR_UNEXPECT_MSG,
19 	YNL_ERROR_ATTR_MISSING,
20 	YNL_ERROR_ATTR_INVALID,
21 	YNL_ERROR_UNKNOWN_NTF,
22 	YNL_ERROR_INV_RESP,
23 };
24 
25 /**
26  * struct ynl_error - error encountered by YNL
27  * @code:	errno (low values) or YNL error code (enum ynl_error_code)
28  * @attr_offs:	offset of bad attribute (for very advanced users)
29  * @msg:	error message
30  *
31  * Error information for when YNL operations fail.
32  * Users should interact with the err member of struct ynl_sock directly.
33  * The main exception to that rule is ynl_sock_create().
34  */
35 struct ynl_error {
36 	enum ynl_error_code code;
37 	unsigned int attr_offs;
38 	char msg[512];
39 };
40 
41 /**
42  * struct ynl_family - YNL family info
43  * Family description generated by codegen. Pass to ynl_sock_create().
44  */
45 struct ynl_family {
46 /* private: */
47 	const char *name;
48 	size_t hdr_len;
49 	const struct ynl_ntf_info *ntf_info;
50 	unsigned int ntf_info_size;
51 };
52 
53 /**
54  * struct ynl_sock - YNL wrapped netlink socket
55  * @err: YNL error descriptor, cleared on every request.
56  */
57 struct ynl_sock {
58 	struct ynl_error err;
59 
60 /* private: */
61 	const struct ynl_family *family;
62 	int socket;
63 	__u32 seq;
64 	__u32 portid;
65 	__u16 family_id;
66 
67 	unsigned int n_mcast_groups;
68 	struct {
69 		unsigned int id;
70 		char name[GENL_NAMSIZ];
71 	} *mcast_groups;
72 
73 	struct ynl_ntf_base_type *ntf_first;
74 	struct ynl_ntf_base_type **ntf_last_next;
75 
76 	struct nlmsghdr *nlh;
77 	struct ynl_policy_nest *req_policy;
78 	unsigned char *tx_buf;
79 	unsigned char *rx_buf;
80 	unsigned char raw_buf[];
81 };
82 
83 struct ynl_sock *
84 ynl_sock_create(const struct ynl_family *yf, struct ynl_error *e);
85 void ynl_sock_destroy(struct ynl_sock *ys);
86 
87 #define ynl_dump_foreach(dump, iter)					\
88 	for (typeof(dump->obj) *iter = &dump->obj;			\
89 	     !ynl_dump_obj_is_last(iter);				\
90 	     iter = ynl_dump_obj_next(iter))
91 
92 int ynl_subscribe(struct ynl_sock *ys, const char *grp_name);
93 int ynl_socket_get_fd(struct ynl_sock *ys);
94 int ynl_ntf_check(struct ynl_sock *ys);
95 
96 /**
97  * ynl_has_ntf() - check if socket has *parsed* notifications
98  * @ys: active YNL socket
99  *
100  * Note that this does not take into account notifications sitting
101  * in netlink socket, just the notifications which have already been
102  * read and parsed (e.g. during a ynl_ntf_check() call).
103  */
104 static inline bool ynl_has_ntf(struct ynl_sock *ys)
105 {
106 	return ys->ntf_last_next != &ys->ntf_first;
107 }
108 struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys);
109 
110 void ynl_ntf_free(struct ynl_ntf_base_type *ntf);
111 #endif
112