1
2
3#ifndef _NET_ETHTOOL_NETLINK_H
4#define _NET_ETHTOOL_NETLINK_H
5
6#include <linux/ethtool_netlink.h>
7#include <linux/netdevice.h>
8#include <net/genetlink.h>
9#include <net/sock.h>
10
11struct ethnl_req_info;
12
13int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
14 const struct nlattr *nest, struct net *net,
15 struct netlink_ext_ack *extack,
16 bool require_dev);
17int ethnl_fill_reply_header(struct sk_buff *skb, struct net_device *dev,
18 u16 attrtype);
19struct sk_buff *ethnl_reply_init(size_t payload, struct net_device *dev, u8 cmd,
20 u16 hdr_attrtype, struct genl_info *info,
21 void **ehdrp);
22void *ethnl_dump_put(struct sk_buff *skb, struct netlink_callback *cb, u8 cmd);
23void *ethnl_bcastmsg_put(struct sk_buff *skb, u8 cmd);
24int ethnl_multicast(struct sk_buff *skb, struct net_device *dev);
25
26
27
28
29
30
31
32static inline int ethnl_strz_size(const char *s)
33{
34 return nla_total_size(strnlen(s, ETH_GSTRING_LEN) + 1);
35}
36
37
38
39
40
41
42
43
44
45
46
47static inline int ethnl_put_strz(struct sk_buff *skb, u16 attrtype,
48 const char *s)
49{
50 unsigned int len = strnlen(s, ETH_GSTRING_LEN);
51 struct nlattr *attr;
52
53 attr = nla_reserve(skb, attrtype, len + 1);
54 if (!attr)
55 return -EMSGSIZE;
56
57 memcpy(nla_data(attr), s, len);
58 ((char *)nla_data(attr))[len] = '\0';
59 return 0;
60}
61
62
63
64
65
66
67
68
69
70
71
72
73static inline void ethnl_update_u32(u32 *dst, const struct nlattr *attr,
74 bool *mod)
75{
76 u32 val;
77
78 if (!attr)
79 return;
80 val = nla_get_u32(attr);
81 if (*dst == val)
82 return;
83
84 *dst = val;
85 *mod = true;
86}
87
88
89
90
91
92
93
94
95
96
97
98
99static inline void ethnl_update_u8(u8 *dst, const struct nlattr *attr,
100 bool *mod)
101{
102 u8 val;
103
104 if (!attr)
105 return;
106 val = nla_get_u8(attr);
107 if (*dst == val)
108 return;
109
110 *dst = val;
111 *mod = true;
112}
113
114
115
116
117
118
119
120
121
122
123
124
125static inline void ethnl_update_bool32(u32 *dst, const struct nlattr *attr,
126 bool *mod)
127{
128 u8 val;
129
130 if (!attr)
131 return;
132 val = !!nla_get_u8(attr);
133 if (!!*dst == val)
134 return;
135
136 *dst = val;
137 *mod = true;
138}
139
140
141
142
143
144
145
146
147
148
149
150
151
152static inline void ethnl_update_binary(void *dst, unsigned int len,
153 const struct nlattr *attr, bool *mod)
154{
155 if (!attr)
156 return;
157 if (nla_len(attr) < len)
158 len = nla_len(attr);
159 if (!memcmp(dst, nla_data(attr), len))
160 return;
161
162 memcpy(dst, nla_data(attr), len);
163 *mod = true;
164}
165
166
167
168
169
170
171
172
173
174
175
176static inline void ethnl_update_bitfield32(u32 *dst, const struct nlattr *attr,
177 bool *mod)
178{
179 struct nla_bitfield32 change;
180 u32 newval;
181
182 if (!attr)
183 return;
184 change = nla_get_bitfield32(attr);
185 newval = (*dst & ~change.selector) | (change.value & change.selector);
186 if (*dst == newval)
187 return;
188
189 *dst = newval;
190 *mod = true;
191}
192
193
194
195
196
197
198
199
200
201static inline unsigned int ethnl_reply_header_size(void)
202{
203 return nla_total_size(nla_total_size(sizeof(u32)) +
204 nla_total_size(IFNAMSIZ));
205}
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231struct ethnl_req_info {
232 struct net_device *dev;
233 u32 flags;
234};
235
236
237
238
239
240
241
242
243
244
245
246struct ethnl_reply_data {
247 struct net_device *dev;
248};
249
250static inline int ethnl_ops_begin(struct net_device *dev)
251{
252 if (dev && dev->ethtool_ops->begin)
253 return dev->ethtool_ops->begin(dev);
254 else
255 return 0;
256}
257
258static inline void ethnl_ops_complete(struct net_device *dev)
259{
260 if (dev && dev->ethtool_ops->complete)
261 dev->ethtool_ops->complete(dev);
262}
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309struct ethnl_request_ops {
310 u8 request_cmd;
311 u8 reply_cmd;
312 u16 hdr_attr;
313 unsigned int req_info_size;
314 unsigned int reply_data_size;
315 bool allow_nodev_do;
316
317 int (*parse_request)(struct ethnl_req_info *req_info,
318 struct nlattr **tb,
319 struct netlink_ext_ack *extack);
320 int (*prepare_data)(const struct ethnl_req_info *req_info,
321 struct ethnl_reply_data *reply_data,
322 struct genl_info *info);
323 int (*reply_size)(const struct ethnl_req_info *req_info,
324 const struct ethnl_reply_data *reply_data);
325 int (*fill_reply)(struct sk_buff *skb,
326 const struct ethnl_req_info *req_info,
327 const struct ethnl_reply_data *reply_data);
328 void (*cleanup_data)(struct ethnl_reply_data *reply_data);
329};
330
331
332
333extern const struct ethnl_request_ops ethnl_strset_request_ops;
334extern const struct ethnl_request_ops ethnl_linkinfo_request_ops;
335extern const struct ethnl_request_ops ethnl_linkmodes_request_ops;
336extern const struct ethnl_request_ops ethnl_linkstate_request_ops;
337extern const struct ethnl_request_ops ethnl_debug_request_ops;
338extern const struct ethnl_request_ops ethnl_wol_request_ops;
339extern const struct ethnl_request_ops ethnl_features_request_ops;
340extern const struct ethnl_request_ops ethnl_privflags_request_ops;
341extern const struct ethnl_request_ops ethnl_rings_request_ops;
342extern const struct ethnl_request_ops ethnl_channels_request_ops;
343extern const struct ethnl_request_ops ethnl_coalesce_request_ops;
344extern const struct ethnl_request_ops ethnl_pause_request_ops;
345extern const struct ethnl_request_ops ethnl_eee_request_ops;
346extern const struct ethnl_request_ops ethnl_tsinfo_request_ops;
347extern const struct ethnl_request_ops ethnl_fec_request_ops;
348extern const struct ethnl_request_ops ethnl_module_eeprom_request_ops;
349extern const struct ethnl_request_ops ethnl_stats_request_ops;
350
351extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
352extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
353extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_ONLY + 1];
354extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1];
355extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1];
356extern const struct nla_policy ethnl_linkmodes_get_policy[ETHTOOL_A_LINKMODES_HEADER + 1];
357extern const struct nla_policy ethnl_linkmodes_set_policy[ETHTOOL_A_LINKMODES_LANES + 1];
358extern const struct nla_policy ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_HEADER + 1];
359extern const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_HEADER + 1];
360extern const struct nla_policy ethnl_debug_set_policy[ETHTOOL_A_DEBUG_MSGMASK + 1];
361extern const struct nla_policy ethnl_wol_get_policy[ETHTOOL_A_WOL_HEADER + 1];
362extern const struct nla_policy ethnl_wol_set_policy[ETHTOOL_A_WOL_SOPASS + 1];
363extern const struct nla_policy ethnl_features_get_policy[ETHTOOL_A_FEATURES_HEADER + 1];
364extern const struct nla_policy ethnl_features_set_policy[ETHTOOL_A_FEATURES_WANTED + 1];
365extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1];
366extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1];
367extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1];
368extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_TX + 1];
369extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1];
370extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1];
371extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1];
372extern const struct nla_policy ethnl_coalesce_set_policy[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL + 1];
373extern const struct nla_policy ethnl_pause_get_policy[ETHTOOL_A_PAUSE_HEADER + 1];
374extern const struct nla_policy ethnl_pause_set_policy[ETHTOOL_A_PAUSE_TX + 1];
375extern const struct nla_policy ethnl_eee_get_policy[ETHTOOL_A_EEE_HEADER + 1];
376extern const struct nla_policy ethnl_eee_set_policy[ETHTOOL_A_EEE_TX_LPI_TIMER + 1];
377extern const struct nla_policy ethnl_tsinfo_get_policy[ETHTOOL_A_TSINFO_HEADER + 1];
378extern const struct nla_policy ethnl_cable_test_act_policy[ETHTOOL_A_CABLE_TEST_HEADER + 1];
379extern const struct nla_policy ethnl_cable_test_tdr_act_policy[ETHTOOL_A_CABLE_TEST_TDR_CFG + 1];
380extern const struct nla_policy ethnl_tunnel_info_get_policy[ETHTOOL_A_TUNNEL_INFO_HEADER + 1];
381extern const struct nla_policy ethnl_fec_get_policy[ETHTOOL_A_FEC_HEADER + 1];
382extern const struct nla_policy ethnl_fec_set_policy[ETHTOOL_A_FEC_AUTO + 1];
383extern const struct nla_policy ethnl_module_eeprom_get_policy[ETHTOOL_A_MODULE_EEPROM_DATA + 1];
384extern const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1];
385
386int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info);
387int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info);
388int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info);
389int ethnl_set_wol(struct sk_buff *skb, struct genl_info *info);
390int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
391int ethnl_set_privflags(struct sk_buff *skb, struct genl_info *info);
392int ethnl_set_rings(struct sk_buff *skb, struct genl_info *info);
393int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info);
394int ethnl_set_coalesce(struct sk_buff *skb, struct genl_info *info);
395int ethnl_set_pause(struct sk_buff *skb, struct genl_info *info);
396int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info);
397int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
398int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info);
399int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info);
400int ethnl_tunnel_info_start(struct netlink_callback *cb);
401int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
402int ethnl_set_fec(struct sk_buff *skb, struct genl_info *info);
403
404extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN];
405extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN];
406extern const char stats_eth_mac_names[__ETHTOOL_A_STATS_ETH_MAC_CNT][ETH_GSTRING_LEN];
407extern const char stats_eth_ctrl_names[__ETHTOOL_A_STATS_ETH_CTRL_CNT][ETH_GSTRING_LEN];
408extern const char stats_rmon_names[__ETHTOOL_A_STATS_RMON_CNT][ETH_GSTRING_LEN];
409
410#endif
411