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
250int ethnl_ops_begin(struct net_device *dev);
251void ethnl_ops_complete(struct net_device *dev);
252
253
254
255
256
257
258
259
260
261
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
298struct ethnl_request_ops {
299 u8 request_cmd;
300 u8 reply_cmd;
301 u16 hdr_attr;
302 unsigned int req_info_size;
303 unsigned int reply_data_size;
304 bool allow_nodev_do;
305
306 int (*parse_request)(struct ethnl_req_info *req_info,
307 struct nlattr **tb,
308 struct netlink_ext_ack *extack);
309 int (*prepare_data)(const struct ethnl_req_info *req_info,
310 struct ethnl_reply_data *reply_data,
311 struct genl_info *info);
312 int (*reply_size)(const struct ethnl_req_info *req_info,
313 const struct ethnl_reply_data *reply_data);
314 int (*fill_reply)(struct sk_buff *skb,
315 const struct ethnl_req_info *req_info,
316 const struct ethnl_reply_data *reply_data);
317 void (*cleanup_data)(struct ethnl_reply_data *reply_data);
318};
319
320
321
322extern const struct ethnl_request_ops ethnl_strset_request_ops;
323extern const struct ethnl_request_ops ethnl_linkinfo_request_ops;
324extern const struct ethnl_request_ops ethnl_linkmodes_request_ops;
325extern const struct ethnl_request_ops ethnl_linkstate_request_ops;
326extern const struct ethnl_request_ops ethnl_debug_request_ops;
327extern const struct ethnl_request_ops ethnl_wol_request_ops;
328extern const struct ethnl_request_ops ethnl_features_request_ops;
329extern const struct ethnl_request_ops ethnl_privflags_request_ops;
330extern const struct ethnl_request_ops ethnl_rings_request_ops;
331extern const struct ethnl_request_ops ethnl_channels_request_ops;
332extern const struct ethnl_request_ops ethnl_coalesce_request_ops;
333extern const struct ethnl_request_ops ethnl_pause_request_ops;
334extern const struct ethnl_request_ops ethnl_eee_request_ops;
335extern const struct ethnl_request_ops ethnl_tsinfo_request_ops;
336extern const struct ethnl_request_ops ethnl_fec_request_ops;
337extern const struct ethnl_request_ops ethnl_module_eeprom_request_ops;
338extern const struct ethnl_request_ops ethnl_stats_request_ops;
339extern const struct ethnl_request_ops ethnl_phc_vclocks_request_ops;
340
341extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
342extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
343extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_ONLY + 1];
344extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1];
345extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1];
346extern const struct nla_policy ethnl_linkmodes_get_policy[ETHTOOL_A_LINKMODES_HEADER + 1];
347extern const struct nla_policy ethnl_linkmodes_set_policy[ETHTOOL_A_LINKMODES_LANES + 1];
348extern const struct nla_policy ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_HEADER + 1];
349extern const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_HEADER + 1];
350extern const struct nla_policy ethnl_debug_set_policy[ETHTOOL_A_DEBUG_MSGMASK + 1];
351extern const struct nla_policy ethnl_wol_get_policy[ETHTOOL_A_WOL_HEADER + 1];
352extern const struct nla_policy ethnl_wol_set_policy[ETHTOOL_A_WOL_SOPASS + 1];
353extern const struct nla_policy ethnl_features_get_policy[ETHTOOL_A_FEATURES_HEADER + 1];
354extern const struct nla_policy ethnl_features_set_policy[ETHTOOL_A_FEATURES_WANTED + 1];
355extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1];
356extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1];
357extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1];
358extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_TX + 1];
359extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1];
360extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1];
361extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1];
362extern const struct nla_policy ethnl_coalesce_set_policy[ETHTOOL_A_COALESCE_MAX + 1];
363extern const struct nla_policy ethnl_pause_get_policy[ETHTOOL_A_PAUSE_HEADER + 1];
364extern const struct nla_policy ethnl_pause_set_policy[ETHTOOL_A_PAUSE_TX + 1];
365extern const struct nla_policy ethnl_eee_get_policy[ETHTOOL_A_EEE_HEADER + 1];
366extern const struct nla_policy ethnl_eee_set_policy[ETHTOOL_A_EEE_TX_LPI_TIMER + 1];
367extern const struct nla_policy ethnl_tsinfo_get_policy[ETHTOOL_A_TSINFO_HEADER + 1];
368extern const struct nla_policy ethnl_cable_test_act_policy[ETHTOOL_A_CABLE_TEST_HEADER + 1];
369extern const struct nla_policy ethnl_cable_test_tdr_act_policy[ETHTOOL_A_CABLE_TEST_TDR_CFG + 1];
370extern const struct nla_policy ethnl_tunnel_info_get_policy[ETHTOOL_A_TUNNEL_INFO_HEADER + 1];
371extern const struct nla_policy ethnl_fec_get_policy[ETHTOOL_A_FEC_HEADER + 1];
372extern const struct nla_policy ethnl_fec_set_policy[ETHTOOL_A_FEC_AUTO + 1];
373extern const struct nla_policy ethnl_module_eeprom_get_policy[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS + 1];
374extern const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1];
375extern const struct nla_policy ethnl_phc_vclocks_get_policy[ETHTOOL_A_PHC_VCLOCKS_HEADER + 1];
376
377int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info);
378int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info);
379int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info);
380int ethnl_set_wol(struct sk_buff *skb, struct genl_info *info);
381int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
382int ethnl_set_privflags(struct sk_buff *skb, struct genl_info *info);
383int ethnl_set_rings(struct sk_buff *skb, struct genl_info *info);
384int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info);
385int ethnl_set_coalesce(struct sk_buff *skb, struct genl_info *info);
386int ethnl_set_pause(struct sk_buff *skb, struct genl_info *info);
387int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info);
388int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
389int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info);
390int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info);
391int ethnl_tunnel_info_start(struct netlink_callback *cb);
392int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
393int ethnl_set_fec(struct sk_buff *skb, struct genl_info *info);
394
395extern const char stats_std_names[__ETHTOOL_STATS_CNT][ETH_GSTRING_LEN];
396extern const char stats_eth_phy_names[__ETHTOOL_A_STATS_ETH_PHY_CNT][ETH_GSTRING_LEN];
397extern const char stats_eth_mac_names[__ETHTOOL_A_STATS_ETH_MAC_CNT][ETH_GSTRING_LEN];
398extern const char stats_eth_ctrl_names[__ETHTOOL_A_STATS_ETH_CTRL_CNT][ETH_GSTRING_LEN];
399extern const char stats_rmon_names[__ETHTOOL_A_STATS_RMON_CNT][ETH_GSTRING_LEN];
400
401#endif
402