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