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