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