1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 #ifndef __YNL_C_PRIV_H 3 #define __YNL_C_PRIV_H 1 4 5 #include <stddef.h> 6 #include <libmnl/libmnl.h> 7 #include <linux/types.h> 8 9 /* 10 * YNL internals / low level stuff 11 */ 12 13 /* Generic mnl helper code */ 14 15 enum ynl_policy_type { 16 YNL_PT_REJECT = 1, 17 YNL_PT_IGNORE, 18 YNL_PT_NEST, 19 YNL_PT_FLAG, 20 YNL_PT_BINARY, 21 YNL_PT_U8, 22 YNL_PT_U16, 23 YNL_PT_U32, 24 YNL_PT_U64, 25 YNL_PT_UINT, 26 YNL_PT_NUL_STR, 27 YNL_PT_BITFIELD32, 28 }; 29 30 struct ynl_policy_attr { 31 enum ynl_policy_type type; 32 unsigned int len; 33 const char *name; 34 struct ynl_policy_nest *nest; 35 }; 36 37 struct ynl_policy_nest { 38 unsigned int max_attr; 39 struct ynl_policy_attr *table; 40 }; 41 42 struct ynl_parse_arg { 43 struct ynl_sock *ys; 44 struct ynl_policy_nest *rsp_policy; 45 void *data; 46 }; 47 48 struct ynl_dump_list_type { 49 struct ynl_dump_list_type *next; 50 unsigned char data[] __attribute__((aligned(8))); 51 }; 52 extern struct ynl_dump_list_type *YNL_LIST_END; 53 54 static inline bool ynl_dump_obj_is_last(void *obj) 55 { 56 unsigned long uptr = (unsigned long)obj; 57 58 uptr -= offsetof(struct ynl_dump_list_type, data); 59 return uptr == (unsigned long)YNL_LIST_END; 60 } 61 62 static inline void *ynl_dump_obj_next(void *obj) 63 { 64 unsigned long uptr = (unsigned long)obj; 65 struct ynl_dump_list_type *list; 66 67 uptr -= offsetof(struct ynl_dump_list_type, data); 68 list = (void *)uptr; 69 uptr = (unsigned long)list->next; 70 uptr += offsetof(struct ynl_dump_list_type, data); 71 72 return (void *)uptr; 73 } 74 75 struct ynl_ntf_base_type { 76 __u16 family; 77 __u8 cmd; 78 struct ynl_ntf_base_type *next; 79 void (*free)(struct ynl_ntf_base_type *ntf); 80 unsigned char data[] __attribute__((aligned(8))); 81 }; 82 83 extern mnl_cb_t ynl_cb_array[NLMSG_MIN_TYPE]; 84 85 struct nlmsghdr * 86 ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version); 87 struct nlmsghdr * 88 ynl_gemsg_start_dump(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version); 89 90 int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr); 91 92 int ynl_recv_ack(struct ynl_sock *ys, int ret); 93 int ynl_cb_null(const struct nlmsghdr *nlh, void *data); 94 95 /* YNL specific helpers used by the auto-generated code */ 96 97 struct ynl_req_state { 98 struct ynl_parse_arg yarg; 99 mnl_cb_t cb; 100 __u32 rsp_cmd; 101 }; 102 103 struct ynl_dump_state { 104 struct ynl_sock *ys; 105 struct ynl_policy_nest *rsp_policy; 106 void *first; 107 struct ynl_dump_list_type *last; 108 size_t alloc_sz; 109 mnl_cb_t cb; 110 __u32 rsp_cmd; 111 }; 112 113 struct ynl_ntf_info { 114 struct ynl_policy_nest *policy; 115 mnl_cb_t cb; 116 size_t alloc_sz; 117 void (*free)(struct ynl_ntf_base_type *ntf); 118 }; 119 120 int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *req_nlh, 121 struct ynl_req_state *yrs); 122 int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghdr *req_nlh, 123 struct ynl_dump_state *yds); 124 125 void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd); 126 int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg); 127 128 #ifndef MNL_HAS_AUTO_SCALARS 129 static inline uint64_t mnl_attr_get_uint(const struct nlattr *attr) 130 { 131 if (mnl_attr_get_payload_len(attr) == 4) 132 return mnl_attr_get_u32(attr); 133 return mnl_attr_get_u64(attr); 134 } 135 136 static inline void 137 mnl_attr_put_uint(struct nlmsghdr *nlh, uint16_t type, uint64_t data) 138 { 139 if ((uint32_t)data == (uint64_t)data) 140 return mnl_attr_put_u32(nlh, type, data); 141 return mnl_attr_put_u64(nlh, type, data); 142 } 143 #endif 144 #endif 145