// SPDX-License-Identifier: GPL-2.0-only
#include <net/netdev_lock.h>
#include "netlink.h"
#include "common.h"
struct rss_req_info {
struct ethnl_req_info base;
u32 rss_context;
};
struct rss_reply_data {
struct ethnl_reply_data base;
bool has_flow_hash;
bool no_key_fields;
u32 indir_size;
u32 hkey_size;
u32 hfunc;
u32 input_xfrm;
u32 *indir_table;
u8 *hkey;
int flow_hash[__ETHTOOL_A_FLOW_CNT];
};
static const u8 ethtool_rxfh_ft_nl2ioctl[] = {
[ETHTOOL_A_FLOW_ETHER] = ETHER_FLOW,
[ETHTOOL_A_FLOW_IP4] = IPV4_FLOW,
[ETHTOOL_A_FLOW_IP6] = IPV6_FLOW,
[ETHTOOL_A_FLOW_TCP4] = TCP_V4_FLOW,
[ETHTOOL_A_FLOW_UDP4] = UDP_V4_FLOW,
[ETHTOOL_A_FLOW_SCTP4] = SCTP_V4_FLOW,
[ETHTOOL_A_FLOW_AH_ESP4] = AH_ESP_V4_FLOW,
[ETHTOOL_A_FLOW_TCP6] = TCP_V6_FLOW,
[ETHTOOL_A_FLOW_UDP6] = UDP_V6_FLOW,
[ETHTOOL_A_FLOW_SCTP6] = SCTP_V6_FLOW,
[ETHTOOL_A_FLOW_AH_ESP6] = AH_ESP_V6_FLOW,
[ETHTOOL_A_FLOW_AH4] = AH_V4_FLOW,
[ETHTOOL_A_FLOW_ESP4] = ESP_V4_FLOW,
[ETHTOOL_A_FLOW_AH6] = AH_V6_FLOW,
[ETHTOOL_A_FLOW_ESP6] = ESP_V6_FLOW,
[ETHTOOL_A_FLOW_GTPU4] = GTPU_V4_FLOW,
[ETHTOOL_A_FLOW_GTPU6] = GTPU_V6_FLOW,
[ETHTOOL_A_FLOW_GTPC4] = GTPC_V4_FLOW,
[ETHTOOL_A_FLOW_GTPC6] = GTPC_V6_FLOW,
[ETHTOOL_A_FLOW_GTPC_TEID4] = GTPC_TEID_V4_FLOW,
[ETHTOOL_A_FLOW_GTPC_TEID6] = GTPC_TEID_V6_FLOW,
[ETHTOOL_A_FLOW_GTPU_EH4] = GTPU_EH_V4_FLOW,
[ETHTOOL_A_FLOW_GTPU_EH6] = GTPU_EH_V6_FLOW,
[ETHTOOL_A_FLOW_GTPU_UL4] = GTPU_UL_V4_FLOW,
[ETHTOOL_A_FLOW_GTPU_UL6] = GTPU_UL_V6_FLOW,
[ETHTOOL_A_FLOW_GTPU_DL4] = GTPU_DL_V4_FLOW,
[ETHTOOL_A_FLOW_GTPU_DL6] = GTPU_DL_V6_FLOW,
};
#define RSS_REQINFO(__req_base) \
container_of(__req_base, struct rss_req_info, base)
#define RSS_REPDATA(__reply_base) \
container_of(__reply_base, struct rss_reply_data, base)
const struct nla_policy ethnl_rss_get_policy[] = {
[ETHTOOL_A_RSS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
[ETHTOOL_A_RSS_CONTEXT] = { .type = NLA_U32 },
[ETHTOOL_A_RSS_START_CONTEXT] = { .type = NLA_U32 },
};
static int
rss_parse_request(struct ethnl_req_info *req_info, struct nlattr **tb,
struct netlink_ext_ack *extack)
{
struct rss_req_info *request = RSS_REQINFO(req_info);
if (tb[ETHTOOL_A_RSS_CONTEXT])
request->rss_context = nla_get_u32(tb[ETHTOOL_A_RSS_CONTEXT]);
if (tb[ETHTOOL_A_RSS_START_CONTEXT]) {
NL_SET_BAD_ATTR(extack, tb[ETHTOOL_A_RSS_START_CONTEXT]);
return -EINVAL;
}
return 0;
}
static void
rss_prepare_flow_hash(const struct rss_req_info *req, struct net_device *dev,
struct