net/ethtool/tsinfo.c

Source file repositories/reference/linux-study-clean/net/ethtool/tsinfo.c

File Facts

System
Linux kernel
Corpus path
net/ethtool/tsinfo.c
Extension
.c
Size
14967 bytes
Lines
576
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tsinfo_req_info {
	struct ethnl_req_info		base;
	struct hwtstamp_provider_desc	hwprov_desc;
};

struct tsinfo_reply_data {
	struct ethnl_reply_data		base;
	struct kernel_ethtool_ts_info	ts_info;
	struct ethtool_ts_stats		stats;
};

#define TSINFO_REQINFO(__req_base) \
	container_of(__req_base, struct tsinfo_req_info, base)

#define TSINFO_REPDATA(__reply_base) \
	container_of(__reply_base, struct tsinfo_reply_data, base)

#define ETHTOOL_TS_STAT_CNT \
	(__ETHTOOL_A_TS_STAT_CNT - (ETHTOOL_A_TS_STAT_UNSPEC + 1))

const struct nla_policy ethnl_tsinfo_get_policy[ETHTOOL_A_TSINFO_MAX + 1] = {
	[ETHTOOL_A_TSINFO_HEADER]		=
		NLA_POLICY_NESTED(ethnl_header_policy_stats),
	[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER] =
		NLA_POLICY_NESTED(ethnl_ts_hwtst_prov_policy),
};

int ts_parse_hwtst_provider(const struct nlattr *nest,
			    struct hwtstamp_provider_desc *hwprov_desc,
			    struct netlink_ext_ack *extack,
			    bool *mod)
{
	struct nlattr *tb[ARRAY_SIZE(ethnl_ts_hwtst_prov_policy)];
	int ret;

	ret = nla_parse_nested(tb,
			       ARRAY_SIZE(ethnl_ts_hwtst_prov_policy) - 1,
			       nest,
			       ethnl_ts_hwtst_prov_policy, extack);
	if (ret < 0)
		return ret;

	if (NL_REQ_ATTR_CHECK(extack, nest, tb,
			      ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX) ||
	    NL_REQ_ATTR_CHECK(extack, nest, tb,
			      ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER))
		return -EINVAL;

	ethnl_update_u32(&hwprov_desc->index,
			 tb[ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX],
			 mod);
	ethnl_update_u32(&hwprov_desc->qualifier,
			 tb[ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER],
			 mod);

	return 0;
}

static int
tsinfo_parse_request(struct ethnl_req_info *req_base,
		     const struct genl_info *info,
		     struct nlattr **tb,
		     struct netlink_ext_ack *extack)
{
	struct tsinfo_req_info *req = TSINFO_REQINFO(req_base);
	bool mod = false;

	req->hwprov_desc.index = -1;

	if (!tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER])
		return 0;

	if (req_base->flags & ETHTOOL_FLAG_STATS) {
		NL_SET_ERR_MSG(extack, "can't query statistics for a provider");
		return -EOPNOTSUPP;
	}

	return ts_parse_hwtst_provider(tb[ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER],
				       &req->hwprov_desc, extack, &mod);
}

static int tsinfo_prepare_data(const struct ethnl_req_info *req_base,
			       struct ethnl_reply_data *reply_base,
			       const struct genl_info *info)
{
	struct tsinfo_reply_data *data = TSINFO_REPDATA(reply_base);
	struct tsinfo_req_info *req = TSINFO_REQINFO(req_base);
	struct net_device *dev = reply_base->dev;
	int ret;

Annotation

Implementation Notes