| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
- #ifndef __YNL_C_H
- #define __YNL_C_H 1
- #include <stddef.h>
- #include <linux/genetlink.h>
- #include <linux/types.h>
- #include "ynl-priv.h"
- enum ynl_error_code {
- YNL_ERROR_NONE = 0,
- __YNL_ERRNO_END = 4096,
- YNL_ERROR_INTERNAL,
- YNL_ERROR_DUMP_INTER,
- YNL_ERROR_EXPECT_ACK,
- YNL_ERROR_EXPECT_MSG,
- YNL_ERROR_UNEXPECT_MSG,
- YNL_ERROR_ATTR_MISSING,
- YNL_ERROR_ATTR_INVALID,
- YNL_ERROR_UNKNOWN_NTF,
- YNL_ERROR_INV_RESP,
- YNL_ERROR_INPUT_INVALID,
- YNL_ERROR_INPUT_TOO_BIG,
- };
- /**
- * struct ynl_error - error encountered by YNL
- * @code: errno (low values) or YNL error code (enum ynl_error_code)
- * @attr_offs: offset of bad attribute (for very advanced users)
- * @msg: error message
- *
- * Error information for when YNL operations fail.
- * Users should interact with the err member of struct ynl_sock directly.
- * The main exception to that rule is ynl_sock_create().
- */
- struct ynl_error {
- enum ynl_error_code code;
- unsigned int attr_offs;
- char msg[512];
- };
- /**
- * struct ynl_family - YNL family info
- * Family description generated by codegen. Pass to ynl_sock_create().
- */
- struct ynl_family {
- /* private: */
- const char *name;
- size_t hdr_len;
- const struct ynl_ntf_info *ntf_info;
- unsigned int ntf_info_size;
- };
- /**
- * struct ynl_sock - YNL wrapped netlink socket
- * @err: YNL error descriptor, cleared on every request.
- */
- struct ynl_sock {
- struct ynl_error err;
- /* private: */
- const struct ynl_family *family;
- int socket;
- __u32 seq;
- __u32 portid;
- __u16 family_id;
- unsigned int n_mcast_groups;
- struct {
- unsigned int id;
- char name[GENL_NAMSIZ];
- } *mcast_groups;
- struct ynl_ntf_base_type *ntf_first;
- struct ynl_ntf_base_type **ntf_last_next;
- struct nlmsghdr *nlh;
- const struct ynl_policy_nest *req_policy;
- unsigned char *tx_buf;
- unsigned char *rx_buf;
- unsigned char raw_buf[];
- };
- struct ynl_sock *
- ynl_sock_create(const struct ynl_family *yf, struct ynl_error *e);
- void ynl_sock_destroy(struct ynl_sock *ys);
- #define ynl_dump_foreach(dump, iter) \
- for (typeof(dump->obj) *iter = &dump->obj; \
- !ynl_dump_obj_is_last(iter); \
- iter = ynl_dump_obj_next(iter))
- /**
- * ynl_dump_empty() - does the dump have no entries
- * @dump: pointer to the dump list, as returned by a dump call
- *
- * Check if the dump is empty, i.e. contains no objects.
- * Dump calls return NULL on error, and terminator element if empty.
- */
- static inline bool ynl_dump_empty(void *dump)
- {
- return dump == (void *)YNL_LIST_END;
- }
- int ynl_subscribe(struct ynl_sock *ys, const char *grp_name);
- int ynl_socket_get_fd(struct ynl_sock *ys);
- int ynl_ntf_check(struct ynl_sock *ys);
- /**
- * ynl_has_ntf() - check if socket has *parsed* notifications
- * @ys: active YNL socket
- *
- * Note that this does not take into account notifications sitting
- * in netlink socket, just the notifications which have already been
- * read and parsed (e.g. during a ynl_ntf_check() call).
- */
- static inline bool ynl_has_ntf(struct ynl_sock *ys)
- {
- return ys->ntf_last_next != &ys->ntf_first;
- }
- struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys);
- void ynl_ntf_free(struct ynl_ntf_base_type *ntf);
- #endif
|