xref: /linux/tools/net/ynl/lib/ynl.h (revision 1b98f357dadd6ea613a435fbaef1a5dd7b35fd21)
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 <stdbool.h>
6 #include <stddef.h>
7 #include <linux/genetlink.h>
8 #include <linux/types.h>
9 
10 #include "ynl-priv.h"
11 
12 enum ynl_error_code {
13 	YNL_ERROR_NONE = 0,
14 	__YNL_ERRNO_END = 4096,
15 	YNL_ERROR_INTERNAL,
16 	YNL_ERROR_DUMP_INTER,
17 	YNL_ERROR_EXPECT_ACK,
18 	YNL_ERROR_EXPECT_MSG,
19 	YNL_ERROR_UNEXPECT_MSG,
20 	YNL_ERROR_ATTR_MISSING,
21 	YNL_ERROR_ATTR_INVALID,
22 	YNL_ERROR_UNKNOWN_NTF,
23 	YNL_ERROR_INV_RESP,
24 	YNL_ERROR_INPUT_INVALID,
25 	YNL_ERROR_INPUT_TOO_BIG,
26 	YNL_ERROR_SUBMSG_KEY,
27 };
28 
29 /**
30  * struct ynl_error - error encountered by YNL
31  * @code:	errno (low values) or YNL error code (enum ynl_error_code)
32  * @attr_offs:	offset of bad attribute (for very advanced users)
33  * @msg:	error message
34  *
35  * Error information for when YNL operations fail.
36  * Users should interact with the err member of struct ynl_sock directly.
37  * The main exception to that rule is ynl_sock_create().
38  */
39 struct ynl_error {
40 	enum ynl_error_code code;
41 	unsigned int attr_offs;
42 	char msg[512];
43 };
44 
45 /**
46  * struct ynl_family - YNL family info
47  * Family description generated by codegen. Pass to ynl_sock_create().
48  */
49 struct ynl_family {
50 /* private: */
51 	const char *name;
52 	size_t hdr_len;
53 	bool is_classic;
54 	__u16 classic_id;
55 	const struct ynl_ntf_info *ntf_info;
56 	unsigned int ntf_info_size;
57 };
58 
59 /**
60  * struct ynl_sock - YNL wrapped netlink socket
61  * @err: YNL error descriptor, cleared on every request.
62  */
63 struct ynl_sock {
64 	struct ynl_error err;
65 
66 /* private: */
67 	const struct ynl_family *family;
68 	int socket;
69 	__u32 seq;
70 	__u32 portid;
71 	__u16 family_id;
72 
73 	unsigned int n_mcast_groups;
74 	struct {
75 		unsigned int id;
76 		char name[GENL_NAMSIZ];
77 	} *mcast_groups;
78 
79 	struct ynl_ntf_base_type *ntf_first;
80 	struct ynl_ntf_base_type **ntf_last_next;
81 
82 	struct nlmsghdr *nlh;
83 	const struct ynl_policy_nest *req_policy;
84 	size_t req_hdr_len;
85 	unsigned char *tx_buf;
86 	unsigned char *rx_buf;
87 	unsigned char raw_buf[];
88 };
89 
90 /**
91  * struct ynl_string - parsed individual string
92  * @len: length of the string (excluding terminating character)
93  * @str: value of the string
94  *
95  * Parsed and nul-terminated string. This struct is only used for arrays of
96  * strings. Non-array string members are placed directly in respective types.
97  */
98 struct ynl_string {
99 	unsigned int len;
100 	char str[];
101 };
102 
103 struct ynl_sock *
104 ynl_sock_create(const struct ynl_family *yf, struct ynl_error *e);
105 void ynl_sock_destroy(struct ynl_sock *ys);
106 
107 #define ynl_dump_foreach(dump, iter)					\
108 	for (typeof(dump->obj) *iter = &dump->obj;			\
109 	     !ynl_dump_obj_is_last(iter);				\
110 	     iter = ynl_dump_obj_next(iter))
111 
112 /**
113  * ynl_dump_empty() - does the dump have no entries
114  * @dump: pointer to the dump list, as returned by a dump call
115  *
116  * Check if the dump is empty, i.e. contains no objects.
117  * Dump calls return NULL on error, and terminator element if empty.
118  */
119 static inline bool ynl_dump_empty(void *dump)
120 {
121 	return dump == (void *)YNL_LIST_END;
122 }
123 
124 int ynl_subscribe(struct ynl_sock *ys, const char *grp_name);
125 int ynl_socket_get_fd(struct ynl_sock *ys);
126 int ynl_ntf_check(struct ynl_sock *ys);
127 
128 /**
129  * ynl_has_ntf() - check if socket has *parsed* notifications
130  * @ys: active YNL socket
131  *
132  * Note that this does not take into account notifications sitting
133  * in netlink socket, just the notifications which have already been
134  * read and parsed (e.g. during a ynl_ntf_check() call).
135  */
136 static inline bool ynl_has_ntf(struct ynl_sock *ys)
137 {
138 	return ys->ntf_last_next != &ys->ntf_first;
139 }
140 struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys);
141 
142 void ynl_ntf_free(struct ynl_ntf_base_type *ntf);
143 #endif
144