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/ethtool.yaml */
4/* YNL-GEN user source */
5/* YNL-ARG --user-header linux/ethtool_netlink.h --exclude-op stats-get */
6
7#include <stdlib.h>
8#include <string.h>
9#include "ethtool-user.h"
10#include "ynl.h"
11#include <linux/ethtool.h>
12
13#include <libmnl/libmnl.h>
14#include <linux/genetlink.h>
15
16#include "linux/ethtool_netlink.h"
17
18/* Enums */
19static const char * const ethtool_op_strmap[] = {
20	[ETHTOOL_MSG_STRSET_GET] = "strset-get",
21	[ETHTOOL_MSG_LINKINFO_GET] = "linkinfo-get",
22	[3] = "linkinfo-ntf",
23	[ETHTOOL_MSG_LINKMODES_GET] = "linkmodes-get",
24	[5] = "linkmodes-ntf",
25	[ETHTOOL_MSG_LINKSTATE_GET] = "linkstate-get",
26	[ETHTOOL_MSG_DEBUG_GET] = "debug-get",
27	[8] = "debug-ntf",
28	[ETHTOOL_MSG_WOL_GET] = "wol-get",
29	[10] = "wol-ntf",
30	[ETHTOOL_MSG_FEATURES_GET] = "features-get",
31	[ETHTOOL_MSG_FEATURES_SET] = "features-set",
32	[13] = "features-ntf",
33	[14] = "privflags-get",
34	[15] = "privflags-ntf",
35	[16] = "rings-get",
36	[17] = "rings-ntf",
37	[18] = "channels-get",
38	[19] = "channels-ntf",
39	[20] = "coalesce-get",
40	[21] = "coalesce-ntf",
41	[22] = "pause-get",
42	[23] = "pause-ntf",
43	[24] = "eee-get",
44	[25] = "eee-ntf",
45	[26] = "tsinfo-get",
46	[27] = "cable-test-ntf",
47	[28] = "cable-test-tdr-ntf",
48	[29] = "tunnel-info-get",
49	[30] = "fec-get",
50	[31] = "fec-ntf",
51	[32] = "module-eeprom-get",
52	[34] = "phc-vclocks-get",
53	[35] = "module-get",
54	[36] = "module-ntf",
55	[37] = "pse-get",
56	[ETHTOOL_MSG_RSS_GET] = "rss-get",
57	[ETHTOOL_MSG_PLCA_GET_CFG] = "plca-get-cfg",
58	[40] = "plca-get-status",
59	[41] = "plca-ntf",
60	[ETHTOOL_MSG_MM_GET] = "mm-get",
61	[43] = "mm-ntf",
62};
63
64const char *ethtool_op_str(int op)
65{
66	if (op < 0 || op >= (int)MNL_ARRAY_SIZE(ethtool_op_strmap))
67		return NULL;
68	return ethtool_op_strmap[op];
69}
70
71static const char * const ethtool_udp_tunnel_type_strmap[] = {
72	[0] = "vxlan",
73	[1] = "geneve",
74	[2] = "vxlan-gpe",
75};
76
77const char *ethtool_udp_tunnel_type_str(int value)
78{
79	if (value < 0 || value >= (int)MNL_ARRAY_SIZE(ethtool_udp_tunnel_type_strmap))
80		return NULL;
81	return ethtool_udp_tunnel_type_strmap[value];
82}
83
84static const char * const ethtool_stringset_strmap[] = {
85};
86
87const char *ethtool_stringset_str(enum ethtool_stringset value)
88{
89	if (value < 0 || value >= (int)MNL_ARRAY_SIZE(ethtool_stringset_strmap))
90		return NULL;
91	return ethtool_stringset_strmap[value];
92}
93
94/* Policies */
95struct ynl_policy_attr ethtool_header_policy[ETHTOOL_A_HEADER_MAX + 1] = {
96	[ETHTOOL_A_HEADER_DEV_INDEX] = { .name = "dev-index", .type = YNL_PT_U32, },
97	[ETHTOOL_A_HEADER_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, },
98	[ETHTOOL_A_HEADER_FLAGS] = { .name = "flags", .type = YNL_PT_U32, },
99};
100
101struct ynl_policy_nest ethtool_header_nest = {
102	.max_attr = ETHTOOL_A_HEADER_MAX,
103	.table = ethtool_header_policy,
104};
105
106struct ynl_policy_attr ethtool_pause_stat_policy[ETHTOOL_A_PAUSE_STAT_MAX + 1] = {
107	[ETHTOOL_A_PAUSE_STAT_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, },
108	[ETHTOOL_A_PAUSE_STAT_TX_FRAMES] = { .name = "tx-frames", .type = YNL_PT_U64, },
109	[ETHTOOL_A_PAUSE_STAT_RX_FRAMES] = { .name = "rx-frames", .type = YNL_PT_U64, },
110};
111
112struct ynl_policy_nest ethtool_pause_stat_nest = {
113	.max_attr = ETHTOOL_A_PAUSE_STAT_MAX,
114	.table = ethtool_pause_stat_policy,
115};
116
117struct ynl_policy_attr ethtool_cable_test_tdr_cfg_policy[ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX + 1] = {
118	[ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST] = { .name = "first", .type = YNL_PT_U32, },
119	[ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST] = { .name = "last", .type = YNL_PT_U32, },
120	[ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP] = { .name = "step", .type = YNL_PT_U32, },
121	[ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR] = { .name = "pair", .type = YNL_PT_U8, },
122};
123
124struct ynl_policy_nest ethtool_cable_test_tdr_cfg_nest = {
125	.max_attr = ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX,
126	.table = ethtool_cable_test_tdr_cfg_policy,
127};
128
129struct ynl_policy_attr ethtool_fec_stat_policy[ETHTOOL_A_FEC_STAT_MAX + 1] = {
130	[ETHTOOL_A_FEC_STAT_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, },
131	[ETHTOOL_A_FEC_STAT_CORRECTED] = { .name = "corrected", .type = YNL_PT_BINARY,},
132	[ETHTOOL_A_FEC_STAT_UNCORR] = { .name = "uncorr", .type = YNL_PT_BINARY,},
133	[ETHTOOL_A_FEC_STAT_CORR_BITS] = { .name = "corr-bits", .type = YNL_PT_BINARY,},
134};
135
136struct ynl_policy_nest ethtool_fec_stat_nest = {
137	.max_attr = ETHTOOL_A_FEC_STAT_MAX,
138	.table = ethtool_fec_stat_policy,
139};
140
141struct ynl_policy_attr ethtool_mm_stat_policy[ETHTOOL_A_MM_STAT_MAX + 1] = {
142	[ETHTOOL_A_MM_STAT_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, },
143	[ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS] = { .name = "reassembly-errors", .type = YNL_PT_U64, },
144	[ETHTOOL_A_MM_STAT_SMD_ERRORS] = { .name = "smd-errors", .type = YNL_PT_U64, },
145	[ETHTOOL_A_MM_STAT_REASSEMBLY_OK] = { .name = "reassembly-ok", .type = YNL_PT_U64, },
146	[ETHTOOL_A_MM_STAT_RX_FRAG_COUNT] = { .name = "rx-frag-count", .type = YNL_PT_U64, },
147	[ETHTOOL_A_MM_STAT_TX_FRAG_COUNT] = { .name = "tx-frag-count", .type = YNL_PT_U64, },
148	[ETHTOOL_A_MM_STAT_HOLD_COUNT] = { .name = "hold-count", .type = YNL_PT_U64, },
149};
150
151struct ynl_policy_nest ethtool_mm_stat_nest = {
152	.max_attr = ETHTOOL_A_MM_STAT_MAX,
153	.table = ethtool_mm_stat_policy,
154};
155
156struct ynl_policy_attr ethtool_cable_result_policy[ETHTOOL_A_CABLE_RESULT_MAX + 1] = {
157	[ETHTOOL_A_CABLE_RESULT_PAIR] = { .name = "pair", .type = YNL_PT_U8, },
158	[ETHTOOL_A_CABLE_RESULT_CODE] = { .name = "code", .type = YNL_PT_U8, },
159};
160
161struct ynl_policy_nest ethtool_cable_result_nest = {
162	.max_attr = ETHTOOL_A_CABLE_RESULT_MAX,
163	.table = ethtool_cable_result_policy,
164};
165
166struct ynl_policy_attr ethtool_cable_fault_length_policy[ETHTOOL_A_CABLE_FAULT_LENGTH_MAX + 1] = {
167	[ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR] = { .name = "pair", .type = YNL_PT_U8, },
168	[ETHTOOL_A_CABLE_FAULT_LENGTH_CM] = { .name = "cm", .type = YNL_PT_U32, },
169};
170
171struct ynl_policy_nest ethtool_cable_fault_length_nest = {
172	.max_attr = ETHTOOL_A_CABLE_FAULT_LENGTH_MAX,
173	.table = ethtool_cable_fault_length_policy,
174};
175
176struct ynl_policy_attr ethtool_bitset_bit_policy[ETHTOOL_A_BITSET_BIT_MAX + 1] = {
177	[ETHTOOL_A_BITSET_BIT_INDEX] = { .name = "index", .type = YNL_PT_U32, },
178	[ETHTOOL_A_BITSET_BIT_NAME] = { .name = "name", .type = YNL_PT_NUL_STR, },
179	[ETHTOOL_A_BITSET_BIT_VALUE] = { .name = "value", .type = YNL_PT_FLAG, },
180};
181
182struct ynl_policy_nest ethtool_bitset_bit_nest = {
183	.max_attr = ETHTOOL_A_BITSET_BIT_MAX,
184	.table = ethtool_bitset_bit_policy,
185};
186
187struct ynl_policy_attr ethtool_tunnel_udp_entry_policy[ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX + 1] = {
188	[ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT] = { .name = "port", .type = YNL_PT_U16, },
189	[ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE] = { .name = "type", .type = YNL_PT_U32, },
190};
191
192struct ynl_policy_nest ethtool_tunnel_udp_entry_nest = {
193	.max_attr = ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX,
194	.table = ethtool_tunnel_udp_entry_policy,
195};
196
197struct ynl_policy_attr ethtool_string_policy[ETHTOOL_A_STRING_MAX + 1] = {
198	[ETHTOOL_A_STRING_INDEX] = { .name = "index", .type = YNL_PT_U32, },
199	[ETHTOOL_A_STRING_VALUE] = { .name = "value", .type = YNL_PT_NUL_STR, },
200};
201
202struct ynl_policy_nest ethtool_string_nest = {
203	.max_attr = ETHTOOL_A_STRING_MAX,
204	.table = ethtool_string_policy,
205};
206
207struct ynl_policy_attr ethtool_cable_nest_policy[ETHTOOL_A_CABLE_NEST_MAX + 1] = {
208	[ETHTOOL_A_CABLE_NEST_RESULT] = { .name = "result", .type = YNL_PT_NEST, .nest = &ethtool_cable_result_nest, },
209	[ETHTOOL_A_CABLE_NEST_FAULT_LENGTH] = { .name = "fault-length", .type = YNL_PT_NEST, .nest = &ethtool_cable_fault_length_nest, },
210};
211
212struct ynl_policy_nest ethtool_cable_nest_nest = {
213	.max_attr = ETHTOOL_A_CABLE_NEST_MAX,
214	.table = ethtool_cable_nest_policy,
215};
216
217struct ynl_policy_attr ethtool_bitset_bits_policy[ETHTOOL_A_BITSET_BITS_MAX + 1] = {
218	[ETHTOOL_A_BITSET_BITS_BIT] = { .name = "bit", .type = YNL_PT_NEST, .nest = &ethtool_bitset_bit_nest, },
219};
220
221struct ynl_policy_nest ethtool_bitset_bits_nest = {
222	.max_attr = ETHTOOL_A_BITSET_BITS_MAX,
223	.table = ethtool_bitset_bits_policy,
224};
225
226struct ynl_policy_attr ethtool_strings_policy[ETHTOOL_A_STRINGS_MAX + 1] = {
227	[ETHTOOL_A_STRINGS_STRING] = { .name = "string", .type = YNL_PT_NEST, .nest = &ethtool_string_nest, },
228};
229
230struct ynl_policy_nest ethtool_strings_nest = {
231	.max_attr = ETHTOOL_A_STRINGS_MAX,
232	.table = ethtool_strings_policy,
233};
234
235struct ynl_policy_attr ethtool_bitset_policy[ETHTOOL_A_BITSET_MAX + 1] = {
236	[ETHTOOL_A_BITSET_NOMASK] = { .name = "nomask", .type = YNL_PT_FLAG, },
237	[ETHTOOL_A_BITSET_SIZE] = { .name = "size", .type = YNL_PT_U32, },
238	[ETHTOOL_A_BITSET_BITS] = { .name = "bits", .type = YNL_PT_NEST, .nest = &ethtool_bitset_bits_nest, },
239};
240
241struct ynl_policy_nest ethtool_bitset_nest = {
242	.max_attr = ETHTOOL_A_BITSET_MAX,
243	.table = ethtool_bitset_policy,
244};
245
246struct ynl_policy_attr ethtool_stringset_policy[ETHTOOL_A_STRINGSET_MAX + 1] = {
247	[ETHTOOL_A_STRINGSET_ID] = { .name = "id", .type = YNL_PT_U32, },
248	[ETHTOOL_A_STRINGSET_COUNT] = { .name = "count", .type = YNL_PT_U32, },
249	[ETHTOOL_A_STRINGSET_STRINGS] = { .name = "strings", .type = YNL_PT_NEST, .nest = &ethtool_strings_nest, },
250};
251
252struct ynl_policy_nest ethtool_stringset_nest = {
253	.max_attr = ETHTOOL_A_STRINGSET_MAX,
254	.table = ethtool_stringset_policy,
255};
256
257struct ynl_policy_attr ethtool_tunnel_udp_table_policy[ETHTOOL_A_TUNNEL_UDP_TABLE_MAX + 1] = {
258	[ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE] = { .name = "size", .type = YNL_PT_U32, },
259	[ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES] = { .name = "types", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
260	[ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY] = { .name = "entry", .type = YNL_PT_NEST, .nest = &ethtool_tunnel_udp_entry_nest, },
261};
262
263struct ynl_policy_nest ethtool_tunnel_udp_table_nest = {
264	.max_attr = ETHTOOL_A_TUNNEL_UDP_TABLE_MAX,
265	.table = ethtool_tunnel_udp_table_policy,
266};
267
268struct ynl_policy_attr ethtool_stringsets_policy[ETHTOOL_A_STRINGSETS_MAX + 1] = {
269	[ETHTOOL_A_STRINGSETS_STRINGSET] = { .name = "stringset", .type = YNL_PT_NEST, .nest = &ethtool_stringset_nest, },
270};
271
272struct ynl_policy_nest ethtool_stringsets_nest = {
273	.max_attr = ETHTOOL_A_STRINGSETS_MAX,
274	.table = ethtool_stringsets_policy,
275};
276
277struct ynl_policy_attr ethtool_tunnel_udp_policy[ETHTOOL_A_TUNNEL_UDP_MAX + 1] = {
278	[ETHTOOL_A_TUNNEL_UDP_TABLE] = { .name = "table", .type = YNL_PT_NEST, .nest = &ethtool_tunnel_udp_table_nest, },
279};
280
281struct ynl_policy_nest ethtool_tunnel_udp_nest = {
282	.max_attr = ETHTOOL_A_TUNNEL_UDP_MAX,
283	.table = ethtool_tunnel_udp_policy,
284};
285
286struct ynl_policy_attr ethtool_strset_policy[ETHTOOL_A_STRSET_MAX + 1] = {
287	[ETHTOOL_A_STRSET_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
288	[ETHTOOL_A_STRSET_STRINGSETS] = { .name = "stringsets", .type = YNL_PT_NEST, .nest = &ethtool_stringsets_nest, },
289	[ETHTOOL_A_STRSET_COUNTS_ONLY] = { .name = "counts-only", .type = YNL_PT_FLAG, },
290};
291
292struct ynl_policy_nest ethtool_strset_nest = {
293	.max_attr = ETHTOOL_A_STRSET_MAX,
294	.table = ethtool_strset_policy,
295};
296
297struct ynl_policy_attr ethtool_linkinfo_policy[ETHTOOL_A_LINKINFO_MAX + 1] = {
298	[ETHTOOL_A_LINKINFO_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
299	[ETHTOOL_A_LINKINFO_PORT] = { .name = "port", .type = YNL_PT_U8, },
300	[ETHTOOL_A_LINKINFO_PHYADDR] = { .name = "phyaddr", .type = YNL_PT_U8, },
301	[ETHTOOL_A_LINKINFO_TP_MDIX] = { .name = "tp-mdix", .type = YNL_PT_U8, },
302	[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL] = { .name = "tp-mdix-ctrl", .type = YNL_PT_U8, },
303	[ETHTOOL_A_LINKINFO_TRANSCEIVER] = { .name = "transceiver", .type = YNL_PT_U8, },
304};
305
306struct ynl_policy_nest ethtool_linkinfo_nest = {
307	.max_attr = ETHTOOL_A_LINKINFO_MAX,
308	.table = ethtool_linkinfo_policy,
309};
310
311struct ynl_policy_attr ethtool_linkmodes_policy[ETHTOOL_A_LINKMODES_MAX + 1] = {
312	[ETHTOOL_A_LINKMODES_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
313	[ETHTOOL_A_LINKMODES_AUTONEG] = { .name = "autoneg", .type = YNL_PT_U8, },
314	[ETHTOOL_A_LINKMODES_OURS] = { .name = "ours", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
315	[ETHTOOL_A_LINKMODES_PEER] = { .name = "peer", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
316	[ETHTOOL_A_LINKMODES_SPEED] = { .name = "speed", .type = YNL_PT_U32, },
317	[ETHTOOL_A_LINKMODES_DUPLEX] = { .name = "duplex", .type = YNL_PT_U8, },
318	[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG] = { .name = "master-slave-cfg", .type = YNL_PT_U8, },
319	[ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE] = { .name = "master-slave-state", .type = YNL_PT_U8, },
320	[ETHTOOL_A_LINKMODES_LANES] = { .name = "lanes", .type = YNL_PT_U32, },
321	[ETHTOOL_A_LINKMODES_RATE_MATCHING] = { .name = "rate-matching", .type = YNL_PT_U8, },
322};
323
324struct ynl_policy_nest ethtool_linkmodes_nest = {
325	.max_attr = ETHTOOL_A_LINKMODES_MAX,
326	.table = ethtool_linkmodes_policy,
327};
328
329struct ynl_policy_attr ethtool_linkstate_policy[ETHTOOL_A_LINKSTATE_MAX + 1] = {
330	[ETHTOOL_A_LINKSTATE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
331	[ETHTOOL_A_LINKSTATE_LINK] = { .name = "link", .type = YNL_PT_U8, },
332	[ETHTOOL_A_LINKSTATE_SQI] = { .name = "sqi", .type = YNL_PT_U32, },
333	[ETHTOOL_A_LINKSTATE_SQI_MAX] = { .name = "sqi-max", .type = YNL_PT_U32, },
334	[ETHTOOL_A_LINKSTATE_EXT_STATE] = { .name = "ext-state", .type = YNL_PT_U8, },
335	[ETHTOOL_A_LINKSTATE_EXT_SUBSTATE] = { .name = "ext-substate", .type = YNL_PT_U8, },
336	[ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT] = { .name = "ext-down-cnt", .type = YNL_PT_U32, },
337};
338
339struct ynl_policy_nest ethtool_linkstate_nest = {
340	.max_attr = ETHTOOL_A_LINKSTATE_MAX,
341	.table = ethtool_linkstate_policy,
342};
343
344struct ynl_policy_attr ethtool_debug_policy[ETHTOOL_A_DEBUG_MAX + 1] = {
345	[ETHTOOL_A_DEBUG_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
346	[ETHTOOL_A_DEBUG_MSGMASK] = { .name = "msgmask", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
347};
348
349struct ynl_policy_nest ethtool_debug_nest = {
350	.max_attr = ETHTOOL_A_DEBUG_MAX,
351	.table = ethtool_debug_policy,
352};
353
354struct ynl_policy_attr ethtool_wol_policy[ETHTOOL_A_WOL_MAX + 1] = {
355	[ETHTOOL_A_WOL_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
356	[ETHTOOL_A_WOL_MODES] = { .name = "modes", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
357	[ETHTOOL_A_WOL_SOPASS] = { .name = "sopass", .type = YNL_PT_BINARY,},
358};
359
360struct ynl_policy_nest ethtool_wol_nest = {
361	.max_attr = ETHTOOL_A_WOL_MAX,
362	.table = ethtool_wol_policy,
363};
364
365struct ynl_policy_attr ethtool_features_policy[ETHTOOL_A_FEATURES_MAX + 1] = {
366	[ETHTOOL_A_FEATURES_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
367	[ETHTOOL_A_FEATURES_HW] = { .name = "hw", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
368	[ETHTOOL_A_FEATURES_WANTED] = { .name = "wanted", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
369	[ETHTOOL_A_FEATURES_ACTIVE] = { .name = "active", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
370	[ETHTOOL_A_FEATURES_NOCHANGE] = { .name = "nochange", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
371};
372
373struct ynl_policy_nest ethtool_features_nest = {
374	.max_attr = ETHTOOL_A_FEATURES_MAX,
375	.table = ethtool_features_policy,
376};
377
378struct ynl_policy_attr ethtool_privflags_policy[ETHTOOL_A_PRIVFLAGS_MAX + 1] = {
379	[ETHTOOL_A_PRIVFLAGS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
380	[ETHTOOL_A_PRIVFLAGS_FLAGS] = { .name = "flags", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
381};
382
383struct ynl_policy_nest ethtool_privflags_nest = {
384	.max_attr = ETHTOOL_A_PRIVFLAGS_MAX,
385	.table = ethtool_privflags_policy,
386};
387
388struct ynl_policy_attr ethtool_rings_policy[ETHTOOL_A_RINGS_MAX + 1] = {
389	[ETHTOOL_A_RINGS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
390	[ETHTOOL_A_RINGS_RX_MAX] = { .name = "rx-max", .type = YNL_PT_U32, },
391	[ETHTOOL_A_RINGS_RX_MINI_MAX] = { .name = "rx-mini-max", .type = YNL_PT_U32, },
392	[ETHTOOL_A_RINGS_RX_JUMBO_MAX] = { .name = "rx-jumbo-max", .type = YNL_PT_U32, },
393	[ETHTOOL_A_RINGS_TX_MAX] = { .name = "tx-max", .type = YNL_PT_U32, },
394	[ETHTOOL_A_RINGS_RX] = { .name = "rx", .type = YNL_PT_U32, },
395	[ETHTOOL_A_RINGS_RX_MINI] = { .name = "rx-mini", .type = YNL_PT_U32, },
396	[ETHTOOL_A_RINGS_RX_JUMBO] = { .name = "rx-jumbo", .type = YNL_PT_U32, },
397	[ETHTOOL_A_RINGS_TX] = { .name = "tx", .type = YNL_PT_U32, },
398	[ETHTOOL_A_RINGS_RX_BUF_LEN] = { .name = "rx-buf-len", .type = YNL_PT_U32, },
399	[ETHTOOL_A_RINGS_TCP_DATA_SPLIT] = { .name = "tcp-data-split", .type = YNL_PT_U8, },
400	[ETHTOOL_A_RINGS_CQE_SIZE] = { .name = "cqe-size", .type = YNL_PT_U32, },
401	[ETHTOOL_A_RINGS_TX_PUSH] = { .name = "tx-push", .type = YNL_PT_U8, },
402	[ETHTOOL_A_RINGS_RX_PUSH] = { .name = "rx-push", .type = YNL_PT_U8, },
403	[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN] = { .name = "tx-push-buf-len", .type = YNL_PT_U32, },
404	[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX] = { .name = "tx-push-buf-len-max", .type = YNL_PT_U32, },
405};
406
407struct ynl_policy_nest ethtool_rings_nest = {
408	.max_attr = ETHTOOL_A_RINGS_MAX,
409	.table = ethtool_rings_policy,
410};
411
412struct ynl_policy_attr ethtool_channels_policy[ETHTOOL_A_CHANNELS_MAX + 1] = {
413	[ETHTOOL_A_CHANNELS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
414	[ETHTOOL_A_CHANNELS_RX_MAX] = { .name = "rx-max", .type = YNL_PT_U32, },
415	[ETHTOOL_A_CHANNELS_TX_MAX] = { .name = "tx-max", .type = YNL_PT_U32, },
416	[ETHTOOL_A_CHANNELS_OTHER_MAX] = { .name = "other-max", .type = YNL_PT_U32, },
417	[ETHTOOL_A_CHANNELS_COMBINED_MAX] = { .name = "combined-max", .type = YNL_PT_U32, },
418	[ETHTOOL_A_CHANNELS_RX_COUNT] = { .name = "rx-count", .type = YNL_PT_U32, },
419	[ETHTOOL_A_CHANNELS_TX_COUNT] = { .name = "tx-count", .type = YNL_PT_U32, },
420	[ETHTOOL_A_CHANNELS_OTHER_COUNT] = { .name = "other-count", .type = YNL_PT_U32, },
421	[ETHTOOL_A_CHANNELS_COMBINED_COUNT] = { .name = "combined-count", .type = YNL_PT_U32, },
422};
423
424struct ynl_policy_nest ethtool_channels_nest = {
425	.max_attr = ETHTOOL_A_CHANNELS_MAX,
426	.table = ethtool_channels_policy,
427};
428
429struct ynl_policy_attr ethtool_coalesce_policy[ETHTOOL_A_COALESCE_MAX + 1] = {
430	[ETHTOOL_A_COALESCE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
431	[ETHTOOL_A_COALESCE_RX_USECS] = { .name = "rx-usecs", .type = YNL_PT_U32, },
432	[ETHTOOL_A_COALESCE_RX_MAX_FRAMES] = { .name = "rx-max-frames", .type = YNL_PT_U32, },
433	[ETHTOOL_A_COALESCE_RX_USECS_IRQ] = { .name = "rx-usecs-irq", .type = YNL_PT_U32, },
434	[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ] = { .name = "rx-max-frames-irq", .type = YNL_PT_U32, },
435	[ETHTOOL_A_COALESCE_TX_USECS] = { .name = "tx-usecs", .type = YNL_PT_U32, },
436	[ETHTOOL_A_COALESCE_TX_MAX_FRAMES] = { .name = "tx-max-frames", .type = YNL_PT_U32, },
437	[ETHTOOL_A_COALESCE_TX_USECS_IRQ] = { .name = "tx-usecs-irq", .type = YNL_PT_U32, },
438	[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ] = { .name = "tx-max-frames-irq", .type = YNL_PT_U32, },
439	[ETHTOOL_A_COALESCE_STATS_BLOCK_USECS] = { .name = "stats-block-usecs", .type = YNL_PT_U32, },
440	[ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX] = { .name = "use-adaptive-rx", .type = YNL_PT_U8, },
441	[ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX] = { .name = "use-adaptive-tx", .type = YNL_PT_U8, },
442	[ETHTOOL_A_COALESCE_PKT_RATE_LOW] = { .name = "pkt-rate-low", .type = YNL_PT_U32, },
443	[ETHTOOL_A_COALESCE_RX_USECS_LOW] = { .name = "rx-usecs-low", .type = YNL_PT_U32, },
444	[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW] = { .name = "rx-max-frames-low", .type = YNL_PT_U32, },
445	[ETHTOOL_A_COALESCE_TX_USECS_LOW] = { .name = "tx-usecs-low", .type = YNL_PT_U32, },
446	[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW] = { .name = "tx-max-frames-low", .type = YNL_PT_U32, },
447	[ETHTOOL_A_COALESCE_PKT_RATE_HIGH] = { .name = "pkt-rate-high", .type = YNL_PT_U32, },
448	[ETHTOOL_A_COALESCE_RX_USECS_HIGH] = { .name = "rx-usecs-high", .type = YNL_PT_U32, },
449	[ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH] = { .name = "rx-max-frames-high", .type = YNL_PT_U32, },
450	[ETHTOOL_A_COALESCE_TX_USECS_HIGH] = { .name = "tx-usecs-high", .type = YNL_PT_U32, },
451	[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH] = { .name = "tx-max-frames-high", .type = YNL_PT_U32, },
452	[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL] = { .name = "rate-sample-interval", .type = YNL_PT_U32, },
453	[ETHTOOL_A_COALESCE_USE_CQE_MODE_TX] = { .name = "use-cqe-mode-tx", .type = YNL_PT_U8, },
454	[ETHTOOL_A_COALESCE_USE_CQE_MODE_RX] = { .name = "use-cqe-mode-rx", .type = YNL_PT_U8, },
455	[ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES] = { .name = "tx-aggr-max-bytes", .type = YNL_PT_U32, },
456	[ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES] = { .name = "tx-aggr-max-frames", .type = YNL_PT_U32, },
457	[ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS] = { .name = "tx-aggr-time-usecs", .type = YNL_PT_U32, },
458};
459
460struct ynl_policy_nest ethtool_coalesce_nest = {
461	.max_attr = ETHTOOL_A_COALESCE_MAX,
462	.table = ethtool_coalesce_policy,
463};
464
465struct ynl_policy_attr ethtool_pause_policy[ETHTOOL_A_PAUSE_MAX + 1] = {
466	[ETHTOOL_A_PAUSE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
467	[ETHTOOL_A_PAUSE_AUTONEG] = { .name = "autoneg", .type = YNL_PT_U8, },
468	[ETHTOOL_A_PAUSE_RX] = { .name = "rx", .type = YNL_PT_U8, },
469	[ETHTOOL_A_PAUSE_TX] = { .name = "tx", .type = YNL_PT_U8, },
470	[ETHTOOL_A_PAUSE_STATS] = { .name = "stats", .type = YNL_PT_NEST, .nest = &ethtool_pause_stat_nest, },
471	[ETHTOOL_A_PAUSE_STATS_SRC] = { .name = "stats-src", .type = YNL_PT_U32, },
472};
473
474struct ynl_policy_nest ethtool_pause_nest = {
475	.max_attr = ETHTOOL_A_PAUSE_MAX,
476	.table = ethtool_pause_policy,
477};
478
479struct ynl_policy_attr ethtool_eee_policy[ETHTOOL_A_EEE_MAX + 1] = {
480	[ETHTOOL_A_EEE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
481	[ETHTOOL_A_EEE_MODES_OURS] = { .name = "modes-ours", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
482	[ETHTOOL_A_EEE_MODES_PEER] = { .name = "modes-peer", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
483	[ETHTOOL_A_EEE_ACTIVE] = { .name = "active", .type = YNL_PT_U8, },
484	[ETHTOOL_A_EEE_ENABLED] = { .name = "enabled", .type = YNL_PT_U8, },
485	[ETHTOOL_A_EEE_TX_LPI_ENABLED] = { .name = "tx-lpi-enabled", .type = YNL_PT_U8, },
486	[ETHTOOL_A_EEE_TX_LPI_TIMER] = { .name = "tx-lpi-timer", .type = YNL_PT_U32, },
487};
488
489struct ynl_policy_nest ethtool_eee_nest = {
490	.max_attr = ETHTOOL_A_EEE_MAX,
491	.table = ethtool_eee_policy,
492};
493
494struct ynl_policy_attr ethtool_tsinfo_policy[ETHTOOL_A_TSINFO_MAX + 1] = {
495	[ETHTOOL_A_TSINFO_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
496	[ETHTOOL_A_TSINFO_TIMESTAMPING] = { .name = "timestamping", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
497	[ETHTOOL_A_TSINFO_TX_TYPES] = { .name = "tx-types", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
498	[ETHTOOL_A_TSINFO_RX_FILTERS] = { .name = "rx-filters", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
499	[ETHTOOL_A_TSINFO_PHC_INDEX] = { .name = "phc-index", .type = YNL_PT_U32, },
500};
501
502struct ynl_policy_nest ethtool_tsinfo_nest = {
503	.max_attr = ETHTOOL_A_TSINFO_MAX,
504	.table = ethtool_tsinfo_policy,
505};
506
507struct ynl_policy_attr ethtool_cable_test_policy[ETHTOOL_A_CABLE_TEST_MAX + 1] = {
508	[ETHTOOL_A_CABLE_TEST_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
509};
510
511struct ynl_policy_nest ethtool_cable_test_nest = {
512	.max_attr = ETHTOOL_A_CABLE_TEST_MAX,
513	.table = ethtool_cable_test_policy,
514};
515
516struct ynl_policy_attr ethtool_cable_test_ntf_policy[ETHTOOL_A_CABLE_TEST_NTF_MAX + 1] = {
517	[ETHTOOL_A_CABLE_TEST_NTF_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
518	[ETHTOOL_A_CABLE_TEST_NTF_STATUS] = { .name = "status", .type = YNL_PT_U8, },
519	[ETHTOOL_A_CABLE_TEST_NTF_NEST] = { .name = "nest", .type = YNL_PT_NEST, .nest = &ethtool_cable_nest_nest, },
520};
521
522struct ynl_policy_nest ethtool_cable_test_ntf_nest = {
523	.max_attr = ETHTOOL_A_CABLE_TEST_NTF_MAX,
524	.table = ethtool_cable_test_ntf_policy,
525};
526
527struct ynl_policy_attr ethtool_cable_test_tdr_policy[ETHTOOL_A_CABLE_TEST_TDR_MAX + 1] = {
528	[ETHTOOL_A_CABLE_TEST_TDR_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
529	[ETHTOOL_A_CABLE_TEST_TDR_CFG] = { .name = "cfg", .type = YNL_PT_NEST, .nest = &ethtool_cable_test_tdr_cfg_nest, },
530};
531
532struct ynl_policy_nest ethtool_cable_test_tdr_nest = {
533	.max_attr = ETHTOOL_A_CABLE_TEST_TDR_MAX,
534	.table = ethtool_cable_test_tdr_policy,
535};
536
537struct ynl_policy_attr ethtool_cable_test_tdr_ntf_policy[ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX + 1] = {
538	[ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
539	[ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS] = { .name = "status", .type = YNL_PT_U8, },
540	[ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST] = { .name = "nest", .type = YNL_PT_NEST, .nest = &ethtool_cable_nest_nest, },
541};
542
543struct ynl_policy_nest ethtool_cable_test_tdr_ntf_nest = {
544	.max_attr = ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX,
545	.table = ethtool_cable_test_tdr_ntf_policy,
546};
547
548struct ynl_policy_attr ethtool_tunnel_info_policy[ETHTOOL_A_TUNNEL_INFO_MAX + 1] = {
549	[ETHTOOL_A_TUNNEL_INFO_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
550	[ETHTOOL_A_TUNNEL_INFO_UDP_PORTS] = { .name = "udp-ports", .type = YNL_PT_NEST, .nest = &ethtool_tunnel_udp_nest, },
551};
552
553struct ynl_policy_nest ethtool_tunnel_info_nest = {
554	.max_attr = ETHTOOL_A_TUNNEL_INFO_MAX,
555	.table = ethtool_tunnel_info_policy,
556};
557
558struct ynl_policy_attr ethtool_fec_policy[ETHTOOL_A_FEC_MAX + 1] = {
559	[ETHTOOL_A_FEC_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
560	[ETHTOOL_A_FEC_MODES] = { .name = "modes", .type = YNL_PT_NEST, .nest = &ethtool_bitset_nest, },
561	[ETHTOOL_A_FEC_AUTO] = { .name = "auto", .type = YNL_PT_U8, },
562	[ETHTOOL_A_FEC_ACTIVE] = { .name = "active", .type = YNL_PT_U32, },
563	[ETHTOOL_A_FEC_STATS] = { .name = "stats", .type = YNL_PT_NEST, .nest = &ethtool_fec_stat_nest, },
564};
565
566struct ynl_policy_nest ethtool_fec_nest = {
567	.max_attr = ETHTOOL_A_FEC_MAX,
568	.table = ethtool_fec_policy,
569};
570
571struct ynl_policy_attr ethtool_module_eeprom_policy[ETHTOOL_A_MODULE_EEPROM_MAX + 1] = {
572	[ETHTOOL_A_MODULE_EEPROM_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
573	[ETHTOOL_A_MODULE_EEPROM_OFFSET] = { .name = "offset", .type = YNL_PT_U32, },
574	[ETHTOOL_A_MODULE_EEPROM_LENGTH] = { .name = "length", .type = YNL_PT_U32, },
575	[ETHTOOL_A_MODULE_EEPROM_PAGE] = { .name = "page", .type = YNL_PT_U8, },
576	[ETHTOOL_A_MODULE_EEPROM_BANK] = { .name = "bank", .type = YNL_PT_U8, },
577	[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS] = { .name = "i2c-address", .type = YNL_PT_U8, },
578	[ETHTOOL_A_MODULE_EEPROM_DATA] = { .name = "data", .type = YNL_PT_BINARY,},
579};
580
581struct ynl_policy_nest ethtool_module_eeprom_nest = {
582	.max_attr = ETHTOOL_A_MODULE_EEPROM_MAX,
583	.table = ethtool_module_eeprom_policy,
584};
585
586struct ynl_policy_attr ethtool_phc_vclocks_policy[ETHTOOL_A_PHC_VCLOCKS_MAX + 1] = {
587	[ETHTOOL_A_PHC_VCLOCKS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
588	[ETHTOOL_A_PHC_VCLOCKS_NUM] = { .name = "num", .type = YNL_PT_U32, },
589	[ETHTOOL_A_PHC_VCLOCKS_INDEX] = { .name = "index", .type = YNL_PT_BINARY,},
590};
591
592struct ynl_policy_nest ethtool_phc_vclocks_nest = {
593	.max_attr = ETHTOOL_A_PHC_VCLOCKS_MAX,
594	.table = ethtool_phc_vclocks_policy,
595};
596
597struct ynl_policy_attr ethtool_module_policy[ETHTOOL_A_MODULE_MAX + 1] = {
598	[ETHTOOL_A_MODULE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
599	[ETHTOOL_A_MODULE_POWER_MODE_POLICY] = { .name = "power-mode-policy", .type = YNL_PT_U8, },
600	[ETHTOOL_A_MODULE_POWER_MODE] = { .name = "power-mode", .type = YNL_PT_U8, },
601};
602
603struct ynl_policy_nest ethtool_module_nest = {
604	.max_attr = ETHTOOL_A_MODULE_MAX,
605	.table = ethtool_module_policy,
606};
607
608struct ynl_policy_attr ethtool_pse_policy[ETHTOOL_A_PSE_MAX + 1] = {
609	[ETHTOOL_A_PSE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
610	[ETHTOOL_A_PODL_PSE_ADMIN_STATE] = { .name = "admin-state", .type = YNL_PT_U32, },
611	[ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] = { .name = "admin-control", .type = YNL_PT_U32, },
612	[ETHTOOL_A_PODL_PSE_PW_D_STATUS] = { .name = "pw-d-status", .type = YNL_PT_U32, },
613};
614
615struct ynl_policy_nest ethtool_pse_nest = {
616	.max_attr = ETHTOOL_A_PSE_MAX,
617	.table = ethtool_pse_policy,
618};
619
620struct ynl_policy_attr ethtool_rss_policy[ETHTOOL_A_RSS_MAX + 1] = {
621	[ETHTOOL_A_RSS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
622	[ETHTOOL_A_RSS_CONTEXT] = { .name = "context", .type = YNL_PT_U32, },
623	[ETHTOOL_A_RSS_HFUNC] = { .name = "hfunc", .type = YNL_PT_U32, },
624	[ETHTOOL_A_RSS_INDIR] = { .name = "indir", .type = YNL_PT_BINARY,},
625	[ETHTOOL_A_RSS_HKEY] = { .name = "hkey", .type = YNL_PT_BINARY,},
626};
627
628struct ynl_policy_nest ethtool_rss_nest = {
629	.max_attr = ETHTOOL_A_RSS_MAX,
630	.table = ethtool_rss_policy,
631};
632
633struct ynl_policy_attr ethtool_plca_policy[ETHTOOL_A_PLCA_MAX + 1] = {
634	[ETHTOOL_A_PLCA_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
635	[ETHTOOL_A_PLCA_VERSION] = { .name = "version", .type = YNL_PT_U16, },
636	[ETHTOOL_A_PLCA_ENABLED] = { .name = "enabled", .type = YNL_PT_U8, },
637	[ETHTOOL_A_PLCA_STATUS] = { .name = "status", .type = YNL_PT_U8, },
638	[ETHTOOL_A_PLCA_NODE_CNT] = { .name = "node-cnt", .type = YNL_PT_U32, },
639	[ETHTOOL_A_PLCA_NODE_ID] = { .name = "node-id", .type = YNL_PT_U32, },
640	[ETHTOOL_A_PLCA_TO_TMR] = { .name = "to-tmr", .type = YNL_PT_U32, },
641	[ETHTOOL_A_PLCA_BURST_CNT] = { .name = "burst-cnt", .type = YNL_PT_U32, },
642	[ETHTOOL_A_PLCA_BURST_TMR] = { .name = "burst-tmr", .type = YNL_PT_U32, },
643};
644
645struct ynl_policy_nest ethtool_plca_nest = {
646	.max_attr = ETHTOOL_A_PLCA_MAX,
647	.table = ethtool_plca_policy,
648};
649
650struct ynl_policy_attr ethtool_mm_policy[ETHTOOL_A_MM_MAX + 1] = {
651	[ETHTOOL_A_MM_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = &ethtool_header_nest, },
652	[ETHTOOL_A_MM_PMAC_ENABLED] = { .name = "pmac-enabled", .type = YNL_PT_U8, },
653	[ETHTOOL_A_MM_TX_ENABLED] = { .name = "tx-enabled", .type = YNL_PT_U8, },
654	[ETHTOOL_A_MM_TX_ACTIVE] = { .name = "tx-active", .type = YNL_PT_U8, },
655	[ETHTOOL_A_MM_TX_MIN_FRAG_SIZE] = { .name = "tx-min-frag-size", .type = YNL_PT_U32, },
656	[ETHTOOL_A_MM_RX_MIN_FRAG_SIZE] = { .name = "rx-min-frag-size", .type = YNL_PT_U32, },
657	[ETHTOOL_A_MM_VERIFY_ENABLED] = { .name = "verify-enabled", .type = YNL_PT_U8, },
658	[ETHTOOL_A_MM_VERIFY_STATUS] = { .name = "verify-status", .type = YNL_PT_U8, },
659	[ETHTOOL_A_MM_VERIFY_TIME] = { .name = "verify-time", .type = YNL_PT_U32, },
660	[ETHTOOL_A_MM_MAX_VERIFY_TIME] = { .name = "max-verify-time", .type = YNL_PT_U32, },
661	[ETHTOOL_A_MM_STATS] = { .name = "stats", .type = YNL_PT_NEST, .nest = &ethtool_mm_stat_nest, },
662};
663
664struct ynl_policy_nest ethtool_mm_nest = {
665	.max_attr = ETHTOOL_A_MM_MAX,
666	.table = ethtool_mm_policy,
667};
668
669/* Common nested types */
670void ethtool_header_free(struct ethtool_header *obj)
671{
672	free(obj->dev_name);
673}
674
675int ethtool_header_put(struct nlmsghdr *nlh, unsigned int attr_type,
676		       struct ethtool_header *obj)
677{
678	struct nlattr *nest;
679
680	nest = mnl_attr_nest_start(nlh, attr_type);
681	if (obj->_present.dev_index)
682		mnl_attr_put_u32(nlh, ETHTOOL_A_HEADER_DEV_INDEX, obj->dev_index);
683	if (obj->_present.dev_name_len)
684		mnl_attr_put_strz(nlh, ETHTOOL_A_HEADER_DEV_NAME, obj->dev_name);
685	if (obj->_present.flags)
686		mnl_attr_put_u32(nlh, ETHTOOL_A_HEADER_FLAGS, obj->flags);
687	mnl_attr_nest_end(nlh, nest);
688
689	return 0;
690}
691
692int ethtool_header_parse(struct ynl_parse_arg *yarg,
693			 const struct nlattr *nested)
694{
695	struct ethtool_header *dst = yarg->data;
696	const struct nlattr *attr;
697
698	mnl_attr_for_each_nested(attr, nested) {
699		unsigned int type = mnl_attr_get_type(attr);
700
701		if (type == ETHTOOL_A_HEADER_DEV_INDEX) {
702			if (ynl_attr_validate(yarg, attr))
703				return MNL_CB_ERROR;
704			dst->_present.dev_index = 1;
705			dst->dev_index = mnl_attr_get_u32(attr);
706		} else if (type == ETHTOOL_A_HEADER_DEV_NAME) {
707			unsigned int len;
708
709			if (ynl_attr_validate(yarg, attr))
710				return MNL_CB_ERROR;
711
712			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
713			dst->_present.dev_name_len = len;
714			dst->dev_name = malloc(len + 1);
715			memcpy(dst->dev_name, mnl_attr_get_str(attr), len);
716			dst->dev_name[len] = 0;
717		} else if (type == ETHTOOL_A_HEADER_FLAGS) {
718			if (ynl_attr_validate(yarg, attr))
719				return MNL_CB_ERROR;
720			dst->_present.flags = 1;
721			dst->flags = mnl_attr_get_u32(attr);
722		}
723	}
724
725	return 0;
726}
727
728void ethtool_pause_stat_free(struct ethtool_pause_stat *obj)
729{
730}
731
732int ethtool_pause_stat_put(struct nlmsghdr *nlh, unsigned int attr_type,
733			   struct ethtool_pause_stat *obj)
734{
735	struct nlattr *nest;
736
737	nest = mnl_attr_nest_start(nlh, attr_type);
738	if (obj->_present.tx_frames)
739		mnl_attr_put_u64(nlh, ETHTOOL_A_PAUSE_STAT_TX_FRAMES, obj->tx_frames);
740	if (obj->_present.rx_frames)
741		mnl_attr_put_u64(nlh, ETHTOOL_A_PAUSE_STAT_RX_FRAMES, obj->rx_frames);
742	mnl_attr_nest_end(nlh, nest);
743
744	return 0;
745}
746
747int ethtool_pause_stat_parse(struct ynl_parse_arg *yarg,
748			     const struct nlattr *nested)
749{
750	struct ethtool_pause_stat *dst = yarg->data;
751	const struct nlattr *attr;
752
753	mnl_attr_for_each_nested(attr, nested) {
754		unsigned int type = mnl_attr_get_type(attr);
755
756		if (type == ETHTOOL_A_PAUSE_STAT_TX_FRAMES) {
757			if (ynl_attr_validate(yarg, attr))
758				return MNL_CB_ERROR;
759			dst->_present.tx_frames = 1;
760			dst->tx_frames = mnl_attr_get_u64(attr);
761		} else if (type == ETHTOOL_A_PAUSE_STAT_RX_FRAMES) {
762			if (ynl_attr_validate(yarg, attr))
763				return MNL_CB_ERROR;
764			dst->_present.rx_frames = 1;
765			dst->rx_frames = mnl_attr_get_u64(attr);
766		}
767	}
768
769	return 0;
770}
771
772void ethtool_cable_test_tdr_cfg_free(struct ethtool_cable_test_tdr_cfg *obj)
773{
774}
775
776void ethtool_fec_stat_free(struct ethtool_fec_stat *obj)
777{
778	free(obj->corrected);
779	free(obj->uncorr);
780	free(obj->corr_bits);
781}
782
783int ethtool_fec_stat_put(struct nlmsghdr *nlh, unsigned int attr_type,
784			 struct ethtool_fec_stat *obj)
785{
786	struct nlattr *nest;
787
788	nest = mnl_attr_nest_start(nlh, attr_type);
789	if (obj->_present.corrected_len)
790		mnl_attr_put(nlh, ETHTOOL_A_FEC_STAT_CORRECTED, obj->_present.corrected_len, obj->corrected);
791	if (obj->_present.uncorr_len)
792		mnl_attr_put(nlh, ETHTOOL_A_FEC_STAT_UNCORR, obj->_present.uncorr_len, obj->uncorr);
793	if (obj->_present.corr_bits_len)
794		mnl_attr_put(nlh, ETHTOOL_A_FEC_STAT_CORR_BITS, obj->_present.corr_bits_len, obj->corr_bits);
795	mnl_attr_nest_end(nlh, nest);
796
797	return 0;
798}
799
800int ethtool_fec_stat_parse(struct ynl_parse_arg *yarg,
801			   const struct nlattr *nested)
802{
803	struct ethtool_fec_stat *dst = yarg->data;
804	const struct nlattr *attr;
805
806	mnl_attr_for_each_nested(attr, nested) {
807		unsigned int type = mnl_attr_get_type(attr);
808
809		if (type == ETHTOOL_A_FEC_STAT_CORRECTED) {
810			unsigned int len;
811
812			if (ynl_attr_validate(yarg, attr))
813				return MNL_CB_ERROR;
814
815			len = mnl_attr_get_payload_len(attr);
816			dst->_present.corrected_len = len;
817			dst->corrected = malloc(len);
818			memcpy(dst->corrected, mnl_attr_get_payload(attr), len);
819		} else if (type == ETHTOOL_A_FEC_STAT_UNCORR) {
820			unsigned int len;
821
822			if (ynl_attr_validate(yarg, attr))
823				return MNL_CB_ERROR;
824
825			len = mnl_attr_get_payload_len(attr);
826			dst->_present.uncorr_len = len;
827			dst->uncorr = malloc(len);
828			memcpy(dst->uncorr, mnl_attr_get_payload(attr), len);
829		} else if (type == ETHTOOL_A_FEC_STAT_CORR_BITS) {
830			unsigned int len;
831
832			if (ynl_attr_validate(yarg, attr))
833				return MNL_CB_ERROR;
834
835			len = mnl_attr_get_payload_len(attr);
836			dst->_present.corr_bits_len = len;
837			dst->corr_bits = malloc(len);
838			memcpy(dst->corr_bits, mnl_attr_get_payload(attr), len);
839		}
840	}
841
842	return 0;
843}
844
845void ethtool_mm_stat_free(struct ethtool_mm_stat *obj)
846{
847}
848
849int ethtool_mm_stat_parse(struct ynl_parse_arg *yarg,
850			  const struct nlattr *nested)
851{
852	struct ethtool_mm_stat *dst = yarg->data;
853	const struct nlattr *attr;
854
855	mnl_attr_for_each_nested(attr, nested) {
856		unsigned int type = mnl_attr_get_type(attr);
857
858		if (type == ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS) {
859			if (ynl_attr_validate(yarg, attr))
860				return MNL_CB_ERROR;
861			dst->_present.reassembly_errors = 1;
862			dst->reassembly_errors = mnl_attr_get_u64(attr);
863		} else if (type == ETHTOOL_A_MM_STAT_SMD_ERRORS) {
864			if (ynl_attr_validate(yarg, attr))
865				return MNL_CB_ERROR;
866			dst->_present.smd_errors = 1;
867			dst->smd_errors = mnl_attr_get_u64(attr);
868		} else if (type == ETHTOOL_A_MM_STAT_REASSEMBLY_OK) {
869			if (ynl_attr_validate(yarg, attr))
870				return MNL_CB_ERROR;
871			dst->_present.reassembly_ok = 1;
872			dst->reassembly_ok = mnl_attr_get_u64(attr);
873		} else if (type == ETHTOOL_A_MM_STAT_RX_FRAG_COUNT) {
874			if (ynl_attr_validate(yarg, attr))
875				return MNL_CB_ERROR;
876			dst->_present.rx_frag_count = 1;
877			dst->rx_frag_count = mnl_attr_get_u64(attr);
878		} else if (type == ETHTOOL_A_MM_STAT_TX_FRAG_COUNT) {
879			if (ynl_attr_validate(yarg, attr))
880				return MNL_CB_ERROR;
881			dst->_present.tx_frag_count = 1;
882			dst->tx_frag_count = mnl_attr_get_u64(attr);
883		} else if (type == ETHTOOL_A_MM_STAT_HOLD_COUNT) {
884			if (ynl_attr_validate(yarg, attr))
885				return MNL_CB_ERROR;
886			dst->_present.hold_count = 1;
887			dst->hold_count = mnl_attr_get_u64(attr);
888		}
889	}
890
891	return 0;
892}
893
894void ethtool_cable_result_free(struct ethtool_cable_result *obj)
895{
896}
897
898int ethtool_cable_result_parse(struct ynl_parse_arg *yarg,
899			       const struct nlattr *nested)
900{
901	struct ethtool_cable_result *dst = yarg->data;
902	const struct nlattr *attr;
903
904	mnl_attr_for_each_nested(attr, nested) {
905		unsigned int type = mnl_attr_get_type(attr);
906
907		if (type == ETHTOOL_A_CABLE_RESULT_PAIR) {
908			if (ynl_attr_validate(yarg, attr))
909				return MNL_CB_ERROR;
910			dst->_present.pair = 1;
911			dst->pair = mnl_attr_get_u8(attr);
912		} else if (type == ETHTOOL_A_CABLE_RESULT_CODE) {
913			if (ynl_attr_validate(yarg, attr))
914				return MNL_CB_ERROR;
915			dst->_present.code = 1;
916			dst->code = mnl_attr_get_u8(attr);
917		}
918	}
919
920	return 0;
921}
922
923void ethtool_cable_fault_length_free(struct ethtool_cable_fault_length *obj)
924{
925}
926
927int ethtool_cable_fault_length_parse(struct ynl_parse_arg *yarg,
928				     const struct nlattr *nested)
929{
930	struct ethtool_cable_fault_length *dst = yarg->data;
931	const struct nlattr *attr;
932
933	mnl_attr_for_each_nested(attr, nested) {
934		unsigned int type = mnl_attr_get_type(attr);
935
936		if (type == ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR) {
937			if (ynl_attr_validate(yarg, attr))
938				return MNL_CB_ERROR;
939			dst->_present.pair = 1;
940			dst->pair = mnl_attr_get_u8(attr);
941		} else if (type == ETHTOOL_A_CABLE_FAULT_LENGTH_CM) {
942			if (ynl_attr_validate(yarg, attr))
943				return MNL_CB_ERROR;
944			dst->_present.cm = 1;
945			dst->cm = mnl_attr_get_u32(attr);
946		}
947	}
948
949	return 0;
950}
951
952void ethtool_bitset_bit_free(struct ethtool_bitset_bit *obj)
953{
954	free(obj->name);
955}
956
957int ethtool_bitset_bit_put(struct nlmsghdr *nlh, unsigned int attr_type,
958			   struct ethtool_bitset_bit *obj)
959{
960	struct nlattr *nest;
961
962	nest = mnl_attr_nest_start(nlh, attr_type);
963	if (obj->_present.index)
964		mnl_attr_put_u32(nlh, ETHTOOL_A_BITSET_BIT_INDEX, obj->index);
965	if (obj->_present.name_len)
966		mnl_attr_put_strz(nlh, ETHTOOL_A_BITSET_BIT_NAME, obj->name);
967	if (obj->_present.value)
968		mnl_attr_put(nlh, ETHTOOL_A_BITSET_BIT_VALUE, 0, NULL);
969	mnl_attr_nest_end(nlh, nest);
970
971	return 0;
972}
973
974int ethtool_bitset_bit_parse(struct ynl_parse_arg *yarg,
975			     const struct nlattr *nested)
976{
977	struct ethtool_bitset_bit *dst = yarg->data;
978	const struct nlattr *attr;
979
980	mnl_attr_for_each_nested(attr, nested) {
981		unsigned int type = mnl_attr_get_type(attr);
982
983		if (type == ETHTOOL_A_BITSET_BIT_INDEX) {
984			if (ynl_attr_validate(yarg, attr))
985				return MNL_CB_ERROR;
986			dst->_present.index = 1;
987			dst->index = mnl_attr_get_u32(attr);
988		} else if (type == ETHTOOL_A_BITSET_BIT_NAME) {
989			unsigned int len;
990
991			if (ynl_attr_validate(yarg, attr))
992				return MNL_CB_ERROR;
993
994			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
995			dst->_present.name_len = len;
996			dst->name = malloc(len + 1);
997			memcpy(dst->name, mnl_attr_get_str(attr), len);
998			dst->name[len] = 0;
999		} else if (type == ETHTOOL_A_BITSET_BIT_VALUE) {
1000			if (ynl_attr_validate(yarg, attr))
1001				return MNL_CB_ERROR;
1002			dst->_present.value = 1;
1003		}
1004	}
1005
1006	return 0;
1007}
1008
1009void ethtool_tunnel_udp_entry_free(struct ethtool_tunnel_udp_entry *obj)
1010{
1011}
1012
1013int ethtool_tunnel_udp_entry_parse(struct ynl_parse_arg *yarg,
1014				   const struct nlattr *nested)
1015{
1016	struct ethtool_tunnel_udp_entry *dst = yarg->data;
1017	const struct nlattr *attr;
1018
1019	mnl_attr_for_each_nested(attr, nested) {
1020		unsigned int type = mnl_attr_get_type(attr);
1021
1022		if (type == ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT) {
1023			if (ynl_attr_validate(yarg, attr))
1024				return MNL_CB_ERROR;
1025			dst->_present.port = 1;
1026			dst->port = mnl_attr_get_u16(attr);
1027		} else if (type == ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE) {
1028			if (ynl_attr_validate(yarg, attr))
1029				return MNL_CB_ERROR;
1030			dst->_present.type = 1;
1031			dst->type = mnl_attr_get_u32(attr);
1032		}
1033	}
1034
1035	return 0;
1036}
1037
1038void ethtool_string_free(struct ethtool_string *obj)
1039{
1040	free(obj->value);
1041}
1042
1043int ethtool_string_put(struct nlmsghdr *nlh, unsigned int attr_type,
1044		       struct ethtool_string *obj)
1045{
1046	struct nlattr *nest;
1047
1048	nest = mnl_attr_nest_start(nlh, attr_type);
1049	if (obj->_present.index)
1050		mnl_attr_put_u32(nlh, ETHTOOL_A_STRING_INDEX, obj->index);
1051	if (obj->_present.value_len)
1052		mnl_attr_put_strz(nlh, ETHTOOL_A_STRING_VALUE, obj->value);
1053	mnl_attr_nest_end(nlh, nest);
1054
1055	return 0;
1056}
1057
1058int ethtool_string_parse(struct ynl_parse_arg *yarg,
1059			 const struct nlattr *nested)
1060{
1061	struct ethtool_string *dst = yarg->data;
1062	const struct nlattr *attr;
1063
1064	mnl_attr_for_each_nested(attr, nested) {
1065		unsigned int type = mnl_attr_get_type(attr);
1066
1067		if (type == ETHTOOL_A_STRING_INDEX) {
1068			if (ynl_attr_validate(yarg, attr))
1069				return MNL_CB_ERROR;
1070			dst->_present.index = 1;
1071			dst->index = mnl_attr_get_u32(attr);
1072		} else if (type == ETHTOOL_A_STRING_VALUE) {
1073			unsigned int len;
1074
1075			if (ynl_attr_validate(yarg, attr))
1076				return MNL_CB_ERROR;
1077
1078			len = strnlen(mnl_attr_get_str(attr), mnl_attr_get_payload_len(attr));
1079			dst->_present.value_len = len;
1080			dst->value = malloc(len + 1);
1081			memcpy(dst->value, mnl_attr_get_str(attr), len);
1082			dst->value[len] = 0;
1083		}
1084	}
1085
1086	return 0;
1087}
1088
1089void ethtool_cable_nest_free(struct ethtool_cable_nest *obj)
1090{
1091	ethtool_cable_result_free(&obj->result);
1092	ethtool_cable_fault_length_free(&obj->fault_length);
1093}
1094
1095int ethtool_cable_nest_parse(struct ynl_parse_arg *yarg,
1096			     const struct nlattr *nested)
1097{
1098	struct ethtool_cable_nest *dst = yarg->data;
1099	const struct nlattr *attr;
1100	struct ynl_parse_arg parg;
1101
1102	parg.ys = yarg->ys;
1103
1104	mnl_attr_for_each_nested(attr, nested) {
1105		unsigned int type = mnl_attr_get_type(attr);
1106
1107		if (type == ETHTOOL_A_CABLE_NEST_RESULT) {
1108			if (ynl_attr_validate(yarg, attr))
1109				return MNL_CB_ERROR;
1110			dst->_present.result = 1;
1111
1112			parg.rsp_policy = &ethtool_cable_result_nest;
1113			parg.data = &dst->result;
1114			if (ethtool_cable_result_parse(&parg, attr))
1115				return MNL_CB_ERROR;
1116		} else if (type == ETHTOOL_A_CABLE_NEST_FAULT_LENGTH) {
1117			if (ynl_attr_validate(yarg, attr))
1118				return MNL_CB_ERROR;
1119			dst->_present.fault_length = 1;
1120
1121			parg.rsp_policy = &ethtool_cable_fault_length_nest;
1122			parg.data = &dst->fault_length;
1123			if (ethtool_cable_fault_length_parse(&parg, attr))
1124				return MNL_CB_ERROR;
1125		}
1126	}
1127
1128	return 0;
1129}
1130
1131void ethtool_bitset_bits_free(struct ethtool_bitset_bits *obj)
1132{
1133	unsigned int i;
1134
1135	for (i = 0; i < obj->n_bit; i++)
1136		ethtool_bitset_bit_free(&obj->bit[i]);
1137	free(obj->bit);
1138}
1139
1140int ethtool_bitset_bits_put(struct nlmsghdr *nlh, unsigned int attr_type,
1141			    struct ethtool_bitset_bits *obj)
1142{
1143	struct nlattr *nest;
1144
1145	nest = mnl_attr_nest_start(nlh, attr_type);
1146	for (unsigned int i = 0; i < obj->n_bit; i++)
1147		ethtool_bitset_bit_put(nlh, ETHTOOL_A_BITSET_BITS_BIT, &obj->bit[i]);
1148	mnl_attr_nest_end(nlh, nest);
1149
1150	return 0;
1151}
1152
1153int ethtool_bitset_bits_parse(struct ynl_parse_arg *yarg,
1154			      const struct nlattr *nested)
1155{
1156	struct ethtool_bitset_bits *dst = yarg->data;
1157	const struct nlattr *attr;
1158	struct ynl_parse_arg parg;
1159	unsigned int n_bit = 0;
1160	int i;
1161
1162	parg.ys = yarg->ys;
1163
1164	if (dst->bit)
1165		return ynl_error_parse(yarg, "attribute already present (bitset-bits.bit)");
1166
1167	mnl_attr_for_each_nested(attr, nested) {
1168		unsigned int type = mnl_attr_get_type(attr);
1169
1170		if (type == ETHTOOL_A_BITSET_BITS_BIT) {
1171			n_bit++;
1172		}
1173	}
1174
1175	if (n_bit) {
1176		dst->bit = calloc(n_bit, sizeof(*dst->bit));
1177		dst->n_bit = n_bit;
1178		i = 0;
1179		parg.rsp_policy = &ethtool_bitset_bit_nest;
1180		mnl_attr_for_each_nested(attr, nested) {
1181			if (mnl_attr_get_type(attr) == ETHTOOL_A_BITSET_BITS_BIT) {
1182				parg.data = &dst->bit[i];
1183				if (ethtool_bitset_bit_parse(&parg, attr))
1184					return MNL_CB_ERROR;
1185				i++;
1186			}
1187		}
1188	}
1189
1190	return 0;
1191}
1192
1193void ethtool_strings_free(struct ethtool_strings *obj)
1194{
1195	unsigned int i;
1196
1197	for (i = 0; i < obj->n_string; i++)
1198		ethtool_string_free(&obj->string[i]);
1199	free(obj->string);
1200}
1201
1202int ethtool_strings_put(struct nlmsghdr *nlh, unsigned int attr_type,
1203			struct ethtool_strings *obj)
1204{
1205	struct nlattr *nest;
1206
1207	nest = mnl_attr_nest_start(nlh, attr_type);
1208	for (unsigned int i = 0; i < obj->n_string; i++)
1209		ethtool_string_put(nlh, ETHTOOL_A_STRINGS_STRING, &obj->string[i]);
1210	mnl_attr_nest_end(nlh, nest);
1211
1212	return 0;
1213}
1214
1215int ethtool_strings_parse(struct ynl_parse_arg *yarg,
1216			  const struct nlattr *nested)
1217{
1218	struct ethtool_strings *dst = yarg->data;
1219	const struct nlattr *attr;
1220	struct ynl_parse_arg parg;
1221	unsigned int n_string = 0;
1222	int i;
1223
1224	parg.ys = yarg->ys;
1225
1226	if (dst->string)
1227		return ynl_error_parse(yarg, "attribute already present (strings.string)");
1228
1229	mnl_attr_for_each_nested(attr, nested) {
1230		unsigned int type = mnl_attr_get_type(attr);
1231
1232		if (type == ETHTOOL_A_STRINGS_STRING) {
1233			n_string++;
1234		}
1235	}
1236
1237	if (n_string) {
1238		dst->string = calloc(n_string, sizeof(*dst->string));
1239		dst->n_string = n_string;
1240		i = 0;
1241		parg.rsp_policy = &ethtool_string_nest;
1242		mnl_attr_for_each_nested(attr, nested) {
1243			if (mnl_attr_get_type(attr) == ETHTOOL_A_STRINGS_STRING) {
1244				parg.data = &dst->string[i];
1245				if (ethtool_string_parse(&parg, attr))
1246					return MNL_CB_ERROR;
1247				i++;
1248			}
1249		}
1250	}
1251
1252	return 0;
1253}
1254
1255void ethtool_bitset_free(struct ethtool_bitset *obj)
1256{
1257	ethtool_bitset_bits_free(&obj->bits);
1258}
1259
1260int ethtool_bitset_put(struct nlmsghdr *nlh, unsigned int attr_type,
1261		       struct ethtool_bitset *obj)
1262{
1263	struct nlattr *nest;
1264
1265	nest = mnl_attr_nest_start(nlh, attr_type);
1266	if (obj->_present.nomask)
1267		mnl_attr_put(nlh, ETHTOOL_A_BITSET_NOMASK, 0, NULL);
1268	if (obj->_present.size)
1269		mnl_attr_put_u32(nlh, ETHTOOL_A_BITSET_SIZE, obj->size);
1270	if (obj->_present.bits)
1271		ethtool_bitset_bits_put(nlh, ETHTOOL_A_BITSET_BITS, &obj->bits);
1272	mnl_attr_nest_end(nlh, nest);
1273
1274	return 0;
1275}
1276
1277int ethtool_bitset_parse(struct ynl_parse_arg *yarg,
1278			 const struct nlattr *nested)
1279{
1280	struct ethtool_bitset *dst = yarg->data;
1281	const struct nlattr *attr;
1282	struct ynl_parse_arg parg;
1283
1284	parg.ys = yarg->ys;
1285
1286	mnl_attr_for_each_nested(attr, nested) {
1287		unsigned int type = mnl_attr_get_type(attr);
1288
1289		if (type == ETHTOOL_A_BITSET_NOMASK) {
1290			if (ynl_attr_validate(yarg, attr))
1291				return MNL_CB_ERROR;
1292			dst->_present.nomask = 1;
1293		} else if (type == ETHTOOL_A_BITSET_SIZE) {
1294			if (ynl_attr_validate(yarg, attr))
1295				return MNL_CB_ERROR;
1296			dst->_present.size = 1;
1297			dst->size = mnl_attr_get_u32(attr);
1298		} else if (type == ETHTOOL_A_BITSET_BITS) {
1299			if (ynl_attr_validate(yarg, attr))
1300				return MNL_CB_ERROR;
1301			dst->_present.bits = 1;
1302
1303			parg.rsp_policy = &ethtool_bitset_bits_nest;
1304			parg.data = &dst->bits;
1305			if (ethtool_bitset_bits_parse(&parg, attr))
1306				return MNL_CB_ERROR;
1307		}
1308	}
1309
1310	return 0;
1311}
1312
1313void ethtool_stringset_free(struct ethtool_stringset_ *obj)
1314{
1315	unsigned int i;
1316
1317	for (i = 0; i < obj->n_strings; i++)
1318		ethtool_strings_free(&obj->strings[i]);
1319	free(obj->strings);
1320}
1321
1322int ethtool_stringset_put(struct nlmsghdr *nlh, unsigned int attr_type,
1323			  struct ethtool_stringset_ *obj)
1324{
1325	struct nlattr *nest;
1326
1327	nest = mnl_attr_nest_start(nlh, attr_type);
1328	if (obj->_present.id)
1329		mnl_attr_put_u32(nlh, ETHTOOL_A_STRINGSET_ID, obj->id);
1330	if (obj->_present.count)
1331		mnl_attr_put_u32(nlh, ETHTOOL_A_STRINGSET_COUNT, obj->count);
1332	for (unsigned int i = 0; i < obj->n_strings; i++)
1333		ethtool_strings_put(nlh, ETHTOOL_A_STRINGSET_STRINGS, &obj->strings[i]);
1334	mnl_attr_nest_end(nlh, nest);
1335
1336	return 0;
1337}
1338
1339int ethtool_stringset_parse(struct ynl_parse_arg *yarg,
1340			    const struct nlattr *nested)
1341{
1342	struct ethtool_stringset_ *dst = yarg->data;
1343	unsigned int n_strings = 0;
1344	const struct nlattr *attr;
1345	struct ynl_parse_arg parg;
1346	int i;
1347
1348	parg.ys = yarg->ys;
1349
1350	if (dst->strings)
1351		return ynl_error_parse(yarg, "attribute already present (stringset.strings)");
1352
1353	mnl_attr_for_each_nested(attr, nested) {
1354		unsigned int type = mnl_attr_get_type(attr);
1355
1356		if (type == ETHTOOL_A_STRINGSET_ID) {
1357			if (ynl_attr_validate(yarg, attr))
1358				return MNL_CB_ERROR;
1359			dst->_present.id = 1;
1360			dst->id = mnl_attr_get_u32(attr);
1361		} else if (type == ETHTOOL_A_STRINGSET_COUNT) {
1362			if (ynl_attr_validate(yarg, attr))
1363				return MNL_CB_ERROR;
1364			dst->_present.count = 1;
1365			dst->count = mnl_attr_get_u32(attr);
1366		} else if (type == ETHTOOL_A_STRINGSET_STRINGS) {
1367			n_strings++;
1368		}
1369	}
1370
1371	if (n_strings) {
1372		dst->strings = calloc(n_strings, sizeof(*dst->strings));
1373		dst->n_strings = n_strings;
1374		i = 0;
1375		parg.rsp_policy = &ethtool_strings_nest;
1376		mnl_attr_for_each_nested(attr, nested) {
1377			if (mnl_attr_get_type(attr) == ETHTOOL_A_STRINGSET_STRINGS) {
1378				parg.data = &dst->strings[i];
1379				if (ethtool_strings_parse(&parg, attr))
1380					return MNL_CB_ERROR;
1381				i++;
1382			}
1383		}
1384	}
1385
1386	return 0;
1387}
1388
1389void ethtool_tunnel_udp_table_free(struct ethtool_tunnel_udp_table *obj)
1390{
1391	unsigned int i;
1392
1393	ethtool_bitset_free(&obj->types);
1394	for (i = 0; i < obj->n_entry; i++)
1395		ethtool_tunnel_udp_entry_free(&obj->entry[i]);
1396	free(obj->entry);
1397}
1398
1399int ethtool_tunnel_udp_table_parse(struct ynl_parse_arg *yarg,
1400				   const struct nlattr *nested)
1401{
1402	struct ethtool_tunnel_udp_table *dst = yarg->data;
1403	const struct nlattr *attr;
1404	struct ynl_parse_arg parg;
1405	unsigned int n_entry = 0;
1406	int i;
1407
1408	parg.ys = yarg->ys;
1409
1410	if (dst->entry)
1411		return ynl_error_parse(yarg, "attribute already present (tunnel-udp-table.entry)");
1412
1413	mnl_attr_for_each_nested(attr, nested) {
1414		unsigned int type = mnl_attr_get_type(attr);
1415
1416		if (type == ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE) {
1417			if (ynl_attr_validate(yarg, attr))
1418				return MNL_CB_ERROR;
1419			dst->_present.size = 1;
1420			dst->size = mnl_attr_get_u32(attr);
1421		} else if (type == ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES) {
1422			if (ynl_attr_validate(yarg, attr))
1423				return MNL_CB_ERROR;
1424			dst->_present.types = 1;
1425
1426			parg.rsp_policy = &ethtool_bitset_nest;
1427			parg.data = &dst->types;
1428			if (ethtool_bitset_parse(&parg, attr))
1429				return MNL_CB_ERROR;
1430		} else if (type == ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY) {
1431			n_entry++;
1432		}
1433	}
1434
1435	if (n_entry) {
1436		dst->entry = calloc(n_entry, sizeof(*dst->entry));
1437		dst->n_entry = n_entry;
1438		i = 0;
1439		parg.rsp_policy = &ethtool_tunnel_udp_entry_nest;
1440		mnl_attr_for_each_nested(attr, nested) {
1441			if (mnl_attr_get_type(attr) == ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY) {
1442				parg.data = &dst->entry[i];
1443				if (ethtool_tunnel_udp_entry_parse(&parg, attr))
1444					return MNL_CB_ERROR;
1445				i++;
1446			}
1447		}
1448	}
1449
1450	return 0;
1451}
1452
1453void ethtool_stringsets_free(struct ethtool_stringsets *obj)
1454{
1455	unsigned int i;
1456
1457	for (i = 0; i < obj->n_stringset; i++)
1458		ethtool_stringset_free(&obj->stringset[i]);
1459	free(obj->stringset);
1460}
1461
1462int ethtool_stringsets_put(struct nlmsghdr *nlh, unsigned int attr_type,
1463			   struct ethtool_stringsets *obj)
1464{
1465	struct nlattr *nest;
1466
1467	nest = mnl_attr_nest_start(nlh, attr_type);
1468	for (unsigned int i = 0; i < obj->n_stringset; i++)
1469		ethtool_stringset_put(nlh, ETHTOOL_A_STRINGSETS_STRINGSET, &obj->stringset[i]);
1470	mnl_attr_nest_end(nlh, nest);
1471
1472	return 0;
1473}
1474
1475int ethtool_stringsets_parse(struct ynl_parse_arg *yarg,
1476			     const struct nlattr *nested)
1477{
1478	struct ethtool_stringsets *dst = yarg->data;
1479	unsigned int n_stringset = 0;
1480	const struct nlattr *attr;
1481	struct ynl_parse_arg parg;
1482	int i;
1483
1484	parg.ys = yarg->ys;
1485
1486	if (dst->stringset)
1487		return ynl_error_parse(yarg, "attribute already present (stringsets.stringset)");
1488
1489	mnl_attr_for_each_nested(attr, nested) {
1490		unsigned int type = mnl_attr_get_type(attr);
1491
1492		if (type == ETHTOOL_A_STRINGSETS_STRINGSET) {
1493			n_stringset++;
1494		}
1495	}
1496
1497	if (n_stringset) {
1498		dst->stringset = calloc(n_stringset, sizeof(*dst->stringset));
1499		dst->n_stringset = n_stringset;
1500		i = 0;
1501		parg.rsp_policy = &ethtool_stringset_nest;
1502		mnl_attr_for_each_nested(attr, nested) {
1503			if (mnl_attr_get_type(attr) == ETHTOOL_A_STRINGSETS_STRINGSET) {
1504				parg.data = &dst->stringset[i];
1505				if (ethtool_stringset_parse(&parg, attr))
1506					return MNL_CB_ERROR;
1507				i++;
1508			}
1509		}
1510	}
1511
1512	return 0;
1513}
1514
1515void ethtool_tunnel_udp_free(struct ethtool_tunnel_udp *obj)
1516{
1517	ethtool_tunnel_udp_table_free(&obj->table);
1518}
1519
1520int ethtool_tunnel_udp_parse(struct ynl_parse_arg *yarg,
1521			     const struct nlattr *nested)
1522{
1523	struct ethtool_tunnel_udp *dst = yarg->data;
1524	const struct nlattr *attr;
1525	struct ynl_parse_arg parg;
1526
1527	parg.ys = yarg->ys;
1528
1529	mnl_attr_for_each_nested(attr, nested) {
1530		unsigned int type = mnl_attr_get_type(attr);
1531
1532		if (type == ETHTOOL_A_TUNNEL_UDP_TABLE) {
1533			if (ynl_attr_validate(yarg, attr))
1534				return MNL_CB_ERROR;
1535			dst->_present.table = 1;
1536
1537			parg.rsp_policy = &ethtool_tunnel_udp_table_nest;
1538			parg.data = &dst->table;
1539			if (ethtool_tunnel_udp_table_parse(&parg, attr))
1540				return MNL_CB_ERROR;
1541		}
1542	}
1543
1544	return 0;
1545}
1546
1547/* ============== ETHTOOL_MSG_STRSET_GET ============== */
1548/* ETHTOOL_MSG_STRSET_GET - do */
1549void ethtool_strset_get_req_free(struct ethtool_strset_get_req *req)
1550{
1551	ethtool_header_free(&req->header);
1552	ethtool_stringsets_free(&req->stringsets);
1553	free(req);
1554}
1555
1556void ethtool_strset_get_rsp_free(struct ethtool_strset_get_rsp *rsp)
1557{
1558	ethtool_header_free(&rsp->header);
1559	ethtool_stringsets_free(&rsp->stringsets);
1560	free(rsp);
1561}
1562
1563int ethtool_strset_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1564{
1565	struct ethtool_strset_get_rsp *dst;
1566	struct ynl_parse_arg *yarg = data;
1567	const struct nlattr *attr;
1568	struct ynl_parse_arg parg;
1569
1570	dst = yarg->data;
1571	parg.ys = yarg->ys;
1572
1573	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1574		unsigned int type = mnl_attr_get_type(attr);
1575
1576		if (type == ETHTOOL_A_STRSET_HEADER) {
1577			if (ynl_attr_validate(yarg, attr))
1578				return MNL_CB_ERROR;
1579			dst->_present.header = 1;
1580
1581			parg.rsp_policy = &ethtool_header_nest;
1582			parg.data = &dst->header;
1583			if (ethtool_header_parse(&parg, attr))
1584				return MNL_CB_ERROR;
1585		} else if (type == ETHTOOL_A_STRSET_STRINGSETS) {
1586			if (ynl_attr_validate(yarg, attr))
1587				return MNL_CB_ERROR;
1588			dst->_present.stringsets = 1;
1589
1590			parg.rsp_policy = &ethtool_stringsets_nest;
1591			parg.data = &dst->stringsets;
1592			if (ethtool_stringsets_parse(&parg, attr))
1593				return MNL_CB_ERROR;
1594		}
1595	}
1596
1597	return MNL_CB_OK;
1598}
1599
1600struct ethtool_strset_get_rsp *
1601ethtool_strset_get(struct ynl_sock *ys, struct ethtool_strset_get_req *req)
1602{
1603	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1604	struct ethtool_strset_get_rsp *rsp;
1605	struct nlmsghdr *nlh;
1606	int err;
1607
1608	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_STRSET_GET, 1);
1609	ys->req_policy = &ethtool_strset_nest;
1610	yrs.yarg.rsp_policy = &ethtool_strset_nest;
1611
1612	if (req->_present.header)
1613		ethtool_header_put(nlh, ETHTOOL_A_STRSET_HEADER, &req->header);
1614	if (req->_present.stringsets)
1615		ethtool_stringsets_put(nlh, ETHTOOL_A_STRSET_STRINGSETS, &req->stringsets);
1616	if (req->_present.counts_only)
1617		mnl_attr_put(nlh, ETHTOOL_A_STRSET_COUNTS_ONLY, 0, NULL);
1618
1619	rsp = calloc(1, sizeof(*rsp));
1620	yrs.yarg.data = rsp;
1621	yrs.cb = ethtool_strset_get_rsp_parse;
1622	yrs.rsp_cmd = ETHTOOL_MSG_STRSET_GET;
1623
1624	err = ynl_exec(ys, nlh, &yrs);
1625	if (err < 0)
1626		goto err_free;
1627
1628	return rsp;
1629
1630err_free:
1631	ethtool_strset_get_rsp_free(rsp);
1632	return NULL;
1633}
1634
1635/* ETHTOOL_MSG_STRSET_GET - dump */
1636void ethtool_strset_get_list_free(struct ethtool_strset_get_list *rsp)
1637{
1638	struct ethtool_strset_get_list *next = rsp;
1639
1640	while ((void *)next != YNL_LIST_END) {
1641		rsp = next;
1642		next = rsp->next;
1643
1644		ethtool_header_free(&rsp->obj.header);
1645		ethtool_stringsets_free(&rsp->obj.stringsets);
1646		free(rsp);
1647	}
1648}
1649
1650struct ethtool_strset_get_list *
1651ethtool_strset_get_dump(struct ynl_sock *ys,
1652			struct ethtool_strset_get_req_dump *req)
1653{
1654	struct ynl_dump_state yds = {};
1655	struct nlmsghdr *nlh;
1656	int err;
1657
1658	yds.ys = ys;
1659	yds.alloc_sz = sizeof(struct ethtool_strset_get_list);
1660	yds.cb = ethtool_strset_get_rsp_parse;
1661	yds.rsp_cmd = ETHTOOL_MSG_STRSET_GET;
1662	yds.rsp_policy = &ethtool_strset_nest;
1663
1664	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_STRSET_GET, 1);
1665	ys->req_policy = &ethtool_strset_nest;
1666
1667	if (req->_present.header)
1668		ethtool_header_put(nlh, ETHTOOL_A_STRSET_HEADER, &req->header);
1669	if (req->_present.stringsets)
1670		ethtool_stringsets_put(nlh, ETHTOOL_A_STRSET_STRINGSETS, &req->stringsets);
1671	if (req->_present.counts_only)
1672		mnl_attr_put(nlh, ETHTOOL_A_STRSET_COUNTS_ONLY, 0, NULL);
1673
1674	err = ynl_exec_dump(ys, nlh, &yds);
1675	if (err < 0)
1676		goto free_list;
1677
1678	return yds.first;
1679
1680free_list:
1681	ethtool_strset_get_list_free(yds.first);
1682	return NULL;
1683}
1684
1685/* ============== ETHTOOL_MSG_LINKINFO_GET ============== */
1686/* ETHTOOL_MSG_LINKINFO_GET - do */
1687void ethtool_linkinfo_get_req_free(struct ethtool_linkinfo_get_req *req)
1688{
1689	ethtool_header_free(&req->header);
1690	free(req);
1691}
1692
1693void ethtool_linkinfo_get_rsp_free(struct ethtool_linkinfo_get_rsp *rsp)
1694{
1695	ethtool_header_free(&rsp->header);
1696	free(rsp);
1697}
1698
1699int ethtool_linkinfo_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1700{
1701	struct ethtool_linkinfo_get_rsp *dst;
1702	struct ynl_parse_arg *yarg = data;
1703	const struct nlattr *attr;
1704	struct ynl_parse_arg parg;
1705
1706	dst = yarg->data;
1707	parg.ys = yarg->ys;
1708
1709	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1710		unsigned int type = mnl_attr_get_type(attr);
1711
1712		if (type == ETHTOOL_A_LINKINFO_HEADER) {
1713			if (ynl_attr_validate(yarg, attr))
1714				return MNL_CB_ERROR;
1715			dst->_present.header = 1;
1716
1717			parg.rsp_policy = &ethtool_header_nest;
1718			parg.data = &dst->header;
1719			if (ethtool_header_parse(&parg, attr))
1720				return MNL_CB_ERROR;
1721		} else if (type == ETHTOOL_A_LINKINFO_PORT) {
1722			if (ynl_attr_validate(yarg, attr))
1723				return MNL_CB_ERROR;
1724			dst->_present.port = 1;
1725			dst->port = mnl_attr_get_u8(attr);
1726		} else if (type == ETHTOOL_A_LINKINFO_PHYADDR) {
1727			if (ynl_attr_validate(yarg, attr))
1728				return MNL_CB_ERROR;
1729			dst->_present.phyaddr = 1;
1730			dst->phyaddr = mnl_attr_get_u8(attr);
1731		} else if (type == ETHTOOL_A_LINKINFO_TP_MDIX) {
1732			if (ynl_attr_validate(yarg, attr))
1733				return MNL_CB_ERROR;
1734			dst->_present.tp_mdix = 1;
1735			dst->tp_mdix = mnl_attr_get_u8(attr);
1736		} else if (type == ETHTOOL_A_LINKINFO_TP_MDIX_CTRL) {
1737			if (ynl_attr_validate(yarg, attr))
1738				return MNL_CB_ERROR;
1739			dst->_present.tp_mdix_ctrl = 1;
1740			dst->tp_mdix_ctrl = mnl_attr_get_u8(attr);
1741		} else if (type == ETHTOOL_A_LINKINFO_TRANSCEIVER) {
1742			if (ynl_attr_validate(yarg, attr))
1743				return MNL_CB_ERROR;
1744			dst->_present.transceiver = 1;
1745			dst->transceiver = mnl_attr_get_u8(attr);
1746		}
1747	}
1748
1749	return MNL_CB_OK;
1750}
1751
1752struct ethtool_linkinfo_get_rsp *
1753ethtool_linkinfo_get(struct ynl_sock *ys, struct ethtool_linkinfo_get_req *req)
1754{
1755	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1756	struct ethtool_linkinfo_get_rsp *rsp;
1757	struct nlmsghdr *nlh;
1758	int err;
1759
1760	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKINFO_GET, 1);
1761	ys->req_policy = &ethtool_linkinfo_nest;
1762	yrs.yarg.rsp_policy = &ethtool_linkinfo_nest;
1763
1764	if (req->_present.header)
1765		ethtool_header_put(nlh, ETHTOOL_A_LINKINFO_HEADER, &req->header);
1766
1767	rsp = calloc(1, sizeof(*rsp));
1768	yrs.yarg.data = rsp;
1769	yrs.cb = ethtool_linkinfo_get_rsp_parse;
1770	yrs.rsp_cmd = ETHTOOL_MSG_LINKINFO_GET;
1771
1772	err = ynl_exec(ys, nlh, &yrs);
1773	if (err < 0)
1774		goto err_free;
1775
1776	return rsp;
1777
1778err_free:
1779	ethtool_linkinfo_get_rsp_free(rsp);
1780	return NULL;
1781}
1782
1783/* ETHTOOL_MSG_LINKINFO_GET - dump */
1784void ethtool_linkinfo_get_list_free(struct ethtool_linkinfo_get_list *rsp)
1785{
1786	struct ethtool_linkinfo_get_list *next = rsp;
1787
1788	while ((void *)next != YNL_LIST_END) {
1789		rsp = next;
1790		next = rsp->next;
1791
1792		ethtool_header_free(&rsp->obj.header);
1793		free(rsp);
1794	}
1795}
1796
1797struct ethtool_linkinfo_get_list *
1798ethtool_linkinfo_get_dump(struct ynl_sock *ys,
1799			  struct ethtool_linkinfo_get_req_dump *req)
1800{
1801	struct ynl_dump_state yds = {};
1802	struct nlmsghdr *nlh;
1803	int err;
1804
1805	yds.ys = ys;
1806	yds.alloc_sz = sizeof(struct ethtool_linkinfo_get_list);
1807	yds.cb = ethtool_linkinfo_get_rsp_parse;
1808	yds.rsp_cmd = ETHTOOL_MSG_LINKINFO_GET;
1809	yds.rsp_policy = &ethtool_linkinfo_nest;
1810
1811	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_LINKINFO_GET, 1);
1812	ys->req_policy = &ethtool_linkinfo_nest;
1813
1814	if (req->_present.header)
1815		ethtool_header_put(nlh, ETHTOOL_A_LINKINFO_HEADER, &req->header);
1816
1817	err = ynl_exec_dump(ys, nlh, &yds);
1818	if (err < 0)
1819		goto free_list;
1820
1821	return yds.first;
1822
1823free_list:
1824	ethtool_linkinfo_get_list_free(yds.first);
1825	return NULL;
1826}
1827
1828/* ETHTOOL_MSG_LINKINFO_GET - notify */
1829void ethtool_linkinfo_get_ntf_free(struct ethtool_linkinfo_get_ntf *rsp)
1830{
1831	ethtool_header_free(&rsp->obj.header);
1832	free(rsp);
1833}
1834
1835/* ============== ETHTOOL_MSG_LINKINFO_SET ============== */
1836/* ETHTOOL_MSG_LINKINFO_SET - do */
1837void ethtool_linkinfo_set_req_free(struct ethtool_linkinfo_set_req *req)
1838{
1839	ethtool_header_free(&req->header);
1840	free(req);
1841}
1842
1843int ethtool_linkinfo_set(struct ynl_sock *ys,
1844			 struct ethtool_linkinfo_set_req *req)
1845{
1846	struct nlmsghdr *nlh;
1847	int err;
1848
1849	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKINFO_SET, 1);
1850	ys->req_policy = &ethtool_linkinfo_nest;
1851
1852	if (req->_present.header)
1853		ethtool_header_put(nlh, ETHTOOL_A_LINKINFO_HEADER, &req->header);
1854	if (req->_present.port)
1855		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_PORT, req->port);
1856	if (req->_present.phyaddr)
1857		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_PHYADDR, req->phyaddr);
1858	if (req->_present.tp_mdix)
1859		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_TP_MDIX, req->tp_mdix);
1860	if (req->_present.tp_mdix_ctrl)
1861		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_TP_MDIX_CTRL, req->tp_mdix_ctrl);
1862	if (req->_present.transceiver)
1863		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_TRANSCEIVER, req->transceiver);
1864
1865	err = ynl_exec(ys, nlh, NULL);
1866	if (err < 0)
1867		return -1;
1868
1869	return 0;
1870}
1871
1872/* ============== ETHTOOL_MSG_LINKMODES_GET ============== */
1873/* ETHTOOL_MSG_LINKMODES_GET - do */
1874void ethtool_linkmodes_get_req_free(struct ethtool_linkmodes_get_req *req)
1875{
1876	ethtool_header_free(&req->header);
1877	free(req);
1878}
1879
1880void ethtool_linkmodes_get_rsp_free(struct ethtool_linkmodes_get_rsp *rsp)
1881{
1882	ethtool_header_free(&rsp->header);
1883	ethtool_bitset_free(&rsp->ours);
1884	ethtool_bitset_free(&rsp->peer);
1885	free(rsp);
1886}
1887
1888int ethtool_linkmodes_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
1889{
1890	struct ethtool_linkmodes_get_rsp *dst;
1891	struct ynl_parse_arg *yarg = data;
1892	const struct nlattr *attr;
1893	struct ynl_parse_arg parg;
1894
1895	dst = yarg->data;
1896	parg.ys = yarg->ys;
1897
1898	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
1899		unsigned int type = mnl_attr_get_type(attr);
1900
1901		if (type == ETHTOOL_A_LINKMODES_HEADER) {
1902			if (ynl_attr_validate(yarg, attr))
1903				return MNL_CB_ERROR;
1904			dst->_present.header = 1;
1905
1906			parg.rsp_policy = &ethtool_header_nest;
1907			parg.data = &dst->header;
1908			if (ethtool_header_parse(&parg, attr))
1909				return MNL_CB_ERROR;
1910		} else if (type == ETHTOOL_A_LINKMODES_AUTONEG) {
1911			if (ynl_attr_validate(yarg, attr))
1912				return MNL_CB_ERROR;
1913			dst->_present.autoneg = 1;
1914			dst->autoneg = mnl_attr_get_u8(attr);
1915		} else if (type == ETHTOOL_A_LINKMODES_OURS) {
1916			if (ynl_attr_validate(yarg, attr))
1917				return MNL_CB_ERROR;
1918			dst->_present.ours = 1;
1919
1920			parg.rsp_policy = &ethtool_bitset_nest;
1921			parg.data = &dst->ours;
1922			if (ethtool_bitset_parse(&parg, attr))
1923				return MNL_CB_ERROR;
1924		} else if (type == ETHTOOL_A_LINKMODES_PEER) {
1925			if (ynl_attr_validate(yarg, attr))
1926				return MNL_CB_ERROR;
1927			dst->_present.peer = 1;
1928
1929			parg.rsp_policy = &ethtool_bitset_nest;
1930			parg.data = &dst->peer;
1931			if (ethtool_bitset_parse(&parg, attr))
1932				return MNL_CB_ERROR;
1933		} else if (type == ETHTOOL_A_LINKMODES_SPEED) {
1934			if (ynl_attr_validate(yarg, attr))
1935				return MNL_CB_ERROR;
1936			dst->_present.speed = 1;
1937			dst->speed = mnl_attr_get_u32(attr);
1938		} else if (type == ETHTOOL_A_LINKMODES_DUPLEX) {
1939			if (ynl_attr_validate(yarg, attr))
1940				return MNL_CB_ERROR;
1941			dst->_present.duplex = 1;
1942			dst->duplex = mnl_attr_get_u8(attr);
1943		} else if (type == ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG) {
1944			if (ynl_attr_validate(yarg, attr))
1945				return MNL_CB_ERROR;
1946			dst->_present.master_slave_cfg = 1;
1947			dst->master_slave_cfg = mnl_attr_get_u8(attr);
1948		} else if (type == ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE) {
1949			if (ynl_attr_validate(yarg, attr))
1950				return MNL_CB_ERROR;
1951			dst->_present.master_slave_state = 1;
1952			dst->master_slave_state = mnl_attr_get_u8(attr);
1953		} else if (type == ETHTOOL_A_LINKMODES_LANES) {
1954			if (ynl_attr_validate(yarg, attr))
1955				return MNL_CB_ERROR;
1956			dst->_present.lanes = 1;
1957			dst->lanes = mnl_attr_get_u32(attr);
1958		} else if (type == ETHTOOL_A_LINKMODES_RATE_MATCHING) {
1959			if (ynl_attr_validate(yarg, attr))
1960				return MNL_CB_ERROR;
1961			dst->_present.rate_matching = 1;
1962			dst->rate_matching = mnl_attr_get_u8(attr);
1963		}
1964	}
1965
1966	return MNL_CB_OK;
1967}
1968
1969struct ethtool_linkmodes_get_rsp *
1970ethtool_linkmodes_get(struct ynl_sock *ys,
1971		      struct ethtool_linkmodes_get_req *req)
1972{
1973	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
1974	struct ethtool_linkmodes_get_rsp *rsp;
1975	struct nlmsghdr *nlh;
1976	int err;
1977
1978	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKMODES_GET, 1);
1979	ys->req_policy = &ethtool_linkmodes_nest;
1980	yrs.yarg.rsp_policy = &ethtool_linkmodes_nest;
1981
1982	if (req->_present.header)
1983		ethtool_header_put(nlh, ETHTOOL_A_LINKMODES_HEADER, &req->header);
1984
1985	rsp = calloc(1, sizeof(*rsp));
1986	yrs.yarg.data = rsp;
1987	yrs.cb = ethtool_linkmodes_get_rsp_parse;
1988	yrs.rsp_cmd = ETHTOOL_MSG_LINKMODES_GET;
1989
1990	err = ynl_exec(ys, nlh, &yrs);
1991	if (err < 0)
1992		goto err_free;
1993
1994	return rsp;
1995
1996err_free:
1997	ethtool_linkmodes_get_rsp_free(rsp);
1998	return NULL;
1999}
2000
2001/* ETHTOOL_MSG_LINKMODES_GET - dump */
2002void ethtool_linkmodes_get_list_free(struct ethtool_linkmodes_get_list *rsp)
2003{
2004	struct ethtool_linkmodes_get_list *next = rsp;
2005
2006	while ((void *)next != YNL_LIST_END) {
2007		rsp = next;
2008		next = rsp->next;
2009
2010		ethtool_header_free(&rsp->obj.header);
2011		ethtool_bitset_free(&rsp->obj.ours);
2012		ethtool_bitset_free(&rsp->obj.peer);
2013		free(rsp);
2014	}
2015}
2016
2017struct ethtool_linkmodes_get_list *
2018ethtool_linkmodes_get_dump(struct ynl_sock *ys,
2019			   struct ethtool_linkmodes_get_req_dump *req)
2020{
2021	struct ynl_dump_state yds = {};
2022	struct nlmsghdr *nlh;
2023	int err;
2024
2025	yds.ys = ys;
2026	yds.alloc_sz = sizeof(struct ethtool_linkmodes_get_list);
2027	yds.cb = ethtool_linkmodes_get_rsp_parse;
2028	yds.rsp_cmd = ETHTOOL_MSG_LINKMODES_GET;
2029	yds.rsp_policy = &ethtool_linkmodes_nest;
2030
2031	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_LINKMODES_GET, 1);
2032	ys->req_policy = &ethtool_linkmodes_nest;
2033
2034	if (req->_present.header)
2035		ethtool_header_put(nlh, ETHTOOL_A_LINKMODES_HEADER, &req->header);
2036
2037	err = ynl_exec_dump(ys, nlh, &yds);
2038	if (err < 0)
2039		goto free_list;
2040
2041	return yds.first;
2042
2043free_list:
2044	ethtool_linkmodes_get_list_free(yds.first);
2045	return NULL;
2046}
2047
2048/* ETHTOOL_MSG_LINKMODES_GET - notify */
2049void ethtool_linkmodes_get_ntf_free(struct ethtool_linkmodes_get_ntf *rsp)
2050{
2051	ethtool_header_free(&rsp->obj.header);
2052	ethtool_bitset_free(&rsp->obj.ours);
2053	ethtool_bitset_free(&rsp->obj.peer);
2054	free(rsp);
2055}
2056
2057/* ============== ETHTOOL_MSG_LINKMODES_SET ============== */
2058/* ETHTOOL_MSG_LINKMODES_SET - do */
2059void ethtool_linkmodes_set_req_free(struct ethtool_linkmodes_set_req *req)
2060{
2061	ethtool_header_free(&req->header);
2062	ethtool_bitset_free(&req->ours);
2063	ethtool_bitset_free(&req->peer);
2064	free(req);
2065}
2066
2067int ethtool_linkmodes_set(struct ynl_sock *ys,
2068			  struct ethtool_linkmodes_set_req *req)
2069{
2070	struct nlmsghdr *nlh;
2071	int err;
2072
2073	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKMODES_SET, 1);
2074	ys->req_policy = &ethtool_linkmodes_nest;
2075
2076	if (req->_present.header)
2077		ethtool_header_put(nlh, ETHTOOL_A_LINKMODES_HEADER, &req->header);
2078	if (req->_present.autoneg)
2079		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_AUTONEG, req->autoneg);
2080	if (req->_present.ours)
2081		ethtool_bitset_put(nlh, ETHTOOL_A_LINKMODES_OURS, &req->ours);
2082	if (req->_present.peer)
2083		ethtool_bitset_put(nlh, ETHTOOL_A_LINKMODES_PEER, &req->peer);
2084	if (req->_present.speed)
2085		mnl_attr_put_u32(nlh, ETHTOOL_A_LINKMODES_SPEED, req->speed);
2086	if (req->_present.duplex)
2087		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_DUPLEX, req->duplex);
2088	if (req->_present.master_slave_cfg)
2089		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, req->master_slave_cfg);
2090	if (req->_present.master_slave_state)
2091		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, req->master_slave_state);
2092	if (req->_present.lanes)
2093		mnl_attr_put_u32(nlh, ETHTOOL_A_LINKMODES_LANES, req->lanes);
2094	if (req->_present.rate_matching)
2095		mnl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_RATE_MATCHING, req->rate_matching);
2096
2097	err = ynl_exec(ys, nlh, NULL);
2098	if (err < 0)
2099		return -1;
2100
2101	return 0;
2102}
2103
2104/* ============== ETHTOOL_MSG_LINKSTATE_GET ============== */
2105/* ETHTOOL_MSG_LINKSTATE_GET - do */
2106void ethtool_linkstate_get_req_free(struct ethtool_linkstate_get_req *req)
2107{
2108	ethtool_header_free(&req->header);
2109	free(req);
2110}
2111
2112void ethtool_linkstate_get_rsp_free(struct ethtool_linkstate_get_rsp *rsp)
2113{
2114	ethtool_header_free(&rsp->header);
2115	free(rsp);
2116}
2117
2118int ethtool_linkstate_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2119{
2120	struct ethtool_linkstate_get_rsp *dst;
2121	struct ynl_parse_arg *yarg = data;
2122	const struct nlattr *attr;
2123	struct ynl_parse_arg parg;
2124
2125	dst = yarg->data;
2126	parg.ys = yarg->ys;
2127
2128	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2129		unsigned int type = mnl_attr_get_type(attr);
2130
2131		if (type == ETHTOOL_A_LINKSTATE_HEADER) {
2132			if (ynl_attr_validate(yarg, attr))
2133				return MNL_CB_ERROR;
2134			dst->_present.header = 1;
2135
2136			parg.rsp_policy = &ethtool_header_nest;
2137			parg.data = &dst->header;
2138			if (ethtool_header_parse(&parg, attr))
2139				return MNL_CB_ERROR;
2140		} else if (type == ETHTOOL_A_LINKSTATE_LINK) {
2141			if (ynl_attr_validate(yarg, attr))
2142				return MNL_CB_ERROR;
2143			dst->_present.link = 1;
2144			dst->link = mnl_attr_get_u8(attr);
2145		} else if (type == ETHTOOL_A_LINKSTATE_SQI) {
2146			if (ynl_attr_validate(yarg, attr))
2147				return MNL_CB_ERROR;
2148			dst->_present.sqi = 1;
2149			dst->sqi = mnl_attr_get_u32(attr);
2150		} else if (type == ETHTOOL_A_LINKSTATE_SQI_MAX) {
2151			if (ynl_attr_validate(yarg, attr))
2152				return MNL_CB_ERROR;
2153			dst->_present.sqi_max = 1;
2154			dst->sqi_max = mnl_attr_get_u32(attr);
2155		} else if (type == ETHTOOL_A_LINKSTATE_EXT_STATE) {
2156			if (ynl_attr_validate(yarg, attr))
2157				return MNL_CB_ERROR;
2158			dst->_present.ext_state = 1;
2159			dst->ext_state = mnl_attr_get_u8(attr);
2160		} else if (type == ETHTOOL_A_LINKSTATE_EXT_SUBSTATE) {
2161			if (ynl_attr_validate(yarg, attr))
2162				return MNL_CB_ERROR;
2163			dst->_present.ext_substate = 1;
2164			dst->ext_substate = mnl_attr_get_u8(attr);
2165		} else if (type == ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT) {
2166			if (ynl_attr_validate(yarg, attr))
2167				return MNL_CB_ERROR;
2168			dst->_present.ext_down_cnt = 1;
2169			dst->ext_down_cnt = mnl_attr_get_u32(attr);
2170		}
2171	}
2172
2173	return MNL_CB_OK;
2174}
2175
2176struct ethtool_linkstate_get_rsp *
2177ethtool_linkstate_get(struct ynl_sock *ys,
2178		      struct ethtool_linkstate_get_req *req)
2179{
2180	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2181	struct ethtool_linkstate_get_rsp *rsp;
2182	struct nlmsghdr *nlh;
2183	int err;
2184
2185	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKSTATE_GET, 1);
2186	ys->req_policy = &ethtool_linkstate_nest;
2187	yrs.yarg.rsp_policy = &ethtool_linkstate_nest;
2188
2189	if (req->_present.header)
2190		ethtool_header_put(nlh, ETHTOOL_A_LINKSTATE_HEADER, &req->header);
2191
2192	rsp = calloc(1, sizeof(*rsp));
2193	yrs.yarg.data = rsp;
2194	yrs.cb = ethtool_linkstate_get_rsp_parse;
2195	yrs.rsp_cmd = ETHTOOL_MSG_LINKSTATE_GET;
2196
2197	err = ynl_exec(ys, nlh, &yrs);
2198	if (err < 0)
2199		goto err_free;
2200
2201	return rsp;
2202
2203err_free:
2204	ethtool_linkstate_get_rsp_free(rsp);
2205	return NULL;
2206}
2207
2208/* ETHTOOL_MSG_LINKSTATE_GET - dump */
2209void ethtool_linkstate_get_list_free(struct ethtool_linkstate_get_list *rsp)
2210{
2211	struct ethtool_linkstate_get_list *next = rsp;
2212
2213	while ((void *)next != YNL_LIST_END) {
2214		rsp = next;
2215		next = rsp->next;
2216
2217		ethtool_header_free(&rsp->obj.header);
2218		free(rsp);
2219	}
2220}
2221
2222struct ethtool_linkstate_get_list *
2223ethtool_linkstate_get_dump(struct ynl_sock *ys,
2224			   struct ethtool_linkstate_get_req_dump *req)
2225{
2226	struct ynl_dump_state yds = {};
2227	struct nlmsghdr *nlh;
2228	int err;
2229
2230	yds.ys = ys;
2231	yds.alloc_sz = sizeof(struct ethtool_linkstate_get_list);
2232	yds.cb = ethtool_linkstate_get_rsp_parse;
2233	yds.rsp_cmd = ETHTOOL_MSG_LINKSTATE_GET;
2234	yds.rsp_policy = &ethtool_linkstate_nest;
2235
2236	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_LINKSTATE_GET, 1);
2237	ys->req_policy = &ethtool_linkstate_nest;
2238
2239	if (req->_present.header)
2240		ethtool_header_put(nlh, ETHTOOL_A_LINKSTATE_HEADER, &req->header);
2241
2242	err = ynl_exec_dump(ys, nlh, &yds);
2243	if (err < 0)
2244		goto free_list;
2245
2246	return yds.first;
2247
2248free_list:
2249	ethtool_linkstate_get_list_free(yds.first);
2250	return NULL;
2251}
2252
2253/* ============== ETHTOOL_MSG_DEBUG_GET ============== */
2254/* ETHTOOL_MSG_DEBUG_GET - do */
2255void ethtool_debug_get_req_free(struct ethtool_debug_get_req *req)
2256{
2257	ethtool_header_free(&req->header);
2258	free(req);
2259}
2260
2261void ethtool_debug_get_rsp_free(struct ethtool_debug_get_rsp *rsp)
2262{
2263	ethtool_header_free(&rsp->header);
2264	ethtool_bitset_free(&rsp->msgmask);
2265	free(rsp);
2266}
2267
2268int ethtool_debug_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2269{
2270	struct ethtool_debug_get_rsp *dst;
2271	struct ynl_parse_arg *yarg = data;
2272	const struct nlattr *attr;
2273	struct ynl_parse_arg parg;
2274
2275	dst = yarg->data;
2276	parg.ys = yarg->ys;
2277
2278	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2279		unsigned int type = mnl_attr_get_type(attr);
2280
2281		if (type == ETHTOOL_A_DEBUG_HEADER) {
2282			if (ynl_attr_validate(yarg, attr))
2283				return MNL_CB_ERROR;
2284			dst->_present.header = 1;
2285
2286			parg.rsp_policy = &ethtool_header_nest;
2287			parg.data = &dst->header;
2288			if (ethtool_header_parse(&parg, attr))
2289				return MNL_CB_ERROR;
2290		} else if (type == ETHTOOL_A_DEBUG_MSGMASK) {
2291			if (ynl_attr_validate(yarg, attr))
2292				return MNL_CB_ERROR;
2293			dst->_present.msgmask = 1;
2294
2295			parg.rsp_policy = &ethtool_bitset_nest;
2296			parg.data = &dst->msgmask;
2297			if (ethtool_bitset_parse(&parg, attr))
2298				return MNL_CB_ERROR;
2299		}
2300	}
2301
2302	return MNL_CB_OK;
2303}
2304
2305struct ethtool_debug_get_rsp *
2306ethtool_debug_get(struct ynl_sock *ys, struct ethtool_debug_get_req *req)
2307{
2308	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2309	struct ethtool_debug_get_rsp *rsp;
2310	struct nlmsghdr *nlh;
2311	int err;
2312
2313	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_DEBUG_GET, 1);
2314	ys->req_policy = &ethtool_debug_nest;
2315	yrs.yarg.rsp_policy = &ethtool_debug_nest;
2316
2317	if (req->_present.header)
2318		ethtool_header_put(nlh, ETHTOOL_A_DEBUG_HEADER, &req->header);
2319
2320	rsp = calloc(1, sizeof(*rsp));
2321	yrs.yarg.data = rsp;
2322	yrs.cb = ethtool_debug_get_rsp_parse;
2323	yrs.rsp_cmd = ETHTOOL_MSG_DEBUG_GET;
2324
2325	err = ynl_exec(ys, nlh, &yrs);
2326	if (err < 0)
2327		goto err_free;
2328
2329	return rsp;
2330
2331err_free:
2332	ethtool_debug_get_rsp_free(rsp);
2333	return NULL;
2334}
2335
2336/* ETHTOOL_MSG_DEBUG_GET - dump */
2337void ethtool_debug_get_list_free(struct ethtool_debug_get_list *rsp)
2338{
2339	struct ethtool_debug_get_list *next = rsp;
2340
2341	while ((void *)next != YNL_LIST_END) {
2342		rsp = next;
2343		next = rsp->next;
2344
2345		ethtool_header_free(&rsp->obj.header);
2346		ethtool_bitset_free(&rsp->obj.msgmask);
2347		free(rsp);
2348	}
2349}
2350
2351struct ethtool_debug_get_list *
2352ethtool_debug_get_dump(struct ynl_sock *ys,
2353		       struct ethtool_debug_get_req_dump *req)
2354{
2355	struct ynl_dump_state yds = {};
2356	struct nlmsghdr *nlh;
2357	int err;
2358
2359	yds.ys = ys;
2360	yds.alloc_sz = sizeof(struct ethtool_debug_get_list);
2361	yds.cb = ethtool_debug_get_rsp_parse;
2362	yds.rsp_cmd = ETHTOOL_MSG_DEBUG_GET;
2363	yds.rsp_policy = &ethtool_debug_nest;
2364
2365	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_DEBUG_GET, 1);
2366	ys->req_policy = &ethtool_debug_nest;
2367
2368	if (req->_present.header)
2369		ethtool_header_put(nlh, ETHTOOL_A_DEBUG_HEADER, &req->header);
2370
2371	err = ynl_exec_dump(ys, nlh, &yds);
2372	if (err < 0)
2373		goto free_list;
2374
2375	return yds.first;
2376
2377free_list:
2378	ethtool_debug_get_list_free(yds.first);
2379	return NULL;
2380}
2381
2382/* ETHTOOL_MSG_DEBUG_GET - notify */
2383void ethtool_debug_get_ntf_free(struct ethtool_debug_get_ntf *rsp)
2384{
2385	ethtool_header_free(&rsp->obj.header);
2386	ethtool_bitset_free(&rsp->obj.msgmask);
2387	free(rsp);
2388}
2389
2390/* ============== ETHTOOL_MSG_DEBUG_SET ============== */
2391/* ETHTOOL_MSG_DEBUG_SET - do */
2392void ethtool_debug_set_req_free(struct ethtool_debug_set_req *req)
2393{
2394	ethtool_header_free(&req->header);
2395	ethtool_bitset_free(&req->msgmask);
2396	free(req);
2397}
2398
2399int ethtool_debug_set(struct ynl_sock *ys, struct ethtool_debug_set_req *req)
2400{
2401	struct nlmsghdr *nlh;
2402	int err;
2403
2404	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_DEBUG_SET, 1);
2405	ys->req_policy = &ethtool_debug_nest;
2406
2407	if (req->_present.header)
2408		ethtool_header_put(nlh, ETHTOOL_A_DEBUG_HEADER, &req->header);
2409	if (req->_present.msgmask)
2410		ethtool_bitset_put(nlh, ETHTOOL_A_DEBUG_MSGMASK, &req->msgmask);
2411
2412	err = ynl_exec(ys, nlh, NULL);
2413	if (err < 0)
2414		return -1;
2415
2416	return 0;
2417}
2418
2419/* ============== ETHTOOL_MSG_WOL_GET ============== */
2420/* ETHTOOL_MSG_WOL_GET - do */
2421void ethtool_wol_get_req_free(struct ethtool_wol_get_req *req)
2422{
2423	ethtool_header_free(&req->header);
2424	free(req);
2425}
2426
2427void ethtool_wol_get_rsp_free(struct ethtool_wol_get_rsp *rsp)
2428{
2429	ethtool_header_free(&rsp->header);
2430	ethtool_bitset_free(&rsp->modes);
2431	free(rsp->sopass);
2432	free(rsp);
2433}
2434
2435int ethtool_wol_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2436{
2437	struct ynl_parse_arg *yarg = data;
2438	struct ethtool_wol_get_rsp *dst;
2439	const struct nlattr *attr;
2440	struct ynl_parse_arg parg;
2441
2442	dst = yarg->data;
2443	parg.ys = yarg->ys;
2444
2445	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2446		unsigned int type = mnl_attr_get_type(attr);
2447
2448		if (type == ETHTOOL_A_WOL_HEADER) {
2449			if (ynl_attr_validate(yarg, attr))
2450				return MNL_CB_ERROR;
2451			dst->_present.header = 1;
2452
2453			parg.rsp_policy = &ethtool_header_nest;
2454			parg.data = &dst->header;
2455			if (ethtool_header_parse(&parg, attr))
2456				return MNL_CB_ERROR;
2457		} else if (type == ETHTOOL_A_WOL_MODES) {
2458			if (ynl_attr_validate(yarg, attr))
2459				return MNL_CB_ERROR;
2460			dst->_present.modes = 1;
2461
2462			parg.rsp_policy = &ethtool_bitset_nest;
2463			parg.data = &dst->modes;
2464			if (ethtool_bitset_parse(&parg, attr))
2465				return MNL_CB_ERROR;
2466		} else if (type == ETHTOOL_A_WOL_SOPASS) {
2467			unsigned int len;
2468
2469			if (ynl_attr_validate(yarg, attr))
2470				return MNL_CB_ERROR;
2471
2472			len = mnl_attr_get_payload_len(attr);
2473			dst->_present.sopass_len = len;
2474			dst->sopass = malloc(len);
2475			memcpy(dst->sopass, mnl_attr_get_payload(attr), len);
2476		}
2477	}
2478
2479	return MNL_CB_OK;
2480}
2481
2482struct ethtool_wol_get_rsp *
2483ethtool_wol_get(struct ynl_sock *ys, struct ethtool_wol_get_req *req)
2484{
2485	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2486	struct ethtool_wol_get_rsp *rsp;
2487	struct nlmsghdr *nlh;
2488	int err;
2489
2490	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_WOL_GET, 1);
2491	ys->req_policy = &ethtool_wol_nest;
2492	yrs.yarg.rsp_policy = &ethtool_wol_nest;
2493
2494	if (req->_present.header)
2495		ethtool_header_put(nlh, ETHTOOL_A_WOL_HEADER, &req->header);
2496
2497	rsp = calloc(1, sizeof(*rsp));
2498	yrs.yarg.data = rsp;
2499	yrs.cb = ethtool_wol_get_rsp_parse;
2500	yrs.rsp_cmd = ETHTOOL_MSG_WOL_GET;
2501
2502	err = ynl_exec(ys, nlh, &yrs);
2503	if (err < 0)
2504		goto err_free;
2505
2506	return rsp;
2507
2508err_free:
2509	ethtool_wol_get_rsp_free(rsp);
2510	return NULL;
2511}
2512
2513/* ETHTOOL_MSG_WOL_GET - dump */
2514void ethtool_wol_get_list_free(struct ethtool_wol_get_list *rsp)
2515{
2516	struct ethtool_wol_get_list *next = rsp;
2517
2518	while ((void *)next != YNL_LIST_END) {
2519		rsp = next;
2520		next = rsp->next;
2521
2522		ethtool_header_free(&rsp->obj.header);
2523		ethtool_bitset_free(&rsp->obj.modes);
2524		free(rsp->obj.sopass);
2525		free(rsp);
2526	}
2527}
2528
2529struct ethtool_wol_get_list *
2530ethtool_wol_get_dump(struct ynl_sock *ys, struct ethtool_wol_get_req_dump *req)
2531{
2532	struct ynl_dump_state yds = {};
2533	struct nlmsghdr *nlh;
2534	int err;
2535
2536	yds.ys = ys;
2537	yds.alloc_sz = sizeof(struct ethtool_wol_get_list);
2538	yds.cb = ethtool_wol_get_rsp_parse;
2539	yds.rsp_cmd = ETHTOOL_MSG_WOL_GET;
2540	yds.rsp_policy = &ethtool_wol_nest;
2541
2542	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_WOL_GET, 1);
2543	ys->req_policy = &ethtool_wol_nest;
2544
2545	if (req->_present.header)
2546		ethtool_header_put(nlh, ETHTOOL_A_WOL_HEADER, &req->header);
2547
2548	err = ynl_exec_dump(ys, nlh, &yds);
2549	if (err < 0)
2550		goto free_list;
2551
2552	return yds.first;
2553
2554free_list:
2555	ethtool_wol_get_list_free(yds.first);
2556	return NULL;
2557}
2558
2559/* ETHTOOL_MSG_WOL_GET - notify */
2560void ethtool_wol_get_ntf_free(struct ethtool_wol_get_ntf *rsp)
2561{
2562	ethtool_header_free(&rsp->obj.header);
2563	ethtool_bitset_free(&rsp->obj.modes);
2564	free(rsp->obj.sopass);
2565	free(rsp);
2566}
2567
2568/* ============== ETHTOOL_MSG_WOL_SET ============== */
2569/* ETHTOOL_MSG_WOL_SET - do */
2570void ethtool_wol_set_req_free(struct ethtool_wol_set_req *req)
2571{
2572	ethtool_header_free(&req->header);
2573	ethtool_bitset_free(&req->modes);
2574	free(req->sopass);
2575	free(req);
2576}
2577
2578int ethtool_wol_set(struct ynl_sock *ys, struct ethtool_wol_set_req *req)
2579{
2580	struct nlmsghdr *nlh;
2581	int err;
2582
2583	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_WOL_SET, 1);
2584	ys->req_policy = &ethtool_wol_nest;
2585
2586	if (req->_present.header)
2587		ethtool_header_put(nlh, ETHTOOL_A_WOL_HEADER, &req->header);
2588	if (req->_present.modes)
2589		ethtool_bitset_put(nlh, ETHTOOL_A_WOL_MODES, &req->modes);
2590	if (req->_present.sopass_len)
2591		mnl_attr_put(nlh, ETHTOOL_A_WOL_SOPASS, req->_present.sopass_len, req->sopass);
2592
2593	err = ynl_exec(ys, nlh, NULL);
2594	if (err < 0)
2595		return -1;
2596
2597	return 0;
2598}
2599
2600/* ============== ETHTOOL_MSG_FEATURES_GET ============== */
2601/* ETHTOOL_MSG_FEATURES_GET - do */
2602void ethtool_features_get_req_free(struct ethtool_features_get_req *req)
2603{
2604	ethtool_header_free(&req->header);
2605	free(req);
2606}
2607
2608void ethtool_features_get_rsp_free(struct ethtool_features_get_rsp *rsp)
2609{
2610	ethtool_header_free(&rsp->header);
2611	ethtool_bitset_free(&rsp->hw);
2612	ethtool_bitset_free(&rsp->wanted);
2613	ethtool_bitset_free(&rsp->active);
2614	ethtool_bitset_free(&rsp->nochange);
2615	free(rsp);
2616}
2617
2618int ethtool_features_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2619{
2620	struct ethtool_features_get_rsp *dst;
2621	struct ynl_parse_arg *yarg = data;
2622	const struct nlattr *attr;
2623	struct ynl_parse_arg parg;
2624
2625	dst = yarg->data;
2626	parg.ys = yarg->ys;
2627
2628	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2629		unsigned int type = mnl_attr_get_type(attr);
2630
2631		if (type == ETHTOOL_A_FEATURES_HEADER) {
2632			if (ynl_attr_validate(yarg, attr))
2633				return MNL_CB_ERROR;
2634			dst->_present.header = 1;
2635
2636			parg.rsp_policy = &ethtool_header_nest;
2637			parg.data = &dst->header;
2638			if (ethtool_header_parse(&parg, attr))
2639				return MNL_CB_ERROR;
2640		} else if (type == ETHTOOL_A_FEATURES_HW) {
2641			if (ynl_attr_validate(yarg, attr))
2642				return MNL_CB_ERROR;
2643			dst->_present.hw = 1;
2644
2645			parg.rsp_policy = &ethtool_bitset_nest;
2646			parg.data = &dst->hw;
2647			if (ethtool_bitset_parse(&parg, attr))
2648				return MNL_CB_ERROR;
2649		} else if (type == ETHTOOL_A_FEATURES_WANTED) {
2650			if (ynl_attr_validate(yarg, attr))
2651				return MNL_CB_ERROR;
2652			dst->_present.wanted = 1;
2653
2654			parg.rsp_policy = &ethtool_bitset_nest;
2655			parg.data = &dst->wanted;
2656			if (ethtool_bitset_parse(&parg, attr))
2657				return MNL_CB_ERROR;
2658		} else if (type == ETHTOOL_A_FEATURES_ACTIVE) {
2659			if (ynl_attr_validate(yarg, attr))
2660				return MNL_CB_ERROR;
2661			dst->_present.active = 1;
2662
2663			parg.rsp_policy = &ethtool_bitset_nest;
2664			parg.data = &dst->active;
2665			if (ethtool_bitset_parse(&parg, attr))
2666				return MNL_CB_ERROR;
2667		} else if (type == ETHTOOL_A_FEATURES_NOCHANGE) {
2668			if (ynl_attr_validate(yarg, attr))
2669				return MNL_CB_ERROR;
2670			dst->_present.nochange = 1;
2671
2672			parg.rsp_policy = &ethtool_bitset_nest;
2673			parg.data = &dst->nochange;
2674			if (ethtool_bitset_parse(&parg, attr))
2675				return MNL_CB_ERROR;
2676		}
2677	}
2678
2679	return MNL_CB_OK;
2680}
2681
2682struct ethtool_features_get_rsp *
2683ethtool_features_get(struct ynl_sock *ys, struct ethtool_features_get_req *req)
2684{
2685	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2686	struct ethtool_features_get_rsp *rsp;
2687	struct nlmsghdr *nlh;
2688	int err;
2689
2690	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEATURES_GET, 1);
2691	ys->req_policy = &ethtool_features_nest;
2692	yrs.yarg.rsp_policy = &ethtool_features_nest;
2693
2694	if (req->_present.header)
2695		ethtool_header_put(nlh, ETHTOOL_A_FEATURES_HEADER, &req->header);
2696
2697	rsp = calloc(1, sizeof(*rsp));
2698	yrs.yarg.data = rsp;
2699	yrs.cb = ethtool_features_get_rsp_parse;
2700	yrs.rsp_cmd = ETHTOOL_MSG_FEATURES_GET;
2701
2702	err = ynl_exec(ys, nlh, &yrs);
2703	if (err < 0)
2704		goto err_free;
2705
2706	return rsp;
2707
2708err_free:
2709	ethtool_features_get_rsp_free(rsp);
2710	return NULL;
2711}
2712
2713/* ETHTOOL_MSG_FEATURES_GET - dump */
2714void ethtool_features_get_list_free(struct ethtool_features_get_list *rsp)
2715{
2716	struct ethtool_features_get_list *next = rsp;
2717
2718	while ((void *)next != YNL_LIST_END) {
2719		rsp = next;
2720		next = rsp->next;
2721
2722		ethtool_header_free(&rsp->obj.header);
2723		ethtool_bitset_free(&rsp->obj.hw);
2724		ethtool_bitset_free(&rsp->obj.wanted);
2725		ethtool_bitset_free(&rsp->obj.active);
2726		ethtool_bitset_free(&rsp->obj.nochange);
2727		free(rsp);
2728	}
2729}
2730
2731struct ethtool_features_get_list *
2732ethtool_features_get_dump(struct ynl_sock *ys,
2733			  struct ethtool_features_get_req_dump *req)
2734{
2735	struct ynl_dump_state yds = {};
2736	struct nlmsghdr *nlh;
2737	int err;
2738
2739	yds.ys = ys;
2740	yds.alloc_sz = sizeof(struct ethtool_features_get_list);
2741	yds.cb = ethtool_features_get_rsp_parse;
2742	yds.rsp_cmd = ETHTOOL_MSG_FEATURES_GET;
2743	yds.rsp_policy = &ethtool_features_nest;
2744
2745	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_FEATURES_GET, 1);
2746	ys->req_policy = &ethtool_features_nest;
2747
2748	if (req->_present.header)
2749		ethtool_header_put(nlh, ETHTOOL_A_FEATURES_HEADER, &req->header);
2750
2751	err = ynl_exec_dump(ys, nlh, &yds);
2752	if (err < 0)
2753		goto free_list;
2754
2755	return yds.first;
2756
2757free_list:
2758	ethtool_features_get_list_free(yds.first);
2759	return NULL;
2760}
2761
2762/* ETHTOOL_MSG_FEATURES_GET - notify */
2763void ethtool_features_get_ntf_free(struct ethtool_features_get_ntf *rsp)
2764{
2765	ethtool_header_free(&rsp->obj.header);
2766	ethtool_bitset_free(&rsp->obj.hw);
2767	ethtool_bitset_free(&rsp->obj.wanted);
2768	ethtool_bitset_free(&rsp->obj.active);
2769	ethtool_bitset_free(&rsp->obj.nochange);
2770	free(rsp);
2771}
2772
2773/* ============== ETHTOOL_MSG_FEATURES_SET ============== */
2774/* ETHTOOL_MSG_FEATURES_SET - do */
2775void ethtool_features_set_req_free(struct ethtool_features_set_req *req)
2776{
2777	ethtool_header_free(&req->header);
2778	ethtool_bitset_free(&req->hw);
2779	ethtool_bitset_free(&req->wanted);
2780	ethtool_bitset_free(&req->active);
2781	ethtool_bitset_free(&req->nochange);
2782	free(req);
2783}
2784
2785void ethtool_features_set_rsp_free(struct ethtool_features_set_rsp *rsp)
2786{
2787	ethtool_header_free(&rsp->header);
2788	ethtool_bitset_free(&rsp->hw);
2789	ethtool_bitset_free(&rsp->wanted);
2790	ethtool_bitset_free(&rsp->active);
2791	ethtool_bitset_free(&rsp->nochange);
2792	free(rsp);
2793}
2794
2795int ethtool_features_set_rsp_parse(const struct nlmsghdr *nlh, void *data)
2796{
2797	struct ethtool_features_set_rsp *dst;
2798	struct ynl_parse_arg *yarg = data;
2799	const struct nlattr *attr;
2800	struct ynl_parse_arg parg;
2801
2802	dst = yarg->data;
2803	parg.ys = yarg->ys;
2804
2805	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2806		unsigned int type = mnl_attr_get_type(attr);
2807
2808		if (type == ETHTOOL_A_FEATURES_HEADER) {
2809			if (ynl_attr_validate(yarg, attr))
2810				return MNL_CB_ERROR;
2811			dst->_present.header = 1;
2812
2813			parg.rsp_policy = &ethtool_header_nest;
2814			parg.data = &dst->header;
2815			if (ethtool_header_parse(&parg, attr))
2816				return MNL_CB_ERROR;
2817		} else if (type == ETHTOOL_A_FEATURES_HW) {
2818			if (ynl_attr_validate(yarg, attr))
2819				return MNL_CB_ERROR;
2820			dst->_present.hw = 1;
2821
2822			parg.rsp_policy = &ethtool_bitset_nest;
2823			parg.data = &dst->hw;
2824			if (ethtool_bitset_parse(&parg, attr))
2825				return MNL_CB_ERROR;
2826		} else if (type == ETHTOOL_A_FEATURES_WANTED) {
2827			if (ynl_attr_validate(yarg, attr))
2828				return MNL_CB_ERROR;
2829			dst->_present.wanted = 1;
2830
2831			parg.rsp_policy = &ethtool_bitset_nest;
2832			parg.data = &dst->wanted;
2833			if (ethtool_bitset_parse(&parg, attr))
2834				return MNL_CB_ERROR;
2835		} else if (type == ETHTOOL_A_FEATURES_ACTIVE) {
2836			if (ynl_attr_validate(yarg, attr))
2837				return MNL_CB_ERROR;
2838			dst->_present.active = 1;
2839
2840			parg.rsp_policy = &ethtool_bitset_nest;
2841			parg.data = &dst->active;
2842			if (ethtool_bitset_parse(&parg, attr))
2843				return MNL_CB_ERROR;
2844		} else if (type == ETHTOOL_A_FEATURES_NOCHANGE) {
2845			if (ynl_attr_validate(yarg, attr))
2846				return MNL_CB_ERROR;
2847			dst->_present.nochange = 1;
2848
2849			parg.rsp_policy = &ethtool_bitset_nest;
2850			parg.data = &dst->nochange;
2851			if (ethtool_bitset_parse(&parg, attr))
2852				return MNL_CB_ERROR;
2853		}
2854	}
2855
2856	return MNL_CB_OK;
2857}
2858
2859struct ethtool_features_set_rsp *
2860ethtool_features_set(struct ynl_sock *ys, struct ethtool_features_set_req *req)
2861{
2862	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2863	struct ethtool_features_set_rsp *rsp;
2864	struct nlmsghdr *nlh;
2865	int err;
2866
2867	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEATURES_SET, 1);
2868	ys->req_policy = &ethtool_features_nest;
2869	yrs.yarg.rsp_policy = &ethtool_features_nest;
2870
2871	if (req->_present.header)
2872		ethtool_header_put(nlh, ETHTOOL_A_FEATURES_HEADER, &req->header);
2873	if (req->_present.hw)
2874		ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_HW, &req->hw);
2875	if (req->_present.wanted)
2876		ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_WANTED, &req->wanted);
2877	if (req->_present.active)
2878		ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_ACTIVE, &req->active);
2879	if (req->_present.nochange)
2880		ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_NOCHANGE, &req->nochange);
2881
2882	rsp = calloc(1, sizeof(*rsp));
2883	yrs.yarg.data = rsp;
2884	yrs.cb = ethtool_features_set_rsp_parse;
2885	yrs.rsp_cmd = ETHTOOL_MSG_FEATURES_SET;
2886
2887	err = ynl_exec(ys, nlh, &yrs);
2888	if (err < 0)
2889		goto err_free;
2890
2891	return rsp;
2892
2893err_free:
2894	ethtool_features_set_rsp_free(rsp);
2895	return NULL;
2896}
2897
2898/* ============== ETHTOOL_MSG_PRIVFLAGS_GET ============== */
2899/* ETHTOOL_MSG_PRIVFLAGS_GET - do */
2900void ethtool_privflags_get_req_free(struct ethtool_privflags_get_req *req)
2901{
2902	ethtool_header_free(&req->header);
2903	free(req);
2904}
2905
2906void ethtool_privflags_get_rsp_free(struct ethtool_privflags_get_rsp *rsp)
2907{
2908	ethtool_header_free(&rsp->header);
2909	ethtool_bitset_free(&rsp->flags);
2910	free(rsp);
2911}
2912
2913int ethtool_privflags_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
2914{
2915	struct ethtool_privflags_get_rsp *dst;
2916	struct ynl_parse_arg *yarg = data;
2917	const struct nlattr *attr;
2918	struct ynl_parse_arg parg;
2919
2920	dst = yarg->data;
2921	parg.ys = yarg->ys;
2922
2923	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
2924		unsigned int type = mnl_attr_get_type(attr);
2925
2926		if (type == ETHTOOL_A_PRIVFLAGS_HEADER) {
2927			if (ynl_attr_validate(yarg, attr))
2928				return MNL_CB_ERROR;
2929			dst->_present.header = 1;
2930
2931			parg.rsp_policy = &ethtool_header_nest;
2932			parg.data = &dst->header;
2933			if (ethtool_header_parse(&parg, attr))
2934				return MNL_CB_ERROR;
2935		} else if (type == ETHTOOL_A_PRIVFLAGS_FLAGS) {
2936			if (ynl_attr_validate(yarg, attr))
2937				return MNL_CB_ERROR;
2938			dst->_present.flags = 1;
2939
2940			parg.rsp_policy = &ethtool_bitset_nest;
2941			parg.data = &dst->flags;
2942			if (ethtool_bitset_parse(&parg, attr))
2943				return MNL_CB_ERROR;
2944		}
2945	}
2946
2947	return MNL_CB_OK;
2948}
2949
2950struct ethtool_privflags_get_rsp *
2951ethtool_privflags_get(struct ynl_sock *ys,
2952		      struct ethtool_privflags_get_req *req)
2953{
2954	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
2955	struct ethtool_privflags_get_rsp *rsp;
2956	struct nlmsghdr *nlh;
2957	int err;
2958
2959	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PRIVFLAGS_GET, 1);
2960	ys->req_policy = &ethtool_privflags_nest;
2961	yrs.yarg.rsp_policy = &ethtool_privflags_nest;
2962
2963	if (req->_present.header)
2964		ethtool_header_put(nlh, ETHTOOL_A_PRIVFLAGS_HEADER, &req->header);
2965
2966	rsp = calloc(1, sizeof(*rsp));
2967	yrs.yarg.data = rsp;
2968	yrs.cb = ethtool_privflags_get_rsp_parse;
2969	yrs.rsp_cmd = 14;
2970
2971	err = ynl_exec(ys, nlh, &yrs);
2972	if (err < 0)
2973		goto err_free;
2974
2975	return rsp;
2976
2977err_free:
2978	ethtool_privflags_get_rsp_free(rsp);
2979	return NULL;
2980}
2981
2982/* ETHTOOL_MSG_PRIVFLAGS_GET - dump */
2983void ethtool_privflags_get_list_free(struct ethtool_privflags_get_list *rsp)
2984{
2985	struct ethtool_privflags_get_list *next = rsp;
2986
2987	while ((void *)next != YNL_LIST_END) {
2988		rsp = next;
2989		next = rsp->next;
2990
2991		ethtool_header_free(&rsp->obj.header);
2992		ethtool_bitset_free(&rsp->obj.flags);
2993		free(rsp);
2994	}
2995}
2996
2997struct ethtool_privflags_get_list *
2998ethtool_privflags_get_dump(struct ynl_sock *ys,
2999			   struct ethtool_privflags_get_req_dump *req)
3000{
3001	struct ynl_dump_state yds = {};
3002	struct nlmsghdr *nlh;
3003	int err;
3004
3005	yds.ys = ys;
3006	yds.alloc_sz = sizeof(struct ethtool_privflags_get_list);
3007	yds.cb = ethtool_privflags_get_rsp_parse;
3008	yds.rsp_cmd = 14;
3009	yds.rsp_policy = &ethtool_privflags_nest;
3010
3011	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PRIVFLAGS_GET, 1);
3012	ys->req_policy = &ethtool_privflags_nest;
3013
3014	if (req->_present.header)
3015		ethtool_header_put(nlh, ETHTOOL_A_PRIVFLAGS_HEADER, &req->header);
3016
3017	err = ynl_exec_dump(ys, nlh, &yds);
3018	if (err < 0)
3019		goto free_list;
3020
3021	return yds.first;
3022
3023free_list:
3024	ethtool_privflags_get_list_free(yds.first);
3025	return NULL;
3026}
3027
3028/* ETHTOOL_MSG_PRIVFLAGS_GET - notify */
3029void ethtool_privflags_get_ntf_free(struct ethtool_privflags_get_ntf *rsp)
3030{
3031	ethtool_header_free(&rsp->obj.header);
3032	ethtool_bitset_free(&rsp->obj.flags);
3033	free(rsp);
3034}
3035
3036/* ============== ETHTOOL_MSG_PRIVFLAGS_SET ============== */
3037/* ETHTOOL_MSG_PRIVFLAGS_SET - do */
3038void ethtool_privflags_set_req_free(struct ethtool_privflags_set_req *req)
3039{
3040	ethtool_header_free(&req->header);
3041	ethtool_bitset_free(&req->flags);
3042	free(req);
3043}
3044
3045int ethtool_privflags_set(struct ynl_sock *ys,
3046			  struct ethtool_privflags_set_req *req)
3047{
3048	struct nlmsghdr *nlh;
3049	int err;
3050
3051	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PRIVFLAGS_SET, 1);
3052	ys->req_policy = &ethtool_privflags_nest;
3053
3054	if (req->_present.header)
3055		ethtool_header_put(nlh, ETHTOOL_A_PRIVFLAGS_HEADER, &req->header);
3056	if (req->_present.flags)
3057		ethtool_bitset_put(nlh, ETHTOOL_A_PRIVFLAGS_FLAGS, &req->flags);
3058
3059	err = ynl_exec(ys, nlh, NULL);
3060	if (err < 0)
3061		return -1;
3062
3063	return 0;
3064}
3065
3066/* ============== ETHTOOL_MSG_RINGS_GET ============== */
3067/* ETHTOOL_MSG_RINGS_GET - do */
3068void ethtool_rings_get_req_free(struct ethtool_rings_get_req *req)
3069{
3070	ethtool_header_free(&req->header);
3071	free(req);
3072}
3073
3074void ethtool_rings_get_rsp_free(struct ethtool_rings_get_rsp *rsp)
3075{
3076	ethtool_header_free(&rsp->header);
3077	free(rsp);
3078}
3079
3080int ethtool_rings_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
3081{
3082	struct ethtool_rings_get_rsp *dst;
3083	struct ynl_parse_arg *yarg = data;
3084	const struct nlattr *attr;
3085	struct ynl_parse_arg parg;
3086
3087	dst = yarg->data;
3088	parg.ys = yarg->ys;
3089
3090	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
3091		unsigned int type = mnl_attr_get_type(attr);
3092
3093		if (type == ETHTOOL_A_RINGS_HEADER) {
3094			if (ynl_attr_validate(yarg, attr))
3095				return MNL_CB_ERROR;
3096			dst->_present.header = 1;
3097
3098			parg.rsp_policy = &ethtool_header_nest;
3099			parg.data = &dst->header;
3100			if (ethtool_header_parse(&parg, attr))
3101				return MNL_CB_ERROR;
3102		} else if (type == ETHTOOL_A_RINGS_RX_MAX) {
3103			if (ynl_attr_validate(yarg, attr))
3104				return MNL_CB_ERROR;
3105			dst->_present.rx_max = 1;
3106			dst->rx_max = mnl_attr_get_u32(attr);
3107		} else if (type == ETHTOOL_A_RINGS_RX_MINI_MAX) {
3108			if (ynl_attr_validate(yarg, attr))
3109				return MNL_CB_ERROR;
3110			dst->_present.rx_mini_max = 1;
3111			dst->rx_mini_max = mnl_attr_get_u32(attr);
3112		} else if (type == ETHTOOL_A_RINGS_RX_JUMBO_MAX) {
3113			if (ynl_attr_validate(yarg, attr))
3114				return MNL_CB_ERROR;
3115			dst->_present.rx_jumbo_max = 1;
3116			dst->rx_jumbo_max = mnl_attr_get_u32(attr);
3117		} else if (type == ETHTOOL_A_RINGS_TX_MAX) {
3118			if (ynl_attr_validate(yarg, attr))
3119				return MNL_CB_ERROR;
3120			dst->_present.tx_max = 1;
3121			dst->tx_max = mnl_attr_get_u32(attr);
3122		} else if (type == ETHTOOL_A_RINGS_RX) {
3123			if (ynl_attr_validate(yarg, attr))
3124				return MNL_CB_ERROR;
3125			dst->_present.rx = 1;
3126			dst->rx = mnl_attr_get_u32(attr);
3127		} else if (type == ETHTOOL_A_RINGS_RX_MINI) {
3128			if (ynl_attr_validate(yarg, attr))
3129				return MNL_CB_ERROR;
3130			dst->_present.rx_mini = 1;
3131			dst->rx_mini = mnl_attr_get_u32(attr);
3132		} else if (type == ETHTOOL_A_RINGS_RX_JUMBO) {
3133			if (ynl_attr_validate(yarg, attr))
3134				return MNL_CB_ERROR;
3135			dst->_present.rx_jumbo = 1;
3136			dst->rx_jumbo = mnl_attr_get_u32(attr);
3137		} else if (type == ETHTOOL_A_RINGS_TX) {
3138			if (ynl_attr_validate(yarg, attr))
3139				return MNL_CB_ERROR;
3140			dst->_present.tx = 1;
3141			dst->tx = mnl_attr_get_u32(attr);
3142		} else if (type == ETHTOOL_A_RINGS_RX_BUF_LEN) {
3143			if (ynl_attr_validate(yarg, attr))
3144				return MNL_CB_ERROR;
3145			dst->_present.rx_buf_len = 1;
3146			dst->rx_buf_len = mnl_attr_get_u32(attr);
3147		} else if (type == ETHTOOL_A_RINGS_TCP_DATA_SPLIT) {
3148			if (ynl_attr_validate(yarg, attr))
3149				return MNL_CB_ERROR;
3150			dst->_present.tcp_data_split = 1;
3151			dst->tcp_data_split = mnl_attr_get_u8(attr);
3152		} else if (type == ETHTOOL_A_RINGS_CQE_SIZE) {
3153			if (ynl_attr_validate(yarg, attr))
3154				return MNL_CB_ERROR;
3155			dst->_present.cqe_size = 1;
3156			dst->cqe_size = mnl_attr_get_u32(attr);
3157		} else if (type == ETHTOOL_A_RINGS_TX_PUSH) {
3158			if (ynl_attr_validate(yarg, attr))
3159				return MNL_CB_ERROR;
3160			dst->_present.tx_push = 1;
3161			dst->tx_push = mnl_attr_get_u8(attr);
3162		} else if (type == ETHTOOL_A_RINGS_RX_PUSH) {
3163			if (ynl_attr_validate(yarg, attr))
3164				return MNL_CB_ERROR;
3165			dst->_present.rx_push = 1;
3166			dst->rx_push = mnl_attr_get_u8(attr);
3167		} else if (type == ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN) {
3168			if (ynl_attr_validate(yarg, attr))
3169				return MNL_CB_ERROR;
3170			dst->_present.tx_push_buf_len = 1;
3171			dst->tx_push_buf_len = mnl_attr_get_u32(attr);
3172		} else if (type == ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX) {
3173			if (ynl_attr_validate(yarg, attr))
3174				return MNL_CB_ERROR;
3175			dst->_present.tx_push_buf_len_max = 1;
3176			dst->tx_push_buf_len_max = mnl_attr_get_u32(attr);
3177		}
3178	}
3179
3180	return MNL_CB_OK;
3181}
3182
3183struct ethtool_rings_get_rsp *
3184ethtool_rings_get(struct ynl_sock *ys, struct ethtool_rings_get_req *req)
3185{
3186	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
3187	struct ethtool_rings_get_rsp *rsp;
3188	struct nlmsghdr *nlh;
3189	int err;
3190
3191	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_RINGS_GET, 1);
3192	ys->req_policy = &ethtool_rings_nest;
3193	yrs.yarg.rsp_policy = &ethtool_rings_nest;
3194
3195	if (req->_present.header)
3196		ethtool_header_put(nlh, ETHTOOL_A_RINGS_HEADER, &req->header);
3197
3198	rsp = calloc(1, sizeof(*rsp));
3199	yrs.yarg.data = rsp;
3200	yrs.cb = ethtool_rings_get_rsp_parse;
3201	yrs.rsp_cmd = 16;
3202
3203	err = ynl_exec(ys, nlh, &yrs);
3204	if (err < 0)
3205		goto err_free;
3206
3207	return rsp;
3208
3209err_free:
3210	ethtool_rings_get_rsp_free(rsp);
3211	return NULL;
3212}
3213
3214/* ETHTOOL_MSG_RINGS_GET - dump */
3215void ethtool_rings_get_list_free(struct ethtool_rings_get_list *rsp)
3216{
3217	struct ethtool_rings_get_list *next = rsp;
3218
3219	while ((void *)next != YNL_LIST_END) {
3220		rsp = next;
3221		next = rsp->next;
3222
3223		ethtool_header_free(&rsp->obj.header);
3224		free(rsp);
3225	}
3226}
3227
3228struct ethtool_rings_get_list *
3229ethtool_rings_get_dump(struct ynl_sock *ys,
3230		       struct ethtool_rings_get_req_dump *req)
3231{
3232	struct ynl_dump_state yds = {};
3233	struct nlmsghdr *nlh;
3234	int err;
3235
3236	yds.ys = ys;
3237	yds.alloc_sz = sizeof(struct ethtool_rings_get_list);
3238	yds.cb = ethtool_rings_get_rsp_parse;
3239	yds.rsp_cmd = 16;
3240	yds.rsp_policy = &ethtool_rings_nest;
3241
3242	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_RINGS_GET, 1);
3243	ys->req_policy = &ethtool_rings_nest;
3244
3245	if (req->_present.header)
3246		ethtool_header_put(nlh, ETHTOOL_A_RINGS_HEADER, &req->header);
3247
3248	err = ynl_exec_dump(ys, nlh, &yds);
3249	if (err < 0)
3250		goto free_list;
3251
3252	return yds.first;
3253
3254free_list:
3255	ethtool_rings_get_list_free(yds.first);
3256	return NULL;
3257}
3258
3259/* ETHTOOL_MSG_RINGS_GET - notify */
3260void ethtool_rings_get_ntf_free(struct ethtool_rings_get_ntf *rsp)
3261{
3262	ethtool_header_free(&rsp->obj.header);
3263	free(rsp);
3264}
3265
3266/* ============== ETHTOOL_MSG_RINGS_SET ============== */
3267/* ETHTOOL_MSG_RINGS_SET - do */
3268void ethtool_rings_set_req_free(struct ethtool_rings_set_req *req)
3269{
3270	ethtool_header_free(&req->header);
3271	free(req);
3272}
3273
3274int ethtool_rings_set(struct ynl_sock *ys, struct ethtool_rings_set_req *req)
3275{
3276	struct nlmsghdr *nlh;
3277	int err;
3278
3279	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_RINGS_SET, 1);
3280	ys->req_policy = &ethtool_rings_nest;
3281
3282	if (req->_present.header)
3283		ethtool_header_put(nlh, ETHTOOL_A_RINGS_HEADER, &req->header);
3284	if (req->_present.rx_max)
3285		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_MAX, req->rx_max);
3286	if (req->_present.rx_mini_max)
3287		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_MINI_MAX, req->rx_mini_max);
3288	if (req->_present.rx_jumbo_max)
3289		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_JUMBO_MAX, req->rx_jumbo_max);
3290	if (req->_present.tx_max)
3291		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX_MAX, req->tx_max);
3292	if (req->_present.rx)
3293		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX, req->rx);
3294	if (req->_present.rx_mini)
3295		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_MINI, req->rx_mini);
3296	if (req->_present.rx_jumbo)
3297		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_JUMBO, req->rx_jumbo);
3298	if (req->_present.tx)
3299		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX, req->tx);
3300	if (req->_present.rx_buf_len)
3301		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_BUF_LEN, req->rx_buf_len);
3302	if (req->_present.tcp_data_split)
3303		mnl_attr_put_u8(nlh, ETHTOOL_A_RINGS_TCP_DATA_SPLIT, req->tcp_data_split);
3304	if (req->_present.cqe_size)
3305		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_CQE_SIZE, req->cqe_size);
3306	if (req->_present.tx_push)
3307		mnl_attr_put_u8(nlh, ETHTOOL_A_RINGS_TX_PUSH, req->tx_push);
3308	if (req->_present.rx_push)
3309		mnl_attr_put_u8(nlh, ETHTOOL_A_RINGS_RX_PUSH, req->rx_push);
3310	if (req->_present.tx_push_buf_len)
3311		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN, req->tx_push_buf_len);
3312	if (req->_present.tx_push_buf_len_max)
3313		mnl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX, req->tx_push_buf_len_max);
3314
3315	err = ynl_exec(ys, nlh, NULL);
3316	if (err < 0)
3317		return -1;
3318
3319	return 0;
3320}
3321
3322/* ============== ETHTOOL_MSG_CHANNELS_GET ============== */
3323/* ETHTOOL_MSG_CHANNELS_GET - do */
3324void ethtool_channels_get_req_free(struct ethtool_channels_get_req *req)
3325{
3326	ethtool_header_free(&req->header);
3327	free(req);
3328}
3329
3330void ethtool_channels_get_rsp_free(struct ethtool_channels_get_rsp *rsp)
3331{
3332	ethtool_header_free(&rsp->header);
3333	free(rsp);
3334}
3335
3336int ethtool_channels_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
3337{
3338	struct ethtool_channels_get_rsp *dst;
3339	struct ynl_parse_arg *yarg = data;
3340	const struct nlattr *attr;
3341	struct ynl_parse_arg parg;
3342
3343	dst = yarg->data;
3344	parg.ys = yarg->ys;
3345
3346	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
3347		unsigned int type = mnl_attr_get_type(attr);
3348
3349		if (type == ETHTOOL_A_CHANNELS_HEADER) {
3350			if (ynl_attr_validate(yarg, attr))
3351				return MNL_CB_ERROR;
3352			dst->_present.header = 1;
3353
3354			parg.rsp_policy = &ethtool_header_nest;
3355			parg.data = &dst->header;
3356			if (ethtool_header_parse(&parg, attr))
3357				return MNL_CB_ERROR;
3358		} else if (type == ETHTOOL_A_CHANNELS_RX_MAX) {
3359			if (ynl_attr_validate(yarg, attr))
3360				return MNL_CB_ERROR;
3361			dst->_present.rx_max = 1;
3362			dst->rx_max = mnl_attr_get_u32(attr);
3363		} else if (type == ETHTOOL_A_CHANNELS_TX_MAX) {
3364			if (ynl_attr_validate(yarg, attr))
3365				return MNL_CB_ERROR;
3366			dst->_present.tx_max = 1;
3367			dst->tx_max = mnl_attr_get_u32(attr);
3368		} else if (type == ETHTOOL_A_CHANNELS_OTHER_MAX) {
3369			if (ynl_attr_validate(yarg, attr))
3370				return MNL_CB_ERROR;
3371			dst->_present.other_max = 1;
3372			dst->other_max = mnl_attr_get_u32(attr);
3373		} else if (type == ETHTOOL_A_CHANNELS_COMBINED_MAX) {
3374			if (ynl_attr_validate(yarg, attr))
3375				return MNL_CB_ERROR;
3376			dst->_present.combined_max = 1;
3377			dst->combined_max = mnl_attr_get_u32(attr);
3378		} else if (type == ETHTOOL_A_CHANNELS_RX_COUNT) {
3379			if (ynl_attr_validate(yarg, attr))
3380				return MNL_CB_ERROR;
3381			dst->_present.rx_count = 1;
3382			dst->rx_count = mnl_attr_get_u32(attr);
3383		} else if (type == ETHTOOL_A_CHANNELS_TX_COUNT) {
3384			if (ynl_attr_validate(yarg, attr))
3385				return MNL_CB_ERROR;
3386			dst->_present.tx_count = 1;
3387			dst->tx_count = mnl_attr_get_u32(attr);
3388		} else if (type == ETHTOOL_A_CHANNELS_OTHER_COUNT) {
3389			if (ynl_attr_validate(yarg, attr))
3390				return MNL_CB_ERROR;
3391			dst->_present.other_count = 1;
3392			dst->other_count = mnl_attr_get_u32(attr);
3393		} else if (type == ETHTOOL_A_CHANNELS_COMBINED_COUNT) {
3394			if (ynl_attr_validate(yarg, attr))
3395				return MNL_CB_ERROR;
3396			dst->_present.combined_count = 1;
3397			dst->combined_count = mnl_attr_get_u32(attr);
3398		}
3399	}
3400
3401	return MNL_CB_OK;
3402}
3403
3404struct ethtool_channels_get_rsp *
3405ethtool_channels_get(struct ynl_sock *ys, struct ethtool_channels_get_req *req)
3406{
3407	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
3408	struct ethtool_channels_get_rsp *rsp;
3409	struct nlmsghdr *nlh;
3410	int err;
3411
3412	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CHANNELS_GET, 1);
3413	ys->req_policy = &ethtool_channels_nest;
3414	yrs.yarg.rsp_policy = &ethtool_channels_nest;
3415
3416	if (req->_present.header)
3417		ethtool_header_put(nlh, ETHTOOL_A_CHANNELS_HEADER, &req->header);
3418
3419	rsp = calloc(1, sizeof(*rsp));
3420	yrs.yarg.data = rsp;
3421	yrs.cb = ethtool_channels_get_rsp_parse;
3422	yrs.rsp_cmd = 18;
3423
3424	err = ynl_exec(ys, nlh, &yrs);
3425	if (err < 0)
3426		goto err_free;
3427
3428	return rsp;
3429
3430err_free:
3431	ethtool_channels_get_rsp_free(rsp);
3432	return NULL;
3433}
3434
3435/* ETHTOOL_MSG_CHANNELS_GET - dump */
3436void ethtool_channels_get_list_free(struct ethtool_channels_get_list *rsp)
3437{
3438	struct ethtool_channels_get_list *next = rsp;
3439
3440	while ((void *)next != YNL_LIST_END) {
3441		rsp = next;
3442		next = rsp->next;
3443
3444		ethtool_header_free(&rsp->obj.header);
3445		free(rsp);
3446	}
3447}
3448
3449struct ethtool_channels_get_list *
3450ethtool_channels_get_dump(struct ynl_sock *ys,
3451			  struct ethtool_channels_get_req_dump *req)
3452{
3453	struct ynl_dump_state yds = {};
3454	struct nlmsghdr *nlh;
3455	int err;
3456
3457	yds.ys = ys;
3458	yds.alloc_sz = sizeof(struct ethtool_channels_get_list);
3459	yds.cb = ethtool_channels_get_rsp_parse;
3460	yds.rsp_cmd = 18;
3461	yds.rsp_policy = &ethtool_channels_nest;
3462
3463	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_CHANNELS_GET, 1);
3464	ys->req_policy = &ethtool_channels_nest;
3465
3466	if (req->_present.header)
3467		ethtool_header_put(nlh, ETHTOOL_A_CHANNELS_HEADER, &req->header);
3468
3469	err = ynl_exec_dump(ys, nlh, &yds);
3470	if (err < 0)
3471		goto free_list;
3472
3473	return yds.first;
3474
3475free_list:
3476	ethtool_channels_get_list_free(yds.first);
3477	return NULL;
3478}
3479
3480/* ETHTOOL_MSG_CHANNELS_GET - notify */
3481void ethtool_channels_get_ntf_free(struct ethtool_channels_get_ntf *rsp)
3482{
3483	ethtool_header_free(&rsp->obj.header);
3484	free(rsp);
3485}
3486
3487/* ============== ETHTOOL_MSG_CHANNELS_SET ============== */
3488/* ETHTOOL_MSG_CHANNELS_SET - do */
3489void ethtool_channels_set_req_free(struct ethtool_channels_set_req *req)
3490{
3491	ethtool_header_free(&req->header);
3492	free(req);
3493}
3494
3495int ethtool_channels_set(struct ynl_sock *ys,
3496			 struct ethtool_channels_set_req *req)
3497{
3498	struct nlmsghdr *nlh;
3499	int err;
3500
3501	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CHANNELS_SET, 1);
3502	ys->req_policy = &ethtool_channels_nest;
3503
3504	if (req->_present.header)
3505		ethtool_header_put(nlh, ETHTOOL_A_CHANNELS_HEADER, &req->header);
3506	if (req->_present.rx_max)
3507		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_RX_MAX, req->rx_max);
3508	if (req->_present.tx_max)
3509		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_TX_MAX, req->tx_max);
3510	if (req->_present.other_max)
3511		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_OTHER_MAX, req->other_max);
3512	if (req->_present.combined_max)
3513		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_COMBINED_MAX, req->combined_max);
3514	if (req->_present.rx_count)
3515		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_RX_COUNT, req->rx_count);
3516	if (req->_present.tx_count)
3517		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_TX_COUNT, req->tx_count);
3518	if (req->_present.other_count)
3519		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_OTHER_COUNT, req->other_count);
3520	if (req->_present.combined_count)
3521		mnl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_COMBINED_COUNT, req->combined_count);
3522
3523	err = ynl_exec(ys, nlh, NULL);
3524	if (err < 0)
3525		return -1;
3526
3527	return 0;
3528}
3529
3530/* ============== ETHTOOL_MSG_COALESCE_GET ============== */
3531/* ETHTOOL_MSG_COALESCE_GET - do */
3532void ethtool_coalesce_get_req_free(struct ethtool_coalesce_get_req *req)
3533{
3534	ethtool_header_free(&req->header);
3535	free(req);
3536}
3537
3538void ethtool_coalesce_get_rsp_free(struct ethtool_coalesce_get_rsp *rsp)
3539{
3540	ethtool_header_free(&rsp->header);
3541	free(rsp);
3542}
3543
3544int ethtool_coalesce_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
3545{
3546	struct ethtool_coalesce_get_rsp *dst;
3547	struct ynl_parse_arg *yarg = data;
3548	const struct nlattr *attr;
3549	struct ynl_parse_arg parg;
3550
3551	dst = yarg->data;
3552	parg.ys = yarg->ys;
3553
3554	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
3555		unsigned int type = mnl_attr_get_type(attr);
3556
3557		if (type == ETHTOOL_A_COALESCE_HEADER) {
3558			if (ynl_attr_validate(yarg, attr))
3559				return MNL_CB_ERROR;
3560			dst->_present.header = 1;
3561
3562			parg.rsp_policy = &ethtool_header_nest;
3563			parg.data = &dst->header;
3564			if (ethtool_header_parse(&parg, attr))
3565				return MNL_CB_ERROR;
3566		} else if (type == ETHTOOL_A_COALESCE_RX_USECS) {
3567			if (ynl_attr_validate(yarg, attr))
3568				return MNL_CB_ERROR;
3569			dst->_present.rx_usecs = 1;
3570			dst->rx_usecs = mnl_attr_get_u32(attr);
3571		} else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES) {
3572			if (ynl_attr_validate(yarg, attr))
3573				return MNL_CB_ERROR;
3574			dst->_present.rx_max_frames = 1;
3575			dst->rx_max_frames = mnl_attr_get_u32(attr);
3576		} else if (type == ETHTOOL_A_COALESCE_RX_USECS_IRQ) {
3577			if (ynl_attr_validate(yarg, attr))
3578				return MNL_CB_ERROR;
3579			dst->_present.rx_usecs_irq = 1;
3580			dst->rx_usecs_irq = mnl_attr_get_u32(attr);
3581		} else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ) {
3582			if (ynl_attr_validate(yarg, attr))
3583				return MNL_CB_ERROR;
3584			dst->_present.rx_max_frames_irq = 1;
3585			dst->rx_max_frames_irq = mnl_attr_get_u32(attr);
3586		} else if (type == ETHTOOL_A_COALESCE_TX_USECS) {
3587			if (ynl_attr_validate(yarg, attr))
3588				return MNL_CB_ERROR;
3589			dst->_present.tx_usecs = 1;
3590			dst->tx_usecs = mnl_attr_get_u32(attr);
3591		} else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES) {
3592			if (ynl_attr_validate(yarg, attr))
3593				return MNL_CB_ERROR;
3594			dst->_present.tx_max_frames = 1;
3595			dst->tx_max_frames = mnl_attr_get_u32(attr);
3596		} else if (type == ETHTOOL_A_COALESCE_TX_USECS_IRQ) {
3597			if (ynl_attr_validate(yarg, attr))
3598				return MNL_CB_ERROR;
3599			dst->_present.tx_usecs_irq = 1;
3600			dst->tx_usecs_irq = mnl_attr_get_u32(attr);
3601		} else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ) {
3602			if (ynl_attr_validate(yarg, attr))
3603				return MNL_CB_ERROR;
3604			dst->_present.tx_max_frames_irq = 1;
3605			dst->tx_max_frames_irq = mnl_attr_get_u32(attr);
3606		} else if (type == ETHTOOL_A_COALESCE_STATS_BLOCK_USECS) {
3607			if (ynl_attr_validate(yarg, attr))
3608				return MNL_CB_ERROR;
3609			dst->_present.stats_block_usecs = 1;
3610			dst->stats_block_usecs = mnl_attr_get_u32(attr);
3611		} else if (type == ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX) {
3612			if (ynl_attr_validate(yarg, attr))
3613				return MNL_CB_ERROR;
3614			dst->_present.use_adaptive_rx = 1;
3615			dst->use_adaptive_rx = mnl_attr_get_u8(attr);
3616		} else if (type == ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX) {
3617			if (ynl_attr_validate(yarg, attr))
3618				return MNL_CB_ERROR;
3619			dst->_present.use_adaptive_tx = 1;
3620			dst->use_adaptive_tx = mnl_attr_get_u8(attr);
3621		} else if (type == ETHTOOL_A_COALESCE_PKT_RATE_LOW) {
3622			if (ynl_attr_validate(yarg, attr))
3623				return MNL_CB_ERROR;
3624			dst->_present.pkt_rate_low = 1;
3625			dst->pkt_rate_low = mnl_attr_get_u32(attr);
3626		} else if (type == ETHTOOL_A_COALESCE_RX_USECS_LOW) {
3627			if (ynl_attr_validate(yarg, attr))
3628				return MNL_CB_ERROR;
3629			dst->_present.rx_usecs_low = 1;
3630			dst->rx_usecs_low = mnl_attr_get_u32(attr);
3631		} else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW) {
3632			if (ynl_attr_validate(yarg, attr))
3633				return MNL_CB_ERROR;
3634			dst->_present.rx_max_frames_low = 1;
3635			dst->rx_max_frames_low = mnl_attr_get_u32(attr);
3636		} else if (type == ETHTOOL_A_COALESCE_TX_USECS_LOW) {
3637			if (ynl_attr_validate(yarg, attr))
3638				return MNL_CB_ERROR;
3639			dst->_present.tx_usecs_low = 1;
3640			dst->tx_usecs_low = mnl_attr_get_u32(attr);
3641		} else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW) {
3642			if (ynl_attr_validate(yarg, attr))
3643				return MNL_CB_ERROR;
3644			dst->_present.tx_max_frames_low = 1;
3645			dst->tx_max_frames_low = mnl_attr_get_u32(attr);
3646		} else if (type == ETHTOOL_A_COALESCE_PKT_RATE_HIGH) {
3647			if (ynl_attr_validate(yarg, attr))
3648				return MNL_CB_ERROR;
3649			dst->_present.pkt_rate_high = 1;
3650			dst->pkt_rate_high = mnl_attr_get_u32(attr);
3651		} else if (type == ETHTOOL_A_COALESCE_RX_USECS_HIGH) {
3652			if (ynl_attr_validate(yarg, attr))
3653				return MNL_CB_ERROR;
3654			dst->_present.rx_usecs_high = 1;
3655			dst->rx_usecs_high = mnl_attr_get_u32(attr);
3656		} else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH) {
3657			if (ynl_attr_validate(yarg, attr))
3658				return MNL_CB_ERROR;
3659			dst->_present.rx_max_frames_high = 1;
3660			dst->rx_max_frames_high = mnl_attr_get_u32(attr);
3661		} else if (type == ETHTOOL_A_COALESCE_TX_USECS_HIGH) {
3662			if (ynl_attr_validate(yarg, attr))
3663				return MNL_CB_ERROR;
3664			dst->_present.tx_usecs_high = 1;
3665			dst->tx_usecs_high = mnl_attr_get_u32(attr);
3666		} else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH) {
3667			if (ynl_attr_validate(yarg, attr))
3668				return MNL_CB_ERROR;
3669			dst->_present.tx_max_frames_high = 1;
3670			dst->tx_max_frames_high = mnl_attr_get_u32(attr);
3671		} else if (type == ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL) {
3672			if (ynl_attr_validate(yarg, attr))
3673				return MNL_CB_ERROR;
3674			dst->_present.rate_sample_interval = 1;
3675			dst->rate_sample_interval = mnl_attr_get_u32(attr);
3676		} else if (type == ETHTOOL_A_COALESCE_USE_CQE_MODE_TX) {
3677			if (ynl_attr_validate(yarg, attr))
3678				return MNL_CB_ERROR;
3679			dst->_present.use_cqe_mode_tx = 1;
3680			dst->use_cqe_mode_tx = mnl_attr_get_u8(attr);
3681		} else if (type == ETHTOOL_A_COALESCE_USE_CQE_MODE_RX) {
3682			if (ynl_attr_validate(yarg, attr))
3683				return MNL_CB_ERROR;
3684			dst->_present.use_cqe_mode_rx = 1;
3685			dst->use_cqe_mode_rx = mnl_attr_get_u8(attr);
3686		} else if (type == ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES) {
3687			if (ynl_attr_validate(yarg, attr))
3688				return MNL_CB_ERROR;
3689			dst->_present.tx_aggr_max_bytes = 1;
3690			dst->tx_aggr_max_bytes = mnl_attr_get_u32(attr);
3691		} else if (type == ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES) {
3692			if (ynl_attr_validate(yarg, attr))
3693				return MNL_CB_ERROR;
3694			dst->_present.tx_aggr_max_frames = 1;
3695			dst->tx_aggr_max_frames = mnl_attr_get_u32(attr);
3696		} else if (type == ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS) {
3697			if (ynl_attr_validate(yarg, attr))
3698				return MNL_CB_ERROR;
3699			dst->_present.tx_aggr_time_usecs = 1;
3700			dst->tx_aggr_time_usecs = mnl_attr_get_u32(attr);
3701		}
3702	}
3703
3704	return MNL_CB_OK;
3705}
3706
3707struct ethtool_coalesce_get_rsp *
3708ethtool_coalesce_get(struct ynl_sock *ys, struct ethtool_coalesce_get_req *req)
3709{
3710	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
3711	struct ethtool_coalesce_get_rsp *rsp;
3712	struct nlmsghdr *nlh;
3713	int err;
3714
3715	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_COALESCE_GET, 1);
3716	ys->req_policy = &ethtool_coalesce_nest;
3717	yrs.yarg.rsp_policy = &ethtool_coalesce_nest;
3718
3719	if (req->_present.header)
3720		ethtool_header_put(nlh, ETHTOOL_A_COALESCE_HEADER, &req->header);
3721
3722	rsp = calloc(1, sizeof(*rsp));
3723	yrs.yarg.data = rsp;
3724	yrs.cb = ethtool_coalesce_get_rsp_parse;
3725	yrs.rsp_cmd = 20;
3726
3727	err = ynl_exec(ys, nlh, &yrs);
3728	if (err < 0)
3729		goto err_free;
3730
3731	return rsp;
3732
3733err_free:
3734	ethtool_coalesce_get_rsp_free(rsp);
3735	return NULL;
3736}
3737
3738/* ETHTOOL_MSG_COALESCE_GET - dump */
3739void ethtool_coalesce_get_list_free(struct ethtool_coalesce_get_list *rsp)
3740{
3741	struct ethtool_coalesce_get_list *next = rsp;
3742
3743	while ((void *)next != YNL_LIST_END) {
3744		rsp = next;
3745		next = rsp->next;
3746
3747		ethtool_header_free(&rsp->obj.header);
3748		free(rsp);
3749	}
3750}
3751
3752struct ethtool_coalesce_get_list *
3753ethtool_coalesce_get_dump(struct ynl_sock *ys,
3754			  struct ethtool_coalesce_get_req_dump *req)
3755{
3756	struct ynl_dump_state yds = {};
3757	struct nlmsghdr *nlh;
3758	int err;
3759
3760	yds.ys = ys;
3761	yds.alloc_sz = sizeof(struct ethtool_coalesce_get_list);
3762	yds.cb = ethtool_coalesce_get_rsp_parse;
3763	yds.rsp_cmd = 20;
3764	yds.rsp_policy = &ethtool_coalesce_nest;
3765
3766	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_COALESCE_GET, 1);
3767	ys->req_policy = &ethtool_coalesce_nest;
3768
3769	if (req->_present.header)
3770		ethtool_header_put(nlh, ETHTOOL_A_COALESCE_HEADER, &req->header);
3771
3772	err = ynl_exec_dump(ys, nlh, &yds);
3773	if (err < 0)
3774		goto free_list;
3775
3776	return yds.first;
3777
3778free_list:
3779	ethtool_coalesce_get_list_free(yds.first);
3780	return NULL;
3781}
3782
3783/* ETHTOOL_MSG_COALESCE_GET - notify */
3784void ethtool_coalesce_get_ntf_free(struct ethtool_coalesce_get_ntf *rsp)
3785{
3786	ethtool_header_free(&rsp->obj.header);
3787	free(rsp);
3788}
3789
3790/* ============== ETHTOOL_MSG_COALESCE_SET ============== */
3791/* ETHTOOL_MSG_COALESCE_SET - do */
3792void ethtool_coalesce_set_req_free(struct ethtool_coalesce_set_req *req)
3793{
3794	ethtool_header_free(&req->header);
3795	free(req);
3796}
3797
3798int ethtool_coalesce_set(struct ynl_sock *ys,
3799			 struct ethtool_coalesce_set_req *req)
3800{
3801	struct nlmsghdr *nlh;
3802	int err;
3803
3804	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_COALESCE_SET, 1);
3805	ys->req_policy = &ethtool_coalesce_nest;
3806
3807	if (req->_present.header)
3808		ethtool_header_put(nlh, ETHTOOL_A_COALESCE_HEADER, &req->header);
3809	if (req->_present.rx_usecs)
3810		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS, req->rx_usecs);
3811	if (req->_present.rx_max_frames)
3812		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES, req->rx_max_frames);
3813	if (req->_present.rx_usecs_irq)
3814		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS_IRQ, req->rx_usecs_irq);
3815	if (req->_present.rx_max_frames_irq)
3816		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, req->rx_max_frames_irq);
3817	if (req->_present.tx_usecs)
3818		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS, req->tx_usecs);
3819	if (req->_present.tx_max_frames)
3820		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES, req->tx_max_frames);
3821	if (req->_present.tx_usecs_irq)
3822		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS_IRQ, req->tx_usecs_irq);
3823	if (req->_present.tx_max_frames_irq)
3824		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, req->tx_max_frames_irq);
3825	if (req->_present.stats_block_usecs)
3826		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, req->stats_block_usecs);
3827	if (req->_present.use_adaptive_rx)
3828		mnl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, req->use_adaptive_rx);
3829	if (req->_present.use_adaptive_tx)
3830		mnl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, req->use_adaptive_tx);
3831	if (req->_present.pkt_rate_low)
3832		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_PKT_RATE_LOW, req->pkt_rate_low);
3833	if (req->_present.rx_usecs_low)
3834		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS_LOW, req->rx_usecs_low);
3835	if (req->_present.rx_max_frames_low)
3836		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, req->rx_max_frames_low);
3837	if (req->_present.tx_usecs_low)
3838		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS_LOW, req->tx_usecs_low);
3839	if (req->_present.tx_max_frames_low)
3840		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, req->tx_max_frames_low);
3841	if (req->_present.pkt_rate_high)
3842		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_PKT_RATE_HIGH, req->pkt_rate_high);
3843	if (req->_present.rx_usecs_high)
3844		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS_HIGH, req->rx_usecs_high);
3845	if (req->_present.rx_max_frames_high)
3846		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, req->rx_max_frames_high);
3847	if (req->_present.tx_usecs_high)
3848		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS_HIGH, req->tx_usecs_high);
3849	if (req->_present.tx_max_frames_high)
3850		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, req->tx_max_frames_high);
3851	if (req->_present.rate_sample_interval)
3852		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, req->rate_sample_interval);
3853	if (req->_present.use_cqe_mode_tx)
3854		mnl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_CQE_MODE_TX, req->use_cqe_mode_tx);
3855	if (req->_present.use_cqe_mode_rx)
3856		mnl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_CQE_MODE_RX, req->use_cqe_mode_rx);
3857	if (req->_present.tx_aggr_max_bytes)
3858		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES, req->tx_aggr_max_bytes);
3859	if (req->_present.tx_aggr_max_frames)
3860		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES, req->tx_aggr_max_frames);
3861	if (req->_present.tx_aggr_time_usecs)
3862		mnl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS, req->tx_aggr_time_usecs);
3863
3864	err = ynl_exec(ys, nlh, NULL);
3865	if (err < 0)
3866		return -1;
3867
3868	return 0;
3869}
3870
3871/* ============== ETHTOOL_MSG_PAUSE_GET ============== */
3872/* ETHTOOL_MSG_PAUSE_GET - do */
3873void ethtool_pause_get_req_free(struct ethtool_pause_get_req *req)
3874{
3875	ethtool_header_free(&req->header);
3876	free(req);
3877}
3878
3879void ethtool_pause_get_rsp_free(struct ethtool_pause_get_rsp *rsp)
3880{
3881	ethtool_header_free(&rsp->header);
3882	ethtool_pause_stat_free(&rsp->stats);
3883	free(rsp);
3884}
3885
3886int ethtool_pause_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
3887{
3888	struct ethtool_pause_get_rsp *dst;
3889	struct ynl_parse_arg *yarg = data;
3890	const struct nlattr *attr;
3891	struct ynl_parse_arg parg;
3892
3893	dst = yarg->data;
3894	parg.ys = yarg->ys;
3895
3896	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
3897		unsigned int type = mnl_attr_get_type(attr);
3898
3899		if (type == ETHTOOL_A_PAUSE_HEADER) {
3900			if (ynl_attr_validate(yarg, attr))
3901				return MNL_CB_ERROR;
3902			dst->_present.header = 1;
3903
3904			parg.rsp_policy = &ethtool_header_nest;
3905			parg.data = &dst->header;
3906			if (ethtool_header_parse(&parg, attr))
3907				return MNL_CB_ERROR;
3908		} else if (type == ETHTOOL_A_PAUSE_AUTONEG) {
3909			if (ynl_attr_validate(yarg, attr))
3910				return MNL_CB_ERROR;
3911			dst->_present.autoneg = 1;
3912			dst->autoneg = mnl_attr_get_u8(attr);
3913		} else if (type == ETHTOOL_A_PAUSE_RX) {
3914			if (ynl_attr_validate(yarg, attr))
3915				return MNL_CB_ERROR;
3916			dst->_present.rx = 1;
3917			dst->rx = mnl_attr_get_u8(attr);
3918		} else if (type == ETHTOOL_A_PAUSE_TX) {
3919			if (ynl_attr_validate(yarg, attr))
3920				return MNL_CB_ERROR;
3921			dst->_present.tx = 1;
3922			dst->tx = mnl_attr_get_u8(attr);
3923		} else if (type == ETHTOOL_A_PAUSE_STATS) {
3924			if (ynl_attr_validate(yarg, attr))
3925				return MNL_CB_ERROR;
3926			dst->_present.stats = 1;
3927
3928			parg.rsp_policy = &ethtool_pause_stat_nest;
3929			parg.data = &dst->stats;
3930			if (ethtool_pause_stat_parse(&parg, attr))
3931				return MNL_CB_ERROR;
3932		} else if (type == ETHTOOL_A_PAUSE_STATS_SRC) {
3933			if (ynl_attr_validate(yarg, attr))
3934				return MNL_CB_ERROR;
3935			dst->_present.stats_src = 1;
3936			dst->stats_src = mnl_attr_get_u32(attr);
3937		}
3938	}
3939
3940	return MNL_CB_OK;
3941}
3942
3943struct ethtool_pause_get_rsp *
3944ethtool_pause_get(struct ynl_sock *ys, struct ethtool_pause_get_req *req)
3945{
3946	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
3947	struct ethtool_pause_get_rsp *rsp;
3948	struct nlmsghdr *nlh;
3949	int err;
3950
3951	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PAUSE_GET, 1);
3952	ys->req_policy = &ethtool_pause_nest;
3953	yrs.yarg.rsp_policy = &ethtool_pause_nest;
3954
3955	if (req->_present.header)
3956		ethtool_header_put(nlh, ETHTOOL_A_PAUSE_HEADER, &req->header);
3957
3958	rsp = calloc(1, sizeof(*rsp));
3959	yrs.yarg.data = rsp;
3960	yrs.cb = ethtool_pause_get_rsp_parse;
3961	yrs.rsp_cmd = 22;
3962
3963	err = ynl_exec(ys, nlh, &yrs);
3964	if (err < 0)
3965		goto err_free;
3966
3967	return rsp;
3968
3969err_free:
3970	ethtool_pause_get_rsp_free(rsp);
3971	return NULL;
3972}
3973
3974/* ETHTOOL_MSG_PAUSE_GET - dump */
3975void ethtool_pause_get_list_free(struct ethtool_pause_get_list *rsp)
3976{
3977	struct ethtool_pause_get_list *next = rsp;
3978
3979	while ((void *)next != YNL_LIST_END) {
3980		rsp = next;
3981		next = rsp->next;
3982
3983		ethtool_header_free(&rsp->obj.header);
3984		ethtool_pause_stat_free(&rsp->obj.stats);
3985		free(rsp);
3986	}
3987}
3988
3989struct ethtool_pause_get_list *
3990ethtool_pause_get_dump(struct ynl_sock *ys,
3991		       struct ethtool_pause_get_req_dump *req)
3992{
3993	struct ynl_dump_state yds = {};
3994	struct nlmsghdr *nlh;
3995	int err;
3996
3997	yds.ys = ys;
3998	yds.alloc_sz = sizeof(struct ethtool_pause_get_list);
3999	yds.cb = ethtool_pause_get_rsp_parse;
4000	yds.rsp_cmd = 22;
4001	yds.rsp_policy = &ethtool_pause_nest;
4002
4003	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PAUSE_GET, 1);
4004	ys->req_policy = &ethtool_pause_nest;
4005
4006	if (req->_present.header)
4007		ethtool_header_put(nlh, ETHTOOL_A_PAUSE_HEADER, &req->header);
4008
4009	err = ynl_exec_dump(ys, nlh, &yds);
4010	if (err < 0)
4011		goto free_list;
4012
4013	return yds.first;
4014
4015free_list:
4016	ethtool_pause_get_list_free(yds.first);
4017	return NULL;
4018}
4019
4020/* ETHTOOL_MSG_PAUSE_GET - notify */
4021void ethtool_pause_get_ntf_free(struct ethtool_pause_get_ntf *rsp)
4022{
4023	ethtool_header_free(&rsp->obj.header);
4024	ethtool_pause_stat_free(&rsp->obj.stats);
4025	free(rsp);
4026}
4027
4028/* ============== ETHTOOL_MSG_PAUSE_SET ============== */
4029/* ETHTOOL_MSG_PAUSE_SET - do */
4030void ethtool_pause_set_req_free(struct ethtool_pause_set_req *req)
4031{
4032	ethtool_header_free(&req->header);
4033	ethtool_pause_stat_free(&req->stats);
4034	free(req);
4035}
4036
4037int ethtool_pause_set(struct ynl_sock *ys, struct ethtool_pause_set_req *req)
4038{
4039	struct nlmsghdr *nlh;
4040	int err;
4041
4042	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PAUSE_SET, 1);
4043	ys->req_policy = &ethtool_pause_nest;
4044
4045	if (req->_present.header)
4046		ethtool_header_put(nlh, ETHTOOL_A_PAUSE_HEADER, &req->header);
4047	if (req->_present.autoneg)
4048		mnl_attr_put_u8(nlh, ETHTOOL_A_PAUSE_AUTONEG, req->autoneg);
4049	if (req->_present.rx)
4050		mnl_attr_put_u8(nlh, ETHTOOL_A_PAUSE_RX, req->rx);
4051	if (req->_present.tx)
4052		mnl_attr_put_u8(nlh, ETHTOOL_A_PAUSE_TX, req->tx);
4053	if (req->_present.stats)
4054		ethtool_pause_stat_put(nlh, ETHTOOL_A_PAUSE_STATS, &req->stats);
4055	if (req->_present.stats_src)
4056		mnl_attr_put_u32(nlh, ETHTOOL_A_PAUSE_STATS_SRC, req->stats_src);
4057
4058	err = ynl_exec(ys, nlh, NULL);
4059	if (err < 0)
4060		return -1;
4061
4062	return 0;
4063}
4064
4065/* ============== ETHTOOL_MSG_EEE_GET ============== */
4066/* ETHTOOL_MSG_EEE_GET - do */
4067void ethtool_eee_get_req_free(struct ethtool_eee_get_req *req)
4068{
4069	ethtool_header_free(&req->header);
4070	free(req);
4071}
4072
4073void ethtool_eee_get_rsp_free(struct ethtool_eee_get_rsp *rsp)
4074{
4075	ethtool_header_free(&rsp->header);
4076	ethtool_bitset_free(&rsp->modes_ours);
4077	ethtool_bitset_free(&rsp->modes_peer);
4078	free(rsp);
4079}
4080
4081int ethtool_eee_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
4082{
4083	struct ynl_parse_arg *yarg = data;
4084	struct ethtool_eee_get_rsp *dst;
4085	const struct nlattr *attr;
4086	struct ynl_parse_arg parg;
4087
4088	dst = yarg->data;
4089	parg.ys = yarg->ys;
4090
4091	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
4092		unsigned int type = mnl_attr_get_type(attr);
4093
4094		if (type == ETHTOOL_A_EEE_HEADER) {
4095			if (ynl_attr_validate(yarg, attr))
4096				return MNL_CB_ERROR;
4097			dst->_present.header = 1;
4098
4099			parg.rsp_policy = &ethtool_header_nest;
4100			parg.data = &dst->header;
4101			if (ethtool_header_parse(&parg, attr))
4102				return MNL_CB_ERROR;
4103		} else if (type == ETHTOOL_A_EEE_MODES_OURS) {
4104			if (ynl_attr_validate(yarg, attr))
4105				return MNL_CB_ERROR;
4106			dst->_present.modes_ours = 1;
4107
4108			parg.rsp_policy = &ethtool_bitset_nest;
4109			parg.data = &dst->modes_ours;
4110			if (ethtool_bitset_parse(&parg, attr))
4111				return MNL_CB_ERROR;
4112		} else if (type == ETHTOOL_A_EEE_MODES_PEER) {
4113			if (ynl_attr_validate(yarg, attr))
4114				return MNL_CB_ERROR;
4115			dst->_present.modes_peer = 1;
4116
4117			parg.rsp_policy = &ethtool_bitset_nest;
4118			parg.data = &dst->modes_peer;
4119			if (ethtool_bitset_parse(&parg, attr))
4120				return MNL_CB_ERROR;
4121		} else if (type == ETHTOOL_A_EEE_ACTIVE) {
4122			if (ynl_attr_validate(yarg, attr))
4123				return MNL_CB_ERROR;
4124			dst->_present.active = 1;
4125			dst->active = mnl_attr_get_u8(attr);
4126		} else if (type == ETHTOOL_A_EEE_ENABLED) {
4127			if (ynl_attr_validate(yarg, attr))
4128				return MNL_CB_ERROR;
4129			dst->_present.enabled = 1;
4130			dst->enabled = mnl_attr_get_u8(attr);
4131		} else if (type == ETHTOOL_A_EEE_TX_LPI_ENABLED) {
4132			if (ynl_attr_validate(yarg, attr))
4133				return MNL_CB_ERROR;
4134			dst->_present.tx_lpi_enabled = 1;
4135			dst->tx_lpi_enabled = mnl_attr_get_u8(attr);
4136		} else if (type == ETHTOOL_A_EEE_TX_LPI_TIMER) {
4137			if (ynl_attr_validate(yarg, attr))
4138				return MNL_CB_ERROR;
4139			dst->_present.tx_lpi_timer = 1;
4140			dst->tx_lpi_timer = mnl_attr_get_u32(attr);
4141		}
4142	}
4143
4144	return MNL_CB_OK;
4145}
4146
4147struct ethtool_eee_get_rsp *
4148ethtool_eee_get(struct ynl_sock *ys, struct ethtool_eee_get_req *req)
4149{
4150	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
4151	struct ethtool_eee_get_rsp *rsp;
4152	struct nlmsghdr *nlh;
4153	int err;
4154
4155	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_EEE_GET, 1);
4156	ys->req_policy = &ethtool_eee_nest;
4157	yrs.yarg.rsp_policy = &ethtool_eee_nest;
4158
4159	if (req->_present.header)
4160		ethtool_header_put(nlh, ETHTOOL_A_EEE_HEADER, &req->header);
4161
4162	rsp = calloc(1, sizeof(*rsp));
4163	yrs.yarg.data = rsp;
4164	yrs.cb = ethtool_eee_get_rsp_parse;
4165	yrs.rsp_cmd = 24;
4166
4167	err = ynl_exec(ys, nlh, &yrs);
4168	if (err < 0)
4169		goto err_free;
4170
4171	return rsp;
4172
4173err_free:
4174	ethtool_eee_get_rsp_free(rsp);
4175	return NULL;
4176}
4177
4178/* ETHTOOL_MSG_EEE_GET - dump */
4179void ethtool_eee_get_list_free(struct ethtool_eee_get_list *rsp)
4180{
4181	struct ethtool_eee_get_list *next = rsp;
4182
4183	while ((void *)next != YNL_LIST_END) {
4184		rsp = next;
4185		next = rsp->next;
4186
4187		ethtool_header_free(&rsp->obj.header);
4188		ethtool_bitset_free(&rsp->obj.modes_ours);
4189		ethtool_bitset_free(&rsp->obj.modes_peer);
4190		free(rsp);
4191	}
4192}
4193
4194struct ethtool_eee_get_list *
4195ethtool_eee_get_dump(struct ynl_sock *ys, struct ethtool_eee_get_req_dump *req)
4196{
4197	struct ynl_dump_state yds = {};
4198	struct nlmsghdr *nlh;
4199	int err;
4200
4201	yds.ys = ys;
4202	yds.alloc_sz = sizeof(struct ethtool_eee_get_list);
4203	yds.cb = ethtool_eee_get_rsp_parse;
4204	yds.rsp_cmd = 24;
4205	yds.rsp_policy = &ethtool_eee_nest;
4206
4207	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_EEE_GET, 1);
4208	ys->req_policy = &ethtool_eee_nest;
4209
4210	if (req->_present.header)
4211		ethtool_header_put(nlh, ETHTOOL_A_EEE_HEADER, &req->header);
4212
4213	err = ynl_exec_dump(ys, nlh, &yds);
4214	if (err < 0)
4215		goto free_list;
4216
4217	return yds.first;
4218
4219free_list:
4220	ethtool_eee_get_list_free(yds.first);
4221	return NULL;
4222}
4223
4224/* ETHTOOL_MSG_EEE_GET - notify */
4225void ethtool_eee_get_ntf_free(struct ethtool_eee_get_ntf *rsp)
4226{
4227	ethtool_header_free(&rsp->obj.header);
4228	ethtool_bitset_free(&rsp->obj.modes_ours);
4229	ethtool_bitset_free(&rsp->obj.modes_peer);
4230	free(rsp);
4231}
4232
4233/* ============== ETHTOOL_MSG_EEE_SET ============== */
4234/* ETHTOOL_MSG_EEE_SET - do */
4235void ethtool_eee_set_req_free(struct ethtool_eee_set_req *req)
4236{
4237	ethtool_header_free(&req->header);
4238	ethtool_bitset_free(&req->modes_ours);
4239	ethtool_bitset_free(&req->modes_peer);
4240	free(req);
4241}
4242
4243int ethtool_eee_set(struct ynl_sock *ys, struct ethtool_eee_set_req *req)
4244{
4245	struct nlmsghdr *nlh;
4246	int err;
4247
4248	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_EEE_SET, 1);
4249	ys->req_policy = &ethtool_eee_nest;
4250
4251	if (req->_present.header)
4252		ethtool_header_put(nlh, ETHTOOL_A_EEE_HEADER, &req->header);
4253	if (req->_present.modes_ours)
4254		ethtool_bitset_put(nlh, ETHTOOL_A_EEE_MODES_OURS, &req->modes_ours);
4255	if (req->_present.modes_peer)
4256		ethtool_bitset_put(nlh, ETHTOOL_A_EEE_MODES_PEER, &req->modes_peer);
4257	if (req->_present.active)
4258		mnl_attr_put_u8(nlh, ETHTOOL_A_EEE_ACTIVE, req->active);
4259	if (req->_present.enabled)
4260		mnl_attr_put_u8(nlh, ETHTOOL_A_EEE_ENABLED, req->enabled);
4261	if (req->_present.tx_lpi_enabled)
4262		mnl_attr_put_u8(nlh, ETHTOOL_A_EEE_TX_LPI_ENABLED, req->tx_lpi_enabled);
4263	if (req->_present.tx_lpi_timer)
4264		mnl_attr_put_u32(nlh, ETHTOOL_A_EEE_TX_LPI_TIMER, req->tx_lpi_timer);
4265
4266	err = ynl_exec(ys, nlh, NULL);
4267	if (err < 0)
4268		return -1;
4269
4270	return 0;
4271}
4272
4273/* ============== ETHTOOL_MSG_TSINFO_GET ============== */
4274/* ETHTOOL_MSG_TSINFO_GET - do */
4275void ethtool_tsinfo_get_req_free(struct ethtool_tsinfo_get_req *req)
4276{
4277	ethtool_header_free(&req->header);
4278	free(req);
4279}
4280
4281void ethtool_tsinfo_get_rsp_free(struct ethtool_tsinfo_get_rsp *rsp)
4282{
4283	ethtool_header_free(&rsp->header);
4284	ethtool_bitset_free(&rsp->timestamping);
4285	ethtool_bitset_free(&rsp->tx_types);
4286	ethtool_bitset_free(&rsp->rx_filters);
4287	free(rsp);
4288}
4289
4290int ethtool_tsinfo_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
4291{
4292	struct ethtool_tsinfo_get_rsp *dst;
4293	struct ynl_parse_arg *yarg = data;
4294	const struct nlattr *attr;
4295	struct ynl_parse_arg parg;
4296
4297	dst = yarg->data;
4298	parg.ys = yarg->ys;
4299
4300	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
4301		unsigned int type = mnl_attr_get_type(attr);
4302
4303		if (type == ETHTOOL_A_TSINFO_HEADER) {
4304			if (ynl_attr_validate(yarg, attr))
4305				return MNL_CB_ERROR;
4306			dst->_present.header = 1;
4307
4308			parg.rsp_policy = &ethtool_header_nest;
4309			parg.data = &dst->header;
4310			if (ethtool_header_parse(&parg, attr))
4311				return MNL_CB_ERROR;
4312		} else if (type == ETHTOOL_A_TSINFO_TIMESTAMPING) {
4313			if (ynl_attr_validate(yarg, attr))
4314				return MNL_CB_ERROR;
4315			dst->_present.timestamping = 1;
4316
4317			parg.rsp_policy = &ethtool_bitset_nest;
4318			parg.data = &dst->timestamping;
4319			if (ethtool_bitset_parse(&parg, attr))
4320				return MNL_CB_ERROR;
4321		} else if (type == ETHTOOL_A_TSINFO_TX_TYPES) {
4322			if (ynl_attr_validate(yarg, attr))
4323				return MNL_CB_ERROR;
4324			dst->_present.tx_types = 1;
4325
4326			parg.rsp_policy = &ethtool_bitset_nest;
4327			parg.data = &dst->tx_types;
4328			if (ethtool_bitset_parse(&parg, attr))
4329				return MNL_CB_ERROR;
4330		} else if (type == ETHTOOL_A_TSINFO_RX_FILTERS) {
4331			if (ynl_attr_validate(yarg, attr))
4332				return MNL_CB_ERROR;
4333			dst->_present.rx_filters = 1;
4334
4335			parg.rsp_policy = &ethtool_bitset_nest;
4336			parg.data = &dst->rx_filters;
4337			if (ethtool_bitset_parse(&parg, attr))
4338				return MNL_CB_ERROR;
4339		} else if (type == ETHTOOL_A_TSINFO_PHC_INDEX) {
4340			if (ynl_attr_validate(yarg, attr))
4341				return MNL_CB_ERROR;
4342			dst->_present.phc_index = 1;
4343			dst->phc_index = mnl_attr_get_u32(attr);
4344		}
4345	}
4346
4347	return MNL_CB_OK;
4348}
4349
4350struct ethtool_tsinfo_get_rsp *
4351ethtool_tsinfo_get(struct ynl_sock *ys, struct ethtool_tsinfo_get_req *req)
4352{
4353	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
4354	struct ethtool_tsinfo_get_rsp *rsp;
4355	struct nlmsghdr *nlh;
4356	int err;
4357
4358	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_TSINFO_GET, 1);
4359	ys->req_policy = &ethtool_tsinfo_nest;
4360	yrs.yarg.rsp_policy = &ethtool_tsinfo_nest;
4361
4362	if (req->_present.header)
4363		ethtool_header_put(nlh, ETHTOOL_A_TSINFO_HEADER, &req->header);
4364
4365	rsp = calloc(1, sizeof(*rsp));
4366	yrs.yarg.data = rsp;
4367	yrs.cb = ethtool_tsinfo_get_rsp_parse;
4368	yrs.rsp_cmd = 26;
4369
4370	err = ynl_exec(ys, nlh, &yrs);
4371	if (err < 0)
4372		goto err_free;
4373
4374	return rsp;
4375
4376err_free:
4377	ethtool_tsinfo_get_rsp_free(rsp);
4378	return NULL;
4379}
4380
4381/* ETHTOOL_MSG_TSINFO_GET - dump */
4382void ethtool_tsinfo_get_list_free(struct ethtool_tsinfo_get_list *rsp)
4383{
4384	struct ethtool_tsinfo_get_list *next = rsp;
4385
4386	while ((void *)next != YNL_LIST_END) {
4387		rsp = next;
4388		next = rsp->next;
4389
4390		ethtool_header_free(&rsp->obj.header);
4391		ethtool_bitset_free(&rsp->obj.timestamping);
4392		ethtool_bitset_free(&rsp->obj.tx_types);
4393		ethtool_bitset_free(&rsp->obj.rx_filters);
4394		free(rsp);
4395	}
4396}
4397
4398struct ethtool_tsinfo_get_list *
4399ethtool_tsinfo_get_dump(struct ynl_sock *ys,
4400			struct ethtool_tsinfo_get_req_dump *req)
4401{
4402	struct ynl_dump_state yds = {};
4403	struct nlmsghdr *nlh;
4404	int err;
4405
4406	yds.ys = ys;
4407	yds.alloc_sz = sizeof(struct ethtool_tsinfo_get_list);
4408	yds.cb = ethtool_tsinfo_get_rsp_parse;
4409	yds.rsp_cmd = 26;
4410	yds.rsp_policy = &ethtool_tsinfo_nest;
4411
4412	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_TSINFO_GET, 1);
4413	ys->req_policy = &ethtool_tsinfo_nest;
4414
4415	if (req->_present.header)
4416		ethtool_header_put(nlh, ETHTOOL_A_TSINFO_HEADER, &req->header);
4417
4418	err = ynl_exec_dump(ys, nlh, &yds);
4419	if (err < 0)
4420		goto free_list;
4421
4422	return yds.first;
4423
4424free_list:
4425	ethtool_tsinfo_get_list_free(yds.first);
4426	return NULL;
4427}
4428
4429/* ============== ETHTOOL_MSG_CABLE_TEST_ACT ============== */
4430/* ETHTOOL_MSG_CABLE_TEST_ACT - do */
4431void ethtool_cable_test_act_req_free(struct ethtool_cable_test_act_req *req)
4432{
4433	ethtool_header_free(&req->header);
4434	free(req);
4435}
4436
4437int ethtool_cable_test_act(struct ynl_sock *ys,
4438			   struct ethtool_cable_test_act_req *req)
4439{
4440	struct nlmsghdr *nlh;
4441	int err;
4442
4443	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CABLE_TEST_ACT, 1);
4444	ys->req_policy = &ethtool_cable_test_nest;
4445
4446	if (req->_present.header)
4447		ethtool_header_put(nlh, ETHTOOL_A_CABLE_TEST_HEADER, &req->header);
4448
4449	err = ynl_exec(ys, nlh, NULL);
4450	if (err < 0)
4451		return -1;
4452
4453	return 0;
4454}
4455
4456/* ============== ETHTOOL_MSG_CABLE_TEST_TDR_ACT ============== */
4457/* ETHTOOL_MSG_CABLE_TEST_TDR_ACT - do */
4458void
4459ethtool_cable_test_tdr_act_req_free(struct ethtool_cable_test_tdr_act_req *req)
4460{
4461	ethtool_header_free(&req->header);
4462	free(req);
4463}
4464
4465int ethtool_cable_test_tdr_act(struct ynl_sock *ys,
4466			       struct ethtool_cable_test_tdr_act_req *req)
4467{
4468	struct nlmsghdr *nlh;
4469	int err;
4470
4471	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CABLE_TEST_TDR_ACT, 1);
4472	ys->req_policy = &ethtool_cable_test_tdr_nest;
4473
4474	if (req->_present.header)
4475		ethtool_header_put(nlh, ETHTOOL_A_CABLE_TEST_TDR_HEADER, &req->header);
4476
4477	err = ynl_exec(ys, nlh, NULL);
4478	if (err < 0)
4479		return -1;
4480
4481	return 0;
4482}
4483
4484/* ============== ETHTOOL_MSG_TUNNEL_INFO_GET ============== */
4485/* ETHTOOL_MSG_TUNNEL_INFO_GET - do */
4486void ethtool_tunnel_info_get_req_free(struct ethtool_tunnel_info_get_req *req)
4487{
4488	ethtool_header_free(&req->header);
4489	free(req);
4490}
4491
4492void ethtool_tunnel_info_get_rsp_free(struct ethtool_tunnel_info_get_rsp *rsp)
4493{
4494	ethtool_header_free(&rsp->header);
4495	ethtool_tunnel_udp_free(&rsp->udp_ports);
4496	free(rsp);
4497}
4498
4499int ethtool_tunnel_info_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
4500{
4501	struct ethtool_tunnel_info_get_rsp *dst;
4502	struct ynl_parse_arg *yarg = data;
4503	const struct nlattr *attr;
4504	struct ynl_parse_arg parg;
4505
4506	dst = yarg->data;
4507	parg.ys = yarg->ys;
4508
4509	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
4510		unsigned int type = mnl_attr_get_type(attr);
4511
4512		if (type == ETHTOOL_A_TUNNEL_INFO_HEADER) {
4513			if (ynl_attr_validate(yarg, attr))
4514				return MNL_CB_ERROR;
4515			dst->_present.header = 1;
4516
4517			parg.rsp_policy = &ethtool_header_nest;
4518			parg.data = &dst->header;
4519			if (ethtool_header_parse(&parg, attr))
4520				return MNL_CB_ERROR;
4521		} else if (type == ETHTOOL_A_TUNNEL_INFO_UDP_PORTS) {
4522			if (ynl_attr_validate(yarg, attr))
4523				return MNL_CB_ERROR;
4524			dst->_present.udp_ports = 1;
4525
4526			parg.rsp_policy = &ethtool_tunnel_udp_nest;
4527			parg.data = &dst->udp_ports;
4528			if (ethtool_tunnel_udp_parse(&parg, attr))
4529				return MNL_CB_ERROR;
4530		}
4531	}
4532
4533	return MNL_CB_OK;
4534}
4535
4536struct ethtool_tunnel_info_get_rsp *
4537ethtool_tunnel_info_get(struct ynl_sock *ys,
4538			struct ethtool_tunnel_info_get_req *req)
4539{
4540	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
4541	struct ethtool_tunnel_info_get_rsp *rsp;
4542	struct nlmsghdr *nlh;
4543	int err;
4544
4545	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_TUNNEL_INFO_GET, 1);
4546	ys->req_policy = &ethtool_tunnel_info_nest;
4547	yrs.yarg.rsp_policy = &ethtool_tunnel_info_nest;
4548
4549	if (req->_present.header)
4550		ethtool_header_put(nlh, ETHTOOL_A_TUNNEL_INFO_HEADER, &req->header);
4551
4552	rsp = calloc(1, sizeof(*rsp));
4553	yrs.yarg.data = rsp;
4554	yrs.cb = ethtool_tunnel_info_get_rsp_parse;
4555	yrs.rsp_cmd = 29;
4556
4557	err = ynl_exec(ys, nlh, &yrs);
4558	if (err < 0)
4559		goto err_free;
4560
4561	return rsp;
4562
4563err_free:
4564	ethtool_tunnel_info_get_rsp_free(rsp);
4565	return NULL;
4566}
4567
4568/* ETHTOOL_MSG_TUNNEL_INFO_GET - dump */
4569void
4570ethtool_tunnel_info_get_list_free(struct ethtool_tunnel_info_get_list *rsp)
4571{
4572	struct ethtool_tunnel_info_get_list *next = rsp;
4573
4574	while ((void *)next != YNL_LIST_END) {
4575		rsp = next;
4576		next = rsp->next;
4577
4578		ethtool_header_free(&rsp->obj.header);
4579		ethtool_tunnel_udp_free(&rsp->obj.udp_ports);
4580		free(rsp);
4581	}
4582}
4583
4584struct ethtool_tunnel_info_get_list *
4585ethtool_tunnel_info_get_dump(struct ynl_sock *ys,
4586			     struct ethtool_tunnel_info_get_req_dump *req)
4587{
4588	struct ynl_dump_state yds = {};
4589	struct nlmsghdr *nlh;
4590	int err;
4591
4592	yds.ys = ys;
4593	yds.alloc_sz = sizeof(struct ethtool_tunnel_info_get_list);
4594	yds.cb = ethtool_tunnel_info_get_rsp_parse;
4595	yds.rsp_cmd = 29;
4596	yds.rsp_policy = &ethtool_tunnel_info_nest;
4597
4598	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_TUNNEL_INFO_GET, 1);
4599	ys->req_policy = &ethtool_tunnel_info_nest;
4600
4601	if (req->_present.header)
4602		ethtool_header_put(nlh, ETHTOOL_A_TUNNEL_INFO_HEADER, &req->header);
4603
4604	err = ynl_exec_dump(ys, nlh, &yds);
4605	if (err < 0)
4606		goto free_list;
4607
4608	return yds.first;
4609
4610free_list:
4611	ethtool_tunnel_info_get_list_free(yds.first);
4612	return NULL;
4613}
4614
4615/* ============== ETHTOOL_MSG_FEC_GET ============== */
4616/* ETHTOOL_MSG_FEC_GET - do */
4617void ethtool_fec_get_req_free(struct ethtool_fec_get_req *req)
4618{
4619	ethtool_header_free(&req->header);
4620	free(req);
4621}
4622
4623void ethtool_fec_get_rsp_free(struct ethtool_fec_get_rsp *rsp)
4624{
4625	ethtool_header_free(&rsp->header);
4626	ethtool_bitset_free(&rsp->modes);
4627	ethtool_fec_stat_free(&rsp->stats);
4628	free(rsp);
4629}
4630
4631int ethtool_fec_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
4632{
4633	struct ynl_parse_arg *yarg = data;
4634	struct ethtool_fec_get_rsp *dst;
4635	const struct nlattr *attr;
4636	struct ynl_parse_arg parg;
4637
4638	dst = yarg->data;
4639	parg.ys = yarg->ys;
4640
4641	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
4642		unsigned int type = mnl_attr_get_type(attr);
4643
4644		if (type == ETHTOOL_A_FEC_HEADER) {
4645			if (ynl_attr_validate(yarg, attr))
4646				return MNL_CB_ERROR;
4647			dst->_present.header = 1;
4648
4649			parg.rsp_policy = &ethtool_header_nest;
4650			parg.data = &dst->header;
4651			if (ethtool_header_parse(&parg, attr))
4652				return MNL_CB_ERROR;
4653		} else if (type == ETHTOOL_A_FEC_MODES) {
4654			if (ynl_attr_validate(yarg, attr))
4655				return MNL_CB_ERROR;
4656			dst->_present.modes = 1;
4657
4658			parg.rsp_policy = &ethtool_bitset_nest;
4659			parg.data = &dst->modes;
4660			if (ethtool_bitset_parse(&parg, attr))
4661				return MNL_CB_ERROR;
4662		} else if (type == ETHTOOL_A_FEC_AUTO) {
4663			if (ynl_attr_validate(yarg, attr))
4664				return MNL_CB_ERROR;
4665			dst->_present.auto_ = 1;
4666			dst->auto_ = mnl_attr_get_u8(attr);
4667		} else if (type == ETHTOOL_A_FEC_ACTIVE) {
4668			if (ynl_attr_validate(yarg, attr))
4669				return MNL_CB_ERROR;
4670			dst->_present.active = 1;
4671			dst->active = mnl_attr_get_u32(attr);
4672		} else if (type == ETHTOOL_A_FEC_STATS) {
4673			if (ynl_attr_validate(yarg, attr))
4674				return MNL_CB_ERROR;
4675			dst->_present.stats = 1;
4676
4677			parg.rsp_policy = &ethtool_fec_stat_nest;
4678			parg.data = &dst->stats;
4679			if (ethtool_fec_stat_parse(&parg, attr))
4680				return MNL_CB_ERROR;
4681		}
4682	}
4683
4684	return MNL_CB_OK;
4685}
4686
4687struct ethtool_fec_get_rsp *
4688ethtool_fec_get(struct ynl_sock *ys, struct ethtool_fec_get_req *req)
4689{
4690	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
4691	struct ethtool_fec_get_rsp *rsp;
4692	struct nlmsghdr *nlh;
4693	int err;
4694
4695	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEC_GET, 1);
4696	ys->req_policy = &ethtool_fec_nest;
4697	yrs.yarg.rsp_policy = &ethtool_fec_nest;
4698
4699	if (req->_present.header)
4700		ethtool_header_put(nlh, ETHTOOL_A_FEC_HEADER, &req->header);
4701
4702	rsp = calloc(1, sizeof(*rsp));
4703	yrs.yarg.data = rsp;
4704	yrs.cb = ethtool_fec_get_rsp_parse;
4705	yrs.rsp_cmd = 30;
4706
4707	err = ynl_exec(ys, nlh, &yrs);
4708	if (err < 0)
4709		goto err_free;
4710
4711	return rsp;
4712
4713err_free:
4714	ethtool_fec_get_rsp_free(rsp);
4715	return NULL;
4716}
4717
4718/* ETHTOOL_MSG_FEC_GET - dump */
4719void ethtool_fec_get_list_free(struct ethtool_fec_get_list *rsp)
4720{
4721	struct ethtool_fec_get_list *next = rsp;
4722
4723	while ((void *)next != YNL_LIST_END) {
4724		rsp = next;
4725		next = rsp->next;
4726
4727		ethtool_header_free(&rsp->obj.header);
4728		ethtool_bitset_free(&rsp->obj.modes);
4729		ethtool_fec_stat_free(&rsp->obj.stats);
4730		free(rsp);
4731	}
4732}
4733
4734struct ethtool_fec_get_list *
4735ethtool_fec_get_dump(struct ynl_sock *ys, struct ethtool_fec_get_req_dump *req)
4736{
4737	struct ynl_dump_state yds = {};
4738	struct nlmsghdr *nlh;
4739	int err;
4740
4741	yds.ys = ys;
4742	yds.alloc_sz = sizeof(struct ethtool_fec_get_list);
4743	yds.cb = ethtool_fec_get_rsp_parse;
4744	yds.rsp_cmd = 30;
4745	yds.rsp_policy = &ethtool_fec_nest;
4746
4747	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_FEC_GET, 1);
4748	ys->req_policy = &ethtool_fec_nest;
4749
4750	if (req->_present.header)
4751		ethtool_header_put(nlh, ETHTOOL_A_FEC_HEADER, &req->header);
4752
4753	err = ynl_exec_dump(ys, nlh, &yds);
4754	if (err < 0)
4755		goto free_list;
4756
4757	return yds.first;
4758
4759free_list:
4760	ethtool_fec_get_list_free(yds.first);
4761	return NULL;
4762}
4763
4764/* ETHTOOL_MSG_FEC_GET - notify */
4765void ethtool_fec_get_ntf_free(struct ethtool_fec_get_ntf *rsp)
4766{
4767	ethtool_header_free(&rsp->obj.header);
4768	ethtool_bitset_free(&rsp->obj.modes);
4769	ethtool_fec_stat_free(&rsp->obj.stats);
4770	free(rsp);
4771}
4772
4773/* ============== ETHTOOL_MSG_FEC_SET ============== */
4774/* ETHTOOL_MSG_FEC_SET - do */
4775void ethtool_fec_set_req_free(struct ethtool_fec_set_req *req)
4776{
4777	ethtool_header_free(&req->header);
4778	ethtool_bitset_free(&req->modes);
4779	ethtool_fec_stat_free(&req->stats);
4780	free(req);
4781}
4782
4783int ethtool_fec_set(struct ynl_sock *ys, struct ethtool_fec_set_req *req)
4784{
4785	struct nlmsghdr *nlh;
4786	int err;
4787
4788	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEC_SET, 1);
4789	ys->req_policy = &ethtool_fec_nest;
4790
4791	if (req->_present.header)
4792		ethtool_header_put(nlh, ETHTOOL_A_FEC_HEADER, &req->header);
4793	if (req->_present.modes)
4794		ethtool_bitset_put(nlh, ETHTOOL_A_FEC_MODES, &req->modes);
4795	if (req->_present.auto_)
4796		mnl_attr_put_u8(nlh, ETHTOOL_A_FEC_AUTO, req->auto_);
4797	if (req->_present.active)
4798		mnl_attr_put_u32(nlh, ETHTOOL_A_FEC_ACTIVE, req->active);
4799	if (req->_present.stats)
4800		ethtool_fec_stat_put(nlh, ETHTOOL_A_FEC_STATS, &req->stats);
4801
4802	err = ynl_exec(ys, nlh, NULL);
4803	if (err < 0)
4804		return -1;
4805
4806	return 0;
4807}
4808
4809/* ============== ETHTOOL_MSG_MODULE_EEPROM_GET ============== */
4810/* ETHTOOL_MSG_MODULE_EEPROM_GET - do */
4811void
4812ethtool_module_eeprom_get_req_free(struct ethtool_module_eeprom_get_req *req)
4813{
4814	ethtool_header_free(&req->header);
4815	free(req);
4816}
4817
4818void
4819ethtool_module_eeprom_get_rsp_free(struct ethtool_module_eeprom_get_rsp *rsp)
4820{
4821	ethtool_header_free(&rsp->header);
4822	free(rsp->data);
4823	free(rsp);
4824}
4825
4826int ethtool_module_eeprom_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
4827{
4828	struct ethtool_module_eeprom_get_rsp *dst;
4829	struct ynl_parse_arg *yarg = data;
4830	const struct nlattr *attr;
4831	struct ynl_parse_arg parg;
4832
4833	dst = yarg->data;
4834	parg.ys = yarg->ys;
4835
4836	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
4837		unsigned int type = mnl_attr_get_type(attr);
4838
4839		if (type == ETHTOOL_A_MODULE_EEPROM_HEADER) {
4840			if (ynl_attr_validate(yarg, attr))
4841				return MNL_CB_ERROR;
4842			dst->_present.header = 1;
4843
4844			parg.rsp_policy = &ethtool_header_nest;
4845			parg.data = &dst->header;
4846			if (ethtool_header_parse(&parg, attr))
4847				return MNL_CB_ERROR;
4848		} else if (type == ETHTOOL_A_MODULE_EEPROM_OFFSET) {
4849			if (ynl_attr_validate(yarg, attr))
4850				return MNL_CB_ERROR;
4851			dst->_present.offset = 1;
4852			dst->offset = mnl_attr_get_u32(attr);
4853		} else if (type == ETHTOOL_A_MODULE_EEPROM_LENGTH) {
4854			if (ynl_attr_validate(yarg, attr))
4855				return MNL_CB_ERROR;
4856			dst->_present.length = 1;
4857			dst->length = mnl_attr_get_u32(attr);
4858		} else if (type == ETHTOOL_A_MODULE_EEPROM_PAGE) {
4859			if (ynl_attr_validate(yarg, attr))
4860				return MNL_CB_ERROR;
4861			dst->_present.page = 1;
4862			dst->page = mnl_attr_get_u8(attr);
4863		} else if (type == ETHTOOL_A_MODULE_EEPROM_BANK) {
4864			if (ynl_attr_validate(yarg, attr))
4865				return MNL_CB_ERROR;
4866			dst->_present.bank = 1;
4867			dst->bank = mnl_attr_get_u8(attr);
4868		} else if (type == ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS) {
4869			if (ynl_attr_validate(yarg, attr))
4870				return MNL_CB_ERROR;
4871			dst->_present.i2c_address = 1;
4872			dst->i2c_address = mnl_attr_get_u8(attr);
4873		} else if (type == ETHTOOL_A_MODULE_EEPROM_DATA) {
4874			unsigned int len;
4875
4876			if (ynl_attr_validate(yarg, attr))
4877				return MNL_CB_ERROR;
4878
4879			len = mnl_attr_get_payload_len(attr);
4880			dst->_present.data_len = len;
4881			dst->data = malloc(len);
4882			memcpy(dst->data, mnl_attr_get_payload(attr), len);
4883		}
4884	}
4885
4886	return MNL_CB_OK;
4887}
4888
4889struct ethtool_module_eeprom_get_rsp *
4890ethtool_module_eeprom_get(struct ynl_sock *ys,
4891			  struct ethtool_module_eeprom_get_req *req)
4892{
4893	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
4894	struct ethtool_module_eeprom_get_rsp *rsp;
4895	struct nlmsghdr *nlh;
4896	int err;
4897
4898	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MODULE_EEPROM_GET, 1);
4899	ys->req_policy = &ethtool_module_eeprom_nest;
4900	yrs.yarg.rsp_policy = &ethtool_module_eeprom_nest;
4901
4902	if (req->_present.header)
4903		ethtool_header_put(nlh, ETHTOOL_A_MODULE_EEPROM_HEADER, &req->header);
4904
4905	rsp = calloc(1, sizeof(*rsp));
4906	yrs.yarg.data = rsp;
4907	yrs.cb = ethtool_module_eeprom_get_rsp_parse;
4908	yrs.rsp_cmd = 32;
4909
4910	err = ynl_exec(ys, nlh, &yrs);
4911	if (err < 0)
4912		goto err_free;
4913
4914	return rsp;
4915
4916err_free:
4917	ethtool_module_eeprom_get_rsp_free(rsp);
4918	return NULL;
4919}
4920
4921/* ETHTOOL_MSG_MODULE_EEPROM_GET - dump */
4922void
4923ethtool_module_eeprom_get_list_free(struct ethtool_module_eeprom_get_list *rsp)
4924{
4925	struct ethtool_module_eeprom_get_list *next = rsp;
4926
4927	while ((void *)next != YNL_LIST_END) {
4928		rsp = next;
4929		next = rsp->next;
4930
4931		ethtool_header_free(&rsp->obj.header);
4932		free(rsp->obj.data);
4933		free(rsp);
4934	}
4935}
4936
4937struct ethtool_module_eeprom_get_list *
4938ethtool_module_eeprom_get_dump(struct ynl_sock *ys,
4939			       struct ethtool_module_eeprom_get_req_dump *req)
4940{
4941	struct ynl_dump_state yds = {};
4942	struct nlmsghdr *nlh;
4943	int err;
4944
4945	yds.ys = ys;
4946	yds.alloc_sz = sizeof(struct ethtool_module_eeprom_get_list);
4947	yds.cb = ethtool_module_eeprom_get_rsp_parse;
4948	yds.rsp_cmd = 32;
4949	yds.rsp_policy = &ethtool_module_eeprom_nest;
4950
4951	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_MODULE_EEPROM_GET, 1);
4952	ys->req_policy = &ethtool_module_eeprom_nest;
4953
4954	if (req->_present.header)
4955		ethtool_header_put(nlh, ETHTOOL_A_MODULE_EEPROM_HEADER, &req->header);
4956
4957	err = ynl_exec_dump(ys, nlh, &yds);
4958	if (err < 0)
4959		goto free_list;
4960
4961	return yds.first;
4962
4963free_list:
4964	ethtool_module_eeprom_get_list_free(yds.first);
4965	return NULL;
4966}
4967
4968/* ============== ETHTOOL_MSG_PHC_VCLOCKS_GET ============== */
4969/* ETHTOOL_MSG_PHC_VCLOCKS_GET - do */
4970void ethtool_phc_vclocks_get_req_free(struct ethtool_phc_vclocks_get_req *req)
4971{
4972	ethtool_header_free(&req->header);
4973	free(req);
4974}
4975
4976void ethtool_phc_vclocks_get_rsp_free(struct ethtool_phc_vclocks_get_rsp *rsp)
4977{
4978	ethtool_header_free(&rsp->header);
4979	free(rsp);
4980}
4981
4982int ethtool_phc_vclocks_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
4983{
4984	struct ethtool_phc_vclocks_get_rsp *dst;
4985	struct ynl_parse_arg *yarg = data;
4986	const struct nlattr *attr;
4987	struct ynl_parse_arg parg;
4988
4989	dst = yarg->data;
4990	parg.ys = yarg->ys;
4991
4992	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
4993		unsigned int type = mnl_attr_get_type(attr);
4994
4995		if (type == ETHTOOL_A_PHC_VCLOCKS_HEADER) {
4996			if (ynl_attr_validate(yarg, attr))
4997				return MNL_CB_ERROR;
4998			dst->_present.header = 1;
4999
5000			parg.rsp_policy = &ethtool_header_nest;
5001			parg.data = &dst->header;
5002			if (ethtool_header_parse(&parg, attr))
5003				return MNL_CB_ERROR;
5004		} else if (type == ETHTOOL_A_PHC_VCLOCKS_NUM) {
5005			if (ynl_attr_validate(yarg, attr))
5006				return MNL_CB_ERROR;
5007			dst->_present.num = 1;
5008			dst->num = mnl_attr_get_u32(attr);
5009		}
5010	}
5011
5012	return MNL_CB_OK;
5013}
5014
5015struct ethtool_phc_vclocks_get_rsp *
5016ethtool_phc_vclocks_get(struct ynl_sock *ys,
5017			struct ethtool_phc_vclocks_get_req *req)
5018{
5019	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
5020	struct ethtool_phc_vclocks_get_rsp *rsp;
5021	struct nlmsghdr *nlh;
5022	int err;
5023
5024	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PHC_VCLOCKS_GET, 1);
5025	ys->req_policy = &ethtool_phc_vclocks_nest;
5026	yrs.yarg.rsp_policy = &ethtool_phc_vclocks_nest;
5027
5028	if (req->_present.header)
5029		ethtool_header_put(nlh, ETHTOOL_A_PHC_VCLOCKS_HEADER, &req->header);
5030
5031	rsp = calloc(1, sizeof(*rsp));
5032	yrs.yarg.data = rsp;
5033	yrs.cb = ethtool_phc_vclocks_get_rsp_parse;
5034	yrs.rsp_cmd = 34;
5035
5036	err = ynl_exec(ys, nlh, &yrs);
5037	if (err < 0)
5038		goto err_free;
5039
5040	return rsp;
5041
5042err_free:
5043	ethtool_phc_vclocks_get_rsp_free(rsp);
5044	return NULL;
5045}
5046
5047/* ETHTOOL_MSG_PHC_VCLOCKS_GET - dump */
5048void
5049ethtool_phc_vclocks_get_list_free(struct ethtool_phc_vclocks_get_list *rsp)
5050{
5051	struct ethtool_phc_vclocks_get_list *next = rsp;
5052
5053	while ((void *)next != YNL_LIST_END) {
5054		rsp = next;
5055		next = rsp->next;
5056
5057		ethtool_header_free(&rsp->obj.header);
5058		free(rsp);
5059	}
5060}
5061
5062struct ethtool_phc_vclocks_get_list *
5063ethtool_phc_vclocks_get_dump(struct ynl_sock *ys,
5064			     struct ethtool_phc_vclocks_get_req_dump *req)
5065{
5066	struct ynl_dump_state yds = {};
5067	struct nlmsghdr *nlh;
5068	int err;
5069
5070	yds.ys = ys;
5071	yds.alloc_sz = sizeof(struct ethtool_phc_vclocks_get_list);
5072	yds.cb = ethtool_phc_vclocks_get_rsp_parse;
5073	yds.rsp_cmd = 34;
5074	yds.rsp_policy = &ethtool_phc_vclocks_nest;
5075
5076	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PHC_VCLOCKS_GET, 1);
5077	ys->req_policy = &ethtool_phc_vclocks_nest;
5078
5079	if (req->_present.header)
5080		ethtool_header_put(nlh, ETHTOOL_A_PHC_VCLOCKS_HEADER, &req->header);
5081
5082	err = ynl_exec_dump(ys, nlh, &yds);
5083	if (err < 0)
5084		goto free_list;
5085
5086	return yds.first;
5087
5088free_list:
5089	ethtool_phc_vclocks_get_list_free(yds.first);
5090	return NULL;
5091}
5092
5093/* ============== ETHTOOL_MSG_MODULE_GET ============== */
5094/* ETHTOOL_MSG_MODULE_GET - do */
5095void ethtool_module_get_req_free(struct ethtool_module_get_req *req)
5096{
5097	ethtool_header_free(&req->header);
5098	free(req);
5099}
5100
5101void ethtool_module_get_rsp_free(struct ethtool_module_get_rsp *rsp)
5102{
5103	ethtool_header_free(&rsp->header);
5104	free(rsp);
5105}
5106
5107int ethtool_module_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
5108{
5109	struct ethtool_module_get_rsp *dst;
5110	struct ynl_parse_arg *yarg = data;
5111	const struct nlattr *attr;
5112	struct ynl_parse_arg parg;
5113
5114	dst = yarg->data;
5115	parg.ys = yarg->ys;
5116
5117	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
5118		unsigned int type = mnl_attr_get_type(attr);
5119
5120		if (type == ETHTOOL_A_MODULE_HEADER) {
5121			if (ynl_attr_validate(yarg, attr))
5122				return MNL_CB_ERROR;
5123			dst->_present.header = 1;
5124
5125			parg.rsp_policy = &ethtool_header_nest;
5126			parg.data = &dst->header;
5127			if (ethtool_header_parse(&parg, attr))
5128				return MNL_CB_ERROR;
5129		} else if (type == ETHTOOL_A_MODULE_POWER_MODE_POLICY) {
5130			if (ynl_attr_validate(yarg, attr))
5131				return MNL_CB_ERROR;
5132			dst->_present.power_mode_policy = 1;
5133			dst->power_mode_policy = mnl_attr_get_u8(attr);
5134		} else if (type == ETHTOOL_A_MODULE_POWER_MODE) {
5135			if (ynl_attr_validate(yarg, attr))
5136				return MNL_CB_ERROR;
5137			dst->_present.power_mode = 1;
5138			dst->power_mode = mnl_attr_get_u8(attr);
5139		}
5140	}
5141
5142	return MNL_CB_OK;
5143}
5144
5145struct ethtool_module_get_rsp *
5146ethtool_module_get(struct ynl_sock *ys, struct ethtool_module_get_req *req)
5147{
5148	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
5149	struct ethtool_module_get_rsp *rsp;
5150	struct nlmsghdr *nlh;
5151	int err;
5152
5153	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MODULE_GET, 1);
5154	ys->req_policy = &ethtool_module_nest;
5155	yrs.yarg.rsp_policy = &ethtool_module_nest;
5156
5157	if (req->_present.header)
5158		ethtool_header_put(nlh, ETHTOOL_A_MODULE_HEADER, &req->header);
5159
5160	rsp = calloc(1, sizeof(*rsp));
5161	yrs.yarg.data = rsp;
5162	yrs.cb = ethtool_module_get_rsp_parse;
5163	yrs.rsp_cmd = 35;
5164
5165	err = ynl_exec(ys, nlh, &yrs);
5166	if (err < 0)
5167		goto err_free;
5168
5169	return rsp;
5170
5171err_free:
5172	ethtool_module_get_rsp_free(rsp);
5173	return NULL;
5174}
5175
5176/* ETHTOOL_MSG_MODULE_GET - dump */
5177void ethtool_module_get_list_free(struct ethtool_module_get_list *rsp)
5178{
5179	struct ethtool_module_get_list *next = rsp;
5180
5181	while ((void *)next != YNL_LIST_END) {
5182		rsp = next;
5183		next = rsp->next;
5184
5185		ethtool_header_free(&rsp->obj.header);
5186		free(rsp);
5187	}
5188}
5189
5190struct ethtool_module_get_list *
5191ethtool_module_get_dump(struct ynl_sock *ys,
5192			struct ethtool_module_get_req_dump *req)
5193{
5194	struct ynl_dump_state yds = {};
5195	struct nlmsghdr *nlh;
5196	int err;
5197
5198	yds.ys = ys;
5199	yds.alloc_sz = sizeof(struct ethtool_module_get_list);
5200	yds.cb = ethtool_module_get_rsp_parse;
5201	yds.rsp_cmd = 35;
5202	yds.rsp_policy = &ethtool_module_nest;
5203
5204	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_MODULE_GET, 1);
5205	ys->req_policy = &ethtool_module_nest;
5206
5207	if (req->_present.header)
5208		ethtool_header_put(nlh, ETHTOOL_A_MODULE_HEADER, &req->header);
5209
5210	err = ynl_exec_dump(ys, nlh, &yds);
5211	if (err < 0)
5212		goto free_list;
5213
5214	return yds.first;
5215
5216free_list:
5217	ethtool_module_get_list_free(yds.first);
5218	return NULL;
5219}
5220
5221/* ETHTOOL_MSG_MODULE_GET - notify */
5222void ethtool_module_get_ntf_free(struct ethtool_module_get_ntf *rsp)
5223{
5224	ethtool_header_free(&rsp->obj.header);
5225	free(rsp);
5226}
5227
5228/* ============== ETHTOOL_MSG_MODULE_SET ============== */
5229/* ETHTOOL_MSG_MODULE_SET - do */
5230void ethtool_module_set_req_free(struct ethtool_module_set_req *req)
5231{
5232	ethtool_header_free(&req->header);
5233	free(req);
5234}
5235
5236int ethtool_module_set(struct ynl_sock *ys, struct ethtool_module_set_req *req)
5237{
5238	struct nlmsghdr *nlh;
5239	int err;
5240
5241	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MODULE_SET, 1);
5242	ys->req_policy = &ethtool_module_nest;
5243
5244	if (req->_present.header)
5245		ethtool_header_put(nlh, ETHTOOL_A_MODULE_HEADER, &req->header);
5246	if (req->_present.power_mode_policy)
5247		mnl_attr_put_u8(nlh, ETHTOOL_A_MODULE_POWER_MODE_POLICY, req->power_mode_policy);
5248	if (req->_present.power_mode)
5249		mnl_attr_put_u8(nlh, ETHTOOL_A_MODULE_POWER_MODE, req->power_mode);
5250
5251	err = ynl_exec(ys, nlh, NULL);
5252	if (err < 0)
5253		return -1;
5254
5255	return 0;
5256}
5257
5258/* ============== ETHTOOL_MSG_PSE_GET ============== */
5259/* ETHTOOL_MSG_PSE_GET - do */
5260void ethtool_pse_get_req_free(struct ethtool_pse_get_req *req)
5261{
5262	ethtool_header_free(&req->header);
5263	free(req);
5264}
5265
5266void ethtool_pse_get_rsp_free(struct ethtool_pse_get_rsp *rsp)
5267{
5268	ethtool_header_free(&rsp->header);
5269	free(rsp);
5270}
5271
5272int ethtool_pse_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
5273{
5274	struct ynl_parse_arg *yarg = data;
5275	struct ethtool_pse_get_rsp *dst;
5276	const struct nlattr *attr;
5277	struct ynl_parse_arg parg;
5278
5279	dst = yarg->data;
5280	parg.ys = yarg->ys;
5281
5282	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
5283		unsigned int type = mnl_attr_get_type(attr);
5284
5285		if (type == ETHTOOL_A_PSE_HEADER) {
5286			if (ynl_attr_validate(yarg, attr))
5287				return MNL_CB_ERROR;
5288			dst->_present.header = 1;
5289
5290			parg.rsp_policy = &ethtool_header_nest;
5291			parg.data = &dst->header;
5292			if (ethtool_header_parse(&parg, attr))
5293				return MNL_CB_ERROR;
5294		} else if (type == ETHTOOL_A_PODL_PSE_ADMIN_STATE) {
5295			if (ynl_attr_validate(yarg, attr))
5296				return MNL_CB_ERROR;
5297			dst->_present.admin_state = 1;
5298			dst->admin_state = mnl_attr_get_u32(attr);
5299		} else if (type == ETHTOOL_A_PODL_PSE_ADMIN_CONTROL) {
5300			if (ynl_attr_validate(yarg, attr))
5301				return MNL_CB_ERROR;
5302			dst->_present.admin_control = 1;
5303			dst->admin_control = mnl_attr_get_u32(attr);
5304		} else if (type == ETHTOOL_A_PODL_PSE_PW_D_STATUS) {
5305			if (ynl_attr_validate(yarg, attr))
5306				return MNL_CB_ERROR;
5307			dst->_present.pw_d_status = 1;
5308			dst->pw_d_status = mnl_attr_get_u32(attr);
5309		}
5310	}
5311
5312	return MNL_CB_OK;
5313}
5314
5315struct ethtool_pse_get_rsp *
5316ethtool_pse_get(struct ynl_sock *ys, struct ethtool_pse_get_req *req)
5317{
5318	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
5319	struct ethtool_pse_get_rsp *rsp;
5320	struct nlmsghdr *nlh;
5321	int err;
5322
5323	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PSE_GET, 1);
5324	ys->req_policy = &ethtool_pse_nest;
5325	yrs.yarg.rsp_policy = &ethtool_pse_nest;
5326
5327	if (req->_present.header)
5328		ethtool_header_put(nlh, ETHTOOL_A_PSE_HEADER, &req->header);
5329
5330	rsp = calloc(1, sizeof(*rsp));
5331	yrs.yarg.data = rsp;
5332	yrs.cb = ethtool_pse_get_rsp_parse;
5333	yrs.rsp_cmd = 37;
5334
5335	err = ynl_exec(ys, nlh, &yrs);
5336	if (err < 0)
5337		goto err_free;
5338
5339	return rsp;
5340
5341err_free:
5342	ethtool_pse_get_rsp_free(rsp);
5343	return NULL;
5344}
5345
5346/* ETHTOOL_MSG_PSE_GET - dump */
5347void ethtool_pse_get_list_free(struct ethtool_pse_get_list *rsp)
5348{
5349	struct ethtool_pse_get_list *next = rsp;
5350
5351	while ((void *)next != YNL_LIST_END) {
5352		rsp = next;
5353		next = rsp->next;
5354
5355		ethtool_header_free(&rsp->obj.header);
5356		free(rsp);
5357	}
5358}
5359
5360struct ethtool_pse_get_list *
5361ethtool_pse_get_dump(struct ynl_sock *ys, struct ethtool_pse_get_req_dump *req)
5362{
5363	struct ynl_dump_state yds = {};
5364	struct nlmsghdr *nlh;
5365	int err;
5366
5367	yds.ys = ys;
5368	yds.alloc_sz = sizeof(struct ethtool_pse_get_list);
5369	yds.cb = ethtool_pse_get_rsp_parse;
5370	yds.rsp_cmd = 37;
5371	yds.rsp_policy = &ethtool_pse_nest;
5372
5373	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PSE_GET, 1);
5374	ys->req_policy = &ethtool_pse_nest;
5375
5376	if (req->_present.header)
5377		ethtool_header_put(nlh, ETHTOOL_A_PSE_HEADER, &req->header);
5378
5379	err = ynl_exec_dump(ys, nlh, &yds);
5380	if (err < 0)
5381		goto free_list;
5382
5383	return yds.first;
5384
5385free_list:
5386	ethtool_pse_get_list_free(yds.first);
5387	return NULL;
5388}
5389
5390/* ============== ETHTOOL_MSG_PSE_SET ============== */
5391/* ETHTOOL_MSG_PSE_SET - do */
5392void ethtool_pse_set_req_free(struct ethtool_pse_set_req *req)
5393{
5394	ethtool_header_free(&req->header);
5395	free(req);
5396}
5397
5398int ethtool_pse_set(struct ynl_sock *ys, struct ethtool_pse_set_req *req)
5399{
5400	struct nlmsghdr *nlh;
5401	int err;
5402
5403	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PSE_SET, 1);
5404	ys->req_policy = &ethtool_pse_nest;
5405
5406	if (req->_present.header)
5407		ethtool_header_put(nlh, ETHTOOL_A_PSE_HEADER, &req->header);
5408	if (req->_present.admin_state)
5409		mnl_attr_put_u32(nlh, ETHTOOL_A_PODL_PSE_ADMIN_STATE, req->admin_state);
5410	if (req->_present.admin_control)
5411		mnl_attr_put_u32(nlh, ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, req->admin_control);
5412	if (req->_present.pw_d_status)
5413		mnl_attr_put_u32(nlh, ETHTOOL_A_PODL_PSE_PW_D_STATUS, req->pw_d_status);
5414
5415	err = ynl_exec(ys, nlh, NULL);
5416	if (err < 0)
5417		return -1;
5418
5419	return 0;
5420}
5421
5422/* ============== ETHTOOL_MSG_RSS_GET ============== */
5423/* ETHTOOL_MSG_RSS_GET - do */
5424void ethtool_rss_get_req_free(struct ethtool_rss_get_req *req)
5425{
5426	ethtool_header_free(&req->header);
5427	free(req);
5428}
5429
5430void ethtool_rss_get_rsp_free(struct ethtool_rss_get_rsp *rsp)
5431{
5432	ethtool_header_free(&rsp->header);
5433	free(rsp->indir);
5434	free(rsp->hkey);
5435	free(rsp);
5436}
5437
5438int ethtool_rss_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
5439{
5440	struct ynl_parse_arg *yarg = data;
5441	struct ethtool_rss_get_rsp *dst;
5442	const struct nlattr *attr;
5443	struct ynl_parse_arg parg;
5444
5445	dst = yarg->data;
5446	parg.ys = yarg->ys;
5447
5448	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
5449		unsigned int type = mnl_attr_get_type(attr);
5450
5451		if (type == ETHTOOL_A_RSS_HEADER) {
5452			if (ynl_attr_validate(yarg, attr))
5453				return MNL_CB_ERROR;
5454			dst->_present.header = 1;
5455
5456			parg.rsp_policy = &ethtool_header_nest;
5457			parg.data = &dst->header;
5458			if (ethtool_header_parse(&parg, attr))
5459				return MNL_CB_ERROR;
5460		} else if (type == ETHTOOL_A_RSS_CONTEXT) {
5461			if (ynl_attr_validate(yarg, attr))
5462				return MNL_CB_ERROR;
5463			dst->_present.context = 1;
5464			dst->context = mnl_attr_get_u32(attr);
5465		} else if (type == ETHTOOL_A_RSS_HFUNC) {
5466			if (ynl_attr_validate(yarg, attr))
5467				return MNL_CB_ERROR;
5468			dst->_present.hfunc = 1;
5469			dst->hfunc = mnl_attr_get_u32(attr);
5470		} else if (type == ETHTOOL_A_RSS_INDIR) {
5471			unsigned int len;
5472
5473			if (ynl_attr_validate(yarg, attr))
5474				return MNL_CB_ERROR;
5475
5476			len = mnl_attr_get_payload_len(attr);
5477			dst->_present.indir_len = len;
5478			dst->indir = malloc(len);
5479			memcpy(dst->indir, mnl_attr_get_payload(attr), len);
5480		} else if (type == ETHTOOL_A_RSS_HKEY) {
5481			unsigned int len;
5482
5483			if (ynl_attr_validate(yarg, attr))
5484				return MNL_CB_ERROR;
5485
5486			len = mnl_attr_get_payload_len(attr);
5487			dst->_present.hkey_len = len;
5488			dst->hkey = malloc(len);
5489			memcpy(dst->hkey, mnl_attr_get_payload(attr), len);
5490		}
5491	}
5492
5493	return MNL_CB_OK;
5494}
5495
5496struct ethtool_rss_get_rsp *
5497ethtool_rss_get(struct ynl_sock *ys, struct ethtool_rss_get_req *req)
5498{
5499	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
5500	struct ethtool_rss_get_rsp *rsp;
5501	struct nlmsghdr *nlh;
5502	int err;
5503
5504	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_RSS_GET, 1);
5505	ys->req_policy = &ethtool_rss_nest;
5506	yrs.yarg.rsp_policy = &ethtool_rss_nest;
5507
5508	if (req->_present.header)
5509		ethtool_header_put(nlh, ETHTOOL_A_RSS_HEADER, &req->header);
5510
5511	rsp = calloc(1, sizeof(*rsp));
5512	yrs.yarg.data = rsp;
5513	yrs.cb = ethtool_rss_get_rsp_parse;
5514	yrs.rsp_cmd = ETHTOOL_MSG_RSS_GET;
5515
5516	err = ynl_exec(ys, nlh, &yrs);
5517	if (err < 0)
5518		goto err_free;
5519
5520	return rsp;
5521
5522err_free:
5523	ethtool_rss_get_rsp_free(rsp);
5524	return NULL;
5525}
5526
5527/* ETHTOOL_MSG_RSS_GET - dump */
5528void ethtool_rss_get_list_free(struct ethtool_rss_get_list *rsp)
5529{
5530	struct ethtool_rss_get_list *next = rsp;
5531
5532	while ((void *)next != YNL_LIST_END) {
5533		rsp = next;
5534		next = rsp->next;
5535
5536		ethtool_header_free(&rsp->obj.header);
5537		free(rsp->obj.indir);
5538		free(rsp->obj.hkey);
5539		free(rsp);
5540	}
5541}
5542
5543struct ethtool_rss_get_list *
5544ethtool_rss_get_dump(struct ynl_sock *ys, struct ethtool_rss_get_req_dump *req)
5545{
5546	struct ynl_dump_state yds = {};
5547	struct nlmsghdr *nlh;
5548	int err;
5549
5550	yds.ys = ys;
5551	yds.alloc_sz = sizeof(struct ethtool_rss_get_list);
5552	yds.cb = ethtool_rss_get_rsp_parse;
5553	yds.rsp_cmd = ETHTOOL_MSG_RSS_GET;
5554	yds.rsp_policy = &ethtool_rss_nest;
5555
5556	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_RSS_GET, 1);
5557	ys->req_policy = &ethtool_rss_nest;
5558
5559	if (req->_present.header)
5560		ethtool_header_put(nlh, ETHTOOL_A_RSS_HEADER, &req->header);
5561
5562	err = ynl_exec_dump(ys, nlh, &yds);
5563	if (err < 0)
5564		goto free_list;
5565
5566	return yds.first;
5567
5568free_list:
5569	ethtool_rss_get_list_free(yds.first);
5570	return NULL;
5571}
5572
5573/* ============== ETHTOOL_MSG_PLCA_GET_CFG ============== */
5574/* ETHTOOL_MSG_PLCA_GET_CFG - do */
5575void ethtool_plca_get_cfg_req_free(struct ethtool_plca_get_cfg_req *req)
5576{
5577	ethtool_header_free(&req->header);
5578	free(req);
5579}
5580
5581void ethtool_plca_get_cfg_rsp_free(struct ethtool_plca_get_cfg_rsp *rsp)
5582{
5583	ethtool_header_free(&rsp->header);
5584	free(rsp);
5585}
5586
5587int ethtool_plca_get_cfg_rsp_parse(const struct nlmsghdr *nlh, void *data)
5588{
5589	struct ethtool_plca_get_cfg_rsp *dst;
5590	struct ynl_parse_arg *yarg = data;
5591	const struct nlattr *attr;
5592	struct ynl_parse_arg parg;
5593
5594	dst = yarg->data;
5595	parg.ys = yarg->ys;
5596
5597	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
5598		unsigned int type = mnl_attr_get_type(attr);
5599
5600		if (type == ETHTOOL_A_PLCA_HEADER) {
5601			if (ynl_attr_validate(yarg, attr))
5602				return MNL_CB_ERROR;
5603			dst->_present.header = 1;
5604
5605			parg.rsp_policy = &ethtool_header_nest;
5606			parg.data = &dst->header;
5607			if (ethtool_header_parse(&parg, attr))
5608				return MNL_CB_ERROR;
5609		} else if (type == ETHTOOL_A_PLCA_VERSION) {
5610			if (ynl_attr_validate(yarg, attr))
5611				return MNL_CB_ERROR;
5612			dst->_present.version = 1;
5613			dst->version = mnl_attr_get_u16(attr);
5614		} else if (type == ETHTOOL_A_PLCA_ENABLED) {
5615			if (ynl_attr_validate(yarg, attr))
5616				return MNL_CB_ERROR;
5617			dst->_present.enabled = 1;
5618			dst->enabled = mnl_attr_get_u8(attr);
5619		} else if (type == ETHTOOL_A_PLCA_STATUS) {
5620			if (ynl_attr_validate(yarg, attr))
5621				return MNL_CB_ERROR;
5622			dst->_present.status = 1;
5623			dst->status = mnl_attr_get_u8(attr);
5624		} else if (type == ETHTOOL_A_PLCA_NODE_CNT) {
5625			if (ynl_attr_validate(yarg, attr))
5626				return MNL_CB_ERROR;
5627			dst->_present.node_cnt = 1;
5628			dst->node_cnt = mnl_attr_get_u32(attr);
5629		} else if (type == ETHTOOL_A_PLCA_NODE_ID) {
5630			if (ynl_attr_validate(yarg, attr))
5631				return MNL_CB_ERROR;
5632			dst->_present.node_id = 1;
5633			dst->node_id = mnl_attr_get_u32(attr);
5634		} else if (type == ETHTOOL_A_PLCA_TO_TMR) {
5635			if (ynl_attr_validate(yarg, attr))
5636				return MNL_CB_ERROR;
5637			dst->_present.to_tmr = 1;
5638			dst->to_tmr = mnl_attr_get_u32(attr);
5639		} else if (type == ETHTOOL_A_PLCA_BURST_CNT) {
5640			if (ynl_attr_validate(yarg, attr))
5641				return MNL_CB_ERROR;
5642			dst->_present.burst_cnt = 1;
5643			dst->burst_cnt = mnl_attr_get_u32(attr);
5644		} else if (type == ETHTOOL_A_PLCA_BURST_TMR) {
5645			if (ynl_attr_validate(yarg, attr))
5646				return MNL_CB_ERROR;
5647			dst->_present.burst_tmr = 1;
5648			dst->burst_tmr = mnl_attr_get_u32(attr);
5649		}
5650	}
5651
5652	return MNL_CB_OK;
5653}
5654
5655struct ethtool_plca_get_cfg_rsp *
5656ethtool_plca_get_cfg(struct ynl_sock *ys, struct ethtool_plca_get_cfg_req *req)
5657{
5658	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
5659	struct ethtool_plca_get_cfg_rsp *rsp;
5660	struct nlmsghdr *nlh;
5661	int err;
5662
5663	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_CFG, 1);
5664	ys->req_policy = &ethtool_plca_nest;
5665	yrs.yarg.rsp_policy = &ethtool_plca_nest;
5666
5667	if (req->_present.header)
5668		ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header);
5669
5670	rsp = calloc(1, sizeof(*rsp));
5671	yrs.yarg.data = rsp;
5672	yrs.cb = ethtool_plca_get_cfg_rsp_parse;
5673	yrs.rsp_cmd = ETHTOOL_MSG_PLCA_GET_CFG;
5674
5675	err = ynl_exec(ys, nlh, &yrs);
5676	if (err < 0)
5677		goto err_free;
5678
5679	return rsp;
5680
5681err_free:
5682	ethtool_plca_get_cfg_rsp_free(rsp);
5683	return NULL;
5684}
5685
5686/* ETHTOOL_MSG_PLCA_GET_CFG - dump */
5687void ethtool_plca_get_cfg_list_free(struct ethtool_plca_get_cfg_list *rsp)
5688{
5689	struct ethtool_plca_get_cfg_list *next = rsp;
5690
5691	while ((void *)next != YNL_LIST_END) {
5692		rsp = next;
5693		next = rsp->next;
5694
5695		ethtool_header_free(&rsp->obj.header);
5696		free(rsp);
5697	}
5698}
5699
5700struct ethtool_plca_get_cfg_list *
5701ethtool_plca_get_cfg_dump(struct ynl_sock *ys,
5702			  struct ethtool_plca_get_cfg_req_dump *req)
5703{
5704	struct ynl_dump_state yds = {};
5705	struct nlmsghdr *nlh;
5706	int err;
5707
5708	yds.ys = ys;
5709	yds.alloc_sz = sizeof(struct ethtool_plca_get_cfg_list);
5710	yds.cb = ethtool_plca_get_cfg_rsp_parse;
5711	yds.rsp_cmd = ETHTOOL_MSG_PLCA_GET_CFG;
5712	yds.rsp_policy = &ethtool_plca_nest;
5713
5714	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_CFG, 1);
5715	ys->req_policy = &ethtool_plca_nest;
5716
5717	if (req->_present.header)
5718		ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header);
5719
5720	err = ynl_exec_dump(ys, nlh, &yds);
5721	if (err < 0)
5722		goto free_list;
5723
5724	return yds.first;
5725
5726free_list:
5727	ethtool_plca_get_cfg_list_free(yds.first);
5728	return NULL;
5729}
5730
5731/* ETHTOOL_MSG_PLCA_GET_CFG - notify */
5732void ethtool_plca_get_cfg_ntf_free(struct ethtool_plca_get_cfg_ntf *rsp)
5733{
5734	ethtool_header_free(&rsp->obj.header);
5735	free(rsp);
5736}
5737
5738/* ============== ETHTOOL_MSG_PLCA_SET_CFG ============== */
5739/* ETHTOOL_MSG_PLCA_SET_CFG - do */
5740void ethtool_plca_set_cfg_req_free(struct ethtool_plca_set_cfg_req *req)
5741{
5742	ethtool_header_free(&req->header);
5743	free(req);
5744}
5745
5746int ethtool_plca_set_cfg(struct ynl_sock *ys,
5747			 struct ethtool_plca_set_cfg_req *req)
5748{
5749	struct nlmsghdr *nlh;
5750	int err;
5751
5752	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PLCA_SET_CFG, 1);
5753	ys->req_policy = &ethtool_plca_nest;
5754
5755	if (req->_present.header)
5756		ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header);
5757	if (req->_present.version)
5758		mnl_attr_put_u16(nlh, ETHTOOL_A_PLCA_VERSION, req->version);
5759	if (req->_present.enabled)
5760		mnl_attr_put_u8(nlh, ETHTOOL_A_PLCA_ENABLED, req->enabled);
5761	if (req->_present.status)
5762		mnl_attr_put_u8(nlh, ETHTOOL_A_PLCA_STATUS, req->status);
5763	if (req->_present.node_cnt)
5764		mnl_attr_put_u32(nlh, ETHTOOL_A_PLCA_NODE_CNT, req->node_cnt);
5765	if (req->_present.node_id)
5766		mnl_attr_put_u32(nlh, ETHTOOL_A_PLCA_NODE_ID, req->node_id);
5767	if (req->_present.to_tmr)
5768		mnl_attr_put_u32(nlh, ETHTOOL_A_PLCA_TO_TMR, req->to_tmr);
5769	if (req->_present.burst_cnt)
5770		mnl_attr_put_u32(nlh, ETHTOOL_A_PLCA_BURST_CNT, req->burst_cnt);
5771	if (req->_present.burst_tmr)
5772		mnl_attr_put_u32(nlh, ETHTOOL_A_PLCA_BURST_TMR, req->burst_tmr);
5773
5774	err = ynl_exec(ys, nlh, NULL);
5775	if (err < 0)
5776		return -1;
5777
5778	return 0;
5779}
5780
5781/* ============== ETHTOOL_MSG_PLCA_GET_STATUS ============== */
5782/* ETHTOOL_MSG_PLCA_GET_STATUS - do */
5783void ethtool_plca_get_status_req_free(struct ethtool_plca_get_status_req *req)
5784{
5785	ethtool_header_free(&req->header);
5786	free(req);
5787}
5788
5789void ethtool_plca_get_status_rsp_free(struct ethtool_plca_get_status_rsp *rsp)
5790{
5791	ethtool_header_free(&rsp->header);
5792	free(rsp);
5793}
5794
5795int ethtool_plca_get_status_rsp_parse(const struct nlmsghdr *nlh, void *data)
5796{
5797	struct ethtool_plca_get_status_rsp *dst;
5798	struct ynl_parse_arg *yarg = data;
5799	const struct nlattr *attr;
5800	struct ynl_parse_arg parg;
5801
5802	dst = yarg->data;
5803	parg.ys = yarg->ys;
5804
5805	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
5806		unsigned int type = mnl_attr_get_type(attr);
5807
5808		if (type == ETHTOOL_A_PLCA_HEADER) {
5809			if (ynl_attr_validate(yarg, attr))
5810				return MNL_CB_ERROR;
5811			dst->_present.header = 1;
5812
5813			parg.rsp_policy = &ethtool_header_nest;
5814			parg.data = &dst->header;
5815			if (ethtool_header_parse(&parg, attr))
5816				return MNL_CB_ERROR;
5817		} else if (type == ETHTOOL_A_PLCA_VERSION) {
5818			if (ynl_attr_validate(yarg, attr))
5819				return MNL_CB_ERROR;
5820			dst->_present.version = 1;
5821			dst->version = mnl_attr_get_u16(attr);
5822		} else if (type == ETHTOOL_A_PLCA_ENABLED) {
5823			if (ynl_attr_validate(yarg, attr))
5824				return MNL_CB_ERROR;
5825			dst->_present.enabled = 1;
5826			dst->enabled = mnl_attr_get_u8(attr);
5827		} else if (type == ETHTOOL_A_PLCA_STATUS) {
5828			if (ynl_attr_validate(yarg, attr))
5829				return MNL_CB_ERROR;
5830			dst->_present.status = 1;
5831			dst->status = mnl_attr_get_u8(attr);
5832		} else if (type == ETHTOOL_A_PLCA_NODE_CNT) {
5833			if (ynl_attr_validate(yarg, attr))
5834				return MNL_CB_ERROR;
5835			dst->_present.node_cnt = 1;
5836			dst->node_cnt = mnl_attr_get_u32(attr);
5837		} else if (type == ETHTOOL_A_PLCA_NODE_ID) {
5838			if (ynl_attr_validate(yarg, attr))
5839				return MNL_CB_ERROR;
5840			dst->_present.node_id = 1;
5841			dst->node_id = mnl_attr_get_u32(attr);
5842		} else if (type == ETHTOOL_A_PLCA_TO_TMR) {
5843			if (ynl_attr_validate(yarg, attr))
5844				return MNL_CB_ERROR;
5845			dst->_present.to_tmr = 1;
5846			dst->to_tmr = mnl_attr_get_u32(attr);
5847		} else if (type == ETHTOOL_A_PLCA_BURST_CNT) {
5848			if (ynl_attr_validate(yarg, attr))
5849				return MNL_CB_ERROR;
5850			dst->_present.burst_cnt = 1;
5851			dst->burst_cnt = mnl_attr_get_u32(attr);
5852		} else if (type == ETHTOOL_A_PLCA_BURST_TMR) {
5853			if (ynl_attr_validate(yarg, attr))
5854				return MNL_CB_ERROR;
5855			dst->_present.burst_tmr = 1;
5856			dst->burst_tmr = mnl_attr_get_u32(attr);
5857		}
5858	}
5859
5860	return MNL_CB_OK;
5861}
5862
5863struct ethtool_plca_get_status_rsp *
5864ethtool_plca_get_status(struct ynl_sock *ys,
5865			struct ethtool_plca_get_status_req *req)
5866{
5867	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
5868	struct ethtool_plca_get_status_rsp *rsp;
5869	struct nlmsghdr *nlh;
5870	int err;
5871
5872	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_STATUS, 1);
5873	ys->req_policy = &ethtool_plca_nest;
5874	yrs.yarg.rsp_policy = &ethtool_plca_nest;
5875
5876	if (req->_present.header)
5877		ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header);
5878
5879	rsp = calloc(1, sizeof(*rsp));
5880	yrs.yarg.data = rsp;
5881	yrs.cb = ethtool_plca_get_status_rsp_parse;
5882	yrs.rsp_cmd = 40;
5883
5884	err = ynl_exec(ys, nlh, &yrs);
5885	if (err < 0)
5886		goto err_free;
5887
5888	return rsp;
5889
5890err_free:
5891	ethtool_plca_get_status_rsp_free(rsp);
5892	return NULL;
5893}
5894
5895/* ETHTOOL_MSG_PLCA_GET_STATUS - dump */
5896void
5897ethtool_plca_get_status_list_free(struct ethtool_plca_get_status_list *rsp)
5898{
5899	struct ethtool_plca_get_status_list *next = rsp;
5900
5901	while ((void *)next != YNL_LIST_END) {
5902		rsp = next;
5903		next = rsp->next;
5904
5905		ethtool_header_free(&rsp->obj.header);
5906		free(rsp);
5907	}
5908}
5909
5910struct ethtool_plca_get_status_list *
5911ethtool_plca_get_status_dump(struct ynl_sock *ys,
5912			     struct ethtool_plca_get_status_req_dump *req)
5913{
5914	struct ynl_dump_state yds = {};
5915	struct nlmsghdr *nlh;
5916	int err;
5917
5918	yds.ys = ys;
5919	yds.alloc_sz = sizeof(struct ethtool_plca_get_status_list);
5920	yds.cb = ethtool_plca_get_status_rsp_parse;
5921	yds.rsp_cmd = 40;
5922	yds.rsp_policy = &ethtool_plca_nest;
5923
5924	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_STATUS, 1);
5925	ys->req_policy = &ethtool_plca_nest;
5926
5927	if (req->_present.header)
5928		ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header);
5929
5930	err = ynl_exec_dump(ys, nlh, &yds);
5931	if (err < 0)
5932		goto free_list;
5933
5934	return yds.first;
5935
5936free_list:
5937	ethtool_plca_get_status_list_free(yds.first);
5938	return NULL;
5939}
5940
5941/* ============== ETHTOOL_MSG_MM_GET ============== */
5942/* ETHTOOL_MSG_MM_GET - do */
5943void ethtool_mm_get_req_free(struct ethtool_mm_get_req *req)
5944{
5945	ethtool_header_free(&req->header);
5946	free(req);
5947}
5948
5949void ethtool_mm_get_rsp_free(struct ethtool_mm_get_rsp *rsp)
5950{
5951	ethtool_header_free(&rsp->header);
5952	ethtool_mm_stat_free(&rsp->stats);
5953	free(rsp);
5954}
5955
5956int ethtool_mm_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
5957{
5958	struct ynl_parse_arg *yarg = data;
5959	struct ethtool_mm_get_rsp *dst;
5960	const struct nlattr *attr;
5961	struct ynl_parse_arg parg;
5962
5963	dst = yarg->data;
5964	parg.ys = yarg->ys;
5965
5966	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
5967		unsigned int type = mnl_attr_get_type(attr);
5968
5969		if (type == ETHTOOL_A_MM_HEADER) {
5970			if (ynl_attr_validate(yarg, attr))
5971				return MNL_CB_ERROR;
5972			dst->_present.header = 1;
5973
5974			parg.rsp_policy = &ethtool_header_nest;
5975			parg.data = &dst->header;
5976			if (ethtool_header_parse(&parg, attr))
5977				return MNL_CB_ERROR;
5978		} else if (type == ETHTOOL_A_MM_PMAC_ENABLED) {
5979			if (ynl_attr_validate(yarg, attr))
5980				return MNL_CB_ERROR;
5981			dst->_present.pmac_enabled = 1;
5982			dst->pmac_enabled = mnl_attr_get_u8(attr);
5983		} else if (type == ETHTOOL_A_MM_TX_ENABLED) {
5984			if (ynl_attr_validate(yarg, attr))
5985				return MNL_CB_ERROR;
5986			dst->_present.tx_enabled = 1;
5987			dst->tx_enabled = mnl_attr_get_u8(attr);
5988		} else if (type == ETHTOOL_A_MM_TX_ACTIVE) {
5989			if (ynl_attr_validate(yarg, attr))
5990				return MNL_CB_ERROR;
5991			dst->_present.tx_active = 1;
5992			dst->tx_active = mnl_attr_get_u8(attr);
5993		} else if (type == ETHTOOL_A_MM_TX_MIN_FRAG_SIZE) {
5994			if (ynl_attr_validate(yarg, attr))
5995				return MNL_CB_ERROR;
5996			dst->_present.tx_min_frag_size = 1;
5997			dst->tx_min_frag_size = mnl_attr_get_u32(attr);
5998		} else if (type == ETHTOOL_A_MM_RX_MIN_FRAG_SIZE) {
5999			if (ynl_attr_validate(yarg, attr))
6000				return MNL_CB_ERROR;
6001			dst->_present.rx_min_frag_size = 1;
6002			dst->rx_min_frag_size = mnl_attr_get_u32(attr);
6003		} else if (type == ETHTOOL_A_MM_VERIFY_ENABLED) {
6004			if (ynl_attr_validate(yarg, attr))
6005				return MNL_CB_ERROR;
6006			dst->_present.verify_enabled = 1;
6007			dst->verify_enabled = mnl_attr_get_u8(attr);
6008		} else if (type == ETHTOOL_A_MM_VERIFY_TIME) {
6009			if (ynl_attr_validate(yarg, attr))
6010				return MNL_CB_ERROR;
6011			dst->_present.verify_time = 1;
6012			dst->verify_time = mnl_attr_get_u32(attr);
6013		} else if (type == ETHTOOL_A_MM_MAX_VERIFY_TIME) {
6014			if (ynl_attr_validate(yarg, attr))
6015				return MNL_CB_ERROR;
6016			dst->_present.max_verify_time = 1;
6017			dst->max_verify_time = mnl_attr_get_u32(attr);
6018		} else if (type == ETHTOOL_A_MM_STATS) {
6019			if (ynl_attr_validate(yarg, attr))
6020				return MNL_CB_ERROR;
6021			dst->_present.stats = 1;
6022
6023			parg.rsp_policy = &ethtool_mm_stat_nest;
6024			parg.data = &dst->stats;
6025			if (ethtool_mm_stat_parse(&parg, attr))
6026				return MNL_CB_ERROR;
6027		}
6028	}
6029
6030	return MNL_CB_OK;
6031}
6032
6033struct ethtool_mm_get_rsp *
6034ethtool_mm_get(struct ynl_sock *ys, struct ethtool_mm_get_req *req)
6035{
6036	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
6037	struct ethtool_mm_get_rsp *rsp;
6038	struct nlmsghdr *nlh;
6039	int err;
6040
6041	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MM_GET, 1);
6042	ys->req_policy = &ethtool_mm_nest;
6043	yrs.yarg.rsp_policy = &ethtool_mm_nest;
6044
6045	if (req->_present.header)
6046		ethtool_header_put(nlh, ETHTOOL_A_MM_HEADER, &req->header);
6047
6048	rsp = calloc(1, sizeof(*rsp));
6049	yrs.yarg.data = rsp;
6050	yrs.cb = ethtool_mm_get_rsp_parse;
6051	yrs.rsp_cmd = ETHTOOL_MSG_MM_GET;
6052
6053	err = ynl_exec(ys, nlh, &yrs);
6054	if (err < 0)
6055		goto err_free;
6056
6057	return rsp;
6058
6059err_free:
6060	ethtool_mm_get_rsp_free(rsp);
6061	return NULL;
6062}
6063
6064/* ETHTOOL_MSG_MM_GET - dump */
6065void ethtool_mm_get_list_free(struct ethtool_mm_get_list *rsp)
6066{
6067	struct ethtool_mm_get_list *next = rsp;
6068
6069	while ((void *)next != YNL_LIST_END) {
6070		rsp = next;
6071		next = rsp->next;
6072
6073		ethtool_header_free(&rsp->obj.header);
6074		ethtool_mm_stat_free(&rsp->obj.stats);
6075		free(rsp);
6076	}
6077}
6078
6079struct ethtool_mm_get_list *
6080ethtool_mm_get_dump(struct ynl_sock *ys, struct ethtool_mm_get_req_dump *req)
6081{
6082	struct ynl_dump_state yds = {};
6083	struct nlmsghdr *nlh;
6084	int err;
6085
6086	yds.ys = ys;
6087	yds.alloc_sz = sizeof(struct ethtool_mm_get_list);
6088	yds.cb = ethtool_mm_get_rsp_parse;
6089	yds.rsp_cmd = ETHTOOL_MSG_MM_GET;
6090	yds.rsp_policy = &ethtool_mm_nest;
6091
6092	nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_MM_GET, 1);
6093	ys->req_policy = &ethtool_mm_nest;
6094
6095	if (req->_present.header)
6096		ethtool_header_put(nlh, ETHTOOL_A_MM_HEADER, &req->header);
6097
6098	err = ynl_exec_dump(ys, nlh, &yds);
6099	if (err < 0)
6100		goto free_list;
6101
6102	return yds.first;
6103
6104free_list:
6105	ethtool_mm_get_list_free(yds.first);
6106	return NULL;
6107}
6108
6109/* ETHTOOL_MSG_MM_GET - notify */
6110void ethtool_mm_get_ntf_free(struct ethtool_mm_get_ntf *rsp)
6111{
6112	ethtool_header_free(&rsp->obj.header);
6113	ethtool_mm_stat_free(&rsp->obj.stats);
6114	free(rsp);
6115}
6116
6117/* ============== ETHTOOL_MSG_MM_SET ============== */
6118/* ETHTOOL_MSG_MM_SET - do */
6119void ethtool_mm_set_req_free(struct ethtool_mm_set_req *req)
6120{
6121	ethtool_header_free(&req->header);
6122	free(req);
6123}
6124
6125int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req)
6126{
6127	struct nlmsghdr *nlh;
6128	int err;
6129
6130	nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MM_SET, 1);
6131	ys->req_policy = &ethtool_mm_nest;
6132
6133	if (req->_present.header)
6134		ethtool_header_put(nlh, ETHTOOL_A_MM_HEADER, &req->header);
6135	if (req->_present.verify_enabled)
6136		mnl_attr_put_u8(nlh, ETHTOOL_A_MM_VERIFY_ENABLED, req->verify_enabled);
6137	if (req->_present.verify_time)
6138		mnl_attr_put_u32(nlh, ETHTOOL_A_MM_VERIFY_TIME, req->verify_time);
6139	if (req->_present.tx_enabled)
6140		mnl_attr_put_u8(nlh, ETHTOOL_A_MM_TX_ENABLED, req->tx_enabled);
6141	if (req->_present.pmac_enabled)
6142		mnl_attr_put_u8(nlh, ETHTOOL_A_MM_PMAC_ENABLED, req->pmac_enabled);
6143	if (req->_present.tx_min_frag_size)
6144		mnl_attr_put_u32(nlh, ETHTOOL_A_MM_TX_MIN_FRAG_SIZE, req->tx_min_frag_size);
6145
6146	err = ynl_exec(ys, nlh, NULL);
6147	if (err < 0)
6148		return -1;
6149
6150	return 0;
6151}
6152
6153/* ETHTOOL_MSG_CABLE_TEST_NTF - event */
6154int ethtool_cable_test_ntf_rsp_parse(const struct nlmsghdr *nlh, void *data)
6155{
6156	struct ethtool_cable_test_ntf_rsp *dst;
6157	struct ynl_parse_arg *yarg = data;
6158	const struct nlattr *attr;
6159	struct ynl_parse_arg parg;
6160
6161	dst = yarg->data;
6162	parg.ys = yarg->ys;
6163
6164	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
6165		unsigned int type = mnl_attr_get_type(attr);
6166
6167		if (type == ETHTOOL_A_CABLE_TEST_NTF_HEADER) {
6168			if (ynl_attr_validate(yarg, attr))
6169				return MNL_CB_ERROR;
6170			dst->_present.header = 1;
6171
6172			parg.rsp_policy = &ethtool_header_nest;
6173			parg.data = &dst->header;
6174			if (ethtool_header_parse(&parg, attr))
6175				return MNL_CB_ERROR;
6176		} else if (type == ETHTOOL_A_CABLE_TEST_NTF_STATUS) {
6177			if (ynl_attr_validate(yarg, attr))
6178				return MNL_CB_ERROR;
6179			dst->_present.status = 1;
6180			dst->status = mnl_attr_get_u8(attr);
6181		}
6182	}
6183
6184	return MNL_CB_OK;
6185}
6186
6187void ethtool_cable_test_ntf_free(struct ethtool_cable_test_ntf *rsp)
6188{
6189	ethtool_header_free(&rsp->obj.header);
6190	free(rsp);
6191}
6192
6193/* ETHTOOL_MSG_CABLE_TEST_TDR_NTF - event */
6194int ethtool_cable_test_tdr_ntf_rsp_parse(const struct nlmsghdr *nlh,
6195					 void *data)
6196{
6197	struct ethtool_cable_test_tdr_ntf_rsp *dst;
6198	struct ynl_parse_arg *yarg = data;
6199	const struct nlattr *attr;
6200	struct ynl_parse_arg parg;
6201
6202	dst = yarg->data;
6203	parg.ys = yarg->ys;
6204
6205	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
6206		unsigned int type = mnl_attr_get_type(attr);
6207
6208		if (type == ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER) {
6209			if (ynl_attr_validate(yarg, attr))
6210				return MNL_CB_ERROR;
6211			dst->_present.header = 1;
6212
6213			parg.rsp_policy = &ethtool_header_nest;
6214			parg.data = &dst->header;
6215			if (ethtool_header_parse(&parg, attr))
6216				return MNL_CB_ERROR;
6217		} else if (type == ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS) {
6218			if (ynl_attr_validate(yarg, attr))
6219				return MNL_CB_ERROR;
6220			dst->_present.status = 1;
6221			dst->status = mnl_attr_get_u8(attr);
6222		} else if (type == ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST) {
6223			if (ynl_attr_validate(yarg, attr))
6224				return MNL_CB_ERROR;
6225			dst->_present.nest = 1;
6226
6227			parg.rsp_policy = &ethtool_cable_nest_nest;
6228			parg.data = &dst->nest;
6229			if (ethtool_cable_nest_parse(&parg, attr))
6230				return MNL_CB_ERROR;
6231		}
6232	}
6233
6234	return MNL_CB_OK;
6235}
6236
6237void ethtool_cable_test_tdr_ntf_free(struct ethtool_cable_test_tdr_ntf *rsp)
6238{
6239	ethtool_header_free(&rsp->obj.header);
6240	ethtool_cable_nest_free(&rsp->obj.nest);
6241	free(rsp);
6242}
6243
6244static const struct ynl_ntf_info ethtool_ntf_info[] =  {
6245	[ETHTOOL_MSG_LINKINFO_NTF] =  {
6246		.alloc_sz	= sizeof(struct ethtool_linkinfo_get_ntf),
6247		.cb		= ethtool_linkinfo_get_rsp_parse,
6248		.policy		= &ethtool_linkinfo_nest,
6249		.free		= (void *)ethtool_linkinfo_get_ntf_free,
6250	},
6251	[ETHTOOL_MSG_LINKMODES_NTF] =  {
6252		.alloc_sz	= sizeof(struct ethtool_linkmodes_get_ntf),
6253		.cb		= ethtool_linkmodes_get_rsp_parse,
6254		.policy		= &ethtool_linkmodes_nest,
6255		.free		= (void *)ethtool_linkmodes_get_ntf_free,
6256	},
6257	[ETHTOOL_MSG_DEBUG_NTF] =  {
6258		.alloc_sz	= sizeof(struct ethtool_debug_get_ntf),
6259		.cb		= ethtool_debug_get_rsp_parse,
6260		.policy		= &ethtool_debug_nest,
6261		.free		= (void *)ethtool_debug_get_ntf_free,
6262	},
6263	[ETHTOOL_MSG_WOL_NTF] =  {
6264		.alloc_sz	= sizeof(struct ethtool_wol_get_ntf),
6265		.cb		= ethtool_wol_get_rsp_parse,
6266		.policy		= &ethtool_wol_nest,
6267		.free		= (void *)ethtool_wol_get_ntf_free,
6268	},
6269	[ETHTOOL_MSG_FEATURES_NTF] =  {
6270		.alloc_sz	= sizeof(struct ethtool_features_get_ntf),
6271		.cb		= ethtool_features_get_rsp_parse,
6272		.policy		= &ethtool_features_nest,
6273		.free		= (void *)ethtool_features_get_ntf_free,
6274	},
6275	[ETHTOOL_MSG_PRIVFLAGS_NTF] =  {
6276		.alloc_sz	= sizeof(struct ethtool_privflags_get_ntf),
6277		.cb		= ethtool_privflags_get_rsp_parse,
6278		.policy		= &ethtool_privflags_nest,
6279		.free		= (void *)ethtool_privflags_get_ntf_free,
6280	},
6281	[ETHTOOL_MSG_RINGS_NTF] =  {
6282		.alloc_sz	= sizeof(struct ethtool_rings_get_ntf),
6283		.cb		= ethtool_rings_get_rsp_parse,
6284		.policy		= &ethtool_rings_nest,
6285		.free		= (void *)ethtool_rings_get_ntf_free,
6286	},
6287	[ETHTOOL_MSG_CHANNELS_NTF] =  {
6288		.alloc_sz	= sizeof(struct ethtool_channels_get_ntf),
6289		.cb		= ethtool_channels_get_rsp_parse,
6290		.policy		= &ethtool_channels_nest,
6291		.free		= (void *)ethtool_channels_get_ntf_free,
6292	},
6293	[ETHTOOL_MSG_COALESCE_NTF] =  {
6294		.alloc_sz	= sizeof(struct ethtool_coalesce_get_ntf),
6295		.cb		= ethtool_coalesce_get_rsp_parse,
6296		.policy		= &ethtool_coalesce_nest,
6297		.free		= (void *)ethtool_coalesce_get_ntf_free,
6298	},
6299	[ETHTOOL_MSG_PAUSE_NTF] =  {
6300		.alloc_sz	= sizeof(struct ethtool_pause_get_ntf),
6301		.cb		= ethtool_pause_get_rsp_parse,
6302		.policy		= &ethtool_pause_nest,
6303		.free		= (void *)ethtool_pause_get_ntf_free,
6304	},
6305	[ETHTOOL_MSG_EEE_NTF] =  {
6306		.alloc_sz	= sizeof(struct ethtool_eee_get_ntf),
6307		.cb		= ethtool_eee_get_rsp_parse,
6308		.policy		= &ethtool_eee_nest,
6309		.free		= (void *)ethtool_eee_get_ntf_free,
6310	},
6311	[ETHTOOL_MSG_CABLE_TEST_NTF] =  {
6312		.alloc_sz	= sizeof(struct ethtool_cable_test_ntf),
6313		.cb		= ethtool_cable_test_ntf_rsp_parse,
6314		.policy		= &ethtool_cable_test_ntf_nest,
6315		.free		= (void *)ethtool_cable_test_ntf_free,
6316	},
6317	[ETHTOOL_MSG_CABLE_TEST_TDR_NTF] =  {
6318		.alloc_sz	= sizeof(struct ethtool_cable_test_tdr_ntf),
6319		.cb		= ethtool_cable_test_tdr_ntf_rsp_parse,
6320		.policy		= &ethtool_cable_test_tdr_ntf_nest,
6321		.free		= (void *)ethtool_cable_test_tdr_ntf_free,
6322	},
6323	[ETHTOOL_MSG_FEC_NTF] =  {
6324		.alloc_sz	= sizeof(struct ethtool_fec_get_ntf),
6325		.cb		= ethtool_fec_get_rsp_parse,
6326		.policy		= &ethtool_fec_nest,
6327		.free		= (void *)ethtool_fec_get_ntf_free,
6328	},
6329	[ETHTOOL_MSG_MODULE_NTF] =  {
6330		.alloc_sz	= sizeof(struct ethtool_module_get_ntf),
6331		.cb		= ethtool_module_get_rsp_parse,
6332		.policy		= &ethtool_module_nest,
6333		.free		= (void *)ethtool_module_get_ntf_free,
6334	},
6335	[ETHTOOL_MSG_PLCA_NTF] =  {
6336		.alloc_sz	= sizeof(struct ethtool_plca_get_cfg_ntf),
6337		.cb		= ethtool_plca_get_cfg_rsp_parse,
6338		.policy		= &ethtool_plca_nest,
6339		.free		= (void *)ethtool_plca_get_cfg_ntf_free,
6340	},
6341	[ETHTOOL_MSG_MM_NTF] =  {
6342		.alloc_sz	= sizeof(struct ethtool_mm_get_ntf),
6343		.cb		= ethtool_mm_get_rsp_parse,
6344		.policy		= &ethtool_mm_nest,
6345		.free		= (void *)ethtool_mm_get_ntf_free,
6346	},
6347};
6348
6349const struct ynl_family ynl_ethtool_family =  {
6350	.name		= "ethtool",
6351	.ntf_info	= ethtool_ntf_info,
6352	.ntf_info_size	= MNL_ARRAY_SIZE(ethtool_ntf_info),
6353};
6354