// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause1#ifndef __YNL_C_H2#define __YNL_C_H 134#include <stdbool.h>5#include <stddef.h>6#include <linux/genetlink.h>7#include <linux/types.h>89#include "ynl-priv.h"1011enum ynl_error_code {12YNL_ERROR_NONE = 0,13__YNL_ERRNO_END = 4096,14YNL_ERROR_INTERNAL,15YNL_ERROR_DUMP_INTER,16YNL_ERROR_EXPECT_ACK,17YNL_ERROR_EXPECT_MSG,18YNL_ERROR_UNEXPECT_MSG,19YNL_ERROR_ATTR_MISSING,20YNL_ERROR_ATTR_INVALID,21YNL_ERROR_UNKNOWN_NTF,22YNL_ERROR_INV_RESP,23YNL_ERROR_INPUT_INVALID,24YNL_ERROR_INPUT_TOO_BIG,25YNL_ERROR_SUBMSG_KEY,26};2728/**29* struct ynl_error - error encountered by YNL30* @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 message33*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*/38struct ynl_error {39enum ynl_error_code code;40unsigned int attr_offs;41char msg[512];42};4344/**45* struct ynl_family - YNL family info46* Family description generated by codegen. Pass to ynl_sock_create().47*/48struct ynl_family {49/* private: */50const char *name;51size_t hdr_len;52bool is_classic;53__u16 classic_id;54const struct ynl_ntf_info *ntf_info;55unsigned int ntf_info_size;56};5758/**59* struct ynl_sock - YNL wrapped netlink socket60* @err: YNL error descriptor, cleared on every request.61*/62struct ynl_sock {63struct ynl_error err;6465/* private: */66const struct ynl_family *family;67int socket;68__u32 seq;69__u32 portid;70__u16 family_id;7172unsigned int n_mcast_groups;73struct {74unsigned int id;75char name[GENL_NAMSIZ];76} *mcast_groups;7778struct ynl_ntf_base_type *ntf_first;79struct ynl_ntf_base_type **ntf_last_next;8081struct nlmsghdr *nlh;82const struct ynl_policy_nest *req_policy;83size_t req_hdr_len;84unsigned char *tx_buf;85unsigned char *rx_buf;86unsigned char raw_buf[];87};8889/**90* struct ynl_string - parsed individual string91* @len: length of the string (excluding terminating character)92* @str: value of the string93*94* Parsed and nul-terminated string. This struct is only used for arrays of95* strings. Non-array string members are placed directly in respective types.96*/97struct ynl_string {98unsigned int len;99char str[];100};101102struct ynl_sock *103ynl_sock_create(const struct ynl_family *yf, struct ynl_error *e);104void ynl_sock_destroy(struct ynl_sock *ys);105106#define ynl_dump_foreach(dump, iter) \107for (typeof(dump->obj) *iter = &dump->obj; \108!ynl_dump_obj_is_last(iter); \109iter = ynl_dump_obj_next(iter))110111/**112* ynl_dump_empty() - does the dump have no entries113* @dump: pointer to the dump list, as returned by a dump call114*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*/118static inline bool ynl_dump_empty(void *dump)119{120return dump == (void *)YNL_LIST_END;121}122123int ynl_subscribe(struct ynl_sock *ys, const char *grp_name);124int ynl_socket_get_fd(struct ynl_sock *ys);125int ynl_ntf_check(struct ynl_sock *ys);126127/**128* ynl_has_ntf() - check if socket has *parsed* notifications129* @ys: active YNL socket130*131* Note that this does not take into account notifications sitting132* in netlink socket, just the notifications which have already been133* read and parsed (e.g. during a ynl_ntf_check() call).134*/135static inline bool ynl_has_ntf(struct ynl_sock *ys)136{137return ys->ntf_last_next != &ys->ntf_first;138}139struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys);140141void ynl_ntf_free(struct ynl_ntf_base_type *ntf);142#endif143144145