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