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/netdev.yaml */
4 /* YNL-GEN user source */
5 
6 #include <stdlib.h>
7 #include "netdev-user.h"
8 #include "ynl.h"
9 #include <linux/netdev.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 netdev_op_strmap[] = {
19 	[NETDEV_CMD_DEV_GET] = "dev-get",
20 	[NETDEV_CMD_DEV_ADD_NTF] = "dev-add-ntf",
21 	[NETDEV_CMD_DEV_DEL_NTF] = "dev-del-ntf",
22 	[NETDEV_CMD_DEV_CHANGE_NTF] = "dev-change-ntf",
23 };
24 
25 const char *netdev_op_str(int op)
26 {
27 	if (op < 0 || op >= (int)MNL_ARRAY_SIZE(netdev_op_strmap))
28 		return NULL;
29 	return netdev_op_strmap[op];
30 }
31 
32 static const char * const netdev_xdp_act_strmap[] = {
33 	[0] = "basic",
34 	[1] = "redirect",
35 	[2] = "ndo-xmit",
36 	[3] = "xsk-zerocopy",
37 	[4] = "hw-offload",
38 	[5] = "rx-sg",
39 	[6] = "ndo-xmit-sg",
40 };
41 
42 const char *netdev_xdp_act_str(enum netdev_xdp_act value)
43 {
44 	value = ffs(value) - 1;
45 	if (value < 0 || value >= (int)MNL_ARRAY_SIZE(netdev_xdp_act_strmap))
46 		return NULL;
47 	return netdev_xdp_act_strmap[value];
48 }
49 
50 /* Policies */
51 struct ynl_policy_attr netdev_dev_policy[NETDEV_A_DEV_MAX + 1] = {
52 	[NETDEV_A_DEV_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, },
53 	[NETDEV_A_DEV_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, },
54 	[NETDEV_A_DEV_XDP_FEATURES] = { .name = "xdp-features", .type = YNL_PT_U64, },
55 };
56 
57 struct ynl_policy_nest netdev_dev_nest = {
58 	.max_attr = NETDEV_A_DEV_MAX,
59 	.table = netdev_dev_policy,
60 };
61 
62 /* Common nested types */
63 /* ============== NETDEV_CMD_DEV_GET ============== */
64 /* NETDEV_CMD_DEV_GET - do */
65 void netdev_dev_get_req_free(struct netdev_dev_get_req *req)
66 {
67 	free(req);
68 }
69 
70 void netdev_dev_get_rsp_free(struct netdev_dev_get_rsp *rsp)
71 {
72 	free(rsp);
73 }
74 
75 int netdev_dev_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
76 {
77 	struct ynl_parse_arg *yarg = data;
78 	struct netdev_dev_get_rsp *dst;
79 	const struct nlattr *attr;
80 
81 	dst = yarg->data;
82 
83 	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
84 		if (mnl_attr_get_type(attr) == NETDEV_A_DEV_IFINDEX) {
85 			if (ynl_attr_validate(yarg, attr))
86 				return MNL_CB_ERROR;
87 			dst->_present.ifindex = 1;
88 			dst->ifindex = mnl_attr_get_u32(attr);
89 		}
90 		else if (mnl_attr_get_type(attr) == NETDEV_A_DEV_XDP_FEATURES) {
91 			if (ynl_attr_validate(yarg, attr))
92 				return MNL_CB_ERROR;
93 			dst->_present.xdp_features = 1;
94 			dst->xdp_features = mnl_attr_get_u64(attr);
95 		}
96 	}
97 
98 	return MNL_CB_OK;
99 }
100 
101 struct netdev_dev_get_rsp *
102 netdev_dev_get(struct ynl_sock *ys, struct netdev_dev_get_req *req)
103 {
104 	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
105 	struct netdev_dev_get_rsp *rsp;
106 	struct nlmsghdr *nlh;
107 	int err;
108 
109 	nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1);
110 	ys->req_policy = &netdev_dev_nest;
111 	yrs.yarg.rsp_policy = &netdev_dev_nest;
112 
113 	if (req->_present.ifindex)
114 		mnl_attr_put_u32(nlh, NETDEV_A_DEV_IFINDEX, req->ifindex);
115 
116 	rsp = calloc(1, sizeof(*rsp));
117 	yrs.yarg.data = rsp;
118 	yrs.cb = netdev_dev_get_rsp_parse;
119 	yrs.rsp_cmd = NETDEV_CMD_DEV_GET;
120 
121 	err = ynl_exec(ys, nlh, &yrs);
122 	if (err < 0)
123 		goto err_free;
124 
125 	return rsp;
126 
127 err_free:
128 	netdev_dev_get_rsp_free(rsp);
129 	return NULL;
130 }
131 
132 /* NETDEV_CMD_DEV_GET - dump */
133 void netdev_dev_get_list_free(struct netdev_dev_get_list *rsp)
134 {
135 	struct netdev_dev_get_list *next = rsp;
136 
137 	while ((void *)next != YNL_LIST_END) {
138 		rsp = next;
139 		next = rsp->next;
140 
141 		free(rsp);
142 	}
143 }
144 
145 struct netdev_dev_get_list *netdev_dev_get_dump(struct ynl_sock *ys)
146 {
147 	struct ynl_dump_state yds = {};
148 	struct nlmsghdr *nlh;
149 	int err;
150 
151 	yds.ys = ys;
152 	yds.alloc_sz = sizeof(struct netdev_dev_get_list);
153 	yds.cb = netdev_dev_get_rsp_parse;
154 	yds.rsp_cmd = NETDEV_CMD_DEV_GET;
155 	yds.rsp_policy = &netdev_dev_nest;
156 
157 	nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1);
158 
159 	err = ynl_exec_dump(ys, nlh, &yds);
160 	if (err < 0)
161 		goto free_list;
162 
163 	return yds.first;
164 
165 free_list:
166 	netdev_dev_get_list_free(yds.first);
167 	return NULL;
168 }
169 
170 /* NETDEV_CMD_DEV_GET - notify */
171 void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp)
172 {
173 	free(rsp);
174 }
175 
176 /* --------------- Common notification parsing --------------- */
177 struct ynl_ntf_base_type *netdev_ntf_parse(struct ynl_sock *ys)
178 {
179 	struct ynl_parse_arg yarg = { .ys = ys, };
180 	struct ynl_ntf_base_type *rsp;
181 	struct genlmsghdr *genlh;
182 	struct nlmsghdr *nlh;
183 	mnl_cb_t parse;
184 	int len, err;
185 
186 	len = mnl_socket_recvfrom(ys->sock, ys->rx_buf, MNL_SOCKET_BUFFER_SIZE);
187 	if (len < (ssize_t)(sizeof(*nlh) + sizeof(*genlh)))
188 		return NULL;
189 
190 	nlh = (struct nlmsghdr *)ys->rx_buf;
191 	genlh = mnl_nlmsg_get_payload(nlh);
192 
193 	switch (genlh->cmd) {
194 	case NETDEV_CMD_DEV_ADD_NTF:
195 	case NETDEV_CMD_DEV_DEL_NTF:
196 	case NETDEV_CMD_DEV_CHANGE_NTF:
197 		rsp = calloc(1, sizeof(struct netdev_dev_get_ntf));
198 		parse = netdev_dev_get_rsp_parse;
199 		yarg.rsp_policy = &netdev_dev_nest;
200 		rsp->free = (void *)netdev_dev_get_ntf_free;
201 		break;
202 	default:
203 		ynl_error_unknown_notification(ys, genlh->cmd);
204 		return NULL;
205 	}
206 
207 	yarg.data = rsp->data;
208 
209 	err = mnl_cb_run2(ys->rx_buf, len, 0, 0, parse, &yarg,
210 			 ynl_cb_array, NLMSG_MIN_TYPE);
211 	if (err < 0)
212 		goto err_free;
213 
214 	rsp->family = nlh->nlmsg_type;
215 	rsp->cmd = genlh->cmd;
216 	return rsp;
217 
218 err_free:
219 	free(rsp);
220 	return NULL;
221 }
222 
223 static const struct ynl_ntf_info netdev_ntf_info[] =  {
224 	[NETDEV_CMD_DEV_ADD_NTF] =  {
225 		.alloc_sz	= sizeof(struct netdev_dev_get_ntf),
226 		.cb		= netdev_dev_get_rsp_parse,
227 		.policy		= &netdev_dev_nest,
228 		.free		= (void *)netdev_dev_get_ntf_free,
229 	},
230 	[NETDEV_CMD_DEV_DEL_NTF] =  {
231 		.alloc_sz	= sizeof(struct netdev_dev_get_ntf),
232 		.cb		= netdev_dev_get_rsp_parse,
233 		.policy		= &netdev_dev_nest,
234 		.free		= (void *)netdev_dev_get_ntf_free,
235 	},
236 	[NETDEV_CMD_DEV_CHANGE_NTF] =  {
237 		.alloc_sz	= sizeof(struct netdev_dev_get_ntf),
238 		.cb		= netdev_dev_get_rsp_parse,
239 		.policy		= &netdev_dev_nest,
240 		.free		= (void *)netdev_dev_get_ntf_free,
241 	},
242 };
243 
244 const struct ynl_family ynl_netdev_family =  {
245 	.name		= "netdev",
246 	.ntf_info	= netdev_ntf_info,
247 	.ntf_info_size	= MNL_ARRAY_SIZE(netdev_ntf_info),
248 };
249