Michal Kubecek | 2b4a899 | 2019-12-27 15:55:18 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 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> |
Michal Kubecek | 041b1c5 | 2019-12-27 15:55:23 +0100 | [diff] [blame] | 9 | #include <net/sock.h> |
| 10 | |
| 11 | struct ethnl_req_info; |
| 12 | |
Michal Kubecek | 9813054 | 2020-03-12 21:07:38 +0100 | [diff] [blame] | 13 | int 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); |
Michal Kubecek | 041b1c5 | 2019-12-27 15:55:23 +0100 | [diff] [blame] | 17 | int ethnl_fill_reply_header(struct sk_buff *skb, struct net_device *dev, |
| 18 | u16 attrtype); |
| 19 | struct 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); |
Jakub Kicinski | c7d759e | 2020-07-09 17:42:47 -0700 | [diff] [blame] | 22 | void *ethnl_dump_put(struct sk_buff *skb, struct netlink_callback *cb, u8 cmd); |
Andrew Lunn | 0df960f | 2020-05-10 21:12:35 +0200 | [diff] [blame] | 23 | void *ethnl_bcastmsg_put(struct sk_buff *skb, u8 cmd); |
| 24 | int ethnl_multicast(struct sk_buff *skb, struct net_device *dev); |
Michal Kubecek | 041b1c5 | 2019-12-27 15:55:23 +0100 | [diff] [blame] | 25 | |
| 26 | /** |
| 27 | * ethnl_strz_size() - calculate attribute length for fixed size string |
| 28 | * @s: ETH_GSTRING_LEN sized string (may not be null terminated) |
| 29 | * |
| 30 | * Return: total length of an attribute with null terminated string from @s |
| 31 | */ |
| 32 | static inline int ethnl_strz_size(const char *s) |
| 33 | { |
| 34 | return nla_total_size(strnlen(s, ETH_GSTRING_LEN) + 1); |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * ethnl_put_strz() - put string attribute with fixed size string |
| 39 | * @skb: skb with the message |
| 40 | * @attrype: attribute type |
| 41 | * @s: ETH_GSTRING_LEN sized string (may not be null terminated) |
| 42 | * |
| 43 | * Puts an attribute with null terminated string from @s into the message. |
| 44 | * |
| 45 | * Return: 0 on success, negative error code on failure |
| 46 | */ |
| 47 | static 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 | * ethnl_update_u32() - update u32 value from NLA_U32 attribute |
| 64 | * @dst: value to update |
| 65 | * @attr: netlink attribute with new value or null |
| 66 | * @mod: pointer to bool for modification tracking |
| 67 | * |
| 68 | * Copy the u32 value from NLA_U32 netlink attribute @attr into variable |
| 69 | * pointed to by @dst; do nothing if @attr is null. Bool pointed to by @mod |
| 70 | * is set to true if this function changed the value of *dst, otherwise it |
| 71 | * is left as is. |
| 72 | */ |
| 73 | static 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 | * ethnl_update_u8() - update u8 value from NLA_U8 attribute |
| 90 | * @dst: value to update |
| 91 | * @attr: netlink attribute with new value or null |
| 92 | * @mod: pointer to bool for modification tracking |
| 93 | * |
| 94 | * Copy the u8 value from NLA_U8 netlink attribute @attr into variable |
| 95 | * pointed to by @dst; do nothing if @attr is null. Bool pointed to by @mod |
| 96 | * is set to true if this function changed the value of *dst, otherwise it |
| 97 | * is left as is. |
| 98 | */ |
| 99 | static 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 | * ethnl_update_bool32() - update u32 used as bool from NLA_U8 attribute |
| 116 | * @dst: value to update |
| 117 | * @attr: netlink attribute with new value or null |
| 118 | * @mod: pointer to bool for modification tracking |
| 119 | * |
| 120 | * Use the u8 value from NLA_U8 netlink attribute @attr to set u32 variable |
| 121 | * pointed to by @dst to 0 (if zero) or 1 (if not); do nothing if @attr is |
| 122 | * null. Bool pointed to by @mod is set to true if this function changed the |
| 123 | * logical value of *dst, otherwise it is left as is. |
| 124 | */ |
| 125 | static 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 | * ethnl_update_binary() - update binary data from NLA_BINARY atribute |
| 142 | * @dst: value to update |
| 143 | * @len: destination buffer length |
| 144 | * @attr: netlink attribute with new value or null |
| 145 | * @mod: pointer to bool for modification tracking |
| 146 | * |
| 147 | * Use the u8 value from NLA_U8 netlink attribute @attr to rewrite data block |
| 148 | * of length @len at @dst by attribute payload; do nothing if @attr is null. |
| 149 | * Bool pointed to by @mod is set to true if this function changed the logical |
| 150 | * value of *dst, otherwise it is left as is. |
| 151 | */ |
| 152 | static 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 | * ethnl_update_bitfield32() - update u32 value from NLA_BITFIELD32 attribute |
| 168 | * @dst: value to update |
| 169 | * @attr: netlink attribute with new value or null |
| 170 | * @mod: pointer to bool for modification tracking |
| 171 | * |
| 172 | * Update bits in u32 value which are set in attribute's mask to values from |
| 173 | * attribute's value. Do nothing if @attr is null or the value wouldn't change; |
| 174 | * otherwise, set bool pointed to by @mod to true. |
| 175 | */ |
| 176 | static 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 | * ethnl_reply_header_size() - total size of reply header |
| 195 | * |
| 196 | * This is an upper estimate so that we do not need to hold RTNL lock longer |
| 197 | * than necessary (to prevent rename between size estimate and composing the |
| 198 | * message). Accounts only for device ifindex and name as those are the only |
| 199 | * attributes ethnl_fill_reply_header() puts into the reply header. |
| 200 | */ |
| 201 | static 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 | |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 207 | /* GET request handling */ |
| 208 | |
| 209 | /* Unified processing of GET requests uses two data structures: request info |
| 210 | * and reply data. Request info holds information parsed from client request |
| 211 | * and its stays constant through all request processing. Reply data holds data |
| 212 | * retrieved from ethtool_ops callbacks or other internal sources which is used |
| 213 | * to compose the reply. When processing a dump request, request info is filled |
| 214 | * only once (when the request message is parsed) but reply data is filled for |
| 215 | * each reply message. |
| 216 | * |
| 217 | * Both structures consist of part common for all request types (struct |
| 218 | * ethnl_req_info and struct ethnl_reply_data defined below) and optional |
| 219 | * parts specific for each request type. Common part always starts at offset 0. |
| 220 | */ |
| 221 | |
Michal Kubecek | 041b1c5 | 2019-12-27 15:55:23 +0100 | [diff] [blame] | 222 | /** |
| 223 | * struct ethnl_req_info - base type of request information for GET requests |
| 224 | * @dev: network device the request is for (may be null) |
| 225 | * @flags: request flags common for all request types |
| 226 | * |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 227 | * This is a common base for request specific structures holding data from |
| 228 | * parsed userspace request. These always embed struct ethnl_req_info at |
| 229 | * zero offset. |
Michal Kubecek | 041b1c5 | 2019-12-27 15:55:23 +0100 | [diff] [blame] | 230 | */ |
| 231 | struct ethnl_req_info { |
| 232 | struct net_device *dev; |
| 233 | u32 flags; |
| 234 | }; |
Michal Kubecek | 2b4a899 | 2019-12-27 15:55:18 +0100 | [diff] [blame] | 235 | |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 236 | /** |
| 237 | * struct ethnl_reply_data - base type of reply data for GET requests |
| 238 | * @dev: device for current reply message; in single shot requests it is |
| 239 | * equal to ðnl_req_info.dev; in dumps it's different for each |
| 240 | * reply message |
| 241 | * |
| 242 | * This is a common base for request specific structures holding data for |
| 243 | * kernel reply message. These always embed struct ethnl_reply_data at zero |
| 244 | * offset. |
| 245 | */ |
| 246 | struct ethnl_reply_data { |
| 247 | struct net_device *dev; |
| 248 | }; |
| 249 | |
| 250 | static 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 | |
| 258 | static 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 | * struct ethnl_request_ops - unified handling of GET requests |
| 266 | * @request_cmd: command id for request (GET) |
| 267 | * @reply_cmd: command id for reply (GET_REPLY) |
| 268 | * @hdr_attr: attribute type for request header |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 269 | * @req_info_size: size of request info |
| 270 | * @reply_data_size: size of reply data |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 271 | * @allow_nodev_do: allow non-dump request with no device identification |
| 272 | * @parse_request: |
| 273 | * Parse request except common header (struct ethnl_req_info). Common |
| 274 | * header is already filled on entry, the rest up to @repdata_offset |
| 275 | * is zero initialized. This callback should only modify type specific |
| 276 | * request info by parsed attributes from request message. |
| 277 | * @prepare_data: |
| 278 | * Retrieve and prepare data needed to compose a reply message. Calls to |
| 279 | * ethtool_ops handlers are limited to this callback. Common reply data |
| 280 | * (struct ethnl_reply_data) is filled on entry, type specific part after |
| 281 | * it is zero initialized. This callback should only modify the type |
| 282 | * specific part of reply data. Device identification from struct |
| 283 | * ethnl_reply_data is to be used as for dump requests, it iterates |
| 284 | * through network devices while dev member of struct ethnl_req_info |
| 285 | * points to the device from client request. |
| 286 | * @reply_size: |
| 287 | * Estimate reply message size. Returned value must be sufficient for |
| 288 | * message payload without common reply header. The callback may returned |
| 289 | * estimate higher than actual message size if exact calculation would |
| 290 | * not be worth the saved memory space. |
| 291 | * @fill_reply: |
| 292 | * Fill reply message payload (except for common header) from reply data. |
| 293 | * The callback must not generate more payload than previously called |
| 294 | * ->reply_size() estimated. |
| 295 | * @cleanup_data: |
| 296 | * Optional cleanup called when reply data is no longer needed. Can be |
| 297 | * used e.g. to free any additional data structures outside the main |
| 298 | * structure which were allocated by ->prepare_data(). When processing |
| 299 | * dump requests, ->cleanup() is called for each message. |
| 300 | * |
| 301 | * Description of variable parts of GET request handling when using the |
| 302 | * unified infrastructure. When used, a pointer to an instance of this |
| 303 | * structure is to be added to ðnl_default_requests array and generic |
| 304 | * handlers ethnl_default_doit(), ethnl_default_dumpit(), |
Michal Kubecek | 5cf2a54 | 2019-12-27 15:55:58 +0100 | [diff] [blame] | 305 | * ethnl_default_start() and ethnl_default_done() used in @ethtool_genl_ops; |
| 306 | * ethnl_default_notify() can be used in @ethnl_notify_handlers to send |
| 307 | * notifications of the corresponding type. |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 308 | */ |
| 309 | struct ethnl_request_ops { |
| 310 | u8 request_cmd; |
| 311 | u8 reply_cmd; |
| 312 | u16 hdr_attr; |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 313 | unsigned int req_info_size; |
| 314 | unsigned int reply_data_size; |
Michal Kubecek | 728480f | 2019-12-27 15:55:38 +0100 | [diff] [blame] | 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 | |
Michal Kubecek | 7192169 | 2019-12-27 15:55:43 +0100 | [diff] [blame] | 331 | /* request handlers */ |
| 332 | |
| 333 | extern const struct ethnl_request_ops ethnl_strset_request_ops; |
Michal Kubecek | 459e0b8 | 2019-12-27 15:55:48 +0100 | [diff] [blame] | 334 | extern const struct ethnl_request_ops ethnl_linkinfo_request_ops; |
Michal Kubecek | f625aa9 | 2019-12-27 15:56:08 +0100 | [diff] [blame] | 335 | extern const struct ethnl_request_ops ethnl_linkmodes_request_ops; |
Michal Kubecek | 3d2b847 | 2019-12-27 15:56:23 +0100 | [diff] [blame] | 336 | extern const struct ethnl_request_ops ethnl_linkstate_request_ops; |
Michal Kubecek | 6a94b8c | 2020-01-26 23:11:04 +0100 | [diff] [blame] | 337 | extern const struct ethnl_request_ops ethnl_debug_request_ops; |
Michal Kubecek | 51ea22b | 2020-01-26 23:11:13 +0100 | [diff] [blame] | 338 | extern const struct ethnl_request_ops ethnl_wol_request_ops; |
Michal Kubecek | 0524399 | 2020-03-12 21:07:48 +0100 | [diff] [blame] | 339 | extern const struct ethnl_request_ops ethnl_features_request_ops; |
Michal Kubecek | e16c338 | 2020-03-12 21:08:08 +0100 | [diff] [blame] | 340 | extern const struct ethnl_request_ops ethnl_privflags_request_ops; |
Michal Kubecek | e4a1717 | 2020-03-12 21:08:23 +0100 | [diff] [blame] | 341 | extern const struct ethnl_request_ops ethnl_rings_request_ops; |
Michal Kubecek | 0c84979 | 2020-03-12 21:08:38 +0100 | [diff] [blame] | 342 | extern const struct ethnl_request_ops ethnl_channels_request_ops; |
Michal Kubecek | 2172754 | 2020-03-28 00:01:08 +0100 | [diff] [blame] | 343 | extern const struct ethnl_request_ops ethnl_coalesce_request_ops; |
Michal Kubecek | 7f59fb3 | 2020-03-28 00:01:23 +0100 | [diff] [blame] | 344 | extern const struct ethnl_request_ops ethnl_pause_request_ops; |
Michal Kubecek | b7eeefe | 2020-03-28 00:01:38 +0100 | [diff] [blame] | 345 | extern const struct ethnl_request_ops ethnl_eee_request_ops; |
Michal Kubecek | 5b071c5 | 2020-03-28 00:01:58 +0100 | [diff] [blame] | 346 | extern const struct ethnl_request_ops ethnl_tsinfo_request_ops; |
Michal Kubecek | 7192169 | 2019-12-27 15:55:43 +0100 | [diff] [blame] | 347 | |
Jakub Kicinski | 329d9c3 | 2020-10-05 15:07:36 -0700 | [diff] [blame] | 348 | extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1]; |
Jakub Kicinski | a0de1cd | 2020-10-05 15:07:39 -0700 | [diff] [blame] | 349 | extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1]; |
Jakub Kicinski | ff419af | 2020-10-05 15:07:35 -0700 | [diff] [blame] | 350 | extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_STRINGSETS + 1]; |
| 351 | extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1]; |
| 352 | extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1]; |
| 353 | extern const struct nla_policy ethnl_linkmodes_get_policy[ETHTOOL_A_LINKMODES_HEADER + 1]; |
| 354 | extern const struct nla_policy ethnl_linkmodes_set_policy[ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG + 1]; |
| 355 | extern const struct nla_policy ethnl_linkstate_get_policy[ETHTOOL_A_LINKSTATE_HEADER + 1]; |
| 356 | extern const struct nla_policy ethnl_debug_get_policy[ETHTOOL_A_DEBUG_HEADER + 1]; |
| 357 | extern const struct nla_policy ethnl_debug_set_policy[ETHTOOL_A_DEBUG_MSGMASK + 1]; |
| 358 | extern const struct nla_policy ethnl_wol_get_policy[ETHTOOL_A_WOL_HEADER + 1]; |
| 359 | extern const struct nla_policy ethnl_wol_set_policy[ETHTOOL_A_WOL_SOPASS + 1]; |
| 360 | extern const struct nla_policy ethnl_features_get_policy[ETHTOOL_A_FEATURES_HEADER + 1]; |
| 361 | extern const struct nla_policy ethnl_features_set_policy[ETHTOOL_A_FEATURES_WANTED + 1]; |
| 362 | extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1]; |
| 363 | extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1]; |
| 364 | extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1]; |
| 365 | extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_TX + 1]; |
| 366 | extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1]; |
| 367 | extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1]; |
| 368 | extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1]; |
| 369 | extern const struct nla_policy ethnl_coalesce_set_policy[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL + 1]; |
| 370 | extern const struct nla_policy ethnl_pause_get_policy[ETHTOOL_A_PAUSE_HEADER + 1]; |
| 371 | extern const struct nla_policy ethnl_pause_set_policy[ETHTOOL_A_PAUSE_TX + 1]; |
| 372 | extern const struct nla_policy ethnl_eee_get_policy[ETHTOOL_A_EEE_HEADER + 1]; |
| 373 | extern const struct nla_policy ethnl_eee_set_policy[ETHTOOL_A_EEE_TX_LPI_TIMER + 1]; |
| 374 | extern const struct nla_policy ethnl_tsinfo_get_policy[ETHTOOL_A_TSINFO_HEADER + 1]; |
| 375 | extern const struct nla_policy ethnl_cable_test_act_policy[ETHTOOL_A_CABLE_TEST_HEADER + 1]; |
| 376 | extern const struct nla_policy ethnl_cable_test_tdr_act_policy[ETHTOOL_A_CABLE_TEST_TDR_CFG + 1]; |
| 377 | extern const struct nla_policy ethnl_tunnel_info_get_policy[ETHTOOL_A_TUNNEL_INFO_HEADER + 1]; |
Jakub Kicinski | 4f30974 | 2020-10-05 15:07:33 -0700 | [diff] [blame] | 378 | |
Michal Kubecek | a53f3d4 | 2019-12-27 15:55:53 +0100 | [diff] [blame] | 379 | int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | bfbcfe2 | 2019-12-27 15:56:13 +0100 | [diff] [blame] | 380 | int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | e54d04e | 2020-01-26 23:11:07 +0100 | [diff] [blame] | 381 | int ethnl_set_debug(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | 8d425b1 | 2020-01-26 23:11:16 +0100 | [diff] [blame] | 382 | int ethnl_set_wol(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | 0980bfc | 2020-03-12 21:07:58 +0100 | [diff] [blame] | 383 | int ethnl_set_features(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | f265d79 | 2020-03-12 21:08:13 +0100 | [diff] [blame] | 384 | int ethnl_set_privflags(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | 2fc2929 | 2020-03-12 21:08:28 +0100 | [diff] [blame] | 385 | int ethnl_set_rings(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | e19c591 | 2020-03-12 21:08:43 +0100 | [diff] [blame] | 386 | int ethnl_set_channels(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | 9881418 | 2020-03-28 00:01:13 +0100 | [diff] [blame] | 387 | int ethnl_set_coalesce(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | 3ab8799 | 2020-03-28 00:01:28 +0100 | [diff] [blame] | 388 | int ethnl_set_pause(struct sk_buff *skb, struct genl_info *info); |
Michal Kubecek | fd77be7 | 2020-03-28 00:01:43 +0100 | [diff] [blame] | 389 | int ethnl_set_eee(struct sk_buff *skb, struct genl_info *info); |
Andrew Lunn | 11ca3c42 | 2020-05-10 21:12:33 +0200 | [diff] [blame] | 390 | int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info); |
Andrew Lunn | 1a644de | 2020-05-27 00:21:38 +0200 | [diff] [blame] | 391 | int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info); |
Jakub Kicinski | c7d759e | 2020-07-09 17:42:47 -0700 | [diff] [blame] | 392 | int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info); |
| 393 | int ethnl_tunnel_info_start(struct netlink_callback *cb); |
| 394 | int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb); |
Michal Kubecek | a53f3d4 | 2019-12-27 15:55:53 +0100 | [diff] [blame] | 395 | |
Michal Kubecek | 2b4a899 | 2019-12-27 15:55:18 +0100 | [diff] [blame] | 396 | #endif /* _NET_ETHTOOL_NETLINK_H */ |