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 */
19 static 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 
64 const 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 
71 static const char * const ethtool_udp_tunnel_type_strmap[] = {
72 	[0] = "vxlan",
73 	[1] = "geneve",
74 	[2] = "vxlan-gpe",
75 };
76 
77 const 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 
84 static const char * const ethtool_stringset_strmap[] = {
85 };
86 
87 const 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 */
95 struct 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 
101 struct ynl_policy_nest ethtool_header_nest = {
102 	.max_attr = ETHTOOL_A_HEADER_MAX,
103 	.table = ethtool_header_policy,
104 };
105 
106 struct 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 
112 struct ynl_policy_nest ethtool_pause_stat_nest = {
113 	.max_attr = ETHTOOL_A_PAUSE_STAT_MAX,
114 	.table = ethtool_pause_stat_policy,
115 };
116 
117 struct 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 
124 struct 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 
129 struct 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 
136 struct ynl_policy_nest ethtool_fec_stat_nest = {
137 	.max_attr = ETHTOOL_A_FEC_STAT_MAX,
138 	.table = ethtool_fec_stat_policy,
139 };
140 
141 struct 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 
151 struct ynl_policy_nest ethtool_mm_stat_nest = {
152 	.max_attr = ETHTOOL_A_MM_STAT_MAX,
153 	.table = ethtool_mm_stat_policy,
154 };
155 
156 struct 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 
161 struct ynl_policy_nest ethtool_cable_result_nest = {
162 	.max_attr = ETHTOOL_A_CABLE_RESULT_MAX,
163 	.table = ethtool_cable_result_policy,
164 };
165 
166 struct 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 
171 struct 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 
176 struct 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 
182 struct ynl_policy_nest ethtool_bitset_bit_nest = {
183 	.max_attr = ETHTOOL_A_BITSET_BIT_MAX,
184 	.table = ethtool_bitset_bit_policy,
185 };
186 
187 struct 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 
192 struct 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 
197 struct 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 
202 struct ynl_policy_nest ethtool_string_nest = {
203 	.max_attr = ETHTOOL_A_STRING_MAX,
204 	.table = ethtool_string_policy,
205 };
206 
207 struct 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 
212 struct ynl_policy_nest ethtool_cable_nest_nest = {
213 	.max_attr = ETHTOOL_A_CABLE_NEST_MAX,
214 	.table = ethtool_cable_nest_policy,
215 };
216 
217 struct 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 
221 struct ynl_policy_nest ethtool_bitset_bits_nest = {
222 	.max_attr = ETHTOOL_A_BITSET_BITS_MAX,
223 	.table = ethtool_bitset_bits_policy,
224 };
225 
226 struct 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 
230 struct ynl_policy_nest ethtool_strings_nest = {
231 	.max_attr = ETHTOOL_A_STRINGS_MAX,
232 	.table = ethtool_strings_policy,
233 };
234 
235 struct 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 
241 struct ynl_policy_nest ethtool_bitset_nest = {
242 	.max_attr = ETHTOOL_A_BITSET_MAX,
243 	.table = ethtool_bitset_policy,
244 };
245 
246 struct 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 
252 struct ynl_policy_nest ethtool_stringset_nest = {
253 	.max_attr = ETHTOOL_A_STRINGSET_MAX,
254 	.table = ethtool_stringset_policy,
255 };
256 
257 struct 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 
263 struct 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 
268 struct 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 
272 struct ynl_policy_nest ethtool_stringsets_nest = {
273 	.max_attr = ETHTOOL_A_STRINGSETS_MAX,
274 	.table = ethtool_stringsets_policy,
275 };
276 
277 struct 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 
281 struct ynl_policy_nest ethtool_tunnel_udp_nest = {
282 	.max_attr = ETHTOOL_A_TUNNEL_UDP_MAX,
283 	.table = ethtool_tunnel_udp_policy,
284 };
285 
286 struct 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 
292 struct ynl_policy_nest ethtool_strset_nest = {
293 	.max_attr = ETHTOOL_A_STRSET_MAX,
294 	.table = ethtool_strset_policy,
295 };
296 
297 struct 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 
306 struct ynl_policy_nest ethtool_linkinfo_nest = {
307 	.max_attr = ETHTOOL_A_LINKINFO_MAX,
308 	.table = ethtool_linkinfo_policy,
309 };
310 
311 struct 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 
324 struct ynl_policy_nest ethtool_linkmodes_nest = {
325 	.max_attr = ETHTOOL_A_LINKMODES_MAX,
326 	.table = ethtool_linkmodes_policy,
327 };
328 
329 struct 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 
339 struct ynl_policy_nest ethtool_linkstate_nest = {
340 	.max_attr = ETHTOOL_A_LINKSTATE_MAX,
341 	.table = ethtool_linkstate_policy,
342 };
343 
344 struct 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 
349 struct ynl_policy_nest ethtool_debug_nest = {
350 	.max_attr = ETHTOOL_A_DEBUG_MAX,
351 	.table = ethtool_debug_policy,
352 };
353 
354 struct 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 
360 struct ynl_policy_nest ethtool_wol_nest = {
361 	.max_attr = ETHTOOL_A_WOL_MAX,
362 	.table = ethtool_wol_policy,
363 };
364 
365 struct 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 
373 struct ynl_policy_nest ethtool_features_nest = {
374 	.max_attr = ETHTOOL_A_FEATURES_MAX,
375 	.table = ethtool_features_policy,
376 };
377 
378 struct 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 
383 struct ynl_policy_nest ethtool_privflags_nest = {
384 	.max_attr = ETHTOOL_A_PRIVFLAGS_MAX,
385 	.table = ethtool_privflags_policy,
386 };
387 
388 struct 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 
407 struct ynl_policy_nest ethtool_rings_nest = {
408 	.max_attr = ETHTOOL_A_RINGS_MAX,
409 	.table = ethtool_rings_policy,
410 };
411 
412 struct 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 
424 struct ynl_policy_nest ethtool_channels_nest = {
425 	.max_attr = ETHTOOL_A_CHANNELS_MAX,
426 	.table = ethtool_channels_policy,
427 };
428 
429 struct 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 
460 struct ynl_policy_nest ethtool_coalesce_nest = {
461 	.max_attr = ETHTOOL_A_COALESCE_MAX,
462 	.table = ethtool_coalesce_policy,
463 };
464 
465 struct 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 
474 struct ynl_policy_nest ethtool_pause_nest = {
475 	.max_attr = ETHTOOL_A_PAUSE_MAX,
476 	.table = ethtool_pause_policy,
477 };
478 
479 struct 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 
489 struct ynl_policy_nest ethtool_eee_nest = {
490 	.max_attr = ETHTOOL_A_EEE_MAX,
491 	.table = ethtool_eee_policy,
492 };
493 
494 struct 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 
502 struct ynl_policy_nest ethtool_tsinfo_nest = {
503 	.max_attr = ETHTOOL_A_TSINFO_MAX,
504 	.table = ethtool_tsinfo_policy,
505 };
506 
507 struct 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 
511 struct ynl_policy_nest ethtool_cable_test_nest = {
512 	.max_attr = ETHTOOL_A_CABLE_TEST_MAX,
513 	.table = ethtool_cable_test_policy,
514 };
515 
516 struct 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 
522 struct 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 
527 struct 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 
532 struct 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 
537 struct 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 
543 struct 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 
548 struct 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 
553 struct ynl_policy_nest ethtool_tunnel_info_nest = {
554 	.max_attr = ETHTOOL_A_TUNNEL_INFO_MAX,
555 	.table = ethtool_tunnel_info_policy,
556 };
557 
558 struct 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 
566 struct ynl_policy_nest ethtool_fec_nest = {
567 	.max_attr = ETHTOOL_A_FEC_MAX,
568 	.table = ethtool_fec_policy,
569 };
570 
571 struct 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 
581 struct ynl_policy_nest ethtool_module_eeprom_nest = {
582 	.max_attr = ETHTOOL_A_MODULE_EEPROM_MAX,
583 	.table = ethtool_module_eeprom_policy,
584 };
585 
586 struct 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 
592 struct ynl_policy_nest ethtool_phc_vclocks_nest = {
593 	.max_attr = ETHTOOL_A_PHC_VCLOCKS_MAX,
594 	.table = ethtool_phc_vclocks_policy,
595 };
596 
597 struct 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 
603 struct ynl_policy_nest ethtool_module_nest = {
604 	.max_attr = ETHTOOL_A_MODULE_MAX,
605 	.table = ethtool_module_policy,
606 };
607 
608 struct 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 
615 struct ynl_policy_nest ethtool_pse_nest = {
616 	.max_attr = ETHTOOL_A_PSE_MAX,
617 	.table = ethtool_pse_policy,
618 };
619 
620 struct 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 
628 struct ynl_policy_nest ethtool_rss_nest = {
629 	.max_attr = ETHTOOL_A_RSS_MAX,
630 	.table = ethtool_rss_policy,
631 };
632 
633 struct 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 
645 struct ynl_policy_nest ethtool_plca_nest = {
646 	.max_attr = ETHTOOL_A_PLCA_MAX,
647 	.table = ethtool_plca_policy,
648 };
649 
650 struct 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 
664 struct ynl_policy_nest ethtool_mm_nest = {
665 	.max_attr = ETHTOOL_A_MM_MAX,
666 	.table = ethtool_mm_policy,
667 };
668 
669 /* Common nested types */
670 void ethtool_header_free(struct ethtool_header *obj)
671 {
672 	free(obj->dev_name);
673 }
674 
675 int 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 
692 int 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 
728 void ethtool_pause_stat_free(struct ethtool_pause_stat *obj)
729 {
730 }
731 
732 int 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 
747 int 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 
772 void ethtool_cable_test_tdr_cfg_free(struct ethtool_cable_test_tdr_cfg *obj)
773 {
774 }
775 
776 void 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 
783 int 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 
800 int 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 
845 void ethtool_mm_stat_free(struct ethtool_mm_stat *obj)
846 {
847 }
848 
849 int 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 
894 void ethtool_cable_result_free(struct ethtool_cable_result *obj)
895 {
896 }
897 
898 int 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 
923 void ethtool_cable_fault_length_free(struct ethtool_cable_fault_length *obj)
924 {
925 }
926 
927 int 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 
952 void ethtool_bitset_bit_free(struct ethtool_bitset_bit *obj)
953 {
954 	free(obj->name);
955 }
956 
957 int 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 
974 int 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 
1009 void ethtool_tunnel_udp_entry_free(struct ethtool_tunnel_udp_entry *obj)
1010 {
1011 }
1012 
1013 int 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 
1038 void ethtool_string_free(struct ethtool_string *obj)
1039 {
1040 	free(obj->value);
1041 }
1042 
1043 int 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 
1058 int 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 
1089 void 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 
1095 int 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 
1131 void 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 
1140 int 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 
1153 int 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 
1193 void 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 
1202 int 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 
1215 int 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 
1255 void ethtool_bitset_free(struct ethtool_bitset *obj)
1256 {
1257 	ethtool_bitset_bits_free(&obj->bits);
1258 }
1259 
1260 int 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 
1277 int 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 
1313 void 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 
1322 int 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 
1339 int 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 
1389 void 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 
1399 int 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 
1453 void 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 
1462 int 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 
1475 int 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 
1515 void ethtool_tunnel_udp_free(struct ethtool_tunnel_udp *obj)
1516 {
1517 	ethtool_tunnel_udp_table_free(&obj->table);
1518 }
1519 
1520 int 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 */
1549 void 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 
1556 void 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 
1563 int 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 
1600 struct ethtool_strset_get_rsp *
1601 ethtool_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 
1630 err_free:
1631 	ethtool_strset_get_rsp_free(rsp);
1632 	return NULL;
1633 }
1634 
1635 /* ETHTOOL_MSG_STRSET_GET - dump */
1636 void 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 
1650 struct ethtool_strset_get_list *
1651 ethtool_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 
1680 free_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 */
1687 void ethtool_linkinfo_get_req_free(struct ethtool_linkinfo_get_req *req)
1688 {
1689 	ethtool_header_free(&req->header);
1690 	free(req);
1691 }
1692 
1693 void ethtool_linkinfo_get_rsp_free(struct ethtool_linkinfo_get_rsp *rsp)
1694 {
1695 	ethtool_header_free(&rsp->header);
1696 	free(rsp);
1697 }
1698 
1699 int 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 
1752 struct ethtool_linkinfo_get_rsp *
1753 ethtool_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 
1778 err_free:
1779 	ethtool_linkinfo_get_rsp_free(rsp);
1780 	return NULL;
1781 }
1782 
1783 /* ETHTOOL_MSG_LINKINFO_GET - dump */
1784 void 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 
1797 struct ethtool_linkinfo_get_list *
1798 ethtool_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 
1823 free_list:
1824 	ethtool_linkinfo_get_list_free(yds.first);
1825 	return NULL;
1826 }
1827 
1828 /* ETHTOOL_MSG_LINKINFO_GET - notify */
1829 void 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 */
1837 void ethtool_linkinfo_set_req_free(struct ethtool_linkinfo_set_req *req)
1838 {
1839 	ethtool_header_free(&req->header);
1840 	free(req);
1841 }
1842 
1843 int 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 */
1874 void ethtool_linkmodes_get_req_free(struct ethtool_linkmodes_get_req *req)
1875 {
1876 	ethtool_header_free(&req->header);
1877 	free(req);
1878 }
1879 
1880 void 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 
1888 int 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 
1969 struct ethtool_linkmodes_get_rsp *
1970 ethtool_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 
1996 err_free:
1997 	ethtool_linkmodes_get_rsp_free(rsp);
1998 	return NULL;
1999 }
2000 
2001 /* ETHTOOL_MSG_LINKMODES_GET - dump */
2002 void 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 
2017 struct ethtool_linkmodes_get_list *
2018 ethtool_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 
2043 free_list:
2044 	ethtool_linkmodes_get_list_free(yds.first);
2045 	return NULL;
2046 }
2047 
2048 /* ETHTOOL_MSG_LINKMODES_GET - notify */
2049 void 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 */
2059 void 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 
2067 int 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 */
2106 void ethtool_linkstate_get_req_free(struct ethtool_linkstate_get_req *req)
2107 {
2108 	ethtool_header_free(&req->header);
2109 	free(req);
2110 }
2111 
2112 void ethtool_linkstate_get_rsp_free(struct ethtool_linkstate_get_rsp *rsp)
2113 {
2114 	ethtool_header_free(&rsp->header);
2115 	free(rsp);
2116 }
2117 
2118 int 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 
2176 struct ethtool_linkstate_get_rsp *
2177 ethtool_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 
2203 err_free:
2204 	ethtool_linkstate_get_rsp_free(rsp);
2205 	return NULL;
2206 }
2207 
2208 /* ETHTOOL_MSG_LINKSTATE_GET - dump */
2209 void 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 
2222 struct ethtool_linkstate_get_list *
2223 ethtool_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 
2248 free_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 */
2255 void ethtool_debug_get_req_free(struct ethtool_debug_get_req *req)
2256 {
2257 	ethtool_header_free(&req->header);
2258 	free(req);
2259 }
2260 
2261 void 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 
2268 int 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 
2305 struct ethtool_debug_get_rsp *
2306 ethtool_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 
2331 err_free:
2332 	ethtool_debug_get_rsp_free(rsp);
2333 	return NULL;
2334 }
2335 
2336 /* ETHTOOL_MSG_DEBUG_GET - dump */
2337 void 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 
2351 struct ethtool_debug_get_list *
2352 ethtool_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 
2377 free_list:
2378 	ethtool_debug_get_list_free(yds.first);
2379 	return NULL;
2380 }
2381 
2382 /* ETHTOOL_MSG_DEBUG_GET - notify */
2383 void 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 */
2392 void 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 
2399 int 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 */
2421 void ethtool_wol_get_req_free(struct ethtool_wol_get_req *req)
2422 {
2423 	ethtool_header_free(&req->header);
2424 	free(req);
2425 }
2426 
2427 void 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 
2435 int 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 
2482 struct ethtool_wol_get_rsp *
2483 ethtool_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 
2508 err_free:
2509 	ethtool_wol_get_rsp_free(rsp);
2510 	return NULL;
2511 }
2512 
2513 /* ETHTOOL_MSG_WOL_GET - dump */
2514 void 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 
2529 struct ethtool_wol_get_list *
2530 ethtool_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 
2554 free_list:
2555 	ethtool_wol_get_list_free(yds.first);
2556 	return NULL;
2557 }
2558 
2559 /* ETHTOOL_MSG_WOL_GET - notify */
2560 void 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 */
2570 void 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 
2578 int 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 */
2602 void ethtool_features_get_req_free(struct ethtool_features_get_req *req)
2603 {
2604 	ethtool_header_free(&req->header);
2605 	free(req);
2606 }
2607 
2608 void 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 
2618 int 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 
2682 struct ethtool_features_get_rsp *
2683 ethtool_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 
2708 err_free:
2709 	ethtool_features_get_rsp_free(rsp);
2710 	return NULL;
2711 }
2712 
2713 /* ETHTOOL_MSG_FEATURES_GET - dump */
2714 void 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 
2731 struct ethtool_features_get_list *
2732 ethtool_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 
2757 free_list:
2758 	ethtool_features_get_list_free(yds.first);
2759 	return NULL;
2760 }
2761 
2762 /* ETHTOOL_MSG_FEATURES_GET - notify */
2763 void 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 */
2775 void 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 
2785 void 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 
2795 int 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 
2859 struct ethtool_features_set_rsp *
2860 ethtool_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 
2893 err_free:
2894 	ethtool_features_set_rsp_free(rsp);
2895 	return NULL;
2896 }
2897 
2898 /* ============== ETHTOOL_MSG_PRIVFLAGS_GET ============== */
2899 /* ETHTOOL_MSG_PRIVFLAGS_GET - do */
2900 void ethtool_privflags_get_req_free(struct ethtool_privflags_get_req *req)
2901 {
2902 	ethtool_header_free(&req->header);
2903 	free(req);
2904 }
2905 
2906 void 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 
2913 int 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 
2950 struct ethtool_privflags_get_rsp *
2951 ethtool_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 
2977 err_free:
2978 	ethtool_privflags_get_rsp_free(rsp);
2979 	return NULL;
2980 }
2981 
2982 /* ETHTOOL_MSG_PRIVFLAGS_GET - dump */
2983 void 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 
2997 struct ethtool_privflags_get_list *
2998 ethtool_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 
3023 free_list:
3024 	ethtool_privflags_get_list_free(yds.first);
3025 	return NULL;
3026 }
3027 
3028 /* ETHTOOL_MSG_PRIVFLAGS_GET - notify */
3029 void 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 */
3038 void 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 
3045 int 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 */
3068 void ethtool_rings_get_req_free(struct ethtool_rings_get_req *req)
3069 {
3070 	ethtool_header_free(&req->header);
3071 	free(req);
3072 }
3073 
3074 void ethtool_rings_get_rsp_free(struct ethtool_rings_get_rsp *rsp)
3075 {
3076 	ethtool_header_free(&rsp->header);
3077 	free(rsp);
3078 }
3079 
3080 int 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 
3183 struct ethtool_rings_get_rsp *
3184 ethtool_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 
3209 err_free:
3210 	ethtool_rings_get_rsp_free(rsp);
3211 	return NULL;
3212 }
3213 
3214 /* ETHTOOL_MSG_RINGS_GET - dump */
3215 void 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 
3228 struct ethtool_rings_get_list *
3229 ethtool_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 
3254 free_list:
3255 	ethtool_rings_get_list_free(yds.first);
3256 	return NULL;
3257 }
3258 
3259 /* ETHTOOL_MSG_RINGS_GET - notify */
3260 void 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 */
3268 void ethtool_rings_set_req_free(struct ethtool_rings_set_req *req)
3269 {
3270 	ethtool_header_free(&req->header);
3271 	free(req);
3272 }
3273 
3274 int 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 */
3324 void ethtool_channels_get_req_free(struct ethtool_channels_get_req *req)
3325 {
3326 	ethtool_header_free(&req->header);
3327 	free(req);
3328 }
3329 
3330 void ethtool_channels_get_rsp_free(struct ethtool_channels_get_rsp *rsp)
3331 {
3332 	ethtool_header_free(&rsp->header);
3333 	free(rsp);
3334 }
3335 
3336 int 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 
3404 struct ethtool_channels_get_rsp *
3405 ethtool_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 
3430 err_free:
3431 	ethtool_channels_get_rsp_free(rsp);
3432 	return NULL;
3433 }
3434 
3435 /* ETHTOOL_MSG_CHANNELS_GET - dump */
3436 void 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 
3449 struct ethtool_channels_get_list *
3450 ethtool_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 
3475 free_list:
3476 	ethtool_channels_get_list_free(yds.first);
3477 	return NULL;
3478 }
3479 
3480 /* ETHTOOL_MSG_CHANNELS_GET - notify */
3481 void 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 */
3489 void ethtool_channels_set_req_free(struct ethtool_channels_set_req *req)
3490 {
3491 	ethtool_header_free(&req->header);
3492 	free(req);
3493 }
3494 
3495 int 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 */
3532 void ethtool_coalesce_get_req_free(struct ethtool_coalesce_get_req *req)
3533 {
3534 	ethtool_header_free(&req->header);
3535 	free(req);
3536 }
3537 
3538 void ethtool_coalesce_get_rsp_free(struct ethtool_coalesce_get_rsp *rsp)
3539 {
3540 	ethtool_header_free(&rsp->header);
3541 	free(rsp);
3542 }
3543 
3544 int 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 
3707 struct ethtool_coalesce_get_rsp *
3708 ethtool_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 
3733 err_free:
3734 	ethtool_coalesce_get_rsp_free(rsp);
3735 	return NULL;
3736 }
3737 
3738 /* ETHTOOL_MSG_COALESCE_GET - dump */
3739 void 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 
3752 struct ethtool_coalesce_get_list *
3753 ethtool_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 
3778 free_list:
3779 	ethtool_coalesce_get_list_free(yds.first);
3780 	return NULL;
3781 }
3782 
3783 /* ETHTOOL_MSG_COALESCE_GET - notify */
3784 void 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 */
3792 void ethtool_coalesce_set_req_free(struct ethtool_coalesce_set_req *req)
3793 {
3794 	ethtool_header_free(&req->header);
3795 	free(req);
3796 }
3797 
3798 int 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 */
3873 void ethtool_pause_get_req_free(struct ethtool_pause_get_req *req)
3874 {
3875 	ethtool_header_free(&req->header);
3876 	free(req);
3877 }
3878 
3879 void 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 
3886 int 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 
3943 struct ethtool_pause_get_rsp *
3944 ethtool_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 
3969 err_free:
3970 	ethtool_pause_get_rsp_free(rsp);
3971 	return NULL;
3972 }
3973 
3974 /* ETHTOOL_MSG_PAUSE_GET - dump */
3975 void 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 
3989 struct ethtool_pause_get_list *
3990 ethtool_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 
4015 free_list:
4016 	ethtool_pause_get_list_free(yds.first);
4017 	return NULL;
4018 }
4019 
4020 /* ETHTOOL_MSG_PAUSE_GET - notify */
4021 void 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 */
4030 void 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 
4037 int 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 */
4067 void ethtool_eee_get_req_free(struct ethtool_eee_get_req *req)
4068 {
4069 	ethtool_header_free(&req->header);
4070 	free(req);
4071 }
4072 
4073 void 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 
4081 int 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 
4147 struct ethtool_eee_get_rsp *
4148 ethtool_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 
4173 err_free:
4174 	ethtool_eee_get_rsp_free(rsp);
4175 	return NULL;
4176 }
4177 
4178 /* ETHTOOL_MSG_EEE_GET - dump */
4179 void 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 
4194 struct ethtool_eee_get_list *
4195 ethtool_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 
4219 free_list:
4220 	ethtool_eee_get_list_free(yds.first);
4221 	return NULL;
4222 }
4223 
4224 /* ETHTOOL_MSG_EEE_GET - notify */
4225 void 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 */
4235 void 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 
4243 int 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 */
4275 void ethtool_tsinfo_get_req_free(struct ethtool_tsinfo_get_req *req)
4276 {
4277 	ethtool_header_free(&req->header);
4278 	free(req);
4279 }
4280 
4281 void 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 
4290 int 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 
4350 struct ethtool_tsinfo_get_rsp *
4351 ethtool_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 
4376 err_free:
4377 	ethtool_tsinfo_get_rsp_free(rsp);
4378 	return NULL;
4379 }
4380 
4381 /* ETHTOOL_MSG_TSINFO_GET - dump */
4382 void 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 
4398 struct ethtool_tsinfo_get_list *
4399 ethtool_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 
4424 free_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 */
4431 void 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 
4437 int 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 */
4458 void
4459 ethtool_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 
4465 int 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 */
4486 void 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 
4492 void 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 
4499 int 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 
4536 struct ethtool_tunnel_info_get_rsp *
4537 ethtool_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 
4563 err_free:
4564 	ethtool_tunnel_info_get_rsp_free(rsp);
4565 	return NULL;
4566 }
4567 
4568 /* ETHTOOL_MSG_TUNNEL_INFO_GET - dump */
4569 void
4570 ethtool_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 
4584 struct ethtool_tunnel_info_get_list *
4585 ethtool_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 
4610 free_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 */
4617 void ethtool_fec_get_req_free(struct ethtool_fec_get_req *req)
4618 {
4619 	ethtool_header_free(&req->header);
4620 	free(req);
4621 }
4622 
4623 void 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 
4631 int 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 
4687 struct ethtool_fec_get_rsp *
4688 ethtool_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 
4713 err_free:
4714 	ethtool_fec_get_rsp_free(rsp);
4715 	return NULL;
4716 }
4717 
4718 /* ETHTOOL_MSG_FEC_GET - dump */
4719 void 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 
4734 struct ethtool_fec_get_list *
4735 ethtool_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 
4759 free_list:
4760 	ethtool_fec_get_list_free(yds.first);
4761 	return NULL;
4762 }
4763 
4764 /* ETHTOOL_MSG_FEC_GET - notify */
4765 void 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 */
4775 void 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 
4783 int 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 */
4811 void
4812 ethtool_module_eeprom_get_req_free(struct ethtool_module_eeprom_get_req *req)
4813 {
4814 	ethtool_header_free(&req->header);
4815 	free(req);
4816 }
4817 
4818 void
4819 ethtool_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 
4826 int 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 
4889 struct ethtool_module_eeprom_get_rsp *
4890 ethtool_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 
4916 err_free:
4917 	ethtool_module_eeprom_get_rsp_free(rsp);
4918 	return NULL;
4919 }
4920 
4921 /* ETHTOOL_MSG_MODULE_EEPROM_GET - dump */
4922 void
4923 ethtool_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 
4937 struct ethtool_module_eeprom_get_list *
4938 ethtool_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 
4963 free_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 */
4970 void 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 
4976 void 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 
4982 int 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 
5015 struct ethtool_phc_vclocks_get_rsp *
5016 ethtool_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 
5042 err_free:
5043 	ethtool_phc_vclocks_get_rsp_free(rsp);
5044 	return NULL;
5045 }
5046 
5047 /* ETHTOOL_MSG_PHC_VCLOCKS_GET - dump */
5048 void
5049 ethtool_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 
5062 struct ethtool_phc_vclocks_get_list *
5063 ethtool_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 
5088 free_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 */
5095 void ethtool_module_get_req_free(struct ethtool_module_get_req *req)
5096 {
5097 	ethtool_header_free(&req->header);
5098 	free(req);
5099 }
5100 
5101 void ethtool_module_get_rsp_free(struct ethtool_module_get_rsp *rsp)
5102 {
5103 	ethtool_header_free(&rsp->header);
5104 	free(rsp);
5105 }
5106 
5107 int 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 
5145 struct ethtool_module_get_rsp *
5146 ethtool_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 
5171 err_free:
5172 	ethtool_module_get_rsp_free(rsp);
5173 	return NULL;
5174 }
5175 
5176 /* ETHTOOL_MSG_MODULE_GET - dump */
5177 void 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 
5190 struct ethtool_module_get_list *
5191 ethtool_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 
5216 free_list:
5217 	ethtool_module_get_list_free(yds.first);
5218 	return NULL;
5219 }
5220 
5221 /* ETHTOOL_MSG_MODULE_GET - notify */
5222 void 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 */
5230 void ethtool_module_set_req_free(struct ethtool_module_set_req *req)
5231 {
5232 	ethtool_header_free(&req->header);
5233 	free(req);
5234 }
5235 
5236 int 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 */
5260 void ethtool_pse_get_req_free(struct ethtool_pse_get_req *req)
5261 {
5262 	ethtool_header_free(&req->header);
5263 	free(req);
5264 }
5265 
5266 void ethtool_pse_get_rsp_free(struct ethtool_pse_get_rsp *rsp)
5267 {
5268 	ethtool_header_free(&rsp->header);
5269 	free(rsp);
5270 }
5271 
5272 int 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 
5315 struct ethtool_pse_get_rsp *
5316 ethtool_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 
5341 err_free:
5342 	ethtool_pse_get_rsp_free(rsp);
5343 	return NULL;
5344 }
5345 
5346 /* ETHTOOL_MSG_PSE_GET - dump */
5347 void 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 
5360 struct ethtool_pse_get_list *
5361 ethtool_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 
5385 free_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 */
5392 void ethtool_pse_set_req_free(struct ethtool_pse_set_req *req)
5393 {
5394 	ethtool_header_free(&req->header);
5395 	free(req);
5396 }
5397 
5398 int 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 */
5424 void ethtool_rss_get_req_free(struct ethtool_rss_get_req *req)
5425 {
5426 	ethtool_header_free(&req->header);
5427 	free(req);
5428 }
5429 
5430 void 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 
5438 int 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 
5496 struct ethtool_rss_get_rsp *
5497 ethtool_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 
5522 err_free:
5523 	ethtool_rss_get_rsp_free(rsp);
5524 	return NULL;
5525 }
5526 
5527 /* ETHTOOL_MSG_RSS_GET - dump */
5528 void 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 
5543 struct ethtool_rss_get_list *
5544 ethtool_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 
5568 free_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 */
5575 void 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 
5581 void 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 
5587 int 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 
5655 struct ethtool_plca_get_cfg_rsp *
5656 ethtool_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 
5681 err_free:
5682 	ethtool_plca_get_cfg_rsp_free(rsp);
5683 	return NULL;
5684 }
5685 
5686 /* ETHTOOL_MSG_PLCA_GET_CFG - dump */
5687 void 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 
5700 struct ethtool_plca_get_cfg_list *
5701 ethtool_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 
5726 free_list:
5727 	ethtool_plca_get_cfg_list_free(yds.first);
5728 	return NULL;
5729 }
5730 
5731 /* ETHTOOL_MSG_PLCA_GET_CFG - notify */
5732 void 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 */
5740 void 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 
5746 int 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 */
5783 void 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 
5789 void 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 
5795 int 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 
5863 struct ethtool_plca_get_status_rsp *
5864 ethtool_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 
5890 err_free:
5891 	ethtool_plca_get_status_rsp_free(rsp);
5892 	return NULL;
5893 }
5894 
5895 /* ETHTOOL_MSG_PLCA_GET_STATUS - dump */
5896 void
5897 ethtool_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 
5910 struct ethtool_plca_get_status_list *
5911 ethtool_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 
5936 free_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 */
5943 void ethtool_mm_get_req_free(struct ethtool_mm_get_req *req)
5944 {
5945 	ethtool_header_free(&req->header);
5946 	free(req);
5947 }
5948 
5949 void 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 
5956 int 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 
6033 struct ethtool_mm_get_rsp *
6034 ethtool_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 
6059 err_free:
6060 	ethtool_mm_get_rsp_free(rsp);
6061 	return NULL;
6062 }
6063 
6064 /* ETHTOOL_MSG_MM_GET - dump */
6065 void 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 
6079 struct ethtool_mm_get_list *
6080 ethtool_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 
6104 free_list:
6105 	ethtool_mm_get_list_free(yds.first);
6106 	return NULL;
6107 }
6108 
6109 /* ETHTOOL_MSG_MM_GET - notify */
6110 void 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 */
6119 void ethtool_mm_set_req_free(struct ethtool_mm_set_req *req)
6120 {
6121 	ethtool_header_free(&req->header);
6122 	free(req);
6123 }
6124 
6125 int 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 */
6154 int 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 
6187 void 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 */
6194 int 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 
6237 void 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 
6244 static 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 
6349 const 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