// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
#ifndef __YNL_C_H
#define __YNL_C_H 1

#include <stddef.h>
#include <libmnl/libmnl.h>
#include <linux/genetlink.h>
#include <linux/types.h>

struct mnl_socket;
struct nlmsghdr;

/*
 * User facing code
 */

struct ynl_ntf_base_type;
struct ynl_ntf_info;
struct ynl_sock;

enum ynl_error_code {
	YNL_ERROR_NONE = 0,
	__YNL_ERRNO_END = 4096,
	YNL_ERROR_INTERNAL,
	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,
};

/**
 * 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;
	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;
	struct mnl_socket *sock;
	__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;
	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))

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);

/*
 * YNL internals / low level stuff
 */

/* Generic mnl helper code */

enum ynl_policy_type {
	YNL_PT_REJECT = 1,
	YNL_PT_IGNORE,
	YNL_PT_NEST,
	YNL_PT_FLAG,
	YNL_PT_BINARY,
	YNL_PT_U8,
	YNL_PT_U16,
	YNL_PT_U32,
	YNL_PT_U64,
	YNL_PT_UINT,
	YNL_PT_NUL_STR,
	YNL_PT_BITFIELD32,
};

struct ynl_policy_attr {
	enum ynl_policy_type type;
	unsigned int len;
	const char *name;
	struct ynl_policy_nest *nest;
};

struct ynl_policy_nest {
	unsigned int max_attr;
	struct ynl_policy_attr *table;
};

struct ynl_parse_arg {
	struct ynl_sock *ys;
	struct ynl_policy_nest *rsp_policy;
	void *data;
};

struct ynl_dump_list_type {
	struct ynl_dump_list_type *next;
	unsigned char data[] __attribute__((aligned(8)));
};
extern struct ynl_dump_list_type *YNL_LIST_END;

static inline bool ynl_dump_obj_is_last(void *obj)
{
	unsigned long uptr = (unsigned long)obj;

	uptr -= offsetof(struct ynl_dump_list_type, data);
	return uptr == (unsigned long)YNL_LIST_END;
}

static inline void *ynl_dump_obj_next(void *obj)
{
	unsigned long uptr = (unsigned long)obj;
	struct ynl_dump_list_type *list;

	uptr -= offsetof(struct ynl_dump_list_type, data);
	list = (void *)uptr;
	uptr = (unsigned long)list->next;
	uptr += offsetof(struct ynl_dump_list_type, data);

	return (void *)uptr;
}

struct ynl_ntf_base_type {
	__u16 family;
	__u8 cmd;
	struct ynl_ntf_base_type *next;
	void (*free)(struct ynl_ntf_base_type *ntf);
	unsigned char data[] __attribute__((aligned(8)));
};

extern mnl_cb_t ynl_cb_array[NLMSG_MIN_TYPE];

struct nlmsghdr *
ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version);
struct nlmsghdr *
ynl_gemsg_start_dump(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version);

int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr);

int ynl_recv_ack(struct ynl_sock *ys, int ret);
int ynl_cb_null(const struct nlmsghdr *nlh, void *data);

/* YNL specific helpers used by the auto-generated code */

struct ynl_req_state {
	struct ynl_parse_arg yarg;
	mnl_cb_t cb;
	__u32 rsp_cmd;
};

struct ynl_dump_state {
	struct ynl_sock *ys;
	struct ynl_policy_nest *rsp_policy;
	void *first;
	struct ynl_dump_list_type *last;
	size_t alloc_sz;
	mnl_cb_t cb;
	__u32 rsp_cmd;
};

struct ynl_ntf_info {
	struct ynl_policy_nest *policy;
	mnl_cb_t cb;
	size_t alloc_sz;
	void (*free)(struct ynl_ntf_base_type *ntf);
};

int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
	     struct ynl_req_state *yrs);
int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghdr *req_nlh,
		  struct ynl_dump_state *yds);

void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd);
int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg);

#ifndef MNL_HAS_AUTO_SCALARS
static inline uint64_t mnl_attr_get_uint(const struct nlattr *attr)
{
	if (mnl_attr_get_len(attr) == 4)
		return mnl_attr_get_u32(attr);
	return mnl_attr_get_u64(attr);
}

static inline void
mnl_attr_put_uint(struct nlmsghdr *nlh, uint16_t type, uint64_t data)
{
	if ((uint32_t)data == (uint64_t)data)
		return mnl_attr_put_u32(nlh, type, data);
	return mnl_attr_put_u64(nlh, type, data);
}
#endif
#endif
