162306a36Sopenharmony_ci// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 262306a36Sopenharmony_ci/* Do not edit directly, auto-generated from: */ 362306a36Sopenharmony_ci/* Documentation/netlink/specs/fou.yaml */ 462306a36Sopenharmony_ci/* YNL-GEN user source */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <stdlib.h> 762306a36Sopenharmony_ci#include <string.h> 862306a36Sopenharmony_ci#include "fou-user.h" 962306a36Sopenharmony_ci#include "ynl.h" 1062306a36Sopenharmony_ci#include <linux/fou.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <libmnl/libmnl.h> 1362306a36Sopenharmony_ci#include <linux/genetlink.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* Enums */ 1662306a36Sopenharmony_cistatic const char * const fou_op_strmap[] = { 1762306a36Sopenharmony_ci [FOU_CMD_ADD] = "add", 1862306a36Sopenharmony_ci [FOU_CMD_DEL] = "del", 1962306a36Sopenharmony_ci [FOU_CMD_GET] = "get", 2062306a36Sopenharmony_ci}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ciconst char *fou_op_str(int op) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci if (op < 0 || op >= (int)MNL_ARRAY_SIZE(fou_op_strmap)) 2562306a36Sopenharmony_ci return NULL; 2662306a36Sopenharmony_ci return fou_op_strmap[op]; 2762306a36Sopenharmony_ci} 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic const char * const fou_encap_type_strmap[] = { 3062306a36Sopenharmony_ci [0] = "unspec", 3162306a36Sopenharmony_ci [1] = "direct", 3262306a36Sopenharmony_ci [2] = "gue", 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ciconst char *fou_encap_type_str(int value) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci if (value < 0 || value >= (int)MNL_ARRAY_SIZE(fou_encap_type_strmap)) 3862306a36Sopenharmony_ci return NULL; 3962306a36Sopenharmony_ci return fou_encap_type_strmap[value]; 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* Policies */ 4362306a36Sopenharmony_cistruct ynl_policy_attr fou_policy[FOU_ATTR_MAX + 1] = { 4462306a36Sopenharmony_ci [FOU_ATTR_UNSPEC] = { .name = "unspec", .type = YNL_PT_REJECT, }, 4562306a36Sopenharmony_ci [FOU_ATTR_PORT] = { .name = "port", .type = YNL_PT_U16, }, 4662306a36Sopenharmony_ci [FOU_ATTR_AF] = { .name = "af", .type = YNL_PT_U8, }, 4762306a36Sopenharmony_ci [FOU_ATTR_IPPROTO] = { .name = "ipproto", .type = YNL_PT_U8, }, 4862306a36Sopenharmony_ci [FOU_ATTR_TYPE] = { .name = "type", .type = YNL_PT_U8, }, 4962306a36Sopenharmony_ci [FOU_ATTR_REMCSUM_NOPARTIAL] = { .name = "remcsum_nopartial", .type = YNL_PT_FLAG, }, 5062306a36Sopenharmony_ci [FOU_ATTR_LOCAL_V4] = { .name = "local_v4", .type = YNL_PT_U32, }, 5162306a36Sopenharmony_ci [FOU_ATTR_LOCAL_V6] = { .name = "local_v6", .type = YNL_PT_BINARY,}, 5262306a36Sopenharmony_ci [FOU_ATTR_PEER_V4] = { .name = "peer_v4", .type = YNL_PT_U32, }, 5362306a36Sopenharmony_ci [FOU_ATTR_PEER_V6] = { .name = "peer_v6", .type = YNL_PT_BINARY,}, 5462306a36Sopenharmony_ci [FOU_ATTR_PEER_PORT] = { .name = "peer_port", .type = YNL_PT_U16, }, 5562306a36Sopenharmony_ci [FOU_ATTR_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistruct ynl_policy_nest fou_nest = { 5962306a36Sopenharmony_ci .max_attr = FOU_ATTR_MAX, 6062306a36Sopenharmony_ci .table = fou_policy, 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* Common nested types */ 6462306a36Sopenharmony_ci/* ============== FOU_CMD_ADD ============== */ 6562306a36Sopenharmony_ci/* FOU_CMD_ADD - do */ 6662306a36Sopenharmony_civoid fou_add_req_free(struct fou_add_req *req) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci free(req->local_v6); 6962306a36Sopenharmony_ci free(req->peer_v6); 7062306a36Sopenharmony_ci free(req); 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciint fou_add(struct ynl_sock *ys, struct fou_add_req *req) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci struct nlmsghdr *nlh; 7662306a36Sopenharmony_ci int err; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_ADD, 1); 7962306a36Sopenharmony_ci ys->req_policy = &fou_nest; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci if (req->_present.port) 8262306a36Sopenharmony_ci mnl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); 8362306a36Sopenharmony_ci if (req->_present.ipproto) 8462306a36Sopenharmony_ci mnl_attr_put_u8(nlh, FOU_ATTR_IPPROTO, req->ipproto); 8562306a36Sopenharmony_ci if (req->_present.type) 8662306a36Sopenharmony_ci mnl_attr_put_u8(nlh, FOU_ATTR_TYPE, req->type); 8762306a36Sopenharmony_ci if (req->_present.remcsum_nopartial) 8862306a36Sopenharmony_ci mnl_attr_put(nlh, FOU_ATTR_REMCSUM_NOPARTIAL, 0, NULL); 8962306a36Sopenharmony_ci if (req->_present.local_v4) 9062306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); 9162306a36Sopenharmony_ci if (req->_present.peer_v4) 9262306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); 9362306a36Sopenharmony_ci if (req->_present.local_v6_len) 9462306a36Sopenharmony_ci mnl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->_present.local_v6_len, req->local_v6); 9562306a36Sopenharmony_ci if (req->_present.peer_v6_len) 9662306a36Sopenharmony_ci mnl_attr_put(nlh, FOU_ATTR_PEER_V6, req->_present.peer_v6_len, req->peer_v6); 9762306a36Sopenharmony_ci if (req->_present.peer_port) 9862306a36Sopenharmony_ci mnl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); 9962306a36Sopenharmony_ci if (req->_present.ifindex) 10062306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_IFINDEX, req->ifindex); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci err = ynl_exec(ys, nlh, NULL); 10362306a36Sopenharmony_ci if (err < 0) 10462306a36Sopenharmony_ci return -1; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci return 0; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* ============== FOU_CMD_DEL ============== */ 11062306a36Sopenharmony_ci/* FOU_CMD_DEL - do */ 11162306a36Sopenharmony_civoid fou_del_req_free(struct fou_del_req *req) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci free(req->local_v6); 11462306a36Sopenharmony_ci free(req->peer_v6); 11562306a36Sopenharmony_ci free(req); 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint fou_del(struct ynl_sock *ys, struct fou_del_req *req) 11962306a36Sopenharmony_ci{ 12062306a36Sopenharmony_ci struct nlmsghdr *nlh; 12162306a36Sopenharmony_ci int err; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_DEL, 1); 12462306a36Sopenharmony_ci ys->req_policy = &fou_nest; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if (req->_present.af) 12762306a36Sopenharmony_ci mnl_attr_put_u8(nlh, FOU_ATTR_AF, req->af); 12862306a36Sopenharmony_ci if (req->_present.ifindex) 12962306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_IFINDEX, req->ifindex); 13062306a36Sopenharmony_ci if (req->_present.port) 13162306a36Sopenharmony_ci mnl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); 13262306a36Sopenharmony_ci if (req->_present.peer_port) 13362306a36Sopenharmony_ci mnl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); 13462306a36Sopenharmony_ci if (req->_present.local_v4) 13562306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); 13662306a36Sopenharmony_ci if (req->_present.peer_v4) 13762306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); 13862306a36Sopenharmony_ci if (req->_present.local_v6_len) 13962306a36Sopenharmony_ci mnl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->_present.local_v6_len, req->local_v6); 14062306a36Sopenharmony_ci if (req->_present.peer_v6_len) 14162306a36Sopenharmony_ci mnl_attr_put(nlh, FOU_ATTR_PEER_V6, req->_present.peer_v6_len, req->peer_v6); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci err = ynl_exec(ys, nlh, NULL); 14462306a36Sopenharmony_ci if (err < 0) 14562306a36Sopenharmony_ci return -1; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci return 0; 14862306a36Sopenharmony_ci} 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci/* ============== FOU_CMD_GET ============== */ 15162306a36Sopenharmony_ci/* FOU_CMD_GET - do */ 15262306a36Sopenharmony_civoid fou_get_req_free(struct fou_get_req *req) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci free(req->local_v6); 15562306a36Sopenharmony_ci free(req->peer_v6); 15662306a36Sopenharmony_ci free(req); 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_civoid fou_get_rsp_free(struct fou_get_rsp *rsp) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci free(rsp->local_v6); 16262306a36Sopenharmony_ci free(rsp->peer_v6); 16362306a36Sopenharmony_ci free(rsp); 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ciint fou_get_rsp_parse(const struct nlmsghdr *nlh, void *data) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci struct ynl_parse_arg *yarg = data; 16962306a36Sopenharmony_ci const struct nlattr *attr; 17062306a36Sopenharmony_ci struct fou_get_rsp *dst; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci dst = yarg->data; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { 17562306a36Sopenharmony_ci unsigned int type = mnl_attr_get_type(attr); 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci if (type == FOU_ATTR_PORT) { 17862306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 17962306a36Sopenharmony_ci return MNL_CB_ERROR; 18062306a36Sopenharmony_ci dst->_present.port = 1; 18162306a36Sopenharmony_ci dst->port = mnl_attr_get_u16(attr); 18262306a36Sopenharmony_ci } else if (type == FOU_ATTR_IPPROTO) { 18362306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 18462306a36Sopenharmony_ci return MNL_CB_ERROR; 18562306a36Sopenharmony_ci dst->_present.ipproto = 1; 18662306a36Sopenharmony_ci dst->ipproto = mnl_attr_get_u8(attr); 18762306a36Sopenharmony_ci } else if (type == FOU_ATTR_TYPE) { 18862306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 18962306a36Sopenharmony_ci return MNL_CB_ERROR; 19062306a36Sopenharmony_ci dst->_present.type = 1; 19162306a36Sopenharmony_ci dst->type = mnl_attr_get_u8(attr); 19262306a36Sopenharmony_ci } else if (type == FOU_ATTR_REMCSUM_NOPARTIAL) { 19362306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 19462306a36Sopenharmony_ci return MNL_CB_ERROR; 19562306a36Sopenharmony_ci dst->_present.remcsum_nopartial = 1; 19662306a36Sopenharmony_ci } else if (type == FOU_ATTR_LOCAL_V4) { 19762306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 19862306a36Sopenharmony_ci return MNL_CB_ERROR; 19962306a36Sopenharmony_ci dst->_present.local_v4 = 1; 20062306a36Sopenharmony_ci dst->local_v4 = mnl_attr_get_u32(attr); 20162306a36Sopenharmony_ci } else if (type == FOU_ATTR_PEER_V4) { 20262306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 20362306a36Sopenharmony_ci return MNL_CB_ERROR; 20462306a36Sopenharmony_ci dst->_present.peer_v4 = 1; 20562306a36Sopenharmony_ci dst->peer_v4 = mnl_attr_get_u32(attr); 20662306a36Sopenharmony_ci } else if (type == FOU_ATTR_LOCAL_V6) { 20762306a36Sopenharmony_ci unsigned int len; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 21062306a36Sopenharmony_ci return MNL_CB_ERROR; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci len = mnl_attr_get_payload_len(attr); 21362306a36Sopenharmony_ci dst->_present.local_v6_len = len; 21462306a36Sopenharmony_ci dst->local_v6 = malloc(len); 21562306a36Sopenharmony_ci memcpy(dst->local_v6, mnl_attr_get_payload(attr), len); 21662306a36Sopenharmony_ci } else if (type == FOU_ATTR_PEER_V6) { 21762306a36Sopenharmony_ci unsigned int len; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 22062306a36Sopenharmony_ci return MNL_CB_ERROR; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci len = mnl_attr_get_payload_len(attr); 22362306a36Sopenharmony_ci dst->_present.peer_v6_len = len; 22462306a36Sopenharmony_ci dst->peer_v6 = malloc(len); 22562306a36Sopenharmony_ci memcpy(dst->peer_v6, mnl_attr_get_payload(attr), len); 22662306a36Sopenharmony_ci } else if (type == FOU_ATTR_PEER_PORT) { 22762306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 22862306a36Sopenharmony_ci return MNL_CB_ERROR; 22962306a36Sopenharmony_ci dst->_present.peer_port = 1; 23062306a36Sopenharmony_ci dst->peer_port = mnl_attr_get_u16(attr); 23162306a36Sopenharmony_ci } else if (type == FOU_ATTR_IFINDEX) { 23262306a36Sopenharmony_ci if (ynl_attr_validate(yarg, attr)) 23362306a36Sopenharmony_ci return MNL_CB_ERROR; 23462306a36Sopenharmony_ci dst->_present.ifindex = 1; 23562306a36Sopenharmony_ci dst->ifindex = mnl_attr_get_u32(attr); 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci } 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci return MNL_CB_OK; 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistruct fou_get_rsp *fou_get(struct ynl_sock *ys, struct fou_get_req *req) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; 24562306a36Sopenharmony_ci struct fou_get_rsp *rsp; 24662306a36Sopenharmony_ci struct nlmsghdr *nlh; 24762306a36Sopenharmony_ci int err; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_GET, 1); 25062306a36Sopenharmony_ci ys->req_policy = &fou_nest; 25162306a36Sopenharmony_ci yrs.yarg.rsp_policy = &fou_nest; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci if (req->_present.af) 25462306a36Sopenharmony_ci mnl_attr_put_u8(nlh, FOU_ATTR_AF, req->af); 25562306a36Sopenharmony_ci if (req->_present.ifindex) 25662306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_IFINDEX, req->ifindex); 25762306a36Sopenharmony_ci if (req->_present.port) 25862306a36Sopenharmony_ci mnl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); 25962306a36Sopenharmony_ci if (req->_present.peer_port) 26062306a36Sopenharmony_ci mnl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); 26162306a36Sopenharmony_ci if (req->_present.local_v4) 26262306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); 26362306a36Sopenharmony_ci if (req->_present.peer_v4) 26462306a36Sopenharmony_ci mnl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); 26562306a36Sopenharmony_ci if (req->_present.local_v6_len) 26662306a36Sopenharmony_ci mnl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->_present.local_v6_len, req->local_v6); 26762306a36Sopenharmony_ci if (req->_present.peer_v6_len) 26862306a36Sopenharmony_ci mnl_attr_put(nlh, FOU_ATTR_PEER_V6, req->_present.peer_v6_len, req->peer_v6); 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci rsp = calloc(1, sizeof(*rsp)); 27162306a36Sopenharmony_ci yrs.yarg.data = rsp; 27262306a36Sopenharmony_ci yrs.cb = fou_get_rsp_parse; 27362306a36Sopenharmony_ci yrs.rsp_cmd = FOU_CMD_GET; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci err = ynl_exec(ys, nlh, &yrs); 27662306a36Sopenharmony_ci if (err < 0) 27762306a36Sopenharmony_ci goto err_free; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci return rsp; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cierr_free: 28262306a36Sopenharmony_ci fou_get_rsp_free(rsp); 28362306a36Sopenharmony_ci return NULL; 28462306a36Sopenharmony_ci} 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci/* FOU_CMD_GET - dump */ 28762306a36Sopenharmony_civoid fou_get_list_free(struct fou_get_list *rsp) 28862306a36Sopenharmony_ci{ 28962306a36Sopenharmony_ci struct fou_get_list *next = rsp; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci while ((void *)next != YNL_LIST_END) { 29262306a36Sopenharmony_ci rsp = next; 29362306a36Sopenharmony_ci next = rsp->next; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci free(rsp->obj.local_v6); 29662306a36Sopenharmony_ci free(rsp->obj.peer_v6); 29762306a36Sopenharmony_ci free(rsp); 29862306a36Sopenharmony_ci } 29962306a36Sopenharmony_ci} 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_cistruct fou_get_list *fou_get_dump(struct ynl_sock *ys) 30262306a36Sopenharmony_ci{ 30362306a36Sopenharmony_ci struct ynl_dump_state yds = {}; 30462306a36Sopenharmony_ci struct nlmsghdr *nlh; 30562306a36Sopenharmony_ci int err; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci yds.ys = ys; 30862306a36Sopenharmony_ci yds.alloc_sz = sizeof(struct fou_get_list); 30962306a36Sopenharmony_ci yds.cb = fou_get_rsp_parse; 31062306a36Sopenharmony_ci yds.rsp_cmd = FOU_CMD_GET; 31162306a36Sopenharmony_ci yds.rsp_policy = &fou_nest; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci nlh = ynl_gemsg_start_dump(ys, ys->family_id, FOU_CMD_GET, 1); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci err = ynl_exec_dump(ys, nlh, &yds); 31662306a36Sopenharmony_ci if (err < 0) 31762306a36Sopenharmony_ci goto free_list; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci return yds.first; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_cifree_list: 32262306a36Sopenharmony_ci fou_get_list_free(yds.first); 32362306a36Sopenharmony_ci return NULL; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ciconst struct ynl_family ynl_fou_family = { 32762306a36Sopenharmony_ci .name = "fou", 32862306a36Sopenharmony_ci}; 329