126 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2#ifndef __YNL_C_H3#define __YNL_C_H 14 5#include <stddef.h>6#include <linux/genetlink.h>7#include <linux/types.h>8 9#include "ynl-priv.h"10 11enum 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 YNL29 * @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 message32 *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 */37struct 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 info45 * Family description generated by codegen. Pass to ynl_sock_create().46 */47struct 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 socket57 * @err: YNL error descriptor, cleared on every request.58 */59struct 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 const struct ynl_policy_nest *req_policy;80 unsigned char *tx_buf;81 unsigned char *rx_buf;82 unsigned char raw_buf[];83};84 85struct ynl_sock *86ynl_sock_create(const struct ynl_family *yf, struct ynl_error *e);87void 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 entries96 * @dump: pointer to the dump list, as returned by a dump call97 *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 */101static inline bool ynl_dump_empty(void *dump)102{103 return dump == (void *)YNL_LIST_END;104}105 106int ynl_subscribe(struct ynl_sock *ys, const char *grp_name);107int ynl_socket_get_fd(struct ynl_sock *ys);108int ynl_ntf_check(struct ynl_sock *ys);109 110/**111 * ynl_has_ntf() - check if socket has *parsed* notifications112 * @ys: active YNL socket113 *114 * Note that this does not take into account notifications sitting115 * in netlink socket, just the notifications which have already been116 * read and parsed (e.g. during a ynl_ntf_check() call).117 */118static inline bool ynl_has_ntf(struct ynl_sock *ys)119{120 return ys->ntf_last_next != &ys->ntf_first;121}122struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys);123 124void ynl_ntf_free(struct ynl_ntf_base_type *ntf);125#endif126