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