1 // SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 2 /* Do not edit directly, auto-generated from: */ 3 /* Documentation/netlink/specs/fou.yaml */ 4 /* YNL-GEN user source */ 5 6 #include <stdlib.h> 7 #include "fou-user.h" 8 #include "ynl.h" 9 #include <linux/fou.h> 10 11 #include <stdlib.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <libmnl/libmnl.h> 15 #include <linux/genetlink.h> 16 17 /* Enums */ 18 static const char * const fou_op_strmap[] = { 19 [FOU_CMD_ADD] = "add", 20 [FOU_CMD_DEL] = "del", 21 [FOU_CMD_GET] = "get", 22 }; 23 24 const char *fou_op_str(int op) 25 { 26 if (op < 0 || op >= (int)MNL_ARRAY_SIZE(fou_op_strmap)) 27 return NULL; 28 return fou_op_strmap[op]; 29 } 30 31 static const char * const fou_encap_type_strmap[] = { 32 [0] = "unspec", 33 [1] = "direct", 34 [2] = "gue", 35 }; 36 37 const char *fou_encap_type_str(int value) 38 { 39 if (value < 0 || value >= (int)MNL_ARRAY_SIZE(fou_encap_type_strmap)) 40 return NULL; 41 return fou_encap_type_strmap[value]; 42 } 43 44 /* Policies */ 45 struct ynl_policy_attr fou_policy[FOU_ATTR_MAX + 1] = { 46 [FOU_ATTR_UNSPEC] = { .name = "unspec", .type = YNL_PT_REJECT, }, 47 [FOU_ATTR_PORT] = { .name = "port", .type = YNL_PT_U16, }, 48 [FOU_ATTR_AF] = { .name = "af", .type = YNL_PT_U8, }, 49 [FOU_ATTR_IPPROTO] = { .name = "ipproto", .type = YNL_PT_U8, }, 50 [FOU_ATTR_TYPE] = { .name = "type", .type = YNL_PT_U8, }, 51 [FOU_ATTR_REMCSUM_NOPARTIAL] = { .name = "remcsum_nopartial", .type = YNL_PT_FLAG, }, 52 [FOU_ATTR_LOCAL_V4] = { .name = "local_v4", .type = YNL_PT_U32, }, 53 [FOU_ATTR_LOCAL_V6] = { .name = "local_v6", .type = YNL_PT_BINARY,}, 54 [FOU_ATTR_PEER_V4] = { .name = "peer_v4", .type = YNL_PT_U32, }, 55 [FOU_ATTR_PEER_V6] = { .name = "peer_v6", .type = YNL_PT_BINARY,}, 56 [FOU_ATTR_PEER_PORT] = { .name = "peer_port", .type = YNL_PT_U16, }, 57 [FOU_ATTR_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, 58 }; 59 60 struct ynl_policy_nest fou_nest = { 61 .max_attr = FOU_ATTR_MAX, 62 .table = fou_policy, 63 }; 64 65 /* Common nested types */ 66 /* ============== FOU_CMD_ADD ============== */ 67 /* FOU_CMD_ADD - do */ 68 void fou_add_req_free(struct fou_add_req *req) 69 { 70 free(req->local_v6); 71 free(req->peer_v6); 72 free(req); 73 } 74 75 int fou_add(struct ynl_sock *ys, struct fou_add_req *req) 76 { 77 struct nlmsghdr *nlh; 78 int err; 79 80 nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_ADD, 1); 81 ys->req_policy = &fou_nest; 82 83 if (req->_present.port) 84 mnl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); 85 if (req->_present.ipproto) 86 mnl_attr_put_u8(nlh, FOU_ATTR_IPPROTO, req->ipproto); 87 if (req->_present.type) 88 mnl_attr_put_u8(nlh, FOU_ATTR_TYPE, req->type); 89 if (req->_present.remcsum_nopartial) 90 mnl_attr_put(nlh, FOU_ATTR_REMCSUM_NOPARTIAL, 0, NULL); 91 if (req->_present.local_v4) 92 mnl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); 93 if (req->_present.peer_v4) 94 mnl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); 95 if (req->_present.local_v6_len) 96 mnl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->_present.local_v6_len, req->local_v6); 97 if (req->_present.peer_v6_len) 98 mnl_attr_put(nlh, FOU_ATTR_PEER_V6, req->_present.peer_v6_len, req->peer_v6); 99 if (req->_present.peer_port) 100 mnl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); 101 if (req->_present.ifindex) 102 mnl_attr_put_u32(nlh, FOU_ATTR_IFINDEX, req->ifindex); 103 104 err = ynl_exec(ys, nlh, NULL); 105 if (err < 0) 106 return -1; 107 108 return 0; 109 } 110 111 /* ============== FOU_CMD_DEL ============== */ 112 /* FOU_CMD_DEL - do */ 113 void fou_del_req_free(struct fou_del_req *req) 114 { 115 free(req->local_v6); 116 free(req->peer_v6); 117 free(req); 118 } 119 120 int fou_del(struct ynl_sock *ys, struct fou_del_req *req) 121 { 122 struct nlmsghdr *nlh; 123 int err; 124 125 nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_DEL, 1); 126 ys->req_policy = &fou_nest; 127 128 if (req->_present.af) 129 mnl_attr_put_u8(nlh, FOU_ATTR_AF, req->af); 130 if (req->_present.ifindex) 131 mnl_attr_put_u32(nlh, FOU_ATTR_IFINDEX, req->ifindex); 132 if (req->_present.port) 133 mnl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); 134 if (req->_present.peer_port) 135 mnl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); 136 if (req->_present.local_v4) 137 mnl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); 138 if (req->_present.peer_v4) 139 mnl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); 140 if (req->_present.local_v6_len) 141 mnl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->_present.local_v6_len, req->local_v6); 142 if (req->_present.peer_v6_len) 143 mnl_attr_put(nlh, FOU_ATTR_PEER_V6, req->_present.peer_v6_len, req->peer_v6); 144 145 err = ynl_exec(ys, nlh, NULL); 146 if (err < 0) 147 return -1; 148 149 return 0; 150 } 151 152 /* ============== FOU_CMD_GET ============== */ 153 /* FOU_CMD_GET - do */ 154 void fou_get_req_free(struct fou_get_req *req) 155 { 156 free(req->local_v6); 157 free(req->peer_v6); 158 free(req); 159 } 160 161 void fou_get_rsp_free(struct fou_get_rsp *rsp) 162 { 163 free(rsp->local_v6); 164 free(rsp->peer_v6); 165 free(rsp); 166 } 167 168 int fou_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 169 { 170 struct ynl_parse_arg *yarg = data; 171 const struct nlattr *attr; 172 struct fou_get_rsp *dst; 173 174 dst = yarg->data; 175 176 mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 177 if (mnl_attr_get_type(attr) == FOU_ATTR_PORT) { 178 if (ynl_attr_validate(yarg, attr)) 179 return MNL_CB_ERROR; 180 dst->_present.port = 1; 181 dst->port = mnl_attr_get_u16(attr); 182 } 183 else if (mnl_attr_get_type(attr) == FOU_ATTR_IPPROTO) { 184 if (ynl_attr_validate(yarg, attr)) 185 return MNL_CB_ERROR; 186 dst->_present.ipproto = 1; 187 dst->ipproto = mnl_attr_get_u8(attr); 188 } 189 else if (mnl_attr_get_type(attr) == FOU_ATTR_TYPE) { 190 if (ynl_attr_validate(yarg, attr)) 191 return MNL_CB_ERROR; 192 dst->_present.type = 1; 193 dst->type = mnl_attr_get_u8(attr); 194 } 195 else if (mnl_attr_get_type(attr) == FOU_ATTR_REMCSUM_NOPARTIAL) { 196 if (ynl_attr_validate(yarg, attr)) 197 return MNL_CB_ERROR; 198 dst->_present.remcsum_nopartial = 1; 199 } 200 else if (mnl_attr_get_type(attr) == FOU_ATTR_LOCAL_V4) { 201 if (ynl_attr_validate(yarg, attr)) 202 return MNL_CB_ERROR; 203 dst->_present.local_v4 = 1; 204 dst->local_v4 = mnl_attr_get_u32(attr); 205 } 206 else if (mnl_attr_get_type(attr) == FOU_ATTR_PEER_V4) { 207 if (ynl_attr_validate(yarg, attr)) 208 return MNL_CB_ERROR; 209 dst->_present.peer_v4 = 1; 210 dst->peer_v4 = mnl_attr_get_u32(attr); 211 } 212 else if (mnl_attr_get_type(attr) == FOU_ATTR_LOCAL_V6) { 213 unsigned int len; 214 215 if (ynl_attr_validate(yarg, attr)) 216 return MNL_CB_ERROR; 217 218 len = mnl_attr_get_payload_len(attr); 219 dst->_present.local_v6_len = len; 220 dst->local_v6 = malloc(len); 221 memcpy(dst->local_v6, mnl_attr_get_payload(attr), len); 222 } 223 else if (mnl_attr_get_type(attr) == FOU_ATTR_PEER_V6) { 224 unsigned int len; 225 226 if (ynl_attr_validate(yarg, attr)) 227 return MNL_CB_ERROR; 228 229 len = mnl_attr_get_payload_len(attr); 230 dst->_present.peer_v6_len = len; 231 dst->peer_v6 = malloc(len); 232 memcpy(dst->peer_v6, mnl_attr_get_payload(attr), len); 233 } 234 else if (mnl_attr_get_type(attr) == FOU_ATTR_PEER_PORT) { 235 if (ynl_attr_validate(yarg, attr)) 236 return MNL_CB_ERROR; 237 dst->_present.peer_port = 1; 238 dst->peer_port = mnl_attr_get_u16(attr); 239 } 240 else if (mnl_attr_get_type(attr) == FOU_ATTR_IFINDEX) { 241 if (ynl_attr_validate(yarg, attr)) 242 return MNL_CB_ERROR; 243 dst->_present.ifindex = 1; 244 dst->ifindex = mnl_attr_get_u32(attr); 245 } 246 } 247 248 return MNL_CB_OK; 249 } 250 251 struct fou_get_rsp *fou_get(struct ynl_sock *ys, struct fou_get_req *req) 252 { 253 struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 254 struct fou_get_rsp *rsp; 255 struct nlmsghdr *nlh; 256 int err; 257 258 nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_GET, 1); 259 ys->req_policy = &fou_nest; 260 yrs.yarg.rsp_policy = &fou_nest; 261 262 if (req->_present.af) 263 mnl_attr_put_u8(nlh, FOU_ATTR_AF, req->af); 264 if (req->_present.ifindex) 265 mnl_attr_put_u32(nlh, FOU_ATTR_IFINDEX, req->ifindex); 266 if (req->_present.port) 267 mnl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); 268 if (req->_present.peer_port) 269 mnl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); 270 if (req->_present.local_v4) 271 mnl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); 272 if (req->_present.peer_v4) 273 mnl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); 274 if (req->_present.local_v6_len) 275 mnl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->_present.local_v6_len, req->local_v6); 276 if (req->_present.peer_v6_len) 277 mnl_attr_put(nlh, FOU_ATTR_PEER_V6, req->_present.peer_v6_len, req->peer_v6); 278 279 rsp = calloc(1, sizeof(*rsp)); 280 yrs.yarg.data = rsp; 281 yrs.cb = fou_get_rsp_parse; 282 yrs.rsp_cmd = FOU_CMD_GET; 283 284 err = ynl_exec(ys, nlh, &yrs); 285 if (err < 0) 286 goto err_free; 287 288 return rsp; 289 290 err_free: 291 fou_get_rsp_free(rsp); 292 return NULL; 293 } 294 295 /* FOU_CMD_GET - dump */ 296 void fou_get_list_free(struct fou_get_list *rsp) 297 { 298 struct fou_get_list *next = rsp; 299 300 while ((void *)next != YNL_LIST_END) { 301 rsp = next; 302 next = rsp->next; 303 304 free(rsp->obj.local_v6); 305 free(rsp->obj.peer_v6); 306 free(rsp); 307 } 308 } 309 310 struct fou_get_list *fou_get_dump(struct ynl_sock *ys) 311 { 312 struct ynl_dump_state yds = {}; 313 struct nlmsghdr *nlh; 314 int err; 315 316 yds.ys = ys; 317 yds.alloc_sz = sizeof(struct fou_get_list); 318 yds.cb = fou_get_rsp_parse; 319 yds.rsp_cmd = FOU_CMD_GET; 320 yds.rsp_policy = &fou_nest; 321 322 nlh = ynl_gemsg_start_dump(ys, ys->family_id, FOU_CMD_GET, 1); 323 324 err = ynl_exec_dump(ys, nlh, &yds); 325 if (err < 0) 326 goto free_list; 327 328 return yds.first; 329 330 free_list: 331 fou_get_list_free(yds.first); 332 return NULL; 333 } 334 335 const struct ynl_family ynl_fou_family = { 336 .name = "fou", 337 }; 338