1*1b481fc3SMaciej Żenczykowski /*
2*1b481fc3SMaciej Żenczykowski * stats.c - netlink implementation of stats
3*1b481fc3SMaciej Żenczykowski *
4*1b481fc3SMaciej Żenczykowski * Implementation of "ethtool -S <dev> [--groups <types>] etc."
5*1b481fc3SMaciej Żenczykowski */
6*1b481fc3SMaciej Żenczykowski
7*1b481fc3SMaciej Żenczykowski #include <errno.h>
8*1b481fc3SMaciej Żenczykowski #include <ctype.h>
9*1b481fc3SMaciej Żenczykowski #include <inttypes.h>
10*1b481fc3SMaciej Żenczykowski #include <string.h>
11*1b481fc3SMaciej Żenczykowski #include <stdio.h>
12*1b481fc3SMaciej Żenczykowski
13*1b481fc3SMaciej Żenczykowski #include "../internal.h"
14*1b481fc3SMaciej Żenczykowski #include "../common.h"
15*1b481fc3SMaciej Żenczykowski #include "netlink.h"
16*1b481fc3SMaciej Żenczykowski #include "parser.h"
17*1b481fc3SMaciej Żenczykowski #include "strset.h"
18*1b481fc3SMaciej Żenczykowski
parse_rmon_hist_one(const char * grp_name,const struct nlattr * hist,const char * dir)19*1b481fc3SMaciej Żenczykowski static int parse_rmon_hist_one(const char *grp_name, const struct nlattr *hist,
20*1b481fc3SMaciej Żenczykowski const char *dir)
21*1b481fc3SMaciej Żenczykowski {
22*1b481fc3SMaciej Żenczykowski const struct nlattr *tb[ETHTOOL_A_STATS_GRP_HIST_VAL + 1] = {};
23*1b481fc3SMaciej Żenczykowski DECLARE_ATTR_TB_INFO(tb);
24*1b481fc3SMaciej Żenczykowski unsigned long long val;
25*1b481fc3SMaciej Żenczykowski unsigned int low, hi;
26*1b481fc3SMaciej Żenczykowski int ret;
27*1b481fc3SMaciej Żenczykowski
28*1b481fc3SMaciej Żenczykowski ret = mnl_attr_parse_nested(hist, attr_cb, &tb_info);
29*1b481fc3SMaciej Żenczykowski if (ret < 0) {
30*1b481fc3SMaciej Żenczykowski fprintf(stderr, "invalid kernel response - malformed histogram entry\n");
31*1b481fc3SMaciej Żenczykowski return 1;
32*1b481fc3SMaciej Żenczykowski }
33*1b481fc3SMaciej Żenczykowski
34*1b481fc3SMaciej Żenczykowski if (!tb[ETHTOOL_A_STATS_GRP_HIST_BKT_LOW] ||
35*1b481fc3SMaciej Żenczykowski !tb[ETHTOOL_A_STATS_GRP_HIST_BKT_HI] ||
36*1b481fc3SMaciej Żenczykowski !tb[ETHTOOL_A_STATS_GRP_HIST_VAL]) {
37*1b481fc3SMaciej Żenczykowski fprintf(stderr, "invalid kernel response - histogram entry missing attributes\n");
38*1b481fc3SMaciej Żenczykowski return 1;
39*1b481fc3SMaciej Żenczykowski }
40*1b481fc3SMaciej Żenczykowski
41*1b481fc3SMaciej Żenczykowski low = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_HIST_BKT_LOW]);
42*1b481fc3SMaciej Żenczykowski hi = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_HIST_BKT_HI]);
43*1b481fc3SMaciej Żenczykowski val = mnl_attr_get_u64(tb[ETHTOOL_A_STATS_GRP_HIST_VAL]);
44*1b481fc3SMaciej Żenczykowski
45*1b481fc3SMaciej Żenczykowski if (!is_json_context()) {
46*1b481fc3SMaciej Żenczykowski fprintf(stdout, "%s-%s-etherStatsPkts", dir, grp_name);
47*1b481fc3SMaciej Żenczykowski
48*1b481fc3SMaciej Żenczykowski if (low && hi) {
49*1b481fc3SMaciej Żenczykowski fprintf(stdout, "%uto%uOctets: %llu\n", low, hi, val);
50*1b481fc3SMaciej Żenczykowski } else if (hi) {
51*1b481fc3SMaciej Żenczykowski fprintf(stdout, "%uOctets: %llu\n", hi, val);
52*1b481fc3SMaciej Żenczykowski } else if (low) {
53*1b481fc3SMaciej Żenczykowski fprintf(stdout, "%utoMaxOctets: %llu\n", low, val);
54*1b481fc3SMaciej Żenczykowski } else {
55*1b481fc3SMaciej Żenczykowski fprintf(stderr, "invalid kernel response - bad histogram entry bounds\n");
56*1b481fc3SMaciej Żenczykowski return 1;
57*1b481fc3SMaciej Żenczykowski }
58*1b481fc3SMaciej Żenczykowski } else {
59*1b481fc3SMaciej Żenczykowski open_json_object(NULL);
60*1b481fc3SMaciej Żenczykowski print_uint(PRINT_JSON, "low", NULL, low);
61*1b481fc3SMaciej Żenczykowski print_uint(PRINT_JSON, "high", NULL, hi);
62*1b481fc3SMaciej Żenczykowski print_u64(PRINT_JSON, "val", NULL, val);
63*1b481fc3SMaciej Żenczykowski close_json_object();
64*1b481fc3SMaciej Żenczykowski }
65*1b481fc3SMaciej Żenczykowski
66*1b481fc3SMaciej Żenczykowski return 0;
67*1b481fc3SMaciej Żenczykowski }
68*1b481fc3SMaciej Żenczykowski
parse_rmon_hist(const struct nlattr * grp,const char * grp_name,const char * name,const char * dir,unsigned int type)69*1b481fc3SMaciej Żenczykowski static int parse_rmon_hist(const struct nlattr *grp, const char *grp_name,
70*1b481fc3SMaciej Żenczykowski const char *name, const char *dir, unsigned int type)
71*1b481fc3SMaciej Żenczykowski {
72*1b481fc3SMaciej Żenczykowski const struct nlattr *attr;
73*1b481fc3SMaciej Żenczykowski
74*1b481fc3SMaciej Żenczykowski open_json_array(name, "");
75*1b481fc3SMaciej Żenczykowski
76*1b481fc3SMaciej Żenczykowski mnl_attr_for_each_nested(attr, grp) {
77*1b481fc3SMaciej Żenczykowski if (mnl_attr_get_type(attr) == type &&
78*1b481fc3SMaciej Żenczykowski parse_rmon_hist_one(grp_name, attr, dir))
79*1b481fc3SMaciej Żenczykowski goto err_close_rmon;
80*1b481fc3SMaciej Żenczykowski }
81*1b481fc3SMaciej Żenczykowski close_json_array("");
82*1b481fc3SMaciej Żenczykowski
83*1b481fc3SMaciej Żenczykowski return 0;
84*1b481fc3SMaciej Żenczykowski
85*1b481fc3SMaciej Żenczykowski err_close_rmon:
86*1b481fc3SMaciej Żenczykowski close_json_array("");
87*1b481fc3SMaciej Żenczykowski return 1;
88*1b481fc3SMaciej Żenczykowski }
89*1b481fc3SMaciej Żenczykowski
parse_grp(struct nl_context * nlctx,const struct nlattr * grp,const struct stringset * std_str)90*1b481fc3SMaciej Żenczykowski static int parse_grp(struct nl_context *nlctx, const struct nlattr *grp,
91*1b481fc3SMaciej Żenczykowski const struct stringset *std_str)
92*1b481fc3SMaciej Żenczykowski {
93*1b481fc3SMaciej Żenczykowski const struct nlattr *tb[ETHTOOL_A_STATS_GRP_SS_ID + 1] = {};
94*1b481fc3SMaciej Żenczykowski DECLARE_ATTR_TB_INFO(tb);
95*1b481fc3SMaciej Żenczykowski bool hist_rx = false, hist_tx = false;
96*1b481fc3SMaciej Żenczykowski const struct stringset *stat_str;
97*1b481fc3SMaciej Żenczykowski const struct nlattr *attr, *stat;
98*1b481fc3SMaciej Żenczykowski const char *std_name, *name;
99*1b481fc3SMaciej Żenczykowski unsigned int ss_id, id, s;
100*1b481fc3SMaciej Żenczykowski unsigned long long val;
101*1b481fc3SMaciej Żenczykowski int ret;
102*1b481fc3SMaciej Żenczykowski
103*1b481fc3SMaciej Żenczykowski ret = mnl_attr_parse_nested(grp, attr_cb, &tb_info);
104*1b481fc3SMaciej Żenczykowski if (ret < 0)
105*1b481fc3SMaciej Żenczykowski return 1;
106*1b481fc3SMaciej Żenczykowski
107*1b481fc3SMaciej Żenczykowski if (!tb[ETHTOOL_A_STATS_GRP_ID])
108*1b481fc3SMaciej Żenczykowski return 1;
109*1b481fc3SMaciej Żenczykowski if (!tb[ETHTOOL_A_STATS_GRP_SS_ID])
110*1b481fc3SMaciej Żenczykowski return 0;
111*1b481fc3SMaciej Żenczykowski
112*1b481fc3SMaciej Żenczykowski id = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_ID]);
113*1b481fc3SMaciej Żenczykowski ss_id = mnl_attr_get_u32(tb[ETHTOOL_A_STATS_GRP_SS_ID]);
114*1b481fc3SMaciej Żenczykowski
115*1b481fc3SMaciej Żenczykowski stat_str = global_stringset(ss_id, nlctx->ethnl2_socket);
116*1b481fc3SMaciej Żenczykowski
117*1b481fc3SMaciej Żenczykowski std_name = get_string(std_str, id);
118*1b481fc3SMaciej Żenczykowski open_json_object(std_name);
119*1b481fc3SMaciej Żenczykowski
120*1b481fc3SMaciej Żenczykowski mnl_attr_for_each_nested(attr, grp) {
121*1b481fc3SMaciej Żenczykowski switch (mnl_attr_get_type(attr)) {
122*1b481fc3SMaciej Żenczykowski case ETHTOOL_A_STATS_GRP_STAT:
123*1b481fc3SMaciej Żenczykowski break;
124*1b481fc3SMaciej Żenczykowski case ETHTOOL_A_STATS_GRP_HIST_RX:
125*1b481fc3SMaciej Żenczykowski hist_rx = true;
126*1b481fc3SMaciej Żenczykowski continue;
127*1b481fc3SMaciej Żenczykowski case ETHTOOL_A_STATS_GRP_HIST_TX:
128*1b481fc3SMaciej Żenczykowski hist_tx = true;
129*1b481fc3SMaciej Żenczykowski continue;
130*1b481fc3SMaciej Żenczykowski default:
131*1b481fc3SMaciej Żenczykowski continue;
132*1b481fc3SMaciej Żenczykowski }
133*1b481fc3SMaciej Żenczykowski
134*1b481fc3SMaciej Żenczykowski stat = mnl_attr_get_payload(attr);
135*1b481fc3SMaciej Żenczykowski ret = mnl_attr_validate(stat, MNL_TYPE_U64);
136*1b481fc3SMaciej Żenczykowski if (ret) {
137*1b481fc3SMaciej Żenczykowski fprintf(stderr, "invalid kernel response - bad statistic entry\n");
138*1b481fc3SMaciej Żenczykowski goto err_close_grp;
139*1b481fc3SMaciej Żenczykowski }
140*1b481fc3SMaciej Żenczykowski s = mnl_attr_get_type(stat);
141*1b481fc3SMaciej Żenczykowski name = get_string(stat_str, s);
142*1b481fc3SMaciej Żenczykowski if (!name || !name[0])
143*1b481fc3SMaciej Żenczykowski continue;
144*1b481fc3SMaciej Żenczykowski
145*1b481fc3SMaciej Żenczykowski if (!is_json_context())
146*1b481fc3SMaciej Żenczykowski fprintf(stdout, "%s-%s: ", std_name, name);
147*1b481fc3SMaciej Żenczykowski
148*1b481fc3SMaciej Żenczykowski val = mnl_attr_get_u64(stat);
149*1b481fc3SMaciej Żenczykowski print_u64(PRINT_ANY, name, "%llu\n", val);
150*1b481fc3SMaciej Żenczykowski }
151*1b481fc3SMaciej Żenczykowski
152*1b481fc3SMaciej Żenczykowski if (hist_rx)
153*1b481fc3SMaciej Żenczykowski parse_rmon_hist(grp, std_name, "rx-pktsNtoM", "rx",
154*1b481fc3SMaciej Żenczykowski ETHTOOL_A_STATS_GRP_HIST_RX);
155*1b481fc3SMaciej Żenczykowski if (hist_tx)
156*1b481fc3SMaciej Żenczykowski parse_rmon_hist(grp, std_name, "tx-pktsNtoM", "tx",
157*1b481fc3SMaciej Żenczykowski ETHTOOL_A_STATS_GRP_HIST_TX);
158*1b481fc3SMaciej Żenczykowski
159*1b481fc3SMaciej Żenczykowski close_json_object();
160*1b481fc3SMaciej Żenczykowski
161*1b481fc3SMaciej Żenczykowski return 0;
162*1b481fc3SMaciej Żenczykowski
163*1b481fc3SMaciej Żenczykowski err_close_grp:
164*1b481fc3SMaciej Żenczykowski close_json_object();
165*1b481fc3SMaciej Żenczykowski return 1;
166*1b481fc3SMaciej Żenczykowski }
167*1b481fc3SMaciej Żenczykowski
stats_reply_cb(const struct nlmsghdr * nlhdr,void * data)168*1b481fc3SMaciej Żenczykowski static int stats_reply_cb(const struct nlmsghdr *nlhdr, void *data)
169*1b481fc3SMaciej Żenczykowski {
170*1b481fc3SMaciej Żenczykowski const struct nlattr *tb[ETHTOOL_A_STATS_MAX + 1] = {};
171*1b481fc3SMaciej Żenczykowski DECLARE_ATTR_TB_INFO(tb);
172*1b481fc3SMaciej Żenczykowski struct nl_context *nlctx = data;
173*1b481fc3SMaciej Żenczykowski const struct stringset *std_str;
174*1b481fc3SMaciej Żenczykowski const struct nlattr *attr;
175*1b481fc3SMaciej Żenczykowski bool silent;
176*1b481fc3SMaciej Żenczykowski int err_ret;
177*1b481fc3SMaciej Żenczykowski int ret;
178*1b481fc3SMaciej Żenczykowski
179*1b481fc3SMaciej Żenczykowski silent = nlctx->is_dump || nlctx->is_monitor;
180*1b481fc3SMaciej Żenczykowski err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR;
181*1b481fc3SMaciej Żenczykowski ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
182*1b481fc3SMaciej Żenczykowski if (ret < 0)
183*1b481fc3SMaciej Żenczykowski return err_ret;
184*1b481fc3SMaciej Żenczykowski nlctx->devname = get_dev_name(tb[ETHTOOL_A_STATS_HEADER]);
185*1b481fc3SMaciej Żenczykowski if (!dev_ok(nlctx))
186*1b481fc3SMaciej Żenczykowski return err_ret;
187*1b481fc3SMaciej Żenczykowski
188*1b481fc3SMaciej Żenczykowski ret = netlink_init_ethnl2_socket(nlctx);
189*1b481fc3SMaciej Żenczykowski if (ret < 0)
190*1b481fc3SMaciej Żenczykowski return err_ret;
191*1b481fc3SMaciej Żenczykowski std_str = global_stringset(ETH_SS_STATS_STD, nlctx->ethnl2_socket);
192*1b481fc3SMaciej Żenczykowski
193*1b481fc3SMaciej Żenczykowski if (silent)
194*1b481fc3SMaciej Żenczykowski print_nl();
195*1b481fc3SMaciej Żenczykowski
196*1b481fc3SMaciej Żenczykowski open_json_object(NULL);
197*1b481fc3SMaciej Żenczykowski
198*1b481fc3SMaciej Żenczykowski print_string(PRINT_ANY, "ifname", "Standard stats for %s:\n",
199*1b481fc3SMaciej Żenczykowski nlctx->devname);
200*1b481fc3SMaciej Żenczykowski
201*1b481fc3SMaciej Żenczykowski mnl_attr_for_each(attr, nlhdr, GENL_HDRLEN) {
202*1b481fc3SMaciej Żenczykowski if (mnl_attr_get_type(attr) == ETHTOOL_A_STATS_GRP) {
203*1b481fc3SMaciej Żenczykowski ret = parse_grp(nlctx, attr, std_str);
204*1b481fc3SMaciej Żenczykowski if (ret)
205*1b481fc3SMaciej Żenczykowski goto err_close_dev;
206*1b481fc3SMaciej Żenczykowski }
207*1b481fc3SMaciej Żenczykowski }
208*1b481fc3SMaciej Żenczykowski
209*1b481fc3SMaciej Żenczykowski close_json_object();
210*1b481fc3SMaciej Żenczykowski
211*1b481fc3SMaciej Żenczykowski return MNL_CB_OK;
212*1b481fc3SMaciej Żenczykowski
213*1b481fc3SMaciej Żenczykowski err_close_dev:
214*1b481fc3SMaciej Żenczykowski close_json_object();
215*1b481fc3SMaciej Żenczykowski return err_ret;
216*1b481fc3SMaciej Żenczykowski }
217*1b481fc3SMaciej Żenczykowski
218*1b481fc3SMaciej Żenczykowski static const struct bitset_parser_data stats_parser_data = {
219*1b481fc3SMaciej Żenczykowski .no_mask = true,
220*1b481fc3SMaciej Żenczykowski .force_hex = false,
221*1b481fc3SMaciej Żenczykowski };
222*1b481fc3SMaciej Żenczykowski
stats_parse_all_groups(struct nl_context * nlctx,uint16_t type,const void * data,struct nl_msg_buff * msgbuff,void * dest)223*1b481fc3SMaciej Żenczykowski static int stats_parse_all_groups(struct nl_context *nlctx, uint16_t type,
224*1b481fc3SMaciej Żenczykowski const void *data, struct nl_msg_buff *msgbuff,
225*1b481fc3SMaciej Żenczykowski void *dest)
226*1b481fc3SMaciej Żenczykowski {
227*1b481fc3SMaciej Żenczykowski const struct stringset *std_str;
228*1b481fc3SMaciej Żenczykowski struct nlattr *nest;
229*1b481fc3SMaciej Żenczykowski int i, ret, nbits;
230*1b481fc3SMaciej Żenczykowski uint32_t *bits;
231*1b481fc3SMaciej Żenczykowski
232*1b481fc3SMaciej Żenczykowski if (data || dest)
233*1b481fc3SMaciej Żenczykowski return -EFAULT;
234*1b481fc3SMaciej Żenczykowski
235*1b481fc3SMaciej Żenczykowski /* ethnl2 and strset code already does caching */
236*1b481fc3SMaciej Żenczykowski ret = netlink_init_ethnl2_socket(nlctx);
237*1b481fc3SMaciej Żenczykowski if (ret < 0)
238*1b481fc3SMaciej Żenczykowski return ret;
239*1b481fc3SMaciej Żenczykowski std_str = global_stringset(ETH_SS_STATS_STD, nlctx->ethnl2_socket);
240*1b481fc3SMaciej Żenczykowski
241*1b481fc3SMaciej Żenczykowski nbits = get_count(std_str);
242*1b481fc3SMaciej Żenczykowski bits = calloc(DIV_ROUND_UP(nbits, 32), sizeof(uint32_t));
243*1b481fc3SMaciej Żenczykowski if (!bits)
244*1b481fc3SMaciej Żenczykowski return -ENOMEM;
245*1b481fc3SMaciej Żenczykowski
246*1b481fc3SMaciej Żenczykowski for (i = 0; i < nbits; i++)
247*1b481fc3SMaciej Żenczykowski bits[i / 32] |= 1U << (i % 32);
248*1b481fc3SMaciej Żenczykowski
249*1b481fc3SMaciej Żenczykowski ret = -EMSGSIZE;
250*1b481fc3SMaciej Żenczykowski nest = ethnla_nest_start(msgbuff, type);
251*1b481fc3SMaciej Żenczykowski if (!nest)
252*1b481fc3SMaciej Żenczykowski goto err_free;
253*1b481fc3SMaciej Żenczykowski
254*1b481fc3SMaciej Żenczykowski if (ethnla_put_flag(msgbuff, ETHTOOL_A_BITSET_NOMASK, true) ||
255*1b481fc3SMaciej Żenczykowski ethnla_put_u32(msgbuff, ETHTOOL_A_BITSET_SIZE, nbits) ||
256*1b481fc3SMaciej Żenczykowski ethnla_put(msgbuff, ETHTOOL_A_BITSET_VALUE,
257*1b481fc3SMaciej Żenczykowski DIV_ROUND_UP(nbits, 32) * sizeof(uint32_t), bits))
258*1b481fc3SMaciej Żenczykowski goto err_cancel;
259*1b481fc3SMaciej Żenczykowski
260*1b481fc3SMaciej Żenczykowski ethnla_nest_end(msgbuff, nest);
261*1b481fc3SMaciej Żenczykowski free(bits);
262*1b481fc3SMaciej Żenczykowski return 0;
263*1b481fc3SMaciej Żenczykowski
264*1b481fc3SMaciej Żenczykowski err_cancel:
265*1b481fc3SMaciej Żenczykowski ethnla_nest_cancel(msgbuff, nest);
266*1b481fc3SMaciej Żenczykowski err_free:
267*1b481fc3SMaciej Żenczykowski free(bits);
268*1b481fc3SMaciej Żenczykowski return ret;
269*1b481fc3SMaciej Żenczykowski }
270*1b481fc3SMaciej Żenczykowski
271*1b481fc3SMaciej Żenczykowski static const struct lookup_entry_u32 stats_src_values[] = {
272*1b481fc3SMaciej Żenczykowski { .arg = "aggregate", .val = ETHTOOL_MAC_STATS_SRC_AGGREGATE },
273*1b481fc3SMaciej Żenczykowski { .arg = "emac", .val = ETHTOOL_MAC_STATS_SRC_EMAC },
274*1b481fc3SMaciej Żenczykowski { .arg = "pmac", .val = ETHTOOL_MAC_STATS_SRC_PMAC },
275*1b481fc3SMaciej Żenczykowski {}
276*1b481fc3SMaciej Żenczykowski };
277*1b481fc3SMaciej Żenczykowski
278*1b481fc3SMaciej Żenczykowski static const struct param_parser stats_params[] = {
279*1b481fc3SMaciej Żenczykowski {
280*1b481fc3SMaciej Żenczykowski .arg = "--groups",
281*1b481fc3SMaciej Żenczykowski .type = ETHTOOL_A_STATS_GROUPS,
282*1b481fc3SMaciej Żenczykowski .handler = nl_parse_bitset,
283*1b481fc3SMaciej Żenczykowski .handler_data = &stats_parser_data,
284*1b481fc3SMaciej Żenczykowski .min_argc = 1,
285*1b481fc3SMaciej Żenczykowski .alt_group = 1,
286*1b481fc3SMaciej Żenczykowski },
287*1b481fc3SMaciej Żenczykowski {
288*1b481fc3SMaciej Żenczykowski .arg = "--all-groups",
289*1b481fc3SMaciej Żenczykowski .type = ETHTOOL_A_STATS_GROUPS,
290*1b481fc3SMaciej Żenczykowski .handler = stats_parse_all_groups,
291*1b481fc3SMaciej Żenczykowski .alt_group = 1,
292*1b481fc3SMaciej Żenczykowski },
293*1b481fc3SMaciej Żenczykowski {
294*1b481fc3SMaciej Żenczykowski .arg = "--src",
295*1b481fc3SMaciej Żenczykowski .type = ETHTOOL_A_STATS_SRC,
296*1b481fc3SMaciej Żenczykowski .handler = nl_parse_lookup_u32,
297*1b481fc3SMaciej Żenczykowski .handler_data = stats_src_values,
298*1b481fc3SMaciej Żenczykowski .min_argc = 1,
299*1b481fc3SMaciej Żenczykowski },
300*1b481fc3SMaciej Żenczykowski {}
301*1b481fc3SMaciej Żenczykowski };
302*1b481fc3SMaciej Żenczykowski
nl_gstats(struct cmd_context * ctx)303*1b481fc3SMaciej Żenczykowski int nl_gstats(struct cmd_context *ctx)
304*1b481fc3SMaciej Żenczykowski {
305*1b481fc3SMaciej Żenczykowski struct nl_context *nlctx = ctx->nlctx;
306*1b481fc3SMaciej Żenczykowski struct nl_socket *nlsk = nlctx->ethnl_socket;
307*1b481fc3SMaciej Żenczykowski int ret;
308*1b481fc3SMaciej Żenczykowski
309*1b481fc3SMaciej Żenczykowski ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_STATS_GET,
310*1b481fc3SMaciej Żenczykowski ETHTOOL_A_STATS_HEADER, 0);
311*1b481fc3SMaciej Żenczykowski if (ret < 0)
312*1b481fc3SMaciej Żenczykowski return ret;
313*1b481fc3SMaciej Żenczykowski
314*1b481fc3SMaciej Żenczykowski nlctx->cmd = "-S";
315*1b481fc3SMaciej Żenczykowski nlctx->argp = ctx->argp;
316*1b481fc3SMaciej Żenczykowski nlctx->argc = ctx->argc;
317*1b481fc3SMaciej Żenczykowski nlctx->devname = ctx->devname;
318*1b481fc3SMaciej Żenczykowski nlsk = nlctx->ethnl_socket;
319*1b481fc3SMaciej Żenczykowski
320*1b481fc3SMaciej Żenczykowski ret = nl_parser(nlctx, stats_params, NULL, PARSER_GROUP_NONE, NULL);
321*1b481fc3SMaciej Żenczykowski if (ret < 0)
322*1b481fc3SMaciej Żenczykowski return 1;
323*1b481fc3SMaciej Żenczykowski
324*1b481fc3SMaciej Żenczykowski new_json_obj(ctx->json);
325*1b481fc3SMaciej Żenczykowski ret = nlsock_send_get_request(nlsk, stats_reply_cb);
326*1b481fc3SMaciej Żenczykowski delete_json_obj();
327*1b481fc3SMaciej Żenczykowski return ret;
328*1b481fc3SMaciej Żenczykowski }
329*1b481fc3SMaciej Żenczykowski
nl_gstats_chk(struct cmd_context * ctx)330*1b481fc3SMaciej Żenczykowski bool nl_gstats_chk(struct cmd_context *ctx)
331*1b481fc3SMaciej Żenczykowski {
332*1b481fc3SMaciej Żenczykowski return ctx->argc;
333*1b481fc3SMaciej Żenczykowski }
334