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