1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/tools/net/ynl/lib/ynl.h
Jakub Kicinski f6805072c2 tools: ynl-gen: support fixed headers in genetlink
Support genetlink families using simple fixed headers.
Assume fixed header is identical for all ops of the family for now.

Fixed headers are added to the request and reply structs as a _hdr
member, and copied to/from netlink messages appropriately.

Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://lore.kernel.org/r/20231213231432.2944749-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2023-12-14 17:51:21 -08:00

110 lines
2.7 KiB
C

// 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_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;
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;
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);
#endif