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