1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * devlink.c Devlink tool
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Authors: Jiri Pirko <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker */
11*de1e4e89SAndroid Build Coastguard Worker
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <stdbool.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <getopt.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <limits.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <errno.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <linux/genetlink.h>
21*de1e4e89SAndroid Build Coastguard Worker #include <linux/devlink.h>
22*de1e4e89SAndroid Build Coastguard Worker #include <libmnl/libmnl.h>
23*de1e4e89SAndroid Build Coastguard Worker #include <netinet/ether.h>
24*de1e4e89SAndroid Build Coastguard Worker
25*de1e4e89SAndroid Build Coastguard Worker #include "SNAPSHOT.h"
26*de1e4e89SAndroid Build Coastguard Worker #include "list.h"
27*de1e4e89SAndroid Build Coastguard Worker #include "mnlg.h"
28*de1e4e89SAndroid Build Coastguard Worker #include "json_writer.h"
29*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
30*de1e4e89SAndroid Build Coastguard Worker
31*de1e4e89SAndroid Build Coastguard Worker #define ESWITCH_MODE_LEGACY "legacy"
32*de1e4e89SAndroid Build Coastguard Worker #define ESWITCH_MODE_SWITCHDEV "switchdev"
33*de1e4e89SAndroid Build Coastguard Worker #define ESWITCH_INLINE_MODE_NONE "none"
34*de1e4e89SAndroid Build Coastguard Worker #define ESWITCH_INLINE_MODE_LINK "link"
35*de1e4e89SAndroid Build Coastguard Worker #define ESWITCH_INLINE_MODE_NETWORK "network"
36*de1e4e89SAndroid Build Coastguard Worker #define ESWITCH_INLINE_MODE_TRANSPORT "transport"
37*de1e4e89SAndroid Build Coastguard Worker
38*de1e4e89SAndroid Build Coastguard Worker #define pr_err(args...) fprintf(stderr, ##args)
39*de1e4e89SAndroid Build Coastguard Worker #define pr_out(args...) \
40*de1e4e89SAndroid Build Coastguard Worker do { \
41*de1e4e89SAndroid Build Coastguard Worker if (g_indent_newline) { \
42*de1e4e89SAndroid Build Coastguard Worker fprintf(stdout, "%s", g_indent_str); \
43*de1e4e89SAndroid Build Coastguard Worker g_indent_newline = false; \
44*de1e4e89SAndroid Build Coastguard Worker } \
45*de1e4e89SAndroid Build Coastguard Worker fprintf(stdout, ##args); \
46*de1e4e89SAndroid Build Coastguard Worker } while (0)
47*de1e4e89SAndroid Build Coastguard Worker
48*de1e4e89SAndroid Build Coastguard Worker #define pr_out_sp(num, args...) \
49*de1e4e89SAndroid Build Coastguard Worker do { \
50*de1e4e89SAndroid Build Coastguard Worker int ret = fprintf(stdout, ##args); \
51*de1e4e89SAndroid Build Coastguard Worker if (ret < num) \
52*de1e4e89SAndroid Build Coastguard Worker fprintf(stdout, "%*s", num - ret, ""); \
53*de1e4e89SAndroid Build Coastguard Worker } while (0)
54*de1e4e89SAndroid Build Coastguard Worker
55*de1e4e89SAndroid Build Coastguard Worker static int g_indent_level;
56*de1e4e89SAndroid Build Coastguard Worker static bool g_indent_newline;
57*de1e4e89SAndroid Build Coastguard Worker #define INDENT_STR_STEP 2
58*de1e4e89SAndroid Build Coastguard Worker #define INDENT_STR_MAXLEN 32
59*de1e4e89SAndroid Build Coastguard Worker static char g_indent_str[INDENT_STR_MAXLEN + 1] = "";
60*de1e4e89SAndroid Build Coastguard Worker
__pr_out_indent_inc(void)61*de1e4e89SAndroid Build Coastguard Worker static void __pr_out_indent_inc(void)
62*de1e4e89SAndroid Build Coastguard Worker {
63*de1e4e89SAndroid Build Coastguard Worker if (g_indent_level + INDENT_STR_STEP > INDENT_STR_MAXLEN)
64*de1e4e89SAndroid Build Coastguard Worker return;
65*de1e4e89SAndroid Build Coastguard Worker g_indent_level += INDENT_STR_STEP;
66*de1e4e89SAndroid Build Coastguard Worker memset(g_indent_str, ' ', sizeof(g_indent_str));
67*de1e4e89SAndroid Build Coastguard Worker g_indent_str[g_indent_level] = '\0';
68*de1e4e89SAndroid Build Coastguard Worker }
69*de1e4e89SAndroid Build Coastguard Worker
__pr_out_indent_dec(void)70*de1e4e89SAndroid Build Coastguard Worker static void __pr_out_indent_dec(void)
71*de1e4e89SAndroid Build Coastguard Worker {
72*de1e4e89SAndroid Build Coastguard Worker if (g_indent_level - INDENT_STR_STEP < 0)
73*de1e4e89SAndroid Build Coastguard Worker return;
74*de1e4e89SAndroid Build Coastguard Worker g_indent_level -= INDENT_STR_STEP;
75*de1e4e89SAndroid Build Coastguard Worker g_indent_str[g_indent_level] = '\0';
76*de1e4e89SAndroid Build Coastguard Worker }
77*de1e4e89SAndroid Build Coastguard Worker
__pr_out_newline(void)78*de1e4e89SAndroid Build Coastguard Worker static void __pr_out_newline(void)
79*de1e4e89SAndroid Build Coastguard Worker {
80*de1e4e89SAndroid Build Coastguard Worker pr_out("\n");
81*de1e4e89SAndroid Build Coastguard Worker g_indent_newline = true;
82*de1e4e89SAndroid Build Coastguard Worker }
83*de1e4e89SAndroid Build Coastguard Worker
_mnlg_socket_recv_run(struct mnlg_socket * nlg,mnl_cb_t data_cb,void * data)84*de1e4e89SAndroid Build Coastguard Worker static int _mnlg_socket_recv_run(struct mnlg_socket *nlg,
85*de1e4e89SAndroid Build Coastguard Worker mnl_cb_t data_cb, void *data)
86*de1e4e89SAndroid Build Coastguard Worker {
87*de1e4e89SAndroid Build Coastguard Worker int err;
88*de1e4e89SAndroid Build Coastguard Worker
89*de1e4e89SAndroid Build Coastguard Worker err = mnlg_socket_recv_run(nlg, data_cb, data);
90*de1e4e89SAndroid Build Coastguard Worker if (err < 0) {
91*de1e4e89SAndroid Build Coastguard Worker pr_err("devlink answers: %s\n", strerror(errno));
92*de1e4e89SAndroid Build Coastguard Worker return -errno;
93*de1e4e89SAndroid Build Coastguard Worker }
94*de1e4e89SAndroid Build Coastguard Worker return 0;
95*de1e4e89SAndroid Build Coastguard Worker }
96*de1e4e89SAndroid Build Coastguard Worker
_mnlg_socket_sndrcv(struct mnlg_socket * nlg,const struct nlmsghdr * nlh,mnl_cb_t data_cb,void * data)97*de1e4e89SAndroid Build Coastguard Worker static int _mnlg_socket_sndrcv(struct mnlg_socket *nlg,
98*de1e4e89SAndroid Build Coastguard Worker const struct nlmsghdr *nlh,
99*de1e4e89SAndroid Build Coastguard Worker mnl_cb_t data_cb, void *data)
100*de1e4e89SAndroid Build Coastguard Worker {
101*de1e4e89SAndroid Build Coastguard Worker int err;
102*de1e4e89SAndroid Build Coastguard Worker
103*de1e4e89SAndroid Build Coastguard Worker err = mnlg_socket_send(nlg, nlh);
104*de1e4e89SAndroid Build Coastguard Worker if (err < 0) {
105*de1e4e89SAndroid Build Coastguard Worker pr_err("Failed to call mnlg_socket_send\n");
106*de1e4e89SAndroid Build Coastguard Worker return -errno;
107*de1e4e89SAndroid Build Coastguard Worker }
108*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_recv_run(nlg, data_cb, data);
109*de1e4e89SAndroid Build Coastguard Worker }
110*de1e4e89SAndroid Build Coastguard Worker
_mnlg_socket_group_add(struct mnlg_socket * nlg,const char * group_name)111*de1e4e89SAndroid Build Coastguard Worker static int _mnlg_socket_group_add(struct mnlg_socket *nlg,
112*de1e4e89SAndroid Build Coastguard Worker const char *group_name)
113*de1e4e89SAndroid Build Coastguard Worker {
114*de1e4e89SAndroid Build Coastguard Worker int err;
115*de1e4e89SAndroid Build Coastguard Worker
116*de1e4e89SAndroid Build Coastguard Worker err = mnlg_socket_group_add(nlg, group_name);
117*de1e4e89SAndroid Build Coastguard Worker if (err < 0) {
118*de1e4e89SAndroid Build Coastguard Worker pr_err("Failed to call mnlg_socket_group_add\n");
119*de1e4e89SAndroid Build Coastguard Worker return -errno;
120*de1e4e89SAndroid Build Coastguard Worker }
121*de1e4e89SAndroid Build Coastguard Worker return 0;
122*de1e4e89SAndroid Build Coastguard Worker }
123*de1e4e89SAndroid Build Coastguard Worker
124*de1e4e89SAndroid Build Coastguard Worker struct ifname_map {
125*de1e4e89SAndroid Build Coastguard Worker struct list_head list;
126*de1e4e89SAndroid Build Coastguard Worker char *bus_name;
127*de1e4e89SAndroid Build Coastguard Worker char *dev_name;
128*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index;
129*de1e4e89SAndroid Build Coastguard Worker char *ifname;
130*de1e4e89SAndroid Build Coastguard Worker };
131*de1e4e89SAndroid Build Coastguard Worker
ifname_map_alloc(const char * bus_name,const char * dev_name,uint32_t port_index,const char * ifname)132*de1e4e89SAndroid Build Coastguard Worker static struct ifname_map *ifname_map_alloc(const char *bus_name,
133*de1e4e89SAndroid Build Coastguard Worker const char *dev_name,
134*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index,
135*de1e4e89SAndroid Build Coastguard Worker const char *ifname)
136*de1e4e89SAndroid Build Coastguard Worker {
137*de1e4e89SAndroid Build Coastguard Worker struct ifname_map *ifname_map;
138*de1e4e89SAndroid Build Coastguard Worker
139*de1e4e89SAndroid Build Coastguard Worker ifname_map = calloc(1, sizeof(*ifname_map));
140*de1e4e89SAndroid Build Coastguard Worker if (!ifname_map)
141*de1e4e89SAndroid Build Coastguard Worker return NULL;
142*de1e4e89SAndroid Build Coastguard Worker ifname_map->bus_name = strdup(bus_name);
143*de1e4e89SAndroid Build Coastguard Worker ifname_map->dev_name = strdup(dev_name);
144*de1e4e89SAndroid Build Coastguard Worker ifname_map->port_index = port_index;
145*de1e4e89SAndroid Build Coastguard Worker ifname_map->ifname = strdup(ifname);
146*de1e4e89SAndroid Build Coastguard Worker if (!ifname_map->bus_name || !ifname_map->dev_name ||
147*de1e4e89SAndroid Build Coastguard Worker !ifname_map->ifname) {
148*de1e4e89SAndroid Build Coastguard Worker free(ifname_map->ifname);
149*de1e4e89SAndroid Build Coastguard Worker free(ifname_map->dev_name);
150*de1e4e89SAndroid Build Coastguard Worker free(ifname_map->bus_name);
151*de1e4e89SAndroid Build Coastguard Worker free(ifname_map);
152*de1e4e89SAndroid Build Coastguard Worker return NULL;
153*de1e4e89SAndroid Build Coastguard Worker }
154*de1e4e89SAndroid Build Coastguard Worker return ifname_map;
155*de1e4e89SAndroid Build Coastguard Worker }
156*de1e4e89SAndroid Build Coastguard Worker
ifname_map_free(struct ifname_map * ifname_map)157*de1e4e89SAndroid Build Coastguard Worker static void ifname_map_free(struct ifname_map *ifname_map)
158*de1e4e89SAndroid Build Coastguard Worker {
159*de1e4e89SAndroid Build Coastguard Worker free(ifname_map->ifname);
160*de1e4e89SAndroid Build Coastguard Worker free(ifname_map->dev_name);
161*de1e4e89SAndroid Build Coastguard Worker free(ifname_map->bus_name);
162*de1e4e89SAndroid Build Coastguard Worker free(ifname_map);
163*de1e4e89SAndroid Build Coastguard Worker }
164*de1e4e89SAndroid Build Coastguard Worker
165*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_HANDLE BIT(0)
166*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_HANDLEP BIT(1)
167*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_PORT_TYPE BIT(2)
168*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_PORT_COUNT BIT(3)
169*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_SB BIT(4)
170*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_SB_POOL BIT(5)
171*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_SB_SIZE BIT(6)
172*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_SB_TYPE BIT(7)
173*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_SB_THTYPE BIT(8)
174*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_SB_TH BIT(9)
175*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_SB_TC BIT(10)
176*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_ESWITCH_MODE BIT(11)
177*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_ESWITCH_INLINE_MODE BIT(12)
178*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_DPIPE_TABLE_NAME BIT(13)
179*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_DPIPE_TABLE_COUNTERS BIT(14)
180*de1e4e89SAndroid Build Coastguard Worker #define DL_OPT_ESWITCH_ENCAP_MODE BIT(15)
181*de1e4e89SAndroid Build Coastguard Worker
182*de1e4e89SAndroid Build Coastguard Worker struct dl_opts {
183*de1e4e89SAndroid Build Coastguard Worker uint32_t present; /* flags of present items */
184*de1e4e89SAndroid Build Coastguard Worker char *bus_name;
185*de1e4e89SAndroid Build Coastguard Worker char *dev_name;
186*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index;
187*de1e4e89SAndroid Build Coastguard Worker enum devlink_port_type port_type;
188*de1e4e89SAndroid Build Coastguard Worker uint32_t port_count;
189*de1e4e89SAndroid Build Coastguard Worker uint32_t sb_index;
190*de1e4e89SAndroid Build Coastguard Worker uint16_t sb_pool_index;
191*de1e4e89SAndroid Build Coastguard Worker uint32_t sb_pool_size;
192*de1e4e89SAndroid Build Coastguard Worker enum devlink_sb_pool_type sb_pool_type;
193*de1e4e89SAndroid Build Coastguard Worker enum devlink_sb_threshold_type sb_pool_thtype;
194*de1e4e89SAndroid Build Coastguard Worker uint32_t sb_threshold;
195*de1e4e89SAndroid Build Coastguard Worker uint16_t sb_tc_index;
196*de1e4e89SAndroid Build Coastguard Worker enum devlink_eswitch_mode eswitch_mode;
197*de1e4e89SAndroid Build Coastguard Worker enum devlink_eswitch_inline_mode eswitch_inline_mode;
198*de1e4e89SAndroid Build Coastguard Worker const char *dpipe_table_name;
199*de1e4e89SAndroid Build Coastguard Worker bool dpipe_counters_enable;
200*de1e4e89SAndroid Build Coastguard Worker bool eswitch_encap_mode;
201*de1e4e89SAndroid Build Coastguard Worker };
202*de1e4e89SAndroid Build Coastguard Worker
203*de1e4e89SAndroid Build Coastguard Worker struct dl {
204*de1e4e89SAndroid Build Coastguard Worker struct mnlg_socket *nlg;
205*de1e4e89SAndroid Build Coastguard Worker struct list_head ifname_map_list;
206*de1e4e89SAndroid Build Coastguard Worker int argc;
207*de1e4e89SAndroid Build Coastguard Worker char **argv;
208*de1e4e89SAndroid Build Coastguard Worker bool no_nice_names;
209*de1e4e89SAndroid Build Coastguard Worker struct dl_opts opts;
210*de1e4e89SAndroid Build Coastguard Worker json_writer_t *jw;
211*de1e4e89SAndroid Build Coastguard Worker bool json_output;
212*de1e4e89SAndroid Build Coastguard Worker bool pretty_output;
213*de1e4e89SAndroid Build Coastguard Worker bool verbose;
214*de1e4e89SAndroid Build Coastguard Worker struct {
215*de1e4e89SAndroid Build Coastguard Worker bool present;
216*de1e4e89SAndroid Build Coastguard Worker char *bus_name;
217*de1e4e89SAndroid Build Coastguard Worker char *dev_name;
218*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index;
219*de1e4e89SAndroid Build Coastguard Worker } arr_last;
220*de1e4e89SAndroid Build Coastguard Worker };
221*de1e4e89SAndroid Build Coastguard Worker
dl_argc(struct dl * dl)222*de1e4e89SAndroid Build Coastguard Worker static int dl_argc(struct dl *dl)
223*de1e4e89SAndroid Build Coastguard Worker {
224*de1e4e89SAndroid Build Coastguard Worker return dl->argc;
225*de1e4e89SAndroid Build Coastguard Worker }
226*de1e4e89SAndroid Build Coastguard Worker
dl_argv(struct dl * dl)227*de1e4e89SAndroid Build Coastguard Worker static char *dl_argv(struct dl *dl)
228*de1e4e89SAndroid Build Coastguard Worker {
229*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
230*de1e4e89SAndroid Build Coastguard Worker return NULL;
231*de1e4e89SAndroid Build Coastguard Worker return *dl->argv;
232*de1e4e89SAndroid Build Coastguard Worker }
233*de1e4e89SAndroid Build Coastguard Worker
dl_arg_inc(struct dl * dl)234*de1e4e89SAndroid Build Coastguard Worker static void dl_arg_inc(struct dl *dl)
235*de1e4e89SAndroid Build Coastguard Worker {
236*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
237*de1e4e89SAndroid Build Coastguard Worker return;
238*de1e4e89SAndroid Build Coastguard Worker dl->argc--;
239*de1e4e89SAndroid Build Coastguard Worker dl->argv++;
240*de1e4e89SAndroid Build Coastguard Worker }
241*de1e4e89SAndroid Build Coastguard Worker
dl_argv_next(struct dl * dl)242*de1e4e89SAndroid Build Coastguard Worker static char *dl_argv_next(struct dl *dl)
243*de1e4e89SAndroid Build Coastguard Worker {
244*de1e4e89SAndroid Build Coastguard Worker char *ret;
245*de1e4e89SAndroid Build Coastguard Worker
246*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
247*de1e4e89SAndroid Build Coastguard Worker return NULL;
248*de1e4e89SAndroid Build Coastguard Worker
249*de1e4e89SAndroid Build Coastguard Worker ret = *dl->argv;
250*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
251*de1e4e89SAndroid Build Coastguard Worker return ret;
252*de1e4e89SAndroid Build Coastguard Worker }
253*de1e4e89SAndroid Build Coastguard Worker
dl_argv_index(struct dl * dl,unsigned int index)254*de1e4e89SAndroid Build Coastguard Worker static char *dl_argv_index(struct dl *dl, unsigned int index)
255*de1e4e89SAndroid Build Coastguard Worker {
256*de1e4e89SAndroid Build Coastguard Worker if (index >= dl_argc(dl))
257*de1e4e89SAndroid Build Coastguard Worker return NULL;
258*de1e4e89SAndroid Build Coastguard Worker return dl->argv[index];
259*de1e4e89SAndroid Build Coastguard Worker }
260*de1e4e89SAndroid Build Coastguard Worker
strcmpx(const char * str1,const char * str2)261*de1e4e89SAndroid Build Coastguard Worker static int strcmpx(const char *str1, const char *str2)
262*de1e4e89SAndroid Build Coastguard Worker {
263*de1e4e89SAndroid Build Coastguard Worker if (strlen(str1) > strlen(str2))
264*de1e4e89SAndroid Build Coastguard Worker return -1;
265*de1e4e89SAndroid Build Coastguard Worker return strncmp(str1, str2, strlen(str1));
266*de1e4e89SAndroid Build Coastguard Worker }
267*de1e4e89SAndroid Build Coastguard Worker
dl_argv_match(struct dl * dl,const char * pattern)268*de1e4e89SAndroid Build Coastguard Worker static bool dl_argv_match(struct dl *dl, const char *pattern)
269*de1e4e89SAndroid Build Coastguard Worker {
270*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
271*de1e4e89SAndroid Build Coastguard Worker return false;
272*de1e4e89SAndroid Build Coastguard Worker return strcmpx(dl_argv(dl), pattern) == 0;
273*de1e4e89SAndroid Build Coastguard Worker }
274*de1e4e89SAndroid Build Coastguard Worker
dl_no_arg(struct dl * dl)275*de1e4e89SAndroid Build Coastguard Worker static bool dl_no_arg(struct dl *dl)
276*de1e4e89SAndroid Build Coastguard Worker {
277*de1e4e89SAndroid Build Coastguard Worker return dl_argc(dl) == 0;
278*de1e4e89SAndroid Build Coastguard Worker }
279*de1e4e89SAndroid Build Coastguard Worker
280*de1e4e89SAndroid Build Coastguard Worker static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
281*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_BUS_NAME] = MNL_TYPE_NUL_STRING,
282*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING,
283*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_PORT_INDEX] = MNL_TYPE_U32,
284*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_PORT_TYPE] = MNL_TYPE_U16,
285*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_PORT_DESIRED_TYPE] = MNL_TYPE_U16,
286*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_PORT_NETDEV_IFINDEX] = MNL_TYPE_U32,
287*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_PORT_NETDEV_NAME] = MNL_TYPE_NUL_STRING,
288*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_PORT_IBDEV_NAME] = MNL_TYPE_NUL_STRING,
289*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_INDEX] = MNL_TYPE_U32,
290*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_SIZE] = MNL_TYPE_U32,
291*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_INGRESS_POOL_COUNT] = MNL_TYPE_U16,
292*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_EGRESS_POOL_COUNT] = MNL_TYPE_U16,
293*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_INGRESS_TC_COUNT] = MNL_TYPE_U16,
294*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_EGRESS_TC_COUNT] = MNL_TYPE_U16,
295*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_POOL_INDEX] = MNL_TYPE_U16,
296*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_POOL_TYPE] = MNL_TYPE_U8,
297*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_POOL_SIZE] = MNL_TYPE_U32,
298*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = MNL_TYPE_U8,
299*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_THRESHOLD] = MNL_TYPE_U32,
300*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_TC_INDEX] = MNL_TYPE_U16,
301*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_OCC_CUR] = MNL_TYPE_U32,
302*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_SB_OCC_MAX] = MNL_TYPE_U32,
303*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_ESWITCH_MODE] = MNL_TYPE_U16,
304*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = MNL_TYPE_U8,
305*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = MNL_TYPE_U8,
306*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_TABLES] = MNL_TYPE_NESTED,
307*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_TABLE] = MNL_TYPE_NESTED,
308*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_TABLE_NAME] = MNL_TYPE_STRING,
309*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_TABLE_SIZE] = MNL_TYPE_U64,
310*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_TABLE_MATCHES] = MNL_TYPE_NESTED,
311*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_TABLE_ACTIONS] = MNL_TYPE_NESTED,
312*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = MNL_TYPE_U8,
313*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ENTRIES] = MNL_TYPE_NESTED,
314*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ENTRY] = MNL_TYPE_NESTED,
315*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ENTRY_INDEX] = MNL_TYPE_U64,
316*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES] = MNL_TYPE_NESTED,
317*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES] = MNL_TYPE_NESTED,
318*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ENTRY_COUNTER] = MNL_TYPE_U64,
319*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_MATCH] = MNL_TYPE_NESTED,
320*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_MATCH_VALUE] = MNL_TYPE_NESTED,
321*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_MATCH_TYPE] = MNL_TYPE_U32,
322*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ACTION] = MNL_TYPE_NESTED,
323*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ACTION_VALUE] = MNL_TYPE_NESTED,
324*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_ACTION_TYPE] = MNL_TYPE_U32,
325*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_VALUE_MAPPING] = MNL_TYPE_U32,
326*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_HEADERS] = MNL_TYPE_NESTED,
327*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_HEADER] = MNL_TYPE_NESTED,
328*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_HEADER_NAME] = MNL_TYPE_STRING,
329*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_HEADER_ID] = MNL_TYPE_U32,
330*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_HEADER_FIELDS] = MNL_TYPE_NESTED,
331*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_HEADER_GLOBAL] = MNL_TYPE_U8,
332*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_HEADER_INDEX] = MNL_TYPE_U32,
333*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_FIELD] = MNL_TYPE_NESTED,
334*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_FIELD_NAME] = MNL_TYPE_STRING,
335*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_FIELD_ID] = MNL_TYPE_U32,
336*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] = MNL_TYPE_U32,
337*de1e4e89SAndroid Build Coastguard Worker [DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE] = MNL_TYPE_U32,
338*de1e4e89SAndroid Build Coastguard Worker };
339*de1e4e89SAndroid Build Coastguard Worker
attr_cb(const struct nlattr * attr,void * data)340*de1e4e89SAndroid Build Coastguard Worker static int attr_cb(const struct nlattr *attr, void *data)
341*de1e4e89SAndroid Build Coastguard Worker {
342*de1e4e89SAndroid Build Coastguard Worker const struct nlattr **tb = data;
343*de1e4e89SAndroid Build Coastguard Worker int type;
344*de1e4e89SAndroid Build Coastguard Worker
345*de1e4e89SAndroid Build Coastguard Worker if (mnl_attr_type_valid(attr, DEVLINK_ATTR_MAX) < 0)
346*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
347*de1e4e89SAndroid Build Coastguard Worker
348*de1e4e89SAndroid Build Coastguard Worker type = mnl_attr_get_type(attr);
349*de1e4e89SAndroid Build Coastguard Worker if (mnl_attr_validate(attr, devlink_policy[type]) < 0)
350*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
351*de1e4e89SAndroid Build Coastguard Worker
352*de1e4e89SAndroid Build Coastguard Worker tb[type] = attr;
353*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
354*de1e4e89SAndroid Build Coastguard Worker }
355*de1e4e89SAndroid Build Coastguard Worker
ifname_map_cb(const struct nlmsghdr * nlh,void * data)356*de1e4e89SAndroid Build Coastguard Worker static int ifname_map_cb(const struct nlmsghdr *nlh, void *data)
357*de1e4e89SAndroid Build Coastguard Worker {
358*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
359*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
360*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
361*de1e4e89SAndroid Build Coastguard Worker struct ifname_map *ifname_map;
362*de1e4e89SAndroid Build Coastguard Worker const char *bus_name;
363*de1e4e89SAndroid Build Coastguard Worker const char *dev_name;
364*de1e4e89SAndroid Build Coastguard Worker uint32_t port_ifindex;
365*de1e4e89SAndroid Build Coastguard Worker const char *port_ifname;
366*de1e4e89SAndroid Build Coastguard Worker
367*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
368*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
369*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_PORT_INDEX])
370*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
371*de1e4e89SAndroid Build Coastguard Worker
372*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_PORT_NETDEV_NAME])
373*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
374*de1e4e89SAndroid Build Coastguard Worker
375*de1e4e89SAndroid Build Coastguard Worker bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
376*de1e4e89SAndroid Build Coastguard Worker dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
377*de1e4e89SAndroid Build Coastguard Worker port_ifindex = mnl_attr_get_u32(tb[DEVLINK_ATTR_PORT_INDEX]);
378*de1e4e89SAndroid Build Coastguard Worker port_ifname = mnl_attr_get_str(tb[DEVLINK_ATTR_PORT_NETDEV_NAME]);
379*de1e4e89SAndroid Build Coastguard Worker ifname_map = ifname_map_alloc(bus_name, dev_name,
380*de1e4e89SAndroid Build Coastguard Worker port_ifindex, port_ifname);
381*de1e4e89SAndroid Build Coastguard Worker if (!ifname_map)
382*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
383*de1e4e89SAndroid Build Coastguard Worker list_add(&ifname_map->list, &dl->ifname_map_list);
384*de1e4e89SAndroid Build Coastguard Worker
385*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
386*de1e4e89SAndroid Build Coastguard Worker }
387*de1e4e89SAndroid Build Coastguard Worker
ifname_map_fini(struct dl * dl)388*de1e4e89SAndroid Build Coastguard Worker static void ifname_map_fini(struct dl *dl)
389*de1e4e89SAndroid Build Coastguard Worker {
390*de1e4e89SAndroid Build Coastguard Worker struct ifname_map *ifname_map, *tmp;
391*de1e4e89SAndroid Build Coastguard Worker
392*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_safe(ifname_map, tmp,
393*de1e4e89SAndroid Build Coastguard Worker &dl->ifname_map_list, list) {
394*de1e4e89SAndroid Build Coastguard Worker list_del(&ifname_map->list);
395*de1e4e89SAndroid Build Coastguard Worker ifname_map_free(ifname_map);
396*de1e4e89SAndroid Build Coastguard Worker }
397*de1e4e89SAndroid Build Coastguard Worker }
398*de1e4e89SAndroid Build Coastguard Worker
ifname_map_init(struct dl * dl)399*de1e4e89SAndroid Build Coastguard Worker static int ifname_map_init(struct dl *dl)
400*de1e4e89SAndroid Build Coastguard Worker {
401*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
402*de1e4e89SAndroid Build Coastguard Worker int err;
403*de1e4e89SAndroid Build Coastguard Worker
404*de1e4e89SAndroid Build Coastguard Worker INIT_LIST_HEAD(&dl->ifname_map_list);
405*de1e4e89SAndroid Build Coastguard Worker
406*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_GET,
407*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
408*de1e4e89SAndroid Build Coastguard Worker
409*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, ifname_map_cb, dl);
410*de1e4e89SAndroid Build Coastguard Worker if (err) {
411*de1e4e89SAndroid Build Coastguard Worker ifname_map_fini(dl);
412*de1e4e89SAndroid Build Coastguard Worker return err;
413*de1e4e89SAndroid Build Coastguard Worker }
414*de1e4e89SAndroid Build Coastguard Worker return 0;
415*de1e4e89SAndroid Build Coastguard Worker }
416*de1e4e89SAndroid Build Coastguard Worker
ifname_map_lookup(struct dl * dl,const char * ifname,char ** p_bus_name,char ** p_dev_name,uint32_t * p_port_index)417*de1e4e89SAndroid Build Coastguard Worker static int ifname_map_lookup(struct dl *dl, const char *ifname,
418*de1e4e89SAndroid Build Coastguard Worker char **p_bus_name, char **p_dev_name,
419*de1e4e89SAndroid Build Coastguard Worker uint32_t *p_port_index)
420*de1e4e89SAndroid Build Coastguard Worker {
421*de1e4e89SAndroid Build Coastguard Worker struct ifname_map *ifname_map;
422*de1e4e89SAndroid Build Coastguard Worker
423*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(ifname_map, &dl->ifname_map_list, list) {
424*de1e4e89SAndroid Build Coastguard Worker if (strcmp(ifname, ifname_map->ifname) == 0) {
425*de1e4e89SAndroid Build Coastguard Worker *p_bus_name = ifname_map->bus_name;
426*de1e4e89SAndroid Build Coastguard Worker *p_dev_name = ifname_map->dev_name;
427*de1e4e89SAndroid Build Coastguard Worker *p_port_index = ifname_map->port_index;
428*de1e4e89SAndroid Build Coastguard Worker return 0;
429*de1e4e89SAndroid Build Coastguard Worker }
430*de1e4e89SAndroid Build Coastguard Worker }
431*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
432*de1e4e89SAndroid Build Coastguard Worker }
433*de1e4e89SAndroid Build Coastguard Worker
ifname_map_rev_lookup(struct dl * dl,const char * bus_name,const char * dev_name,uint32_t port_index,char ** p_ifname)434*de1e4e89SAndroid Build Coastguard Worker static int ifname_map_rev_lookup(struct dl *dl, const char *bus_name,
435*de1e4e89SAndroid Build Coastguard Worker const char *dev_name, uint32_t port_index,
436*de1e4e89SAndroid Build Coastguard Worker char **p_ifname)
437*de1e4e89SAndroid Build Coastguard Worker {
438*de1e4e89SAndroid Build Coastguard Worker struct ifname_map *ifname_map;
439*de1e4e89SAndroid Build Coastguard Worker
440*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(ifname_map, &dl->ifname_map_list, list) {
441*de1e4e89SAndroid Build Coastguard Worker if (strcmp(bus_name, ifname_map->bus_name) == 0 &&
442*de1e4e89SAndroid Build Coastguard Worker strcmp(dev_name, ifname_map->dev_name) == 0 &&
443*de1e4e89SAndroid Build Coastguard Worker port_index == ifname_map->port_index) {
444*de1e4e89SAndroid Build Coastguard Worker *p_ifname = ifname_map->ifname;
445*de1e4e89SAndroid Build Coastguard Worker return 0;
446*de1e4e89SAndroid Build Coastguard Worker }
447*de1e4e89SAndroid Build Coastguard Worker }
448*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
449*de1e4e89SAndroid Build Coastguard Worker }
450*de1e4e89SAndroid Build Coastguard Worker
strslashcount(char * str)451*de1e4e89SAndroid Build Coastguard Worker static unsigned int strslashcount(char *str)
452*de1e4e89SAndroid Build Coastguard Worker {
453*de1e4e89SAndroid Build Coastguard Worker unsigned int count = 0;
454*de1e4e89SAndroid Build Coastguard Worker char *pos = str;
455*de1e4e89SAndroid Build Coastguard Worker
456*de1e4e89SAndroid Build Coastguard Worker while ((pos = strchr(pos, '/'))) {
457*de1e4e89SAndroid Build Coastguard Worker count++;
458*de1e4e89SAndroid Build Coastguard Worker pos++;
459*de1e4e89SAndroid Build Coastguard Worker }
460*de1e4e89SAndroid Build Coastguard Worker return count;
461*de1e4e89SAndroid Build Coastguard Worker }
462*de1e4e89SAndroid Build Coastguard Worker
strslashrsplit(char * str,char ** before,char ** after)463*de1e4e89SAndroid Build Coastguard Worker static int strslashrsplit(char *str, char **before, char **after)
464*de1e4e89SAndroid Build Coastguard Worker {
465*de1e4e89SAndroid Build Coastguard Worker char *slash;
466*de1e4e89SAndroid Build Coastguard Worker
467*de1e4e89SAndroid Build Coastguard Worker slash = strrchr(str, '/');
468*de1e4e89SAndroid Build Coastguard Worker if (!slash)
469*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
470*de1e4e89SAndroid Build Coastguard Worker *slash = '\0';
471*de1e4e89SAndroid Build Coastguard Worker *before = str;
472*de1e4e89SAndroid Build Coastguard Worker *after = slash + 1;
473*de1e4e89SAndroid Build Coastguard Worker return 0;
474*de1e4e89SAndroid Build Coastguard Worker }
475*de1e4e89SAndroid Build Coastguard Worker
strtouint32_t(const char * str,uint32_t * p_val)476*de1e4e89SAndroid Build Coastguard Worker static int strtouint32_t(const char *str, uint32_t *p_val)
477*de1e4e89SAndroid Build Coastguard Worker {
478*de1e4e89SAndroid Build Coastguard Worker char *endptr;
479*de1e4e89SAndroid Build Coastguard Worker unsigned long int val;
480*de1e4e89SAndroid Build Coastguard Worker
481*de1e4e89SAndroid Build Coastguard Worker val = strtoul(str, &endptr, 10);
482*de1e4e89SAndroid Build Coastguard Worker if (endptr == str || *endptr != '\0')
483*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
484*de1e4e89SAndroid Build Coastguard Worker if (val > UINT_MAX)
485*de1e4e89SAndroid Build Coastguard Worker return -ERANGE;
486*de1e4e89SAndroid Build Coastguard Worker *p_val = val;
487*de1e4e89SAndroid Build Coastguard Worker return 0;
488*de1e4e89SAndroid Build Coastguard Worker }
489*de1e4e89SAndroid Build Coastguard Worker
strtouint16_t(const char * str,uint16_t * p_val)490*de1e4e89SAndroid Build Coastguard Worker static int strtouint16_t(const char *str, uint16_t *p_val)
491*de1e4e89SAndroid Build Coastguard Worker {
492*de1e4e89SAndroid Build Coastguard Worker char *endptr;
493*de1e4e89SAndroid Build Coastguard Worker unsigned long int val;
494*de1e4e89SAndroid Build Coastguard Worker
495*de1e4e89SAndroid Build Coastguard Worker val = strtoul(str, &endptr, 10);
496*de1e4e89SAndroid Build Coastguard Worker if (endptr == str || *endptr != '\0')
497*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
498*de1e4e89SAndroid Build Coastguard Worker if (val > USHRT_MAX)
499*de1e4e89SAndroid Build Coastguard Worker return -ERANGE;
500*de1e4e89SAndroid Build Coastguard Worker *p_val = val;
501*de1e4e89SAndroid Build Coastguard Worker return 0;
502*de1e4e89SAndroid Build Coastguard Worker }
503*de1e4e89SAndroid Build Coastguard Worker
__dl_argv_handle(char * str,char ** p_bus_name,char ** p_dev_name)504*de1e4e89SAndroid Build Coastguard Worker static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
505*de1e4e89SAndroid Build Coastguard Worker {
506*de1e4e89SAndroid Build Coastguard Worker strslashrsplit(str, p_bus_name, p_dev_name);
507*de1e4e89SAndroid Build Coastguard Worker return 0;
508*de1e4e89SAndroid Build Coastguard Worker }
509*de1e4e89SAndroid Build Coastguard Worker
dl_argv_handle(struct dl * dl,char ** p_bus_name,char ** p_dev_name)510*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_handle(struct dl *dl, char **p_bus_name, char **p_dev_name)
511*de1e4e89SAndroid Build Coastguard Worker {
512*de1e4e89SAndroid Build Coastguard Worker char *str = dl_argv_next(dl);
513*de1e4e89SAndroid Build Coastguard Worker
514*de1e4e89SAndroid Build Coastguard Worker if (!str) {
515*de1e4e89SAndroid Build Coastguard Worker pr_err("Devlink identification (\"bus_name/dev_name\") expected\n");
516*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
517*de1e4e89SAndroid Build Coastguard Worker }
518*de1e4e89SAndroid Build Coastguard Worker if (strslashcount(str) != 1) {
519*de1e4e89SAndroid Build Coastguard Worker pr_err("Wrong devlink identification string format.\n");
520*de1e4e89SAndroid Build Coastguard Worker pr_err("Expected \"bus_name/dev_name\".\n");
521*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
522*de1e4e89SAndroid Build Coastguard Worker }
523*de1e4e89SAndroid Build Coastguard Worker return __dl_argv_handle(str, p_bus_name, p_dev_name);
524*de1e4e89SAndroid Build Coastguard Worker }
525*de1e4e89SAndroid Build Coastguard Worker
__dl_argv_handle_port(char * str,char ** p_bus_name,char ** p_dev_name,uint32_t * p_port_index)526*de1e4e89SAndroid Build Coastguard Worker static int __dl_argv_handle_port(char *str,
527*de1e4e89SAndroid Build Coastguard Worker char **p_bus_name, char **p_dev_name,
528*de1e4e89SAndroid Build Coastguard Worker uint32_t *p_port_index)
529*de1e4e89SAndroid Build Coastguard Worker {
530*de1e4e89SAndroid Build Coastguard Worker char *handlestr;
531*de1e4e89SAndroid Build Coastguard Worker char *portstr;
532*de1e4e89SAndroid Build Coastguard Worker int err;
533*de1e4e89SAndroid Build Coastguard Worker
534*de1e4e89SAndroid Build Coastguard Worker err = strslashrsplit(str, &handlestr, &portstr);
535*de1e4e89SAndroid Build Coastguard Worker if (err) {
536*de1e4e89SAndroid Build Coastguard Worker pr_err("Port identification \"%s\" is invalid\n", str);
537*de1e4e89SAndroid Build Coastguard Worker return err;
538*de1e4e89SAndroid Build Coastguard Worker }
539*de1e4e89SAndroid Build Coastguard Worker err = strtouint32_t(portstr, p_port_index);
540*de1e4e89SAndroid Build Coastguard Worker if (err) {
541*de1e4e89SAndroid Build Coastguard Worker pr_err("Port index \"%s\" is not a number or not within range\n",
542*de1e4e89SAndroid Build Coastguard Worker portstr);
543*de1e4e89SAndroid Build Coastguard Worker return err;
544*de1e4e89SAndroid Build Coastguard Worker }
545*de1e4e89SAndroid Build Coastguard Worker err = strslashrsplit(handlestr, p_bus_name, p_dev_name);
546*de1e4e89SAndroid Build Coastguard Worker if (err) {
547*de1e4e89SAndroid Build Coastguard Worker pr_err("Port identification \"%s\" is invalid\n", str);
548*de1e4e89SAndroid Build Coastguard Worker return err;
549*de1e4e89SAndroid Build Coastguard Worker }
550*de1e4e89SAndroid Build Coastguard Worker return 0;
551*de1e4e89SAndroid Build Coastguard Worker }
552*de1e4e89SAndroid Build Coastguard Worker
__dl_argv_handle_port_ifname(struct dl * dl,char * str,char ** p_bus_name,char ** p_dev_name,uint32_t * p_port_index)553*de1e4e89SAndroid Build Coastguard Worker static int __dl_argv_handle_port_ifname(struct dl *dl, char *str,
554*de1e4e89SAndroid Build Coastguard Worker char **p_bus_name, char **p_dev_name,
555*de1e4e89SAndroid Build Coastguard Worker uint32_t *p_port_index)
556*de1e4e89SAndroid Build Coastguard Worker {
557*de1e4e89SAndroid Build Coastguard Worker int err;
558*de1e4e89SAndroid Build Coastguard Worker
559*de1e4e89SAndroid Build Coastguard Worker err = ifname_map_lookup(dl, str, p_bus_name, p_dev_name,
560*de1e4e89SAndroid Build Coastguard Worker p_port_index);
561*de1e4e89SAndroid Build Coastguard Worker if (err) {
562*de1e4e89SAndroid Build Coastguard Worker pr_err("Netdevice \"%s\" not found\n", str);
563*de1e4e89SAndroid Build Coastguard Worker return err;
564*de1e4e89SAndroid Build Coastguard Worker }
565*de1e4e89SAndroid Build Coastguard Worker return 0;
566*de1e4e89SAndroid Build Coastguard Worker }
567*de1e4e89SAndroid Build Coastguard Worker
dl_argv_handle_port(struct dl * dl,char ** p_bus_name,char ** p_dev_name,uint32_t * p_port_index)568*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_handle_port(struct dl *dl, char **p_bus_name,
569*de1e4e89SAndroid Build Coastguard Worker char **p_dev_name, uint32_t *p_port_index)
570*de1e4e89SAndroid Build Coastguard Worker {
571*de1e4e89SAndroid Build Coastguard Worker char *str = dl_argv_next(dl);
572*de1e4e89SAndroid Build Coastguard Worker unsigned int slash_count;
573*de1e4e89SAndroid Build Coastguard Worker
574*de1e4e89SAndroid Build Coastguard Worker if (!str) {
575*de1e4e89SAndroid Build Coastguard Worker pr_err("Port identification (\"bus_name/dev_name/port_index\" or \"netdev ifname\") expected.\n");
576*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
577*de1e4e89SAndroid Build Coastguard Worker }
578*de1e4e89SAndroid Build Coastguard Worker slash_count = strslashcount(str);
579*de1e4e89SAndroid Build Coastguard Worker switch (slash_count) {
580*de1e4e89SAndroid Build Coastguard Worker case 0:
581*de1e4e89SAndroid Build Coastguard Worker return __dl_argv_handle_port_ifname(dl, str, p_bus_name,
582*de1e4e89SAndroid Build Coastguard Worker p_dev_name, p_port_index);
583*de1e4e89SAndroid Build Coastguard Worker case 2:
584*de1e4e89SAndroid Build Coastguard Worker return __dl_argv_handle_port(str, p_bus_name,
585*de1e4e89SAndroid Build Coastguard Worker p_dev_name, p_port_index);
586*de1e4e89SAndroid Build Coastguard Worker default:
587*de1e4e89SAndroid Build Coastguard Worker pr_err("Wrong port identification string format.\n");
588*de1e4e89SAndroid Build Coastguard Worker pr_err("Expected \"bus_name/dev_name/port_index\" or \"netdev_ifname\".\n");
589*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
590*de1e4e89SAndroid Build Coastguard Worker }
591*de1e4e89SAndroid Build Coastguard Worker }
592*de1e4e89SAndroid Build Coastguard Worker
dl_argv_handle_both(struct dl * dl,char ** p_bus_name,char ** p_dev_name,uint32_t * p_port_index,uint32_t * p_handle_bit)593*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_handle_both(struct dl *dl, char **p_bus_name,
594*de1e4e89SAndroid Build Coastguard Worker char **p_dev_name, uint32_t *p_port_index,
595*de1e4e89SAndroid Build Coastguard Worker uint32_t *p_handle_bit)
596*de1e4e89SAndroid Build Coastguard Worker {
597*de1e4e89SAndroid Build Coastguard Worker char *str = dl_argv_next(dl);
598*de1e4e89SAndroid Build Coastguard Worker unsigned int slash_count;
599*de1e4e89SAndroid Build Coastguard Worker int err;
600*de1e4e89SAndroid Build Coastguard Worker
601*de1e4e89SAndroid Build Coastguard Worker if (!str) {
602*de1e4e89SAndroid Build Coastguard Worker pr_err("One of following identifications expected:\n"
603*de1e4e89SAndroid Build Coastguard Worker "Devlink identification (\"bus_name/dev_name\")\n"
604*de1e4e89SAndroid Build Coastguard Worker "Port identification (\"bus_name/dev_name/port_index\" or \"netdev ifname\")\n");
605*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
606*de1e4e89SAndroid Build Coastguard Worker }
607*de1e4e89SAndroid Build Coastguard Worker slash_count = strslashcount(str);
608*de1e4e89SAndroid Build Coastguard Worker if (slash_count == 1) {
609*de1e4e89SAndroid Build Coastguard Worker err = __dl_argv_handle(str, p_bus_name, p_dev_name);
610*de1e4e89SAndroid Build Coastguard Worker if (err)
611*de1e4e89SAndroid Build Coastguard Worker return err;
612*de1e4e89SAndroid Build Coastguard Worker *p_handle_bit = DL_OPT_HANDLE;
613*de1e4e89SAndroid Build Coastguard Worker } else if (slash_count == 2) {
614*de1e4e89SAndroid Build Coastguard Worker err = __dl_argv_handle_port(str, p_bus_name,
615*de1e4e89SAndroid Build Coastguard Worker p_dev_name, p_port_index);
616*de1e4e89SAndroid Build Coastguard Worker if (err)
617*de1e4e89SAndroid Build Coastguard Worker return err;
618*de1e4e89SAndroid Build Coastguard Worker *p_handle_bit = DL_OPT_HANDLEP;
619*de1e4e89SAndroid Build Coastguard Worker } else if (slash_count == 0) {
620*de1e4e89SAndroid Build Coastguard Worker err = __dl_argv_handle_port_ifname(dl, str, p_bus_name,
621*de1e4e89SAndroid Build Coastguard Worker p_dev_name, p_port_index);
622*de1e4e89SAndroid Build Coastguard Worker if (err)
623*de1e4e89SAndroid Build Coastguard Worker return err;
624*de1e4e89SAndroid Build Coastguard Worker *p_handle_bit = DL_OPT_HANDLEP;
625*de1e4e89SAndroid Build Coastguard Worker } else {
626*de1e4e89SAndroid Build Coastguard Worker pr_err("Wrong port identification string format.\n");
627*de1e4e89SAndroid Build Coastguard Worker pr_err("Expected \"bus_name/dev_name\" or \"bus_name/dev_name/port_index\" or \"netdev_ifname\".\n");
628*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
629*de1e4e89SAndroid Build Coastguard Worker }
630*de1e4e89SAndroid Build Coastguard Worker return 0;
631*de1e4e89SAndroid Build Coastguard Worker }
632*de1e4e89SAndroid Build Coastguard Worker
dl_argv_uint32_t(struct dl * dl,uint32_t * p_val)633*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_uint32_t(struct dl *dl, uint32_t *p_val)
634*de1e4e89SAndroid Build Coastguard Worker {
635*de1e4e89SAndroid Build Coastguard Worker char *str = dl_argv_next(dl);
636*de1e4e89SAndroid Build Coastguard Worker int err;
637*de1e4e89SAndroid Build Coastguard Worker
638*de1e4e89SAndroid Build Coastguard Worker if (!str) {
639*de1e4e89SAndroid Build Coastguard Worker pr_err("Unsigned number argument expected\n");
640*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
641*de1e4e89SAndroid Build Coastguard Worker }
642*de1e4e89SAndroid Build Coastguard Worker
643*de1e4e89SAndroid Build Coastguard Worker err = strtouint32_t(str, p_val);
644*de1e4e89SAndroid Build Coastguard Worker if (err) {
645*de1e4e89SAndroid Build Coastguard Worker pr_err("\"%s\" is not a number or not within range\n", str);
646*de1e4e89SAndroid Build Coastguard Worker return err;
647*de1e4e89SAndroid Build Coastguard Worker }
648*de1e4e89SAndroid Build Coastguard Worker return 0;
649*de1e4e89SAndroid Build Coastguard Worker }
650*de1e4e89SAndroid Build Coastguard Worker
dl_argv_uint16_t(struct dl * dl,uint16_t * p_val)651*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_uint16_t(struct dl *dl, uint16_t *p_val)
652*de1e4e89SAndroid Build Coastguard Worker {
653*de1e4e89SAndroid Build Coastguard Worker char *str = dl_argv_next(dl);
654*de1e4e89SAndroid Build Coastguard Worker int err;
655*de1e4e89SAndroid Build Coastguard Worker
656*de1e4e89SAndroid Build Coastguard Worker if (!str) {
657*de1e4e89SAndroid Build Coastguard Worker pr_err("Unsigned number argument expected\n");
658*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
659*de1e4e89SAndroid Build Coastguard Worker }
660*de1e4e89SAndroid Build Coastguard Worker
661*de1e4e89SAndroid Build Coastguard Worker err = strtouint16_t(str, p_val);
662*de1e4e89SAndroid Build Coastguard Worker if (err) {
663*de1e4e89SAndroid Build Coastguard Worker pr_err("\"%s\" is not a number or not within range\n", str);
664*de1e4e89SAndroid Build Coastguard Worker return err;
665*de1e4e89SAndroid Build Coastguard Worker }
666*de1e4e89SAndroid Build Coastguard Worker return 0;
667*de1e4e89SAndroid Build Coastguard Worker }
668*de1e4e89SAndroid Build Coastguard Worker
dl_argv_str(struct dl * dl,const char ** p_str)669*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_str(struct dl *dl, const char **p_str)
670*de1e4e89SAndroid Build Coastguard Worker {
671*de1e4e89SAndroid Build Coastguard Worker const char *str = dl_argv_next(dl);
672*de1e4e89SAndroid Build Coastguard Worker
673*de1e4e89SAndroid Build Coastguard Worker if (!str) {
674*de1e4e89SAndroid Build Coastguard Worker pr_err("String parameter expected\n");
675*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
676*de1e4e89SAndroid Build Coastguard Worker }
677*de1e4e89SAndroid Build Coastguard Worker *p_str = str;
678*de1e4e89SAndroid Build Coastguard Worker return 0;
679*de1e4e89SAndroid Build Coastguard Worker }
680*de1e4e89SAndroid Build Coastguard Worker
port_type_get(const char * typestr,enum devlink_port_type * p_type)681*de1e4e89SAndroid Build Coastguard Worker static int port_type_get(const char *typestr, enum devlink_port_type *p_type)
682*de1e4e89SAndroid Build Coastguard Worker {
683*de1e4e89SAndroid Build Coastguard Worker if (strcmp(typestr, "auto") == 0) {
684*de1e4e89SAndroid Build Coastguard Worker *p_type = DEVLINK_PORT_TYPE_AUTO;
685*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, "eth") == 0) {
686*de1e4e89SAndroid Build Coastguard Worker *p_type = DEVLINK_PORT_TYPE_ETH;
687*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, "ib") == 0) {
688*de1e4e89SAndroid Build Coastguard Worker *p_type = DEVLINK_PORT_TYPE_IB;
689*de1e4e89SAndroid Build Coastguard Worker } else {
690*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown port type \"%s\"\n", typestr);
691*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
692*de1e4e89SAndroid Build Coastguard Worker }
693*de1e4e89SAndroid Build Coastguard Worker return 0;
694*de1e4e89SAndroid Build Coastguard Worker }
695*de1e4e89SAndroid Build Coastguard Worker
pool_type_get(const char * typestr,enum devlink_sb_pool_type * p_type)696*de1e4e89SAndroid Build Coastguard Worker static int pool_type_get(const char *typestr, enum devlink_sb_pool_type *p_type)
697*de1e4e89SAndroid Build Coastguard Worker {
698*de1e4e89SAndroid Build Coastguard Worker if (strcmp(typestr, "ingress") == 0) {
699*de1e4e89SAndroid Build Coastguard Worker *p_type = DEVLINK_SB_POOL_TYPE_INGRESS;
700*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, "egress") == 0) {
701*de1e4e89SAndroid Build Coastguard Worker *p_type = DEVLINK_SB_POOL_TYPE_EGRESS;
702*de1e4e89SAndroid Build Coastguard Worker } else {
703*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown pool type \"%s\"\n", typestr);
704*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
705*de1e4e89SAndroid Build Coastguard Worker }
706*de1e4e89SAndroid Build Coastguard Worker return 0;
707*de1e4e89SAndroid Build Coastguard Worker }
708*de1e4e89SAndroid Build Coastguard Worker
threshold_type_get(const char * typestr,enum devlink_sb_threshold_type * p_type)709*de1e4e89SAndroid Build Coastguard Worker static int threshold_type_get(const char *typestr,
710*de1e4e89SAndroid Build Coastguard Worker enum devlink_sb_threshold_type *p_type)
711*de1e4e89SAndroid Build Coastguard Worker {
712*de1e4e89SAndroid Build Coastguard Worker if (strcmp(typestr, "static") == 0) {
713*de1e4e89SAndroid Build Coastguard Worker *p_type = DEVLINK_SB_THRESHOLD_TYPE_STATIC;
714*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, "dynamic") == 0) {
715*de1e4e89SAndroid Build Coastguard Worker *p_type = DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC;
716*de1e4e89SAndroid Build Coastguard Worker } else {
717*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown threshold type \"%s\"\n", typestr);
718*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
719*de1e4e89SAndroid Build Coastguard Worker }
720*de1e4e89SAndroid Build Coastguard Worker return 0;
721*de1e4e89SAndroid Build Coastguard Worker }
722*de1e4e89SAndroid Build Coastguard Worker
eswitch_mode_get(const char * typestr,enum devlink_eswitch_mode * p_mode)723*de1e4e89SAndroid Build Coastguard Worker static int eswitch_mode_get(const char *typestr,
724*de1e4e89SAndroid Build Coastguard Worker enum devlink_eswitch_mode *p_mode)
725*de1e4e89SAndroid Build Coastguard Worker {
726*de1e4e89SAndroid Build Coastguard Worker if (strcmp(typestr, ESWITCH_MODE_LEGACY) == 0) {
727*de1e4e89SAndroid Build Coastguard Worker *p_mode = DEVLINK_ESWITCH_MODE_LEGACY;
728*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, ESWITCH_MODE_SWITCHDEV) == 0) {
729*de1e4e89SAndroid Build Coastguard Worker *p_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
730*de1e4e89SAndroid Build Coastguard Worker } else {
731*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown eswitch mode \"%s\"\n", typestr);
732*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
733*de1e4e89SAndroid Build Coastguard Worker }
734*de1e4e89SAndroid Build Coastguard Worker return 0;
735*de1e4e89SAndroid Build Coastguard Worker }
736*de1e4e89SAndroid Build Coastguard Worker
eswitch_inline_mode_get(const char * typestr,enum devlink_eswitch_inline_mode * p_mode)737*de1e4e89SAndroid Build Coastguard Worker static int eswitch_inline_mode_get(const char *typestr,
738*de1e4e89SAndroid Build Coastguard Worker enum devlink_eswitch_inline_mode *p_mode)
739*de1e4e89SAndroid Build Coastguard Worker {
740*de1e4e89SAndroid Build Coastguard Worker if (strcmp(typestr, ESWITCH_INLINE_MODE_NONE) == 0) {
741*de1e4e89SAndroid Build Coastguard Worker *p_mode = DEVLINK_ESWITCH_INLINE_MODE_NONE;
742*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, ESWITCH_INLINE_MODE_LINK) == 0) {
743*de1e4e89SAndroid Build Coastguard Worker *p_mode = DEVLINK_ESWITCH_INLINE_MODE_LINK;
744*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, ESWITCH_INLINE_MODE_NETWORK) == 0) {
745*de1e4e89SAndroid Build Coastguard Worker *p_mode = DEVLINK_ESWITCH_INLINE_MODE_NETWORK;
746*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, ESWITCH_INLINE_MODE_TRANSPORT) == 0) {
747*de1e4e89SAndroid Build Coastguard Worker *p_mode = DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT;
748*de1e4e89SAndroid Build Coastguard Worker } else {
749*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown eswitch inline mode \"%s\"\n", typestr);
750*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
751*de1e4e89SAndroid Build Coastguard Worker }
752*de1e4e89SAndroid Build Coastguard Worker return 0;
753*de1e4e89SAndroid Build Coastguard Worker }
754*de1e4e89SAndroid Build Coastguard Worker
dpipe_counters_enable_get(const char * typestr,bool * counters_enable)755*de1e4e89SAndroid Build Coastguard Worker static int dpipe_counters_enable_get(const char *typestr,
756*de1e4e89SAndroid Build Coastguard Worker bool *counters_enable)
757*de1e4e89SAndroid Build Coastguard Worker {
758*de1e4e89SAndroid Build Coastguard Worker if (strcmp(typestr, "enable") == 0) {
759*de1e4e89SAndroid Build Coastguard Worker *counters_enable = 1;
760*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, "disable") == 0) {
761*de1e4e89SAndroid Build Coastguard Worker *counters_enable = 0;
762*de1e4e89SAndroid Build Coastguard Worker } else {
763*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown counter_state \"%s\"\n", typestr);
764*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
765*de1e4e89SAndroid Build Coastguard Worker }
766*de1e4e89SAndroid Build Coastguard Worker return 0;
767*de1e4e89SAndroid Build Coastguard Worker }
768*de1e4e89SAndroid Build Coastguard Worker
eswitch_encap_mode_get(const char * typestr,bool * p_mode)769*de1e4e89SAndroid Build Coastguard Worker static int eswitch_encap_mode_get(const char *typestr, bool *p_mode)
770*de1e4e89SAndroid Build Coastguard Worker {
771*de1e4e89SAndroid Build Coastguard Worker if (strcmp(typestr, "enable") == 0) {
772*de1e4e89SAndroid Build Coastguard Worker *p_mode = true;
773*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(typestr, "disable") == 0) {
774*de1e4e89SAndroid Build Coastguard Worker *p_mode = false;
775*de1e4e89SAndroid Build Coastguard Worker } else {
776*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown eswitch encap mode \"%s\"\n", typestr);
777*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
778*de1e4e89SAndroid Build Coastguard Worker }
779*de1e4e89SAndroid Build Coastguard Worker return 0;
780*de1e4e89SAndroid Build Coastguard Worker }
781*de1e4e89SAndroid Build Coastguard Worker
dl_argv_parse(struct dl * dl,uint32_t o_required,uint32_t o_optional)782*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_parse(struct dl *dl, uint32_t o_required,
783*de1e4e89SAndroid Build Coastguard Worker uint32_t o_optional)
784*de1e4e89SAndroid Build Coastguard Worker {
785*de1e4e89SAndroid Build Coastguard Worker struct dl_opts *opts = &dl->opts;
786*de1e4e89SAndroid Build Coastguard Worker uint32_t o_all = o_required | o_optional;
787*de1e4e89SAndroid Build Coastguard Worker uint32_t o_found = 0;
788*de1e4e89SAndroid Build Coastguard Worker int err;
789*de1e4e89SAndroid Build Coastguard Worker
790*de1e4e89SAndroid Build Coastguard Worker if (o_required & DL_OPT_HANDLE && o_required & DL_OPT_HANDLEP) {
791*de1e4e89SAndroid Build Coastguard Worker uint32_t handle_bit;
792*de1e4e89SAndroid Build Coastguard Worker
793*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_handle_both(dl, &opts->bus_name, &opts->dev_name,
794*de1e4e89SAndroid Build Coastguard Worker &opts->port_index, &handle_bit);
795*de1e4e89SAndroid Build Coastguard Worker if (err)
796*de1e4e89SAndroid Build Coastguard Worker return err;
797*de1e4e89SAndroid Build Coastguard Worker o_found |= handle_bit;
798*de1e4e89SAndroid Build Coastguard Worker } else if (o_required & DL_OPT_HANDLE) {
799*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_handle(dl, &opts->bus_name, &opts->dev_name);
800*de1e4e89SAndroid Build Coastguard Worker if (err)
801*de1e4e89SAndroid Build Coastguard Worker return err;
802*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_HANDLE;
803*de1e4e89SAndroid Build Coastguard Worker } else if (o_required & DL_OPT_HANDLEP) {
804*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_handle_port(dl, &opts->bus_name, &opts->dev_name,
805*de1e4e89SAndroid Build Coastguard Worker &opts->port_index);
806*de1e4e89SAndroid Build Coastguard Worker if (err)
807*de1e4e89SAndroid Build Coastguard Worker return err;
808*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_HANDLEP;
809*de1e4e89SAndroid Build Coastguard Worker }
810*de1e4e89SAndroid Build Coastguard Worker
811*de1e4e89SAndroid Build Coastguard Worker while (dl_argc(dl)) {
812*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "type") &&
813*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_PORT_TYPE)) {
814*de1e4e89SAndroid Build Coastguard Worker const char *typestr;
815*de1e4e89SAndroid Build Coastguard Worker
816*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
817*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &typestr);
818*de1e4e89SAndroid Build Coastguard Worker if (err)
819*de1e4e89SAndroid Build Coastguard Worker return err;
820*de1e4e89SAndroid Build Coastguard Worker err = port_type_get(typestr, &opts->port_type);
821*de1e4e89SAndroid Build Coastguard Worker if (err)
822*de1e4e89SAndroid Build Coastguard Worker return err;
823*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_PORT_TYPE;
824*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "count") &&
825*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_PORT_COUNT)) {
826*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
827*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_uint32_t(dl, &opts->port_count);
828*de1e4e89SAndroid Build Coastguard Worker if (err)
829*de1e4e89SAndroid Build Coastguard Worker return err;
830*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_PORT_COUNT;
831*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "sb") &&
832*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_SB)) {
833*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
834*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_uint32_t(dl, &opts->sb_index);
835*de1e4e89SAndroid Build Coastguard Worker if (err)
836*de1e4e89SAndroid Build Coastguard Worker return err;
837*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_SB;
838*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "pool") &&
839*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_SB_POOL)) {
840*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
841*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_uint16_t(dl, &opts->sb_pool_index);
842*de1e4e89SAndroid Build Coastguard Worker if (err)
843*de1e4e89SAndroid Build Coastguard Worker return err;
844*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_SB_POOL;
845*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "size") &&
846*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_SB_SIZE)) {
847*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
848*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_uint32_t(dl, &opts->sb_pool_size);
849*de1e4e89SAndroid Build Coastguard Worker if (err)
850*de1e4e89SAndroid Build Coastguard Worker return err;
851*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_SB_SIZE;
852*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "type") &&
853*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_SB_TYPE)) {
854*de1e4e89SAndroid Build Coastguard Worker const char *typestr;
855*de1e4e89SAndroid Build Coastguard Worker
856*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
857*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &typestr);
858*de1e4e89SAndroid Build Coastguard Worker if (err)
859*de1e4e89SAndroid Build Coastguard Worker return err;
860*de1e4e89SAndroid Build Coastguard Worker err = pool_type_get(typestr, &opts->sb_pool_type);
861*de1e4e89SAndroid Build Coastguard Worker if (err)
862*de1e4e89SAndroid Build Coastguard Worker return err;
863*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_SB_TYPE;
864*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "thtype") &&
865*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_SB_THTYPE)) {
866*de1e4e89SAndroid Build Coastguard Worker const char *typestr;
867*de1e4e89SAndroid Build Coastguard Worker
868*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
869*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &typestr);
870*de1e4e89SAndroid Build Coastguard Worker if (err)
871*de1e4e89SAndroid Build Coastguard Worker return err;
872*de1e4e89SAndroid Build Coastguard Worker err = threshold_type_get(typestr,
873*de1e4e89SAndroid Build Coastguard Worker &opts->sb_pool_thtype);
874*de1e4e89SAndroid Build Coastguard Worker if (err)
875*de1e4e89SAndroid Build Coastguard Worker return err;
876*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_SB_THTYPE;
877*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "th") &&
878*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_SB_TH)) {
879*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
880*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_uint32_t(dl, &opts->sb_threshold);
881*de1e4e89SAndroid Build Coastguard Worker if (err)
882*de1e4e89SAndroid Build Coastguard Worker return err;
883*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_SB_TH;
884*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "tc") &&
885*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_SB_TC)) {
886*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
887*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_uint16_t(dl, &opts->sb_tc_index);
888*de1e4e89SAndroid Build Coastguard Worker if (err)
889*de1e4e89SAndroid Build Coastguard Worker return err;
890*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_SB_TC;
891*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "mode") &&
892*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_ESWITCH_MODE)) {
893*de1e4e89SAndroid Build Coastguard Worker const char *typestr;
894*de1e4e89SAndroid Build Coastguard Worker
895*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
896*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &typestr);
897*de1e4e89SAndroid Build Coastguard Worker if (err)
898*de1e4e89SAndroid Build Coastguard Worker return err;
899*de1e4e89SAndroid Build Coastguard Worker err = eswitch_mode_get(typestr, &opts->eswitch_mode);
900*de1e4e89SAndroid Build Coastguard Worker if (err)
901*de1e4e89SAndroid Build Coastguard Worker return err;
902*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_ESWITCH_MODE;
903*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "inline-mode") &&
904*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_ESWITCH_INLINE_MODE)) {
905*de1e4e89SAndroid Build Coastguard Worker const char *typestr;
906*de1e4e89SAndroid Build Coastguard Worker
907*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
908*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &typestr);
909*de1e4e89SAndroid Build Coastguard Worker if (err)
910*de1e4e89SAndroid Build Coastguard Worker return err;
911*de1e4e89SAndroid Build Coastguard Worker err = eswitch_inline_mode_get(
912*de1e4e89SAndroid Build Coastguard Worker typestr, &opts->eswitch_inline_mode);
913*de1e4e89SAndroid Build Coastguard Worker if (err)
914*de1e4e89SAndroid Build Coastguard Worker return err;
915*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_ESWITCH_INLINE_MODE;
916*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "name") &&
917*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_DPIPE_TABLE_NAME)) {
918*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
919*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &opts->dpipe_table_name);
920*de1e4e89SAndroid Build Coastguard Worker if (err)
921*de1e4e89SAndroid Build Coastguard Worker return err;
922*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_DPIPE_TABLE_NAME;
923*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "counters") &&
924*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_DPIPE_TABLE_COUNTERS)) {
925*de1e4e89SAndroid Build Coastguard Worker const char *typestr;
926*de1e4e89SAndroid Build Coastguard Worker
927*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
928*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &typestr);
929*de1e4e89SAndroid Build Coastguard Worker if (err)
930*de1e4e89SAndroid Build Coastguard Worker return err;
931*de1e4e89SAndroid Build Coastguard Worker err = dpipe_counters_enable_get(typestr,
932*de1e4e89SAndroid Build Coastguard Worker &opts->dpipe_counters_enable);
933*de1e4e89SAndroid Build Coastguard Worker if (err)
934*de1e4e89SAndroid Build Coastguard Worker return err;
935*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_DPIPE_TABLE_COUNTERS;
936*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "encap") &&
937*de1e4e89SAndroid Build Coastguard Worker (o_all & DL_OPT_ESWITCH_ENCAP_MODE)) {
938*de1e4e89SAndroid Build Coastguard Worker const char *typestr;
939*de1e4e89SAndroid Build Coastguard Worker
940*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
941*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_str(dl, &typestr);
942*de1e4e89SAndroid Build Coastguard Worker if (err)
943*de1e4e89SAndroid Build Coastguard Worker return err;
944*de1e4e89SAndroid Build Coastguard Worker err = eswitch_encap_mode_get(typestr,
945*de1e4e89SAndroid Build Coastguard Worker &opts->eswitch_encap_mode);
946*de1e4e89SAndroid Build Coastguard Worker if (err)
947*de1e4e89SAndroid Build Coastguard Worker return err;
948*de1e4e89SAndroid Build Coastguard Worker o_found |= DL_OPT_ESWITCH_ENCAP_MODE;
949*de1e4e89SAndroid Build Coastguard Worker } else {
950*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown option \"%s\"\n", dl_argv(dl));
951*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
952*de1e4e89SAndroid Build Coastguard Worker }
953*de1e4e89SAndroid Build Coastguard Worker }
954*de1e4e89SAndroid Build Coastguard Worker
955*de1e4e89SAndroid Build Coastguard Worker opts->present = o_found;
956*de1e4e89SAndroid Build Coastguard Worker
957*de1e4e89SAndroid Build Coastguard Worker if ((o_optional & DL_OPT_SB) && !(o_found & DL_OPT_SB)) {
958*de1e4e89SAndroid Build Coastguard Worker opts->sb_index = 0;
959*de1e4e89SAndroid Build Coastguard Worker opts->present |= DL_OPT_SB;
960*de1e4e89SAndroid Build Coastguard Worker }
961*de1e4e89SAndroid Build Coastguard Worker
962*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_PORT_TYPE) && !(o_found & DL_OPT_PORT_TYPE)) {
963*de1e4e89SAndroid Build Coastguard Worker pr_err("Port type option expected.\n");
964*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
965*de1e4e89SAndroid Build Coastguard Worker }
966*de1e4e89SAndroid Build Coastguard Worker
967*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_PORT_COUNT) &&
968*de1e4e89SAndroid Build Coastguard Worker !(o_found & DL_OPT_PORT_COUNT)) {
969*de1e4e89SAndroid Build Coastguard Worker pr_err("Port split count option expected.\n");
970*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
971*de1e4e89SAndroid Build Coastguard Worker }
972*de1e4e89SAndroid Build Coastguard Worker
973*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_SB_POOL) && !(o_found & DL_OPT_SB_POOL)) {
974*de1e4e89SAndroid Build Coastguard Worker pr_err("Pool index option expected.\n");
975*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
976*de1e4e89SAndroid Build Coastguard Worker }
977*de1e4e89SAndroid Build Coastguard Worker
978*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_SB_SIZE) && !(o_found & DL_OPT_SB_SIZE)) {
979*de1e4e89SAndroid Build Coastguard Worker pr_err("Pool size option expected.\n");
980*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
981*de1e4e89SAndroid Build Coastguard Worker }
982*de1e4e89SAndroid Build Coastguard Worker
983*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_SB_TYPE) && !(o_found & DL_OPT_SB_TYPE)) {
984*de1e4e89SAndroid Build Coastguard Worker pr_err("Pool type option expected.\n");
985*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
986*de1e4e89SAndroid Build Coastguard Worker }
987*de1e4e89SAndroid Build Coastguard Worker
988*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_SB_THTYPE) && !(o_found & DL_OPT_SB_THTYPE)) {
989*de1e4e89SAndroid Build Coastguard Worker pr_err("Pool threshold type option expected.\n");
990*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
991*de1e4e89SAndroid Build Coastguard Worker }
992*de1e4e89SAndroid Build Coastguard Worker
993*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_SB_TH) && !(o_found & DL_OPT_SB_TH)) {
994*de1e4e89SAndroid Build Coastguard Worker pr_err("Threshold option expected.\n");
995*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
996*de1e4e89SAndroid Build Coastguard Worker }
997*de1e4e89SAndroid Build Coastguard Worker
998*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_SB_TC) && !(o_found & DL_OPT_SB_TC)) {
999*de1e4e89SAndroid Build Coastguard Worker pr_err("TC index option expected.\n");
1000*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
1001*de1e4e89SAndroid Build Coastguard Worker }
1002*de1e4e89SAndroid Build Coastguard Worker
1003*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_ESWITCH_MODE) &&
1004*de1e4e89SAndroid Build Coastguard Worker !(o_found & DL_OPT_ESWITCH_MODE)) {
1005*de1e4e89SAndroid Build Coastguard Worker pr_err("E-Switch mode option expected.\n");
1006*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
1007*de1e4e89SAndroid Build Coastguard Worker }
1008*de1e4e89SAndroid Build Coastguard Worker
1009*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_ESWITCH_INLINE_MODE) &&
1010*de1e4e89SAndroid Build Coastguard Worker !(o_found & DL_OPT_ESWITCH_INLINE_MODE)) {
1011*de1e4e89SAndroid Build Coastguard Worker pr_err("E-Switch inline-mode option expected.\n");
1012*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
1013*de1e4e89SAndroid Build Coastguard Worker }
1014*de1e4e89SAndroid Build Coastguard Worker
1015*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_DPIPE_TABLE_NAME) &&
1016*de1e4e89SAndroid Build Coastguard Worker !(o_found & DL_OPT_DPIPE_TABLE_NAME)) {
1017*de1e4e89SAndroid Build Coastguard Worker pr_err("Dpipe table name expected\n");
1018*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
1019*de1e4e89SAndroid Build Coastguard Worker }
1020*de1e4e89SAndroid Build Coastguard Worker
1021*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_DPIPE_TABLE_COUNTERS) &&
1022*de1e4e89SAndroid Build Coastguard Worker !(o_found & DL_OPT_DPIPE_TABLE_COUNTERS)) {
1023*de1e4e89SAndroid Build Coastguard Worker pr_err("Dpipe table counter state expected\n");
1024*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
1025*de1e4e89SAndroid Build Coastguard Worker }
1026*de1e4e89SAndroid Build Coastguard Worker
1027*de1e4e89SAndroid Build Coastguard Worker if ((o_required & DL_OPT_ESWITCH_ENCAP_MODE) &&
1028*de1e4e89SAndroid Build Coastguard Worker !(o_found & DL_OPT_ESWITCH_ENCAP_MODE)) {
1029*de1e4e89SAndroid Build Coastguard Worker pr_err("E-Switch encapsulation option expected.\n");
1030*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
1031*de1e4e89SAndroid Build Coastguard Worker }
1032*de1e4e89SAndroid Build Coastguard Worker
1033*de1e4e89SAndroid Build Coastguard Worker return 0;
1034*de1e4e89SAndroid Build Coastguard Worker }
1035*de1e4e89SAndroid Build Coastguard Worker
dl_opts_put(struct nlmsghdr * nlh,struct dl * dl)1036*de1e4e89SAndroid Build Coastguard Worker static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
1037*de1e4e89SAndroid Build Coastguard Worker {
1038*de1e4e89SAndroid Build Coastguard Worker struct dl_opts *opts = &dl->opts;
1039*de1e4e89SAndroid Build Coastguard Worker
1040*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_HANDLE) {
1041*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, opts->bus_name);
1042*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, opts->dev_name);
1043*de1e4e89SAndroid Build Coastguard Worker } else if (opts->present & DL_OPT_HANDLEP) {
1044*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, opts->bus_name);
1045*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, opts->dev_name);
1046*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX,
1047*de1e4e89SAndroid Build Coastguard Worker opts->port_index);
1048*de1e4e89SAndroid Build Coastguard Worker }
1049*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_PORT_TYPE)
1050*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_TYPE,
1051*de1e4e89SAndroid Build Coastguard Worker opts->port_type);
1052*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_PORT_COUNT)
1053*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_SPLIT_COUNT,
1054*de1e4e89SAndroid Build Coastguard Worker opts->port_count);
1055*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB)
1056*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX,
1057*de1e4e89SAndroid Build Coastguard Worker opts->sb_index);
1058*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB_POOL)
1059*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX,
1060*de1e4e89SAndroid Build Coastguard Worker opts->sb_pool_index);
1061*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB_SIZE)
1062*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_POOL_SIZE,
1063*de1e4e89SAndroid Build Coastguard Worker opts->sb_pool_size);
1064*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB_TYPE)
1065*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u8(nlh, DEVLINK_ATTR_SB_POOL_TYPE,
1066*de1e4e89SAndroid Build Coastguard Worker opts->sb_pool_type);
1067*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB_THTYPE)
1068*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u8(nlh, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
1069*de1e4e89SAndroid Build Coastguard Worker opts->sb_pool_thtype);
1070*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB_TH)
1071*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, DEVLINK_ATTR_SB_THRESHOLD,
1072*de1e4e89SAndroid Build Coastguard Worker opts->sb_threshold);
1073*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB_TC)
1074*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u16(nlh, DEVLINK_ATTR_SB_TC_INDEX,
1075*de1e4e89SAndroid Build Coastguard Worker opts->sb_tc_index);
1076*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_ESWITCH_MODE)
1077*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u16(nlh, DEVLINK_ATTR_ESWITCH_MODE,
1078*de1e4e89SAndroid Build Coastguard Worker opts->eswitch_mode);
1079*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_ESWITCH_INLINE_MODE)
1080*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1081*de1e4e89SAndroid Build Coastguard Worker opts->eswitch_inline_mode);
1082*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_DPIPE_TABLE_NAME)
1083*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_strz(nlh, DEVLINK_ATTR_DPIPE_TABLE_NAME,
1084*de1e4e89SAndroid Build Coastguard Worker opts->dpipe_table_name);
1085*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_DPIPE_TABLE_COUNTERS)
1086*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u8(nlh, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1087*de1e4e89SAndroid Build Coastguard Worker opts->dpipe_counters_enable);
1088*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_ESWITCH_ENCAP_MODE)
1089*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_ENCAP_MODE,
1090*de1e4e89SAndroid Build Coastguard Worker opts->eswitch_encap_mode);
1091*de1e4e89SAndroid Build Coastguard Worker }
1092*de1e4e89SAndroid Build Coastguard Worker
dl_argv_parse_put(struct nlmsghdr * nlh,struct dl * dl,uint32_t o_required,uint32_t o_optional)1093*de1e4e89SAndroid Build Coastguard Worker static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
1094*de1e4e89SAndroid Build Coastguard Worker uint32_t o_required, uint32_t o_optional)
1095*de1e4e89SAndroid Build Coastguard Worker {
1096*de1e4e89SAndroid Build Coastguard Worker int err;
1097*de1e4e89SAndroid Build Coastguard Worker
1098*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse(dl, o_required, o_optional);
1099*de1e4e89SAndroid Build Coastguard Worker if (err)
1100*de1e4e89SAndroid Build Coastguard Worker return err;
1101*de1e4e89SAndroid Build Coastguard Worker dl_opts_put(nlh, dl);
1102*de1e4e89SAndroid Build Coastguard Worker return 0;
1103*de1e4e89SAndroid Build Coastguard Worker }
1104*de1e4e89SAndroid Build Coastguard Worker
dl_dump_filter(struct dl * dl,struct nlattr ** tb)1105*de1e4e89SAndroid Build Coastguard Worker static bool dl_dump_filter(struct dl *dl, struct nlattr **tb)
1106*de1e4e89SAndroid Build Coastguard Worker {
1107*de1e4e89SAndroid Build Coastguard Worker struct dl_opts *opts = &dl->opts;
1108*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attr_bus_name = tb[DEVLINK_ATTR_BUS_NAME];
1109*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attr_dev_name = tb[DEVLINK_ATTR_DEV_NAME];
1110*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attr_port_index = tb[DEVLINK_ATTR_PORT_INDEX];
1111*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attr_sb_index = tb[DEVLINK_ATTR_SB_INDEX];
1112*de1e4e89SAndroid Build Coastguard Worker
1113*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_HANDLE &&
1114*de1e4e89SAndroid Build Coastguard Worker attr_bus_name && attr_dev_name) {
1115*de1e4e89SAndroid Build Coastguard Worker const char *bus_name = mnl_attr_get_str(attr_bus_name);
1116*de1e4e89SAndroid Build Coastguard Worker const char *dev_name = mnl_attr_get_str(attr_dev_name);
1117*de1e4e89SAndroid Build Coastguard Worker
1118*de1e4e89SAndroid Build Coastguard Worker if (strcmp(bus_name, opts->bus_name) != 0 ||
1119*de1e4e89SAndroid Build Coastguard Worker strcmp(dev_name, opts->dev_name) != 0)
1120*de1e4e89SAndroid Build Coastguard Worker return false;
1121*de1e4e89SAndroid Build Coastguard Worker }
1122*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_HANDLEP &&
1123*de1e4e89SAndroid Build Coastguard Worker attr_bus_name && attr_dev_name && attr_port_index) {
1124*de1e4e89SAndroid Build Coastguard Worker const char *bus_name = mnl_attr_get_str(attr_bus_name);
1125*de1e4e89SAndroid Build Coastguard Worker const char *dev_name = mnl_attr_get_str(attr_dev_name);
1126*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index = mnl_attr_get_u32(attr_port_index);
1127*de1e4e89SAndroid Build Coastguard Worker
1128*de1e4e89SAndroid Build Coastguard Worker if (strcmp(bus_name, opts->bus_name) != 0 ||
1129*de1e4e89SAndroid Build Coastguard Worker strcmp(dev_name, opts->dev_name) != 0 ||
1130*de1e4e89SAndroid Build Coastguard Worker port_index != opts->port_index)
1131*de1e4e89SAndroid Build Coastguard Worker return false;
1132*de1e4e89SAndroid Build Coastguard Worker }
1133*de1e4e89SAndroid Build Coastguard Worker if (opts->present & DL_OPT_SB && attr_sb_index) {
1134*de1e4e89SAndroid Build Coastguard Worker uint32_t sb_index = mnl_attr_get_u32(attr_sb_index);
1135*de1e4e89SAndroid Build Coastguard Worker
1136*de1e4e89SAndroid Build Coastguard Worker if (sb_index != opts->sb_index)
1137*de1e4e89SAndroid Build Coastguard Worker return false;
1138*de1e4e89SAndroid Build Coastguard Worker }
1139*de1e4e89SAndroid Build Coastguard Worker return true;
1140*de1e4e89SAndroid Build Coastguard Worker }
1141*de1e4e89SAndroid Build Coastguard Worker
cmd_dev_help(void)1142*de1e4e89SAndroid Build Coastguard Worker static void cmd_dev_help(void)
1143*de1e4e89SAndroid Build Coastguard Worker {
1144*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink dev show [ DEV ]\n");
1145*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink dev eswitch set DEV [ mode { legacy | switchdev } ]\n");
1146*de1e4e89SAndroid Build Coastguard Worker pr_err(" [ inline-mode { none | link | network | transport } ]\n");
1147*de1e4e89SAndroid Build Coastguard Worker pr_err(" [ encap { disable | enable } ]\n");
1148*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink dev eswitch show DEV\n");
1149*de1e4e89SAndroid Build Coastguard Worker }
1150*de1e4e89SAndroid Build Coastguard Worker
cmp_arr_last_handle(struct dl * dl,const char * bus_name,const char * dev_name)1151*de1e4e89SAndroid Build Coastguard Worker static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name,
1152*de1e4e89SAndroid Build Coastguard Worker const char *dev_name)
1153*de1e4e89SAndroid Build Coastguard Worker {
1154*de1e4e89SAndroid Build Coastguard Worker if (!dl->arr_last.present)
1155*de1e4e89SAndroid Build Coastguard Worker return false;
1156*de1e4e89SAndroid Build Coastguard Worker return strcmp(dl->arr_last.bus_name, bus_name) == 0 &&
1157*de1e4e89SAndroid Build Coastguard Worker strcmp(dl->arr_last.dev_name, dev_name) == 0;
1158*de1e4e89SAndroid Build Coastguard Worker }
1159*de1e4e89SAndroid Build Coastguard Worker
arr_last_handle_set(struct dl * dl,const char * bus_name,const char * dev_name)1160*de1e4e89SAndroid Build Coastguard Worker static void arr_last_handle_set(struct dl *dl, const char *bus_name,
1161*de1e4e89SAndroid Build Coastguard Worker const char *dev_name)
1162*de1e4e89SAndroid Build Coastguard Worker {
1163*de1e4e89SAndroid Build Coastguard Worker dl->arr_last.present = true;
1164*de1e4e89SAndroid Build Coastguard Worker free(dl->arr_last.dev_name);
1165*de1e4e89SAndroid Build Coastguard Worker free(dl->arr_last.bus_name);
1166*de1e4e89SAndroid Build Coastguard Worker dl->arr_last.bus_name = strdup(bus_name);
1167*de1e4e89SAndroid Build Coastguard Worker dl->arr_last.dev_name = strdup(dev_name);
1168*de1e4e89SAndroid Build Coastguard Worker }
1169*de1e4e89SAndroid Build Coastguard Worker
should_arr_last_handle_start(struct dl * dl,const char * bus_name,const char * dev_name)1170*de1e4e89SAndroid Build Coastguard Worker static bool should_arr_last_handle_start(struct dl *dl, const char *bus_name,
1171*de1e4e89SAndroid Build Coastguard Worker const char *dev_name)
1172*de1e4e89SAndroid Build Coastguard Worker {
1173*de1e4e89SAndroid Build Coastguard Worker return !cmp_arr_last_handle(dl, bus_name, dev_name);
1174*de1e4e89SAndroid Build Coastguard Worker }
1175*de1e4e89SAndroid Build Coastguard Worker
should_arr_last_handle_end(struct dl * dl,const char * bus_name,const char * dev_name)1176*de1e4e89SAndroid Build Coastguard Worker static bool should_arr_last_handle_end(struct dl *dl, const char *bus_name,
1177*de1e4e89SAndroid Build Coastguard Worker const char *dev_name)
1178*de1e4e89SAndroid Build Coastguard Worker {
1179*de1e4e89SAndroid Build Coastguard Worker return dl->arr_last.present &&
1180*de1e4e89SAndroid Build Coastguard Worker !cmp_arr_last_handle(dl, bus_name, dev_name);
1181*de1e4e89SAndroid Build Coastguard Worker }
1182*de1e4e89SAndroid Build Coastguard Worker
__pr_out_handle_start(struct dl * dl,struct nlattr ** tb,bool content,bool array)1183*de1e4e89SAndroid Build Coastguard Worker static void __pr_out_handle_start(struct dl *dl, struct nlattr **tb,
1184*de1e4e89SAndroid Build Coastguard Worker bool content, bool array)
1185*de1e4e89SAndroid Build Coastguard Worker {
1186*de1e4e89SAndroid Build Coastguard Worker const char *bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
1187*de1e4e89SAndroid Build Coastguard Worker const char *dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
1188*de1e4e89SAndroid Build Coastguard Worker char buf[32];
1189*de1e4e89SAndroid Build Coastguard Worker
1190*de1e4e89SAndroid Build Coastguard Worker sprintf(buf, "%s/%s", bus_name, dev_name);
1191*de1e4e89SAndroid Build Coastguard Worker
1192*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
1193*de1e4e89SAndroid Build Coastguard Worker if (array) {
1194*de1e4e89SAndroid Build Coastguard Worker if (should_arr_last_handle_end(dl, bus_name, dev_name))
1195*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(dl->jw);
1196*de1e4e89SAndroid Build Coastguard Worker if (should_arr_last_handle_start(dl, bus_name,
1197*de1e4e89SAndroid Build Coastguard Worker dev_name)) {
1198*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, buf);
1199*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(dl->jw);
1200*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1201*de1e4e89SAndroid Build Coastguard Worker arr_last_handle_set(dl, bus_name, dev_name);
1202*de1e4e89SAndroid Build Coastguard Worker } else {
1203*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1204*de1e4e89SAndroid Build Coastguard Worker }
1205*de1e4e89SAndroid Build Coastguard Worker } else {
1206*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, buf);
1207*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1208*de1e4e89SAndroid Build Coastguard Worker }
1209*de1e4e89SAndroid Build Coastguard Worker } else {
1210*de1e4e89SAndroid Build Coastguard Worker if (array) {
1211*de1e4e89SAndroid Build Coastguard Worker if (should_arr_last_handle_end(dl, bus_name, dev_name))
1212*de1e4e89SAndroid Build Coastguard Worker __pr_out_indent_dec();
1213*de1e4e89SAndroid Build Coastguard Worker if (should_arr_last_handle_start(dl, bus_name,
1214*de1e4e89SAndroid Build Coastguard Worker dev_name)) {
1215*de1e4e89SAndroid Build Coastguard Worker pr_out("%s%s", buf, content ? ":" : "");
1216*de1e4e89SAndroid Build Coastguard Worker __pr_out_newline();
1217*de1e4e89SAndroid Build Coastguard Worker __pr_out_indent_inc();
1218*de1e4e89SAndroid Build Coastguard Worker arr_last_handle_set(dl, bus_name, dev_name);
1219*de1e4e89SAndroid Build Coastguard Worker }
1220*de1e4e89SAndroid Build Coastguard Worker } else {
1221*de1e4e89SAndroid Build Coastguard Worker pr_out("%s%s", buf, content ? ":" : "");
1222*de1e4e89SAndroid Build Coastguard Worker }
1223*de1e4e89SAndroid Build Coastguard Worker }
1224*de1e4e89SAndroid Build Coastguard Worker }
1225*de1e4e89SAndroid Build Coastguard Worker
pr_out_handle_start_arr(struct dl * dl,struct nlattr ** tb)1226*de1e4e89SAndroid Build Coastguard Worker static void pr_out_handle_start_arr(struct dl *dl, struct nlattr **tb)
1227*de1e4e89SAndroid Build Coastguard Worker {
1228*de1e4e89SAndroid Build Coastguard Worker __pr_out_handle_start(dl, tb, true, true);
1229*de1e4e89SAndroid Build Coastguard Worker }
1230*de1e4e89SAndroid Build Coastguard Worker
pr_out_handle_end(struct dl * dl)1231*de1e4e89SAndroid Build Coastguard Worker static void pr_out_handle_end(struct dl *dl)
1232*de1e4e89SAndroid Build Coastguard Worker {
1233*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output)
1234*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(dl->jw);
1235*de1e4e89SAndroid Build Coastguard Worker else
1236*de1e4e89SAndroid Build Coastguard Worker __pr_out_newline();
1237*de1e4e89SAndroid Build Coastguard Worker }
1238*de1e4e89SAndroid Build Coastguard Worker
pr_out_handle(struct dl * dl,struct nlattr ** tb)1239*de1e4e89SAndroid Build Coastguard Worker static void pr_out_handle(struct dl *dl, struct nlattr **tb)
1240*de1e4e89SAndroid Build Coastguard Worker {
1241*de1e4e89SAndroid Build Coastguard Worker __pr_out_handle_start(dl, tb, false, false);
1242*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(dl);
1243*de1e4e89SAndroid Build Coastguard Worker }
1244*de1e4e89SAndroid Build Coastguard Worker
cmp_arr_last_port_handle(struct dl * dl,const char * bus_name,const char * dev_name,uint32_t port_index)1245*de1e4e89SAndroid Build Coastguard Worker static bool cmp_arr_last_port_handle(struct dl *dl, const char *bus_name,
1246*de1e4e89SAndroid Build Coastguard Worker const char *dev_name, uint32_t port_index)
1247*de1e4e89SAndroid Build Coastguard Worker {
1248*de1e4e89SAndroid Build Coastguard Worker return cmp_arr_last_handle(dl, bus_name, dev_name) &&
1249*de1e4e89SAndroid Build Coastguard Worker dl->arr_last.port_index == port_index;
1250*de1e4e89SAndroid Build Coastguard Worker }
1251*de1e4e89SAndroid Build Coastguard Worker
arr_last_port_handle_set(struct dl * dl,const char * bus_name,const char * dev_name,uint32_t port_index)1252*de1e4e89SAndroid Build Coastguard Worker static void arr_last_port_handle_set(struct dl *dl, const char *bus_name,
1253*de1e4e89SAndroid Build Coastguard Worker const char *dev_name, uint32_t port_index)
1254*de1e4e89SAndroid Build Coastguard Worker {
1255*de1e4e89SAndroid Build Coastguard Worker arr_last_handle_set(dl, bus_name, dev_name);
1256*de1e4e89SAndroid Build Coastguard Worker dl->arr_last.port_index = port_index;
1257*de1e4e89SAndroid Build Coastguard Worker }
1258*de1e4e89SAndroid Build Coastguard Worker
should_arr_last_port_handle_start(struct dl * dl,const char * bus_name,const char * dev_name,uint32_t port_index)1259*de1e4e89SAndroid Build Coastguard Worker static bool should_arr_last_port_handle_start(struct dl *dl,
1260*de1e4e89SAndroid Build Coastguard Worker const char *bus_name,
1261*de1e4e89SAndroid Build Coastguard Worker const char *dev_name,
1262*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index)
1263*de1e4e89SAndroid Build Coastguard Worker {
1264*de1e4e89SAndroid Build Coastguard Worker return !cmp_arr_last_port_handle(dl, bus_name, dev_name, port_index);
1265*de1e4e89SAndroid Build Coastguard Worker }
1266*de1e4e89SAndroid Build Coastguard Worker
should_arr_last_port_handle_end(struct dl * dl,const char * bus_name,const char * dev_name,uint32_t port_index)1267*de1e4e89SAndroid Build Coastguard Worker static bool should_arr_last_port_handle_end(struct dl *dl,
1268*de1e4e89SAndroid Build Coastguard Worker const char *bus_name,
1269*de1e4e89SAndroid Build Coastguard Worker const char *dev_name,
1270*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index)
1271*de1e4e89SAndroid Build Coastguard Worker {
1272*de1e4e89SAndroid Build Coastguard Worker return dl->arr_last.present &&
1273*de1e4e89SAndroid Build Coastguard Worker !cmp_arr_last_port_handle(dl, bus_name, dev_name, port_index);
1274*de1e4e89SAndroid Build Coastguard Worker }
1275*de1e4e89SAndroid Build Coastguard Worker
__pr_out_port_handle_start(struct dl * dl,const char * bus_name,const char * dev_name,uint32_t port_index,bool try_nice,bool array)1276*de1e4e89SAndroid Build Coastguard Worker static void __pr_out_port_handle_start(struct dl *dl, const char *bus_name,
1277*de1e4e89SAndroid Build Coastguard Worker const char *dev_name,
1278*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index, bool try_nice,
1279*de1e4e89SAndroid Build Coastguard Worker bool array)
1280*de1e4e89SAndroid Build Coastguard Worker {
1281*de1e4e89SAndroid Build Coastguard Worker static char buf[32];
1282*de1e4e89SAndroid Build Coastguard Worker char *ifname = NULL;
1283*de1e4e89SAndroid Build Coastguard Worker
1284*de1e4e89SAndroid Build Coastguard Worker if (dl->no_nice_names || !try_nice ||
1285*de1e4e89SAndroid Build Coastguard Worker ifname_map_rev_lookup(dl, bus_name, dev_name,
1286*de1e4e89SAndroid Build Coastguard Worker port_index, &ifname) != 0)
1287*de1e4e89SAndroid Build Coastguard Worker sprintf(buf, "%s/%s/%d", bus_name, dev_name, port_index);
1288*de1e4e89SAndroid Build Coastguard Worker else
1289*de1e4e89SAndroid Build Coastguard Worker sprintf(buf, "%s", ifname);
1290*de1e4e89SAndroid Build Coastguard Worker
1291*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
1292*de1e4e89SAndroid Build Coastguard Worker if (array) {
1293*de1e4e89SAndroid Build Coastguard Worker if (should_arr_last_port_handle_end(dl, bus_name,
1294*de1e4e89SAndroid Build Coastguard Worker dev_name,
1295*de1e4e89SAndroid Build Coastguard Worker port_index))
1296*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(dl->jw);
1297*de1e4e89SAndroid Build Coastguard Worker if (should_arr_last_port_handle_start(dl, bus_name,
1298*de1e4e89SAndroid Build Coastguard Worker dev_name,
1299*de1e4e89SAndroid Build Coastguard Worker port_index)) {
1300*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, buf);
1301*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(dl->jw);
1302*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1303*de1e4e89SAndroid Build Coastguard Worker arr_last_port_handle_set(dl, bus_name, dev_name,
1304*de1e4e89SAndroid Build Coastguard Worker port_index);
1305*de1e4e89SAndroid Build Coastguard Worker } else {
1306*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1307*de1e4e89SAndroid Build Coastguard Worker }
1308*de1e4e89SAndroid Build Coastguard Worker } else {
1309*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, buf);
1310*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1311*de1e4e89SAndroid Build Coastguard Worker }
1312*de1e4e89SAndroid Build Coastguard Worker } else {
1313*de1e4e89SAndroid Build Coastguard Worker pr_out("%s:", buf);
1314*de1e4e89SAndroid Build Coastguard Worker }
1315*de1e4e89SAndroid Build Coastguard Worker }
1316*de1e4e89SAndroid Build Coastguard Worker
pr_out_port_handle_start(struct dl * dl,struct nlattr ** tb,bool try_nice)1317*de1e4e89SAndroid Build Coastguard Worker static void pr_out_port_handle_start(struct dl *dl, struct nlattr **tb, bool try_nice)
1318*de1e4e89SAndroid Build Coastguard Worker {
1319*de1e4e89SAndroid Build Coastguard Worker const char *bus_name;
1320*de1e4e89SAndroid Build Coastguard Worker const char *dev_name;
1321*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index;
1322*de1e4e89SAndroid Build Coastguard Worker
1323*de1e4e89SAndroid Build Coastguard Worker bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
1324*de1e4e89SAndroid Build Coastguard Worker dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
1325*de1e4e89SAndroid Build Coastguard Worker port_index = mnl_attr_get_u32(tb[DEVLINK_ATTR_PORT_INDEX]);
1326*de1e4e89SAndroid Build Coastguard Worker __pr_out_port_handle_start(dl, bus_name, dev_name, port_index, try_nice, false);
1327*de1e4e89SAndroid Build Coastguard Worker }
1328*de1e4e89SAndroid Build Coastguard Worker
pr_out_port_handle_start_arr(struct dl * dl,struct nlattr ** tb,bool try_nice)1329*de1e4e89SAndroid Build Coastguard Worker static void pr_out_port_handle_start_arr(struct dl *dl, struct nlattr **tb, bool try_nice)
1330*de1e4e89SAndroid Build Coastguard Worker {
1331*de1e4e89SAndroid Build Coastguard Worker const char *bus_name;
1332*de1e4e89SAndroid Build Coastguard Worker const char *dev_name;
1333*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index;
1334*de1e4e89SAndroid Build Coastguard Worker
1335*de1e4e89SAndroid Build Coastguard Worker bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
1336*de1e4e89SAndroid Build Coastguard Worker dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
1337*de1e4e89SAndroid Build Coastguard Worker port_index = mnl_attr_get_u32(tb[DEVLINK_ATTR_PORT_INDEX]);
1338*de1e4e89SAndroid Build Coastguard Worker __pr_out_port_handle_start(dl, bus_name, dev_name, port_index, try_nice, true);
1339*de1e4e89SAndroid Build Coastguard Worker }
1340*de1e4e89SAndroid Build Coastguard Worker
pr_out_port_handle_end(struct dl * dl)1341*de1e4e89SAndroid Build Coastguard Worker static void pr_out_port_handle_end(struct dl *dl)
1342*de1e4e89SAndroid Build Coastguard Worker {
1343*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output)
1344*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(dl->jw);
1345*de1e4e89SAndroid Build Coastguard Worker else
1346*de1e4e89SAndroid Build Coastguard Worker pr_out("\n");
1347*de1e4e89SAndroid Build Coastguard Worker }
1348*de1e4e89SAndroid Build Coastguard Worker
1349*de1e4e89SAndroid Build Coastguard Worker
pr_out_str(struct dl * dl,const char * name,const char * val)1350*de1e4e89SAndroid Build Coastguard Worker static void pr_out_str(struct dl *dl, const char *name, const char *val)
1351*de1e4e89SAndroid Build Coastguard Worker {
1352*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
1353*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(dl->jw, name, val);
1354*de1e4e89SAndroid Build Coastguard Worker } else {
1355*de1e4e89SAndroid Build Coastguard Worker if (g_indent_newline)
1356*de1e4e89SAndroid Build Coastguard Worker pr_out("%s %s", name, val);
1357*de1e4e89SAndroid Build Coastguard Worker else
1358*de1e4e89SAndroid Build Coastguard Worker pr_out(" %s %s", name, val);
1359*de1e4e89SAndroid Build Coastguard Worker }
1360*de1e4e89SAndroid Build Coastguard Worker }
1361*de1e4e89SAndroid Build Coastguard Worker
pr_out_uint(struct dl * dl,const char * name,unsigned int val)1362*de1e4e89SAndroid Build Coastguard Worker static void pr_out_uint(struct dl *dl, const char *name, unsigned int val)
1363*de1e4e89SAndroid Build Coastguard Worker {
1364*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
1365*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(dl->jw, name, val);
1366*de1e4e89SAndroid Build Coastguard Worker } else {
1367*de1e4e89SAndroid Build Coastguard Worker if (g_indent_newline)
1368*de1e4e89SAndroid Build Coastguard Worker pr_out("%s %u", name, val);
1369*de1e4e89SAndroid Build Coastguard Worker else
1370*de1e4e89SAndroid Build Coastguard Worker pr_out(" %s %u", name, val);
1371*de1e4e89SAndroid Build Coastguard Worker }
1372*de1e4e89SAndroid Build Coastguard Worker }
1373*de1e4e89SAndroid Build Coastguard Worker
pr_out_dev(struct dl * dl,struct nlattr ** tb)1374*de1e4e89SAndroid Build Coastguard Worker static void pr_out_dev(struct dl *dl, struct nlattr **tb)
1375*de1e4e89SAndroid Build Coastguard Worker {
1376*de1e4e89SAndroid Build Coastguard Worker pr_out_handle(dl, tb);
1377*de1e4e89SAndroid Build Coastguard Worker }
1378*de1e4e89SAndroid Build Coastguard Worker
pr_out_section_start(struct dl * dl,const char * name)1379*de1e4e89SAndroid Build Coastguard Worker static void pr_out_section_start(struct dl *dl, const char *name)
1380*de1e4e89SAndroid Build Coastguard Worker {
1381*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
1382*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1383*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, name);
1384*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1385*de1e4e89SAndroid Build Coastguard Worker }
1386*de1e4e89SAndroid Build Coastguard Worker }
1387*de1e4e89SAndroid Build Coastguard Worker
pr_out_section_end(struct dl * dl)1388*de1e4e89SAndroid Build Coastguard Worker static void pr_out_section_end(struct dl *dl)
1389*de1e4e89SAndroid Build Coastguard Worker {
1390*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
1391*de1e4e89SAndroid Build Coastguard Worker if (dl->arr_last.present)
1392*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(dl->jw);
1393*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(dl->jw);
1394*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(dl->jw);
1395*de1e4e89SAndroid Build Coastguard Worker }
1396*de1e4e89SAndroid Build Coastguard Worker }
1397*de1e4e89SAndroid Build Coastguard Worker
pr_out_array_start(struct dl * dl,const char * name)1398*de1e4e89SAndroid Build Coastguard Worker static void pr_out_array_start(struct dl *dl, const char *name)
1399*de1e4e89SAndroid Build Coastguard Worker {
1400*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
1401*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, name);
1402*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(dl->jw);
1403*de1e4e89SAndroid Build Coastguard Worker } else {
1404*de1e4e89SAndroid Build Coastguard Worker if (!g_indent_newline)
1405*de1e4e89SAndroid Build Coastguard Worker __pr_out_newline();
1406*de1e4e89SAndroid Build Coastguard Worker pr_out("%s:", name);
1407*de1e4e89SAndroid Build Coastguard Worker __pr_out_newline();
1408*de1e4e89SAndroid Build Coastguard Worker __pr_out_indent_inc();
1409*de1e4e89SAndroid Build Coastguard Worker }
1410*de1e4e89SAndroid Build Coastguard Worker }
1411*de1e4e89SAndroid Build Coastguard Worker
pr_out_array_end(struct dl * dl)1412*de1e4e89SAndroid Build Coastguard Worker static void pr_out_array_end(struct dl *dl)
1413*de1e4e89SAndroid Build Coastguard Worker {
1414*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output)
1415*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(dl->jw);
1416*de1e4e89SAndroid Build Coastguard Worker else
1417*de1e4e89SAndroid Build Coastguard Worker __pr_out_indent_dec();
1418*de1e4e89SAndroid Build Coastguard Worker }
1419*de1e4e89SAndroid Build Coastguard Worker
pr_out_entry_start(struct dl * dl)1420*de1e4e89SAndroid Build Coastguard Worker static void pr_out_entry_start(struct dl *dl)
1421*de1e4e89SAndroid Build Coastguard Worker {
1422*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output)
1423*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
1424*de1e4e89SAndroid Build Coastguard Worker }
1425*de1e4e89SAndroid Build Coastguard Worker
pr_out_entry_end(struct dl * dl)1426*de1e4e89SAndroid Build Coastguard Worker static void pr_out_entry_end(struct dl *dl)
1427*de1e4e89SAndroid Build Coastguard Worker {
1428*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output)
1429*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(dl->jw);
1430*de1e4e89SAndroid Build Coastguard Worker else
1431*de1e4e89SAndroid Build Coastguard Worker __pr_out_newline();
1432*de1e4e89SAndroid Build Coastguard Worker }
1433*de1e4e89SAndroid Build Coastguard Worker
eswitch_mode_name(uint32_t mode)1434*de1e4e89SAndroid Build Coastguard Worker static const char *eswitch_mode_name(uint32_t mode)
1435*de1e4e89SAndroid Build Coastguard Worker {
1436*de1e4e89SAndroid Build Coastguard Worker switch (mode) {
1437*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_ESWITCH_MODE_LEGACY: return ESWITCH_MODE_LEGACY;
1438*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_ESWITCH_MODE_SWITCHDEV: return ESWITCH_MODE_SWITCHDEV;
1439*de1e4e89SAndroid Build Coastguard Worker default: return "<unknown mode>";
1440*de1e4e89SAndroid Build Coastguard Worker }
1441*de1e4e89SAndroid Build Coastguard Worker }
1442*de1e4e89SAndroid Build Coastguard Worker
eswitch_inline_mode_name(uint32_t mode)1443*de1e4e89SAndroid Build Coastguard Worker static const char *eswitch_inline_mode_name(uint32_t mode)
1444*de1e4e89SAndroid Build Coastguard Worker {
1445*de1e4e89SAndroid Build Coastguard Worker switch (mode) {
1446*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_ESWITCH_INLINE_MODE_NONE:
1447*de1e4e89SAndroid Build Coastguard Worker return ESWITCH_INLINE_MODE_NONE;
1448*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_ESWITCH_INLINE_MODE_LINK:
1449*de1e4e89SAndroid Build Coastguard Worker return ESWITCH_INLINE_MODE_LINK;
1450*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_ESWITCH_INLINE_MODE_NETWORK:
1451*de1e4e89SAndroid Build Coastguard Worker return ESWITCH_INLINE_MODE_NETWORK;
1452*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT:
1453*de1e4e89SAndroid Build Coastguard Worker return ESWITCH_INLINE_MODE_TRANSPORT;
1454*de1e4e89SAndroid Build Coastguard Worker default:
1455*de1e4e89SAndroid Build Coastguard Worker return "<unknown mode>";
1456*de1e4e89SAndroid Build Coastguard Worker }
1457*de1e4e89SAndroid Build Coastguard Worker }
1458*de1e4e89SAndroid Build Coastguard Worker
pr_out_eswitch(struct dl * dl,struct nlattr ** tb)1459*de1e4e89SAndroid Build Coastguard Worker static void pr_out_eswitch(struct dl *dl, struct nlattr **tb)
1460*de1e4e89SAndroid Build Coastguard Worker {
1461*de1e4e89SAndroid Build Coastguard Worker __pr_out_handle_start(dl, tb, true, false);
1462*de1e4e89SAndroid Build Coastguard Worker
1463*de1e4e89SAndroid Build Coastguard Worker if (tb[DEVLINK_ATTR_ESWITCH_MODE])
1464*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "mode",
1465*de1e4e89SAndroid Build Coastguard Worker eswitch_mode_name(mnl_attr_get_u16(tb[DEVLINK_ATTR_ESWITCH_MODE])));
1466*de1e4e89SAndroid Build Coastguard Worker
1467*de1e4e89SAndroid Build Coastguard Worker if (tb[DEVLINK_ATTR_ESWITCH_INLINE_MODE])
1468*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "inline-mode",
1469*de1e4e89SAndroid Build Coastguard Worker eswitch_inline_mode_name(mnl_attr_get_u8(
1470*de1e4e89SAndroid Build Coastguard Worker tb[DEVLINK_ATTR_ESWITCH_INLINE_MODE])));
1471*de1e4e89SAndroid Build Coastguard Worker
1472*de1e4e89SAndroid Build Coastguard Worker if (tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1473*de1e4e89SAndroid Build Coastguard Worker bool encap_mode = !!mnl_attr_get_u8(tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1474*de1e4e89SAndroid Build Coastguard Worker
1475*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "encap", encap_mode ? "enable" : "disable");
1476*de1e4e89SAndroid Build Coastguard Worker }
1477*de1e4e89SAndroid Build Coastguard Worker
1478*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(dl);
1479*de1e4e89SAndroid Build Coastguard Worker }
1480*de1e4e89SAndroid Build Coastguard Worker
cmd_dev_eswitch_show_cb(const struct nlmsghdr * nlh,void * data)1481*de1e4e89SAndroid Build Coastguard Worker static int cmd_dev_eswitch_show_cb(const struct nlmsghdr *nlh, void *data)
1482*de1e4e89SAndroid Build Coastguard Worker {
1483*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
1484*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
1485*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
1486*de1e4e89SAndroid Build Coastguard Worker
1487*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
1488*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
1489*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
1490*de1e4e89SAndroid Build Coastguard Worker pr_out_eswitch(dl, tb);
1491*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
1492*de1e4e89SAndroid Build Coastguard Worker }
1493*de1e4e89SAndroid Build Coastguard Worker
cmd_dev_eswitch_show(struct dl * dl)1494*de1e4e89SAndroid Build Coastguard Worker static int cmd_dev_eswitch_show(struct dl *dl)
1495*de1e4e89SAndroid Build Coastguard Worker {
1496*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1497*de1e4e89SAndroid Build Coastguard Worker int err;
1498*de1e4e89SAndroid Build Coastguard Worker
1499*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_ESWITCH_GET,
1500*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
1501*de1e4e89SAndroid Build Coastguard Worker
1502*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0);
1503*de1e4e89SAndroid Build Coastguard Worker if (err)
1504*de1e4e89SAndroid Build Coastguard Worker return err;
1505*de1e4e89SAndroid Build Coastguard Worker
1506*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "dev");
1507*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_eswitch_show_cb, dl);
1508*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
1509*de1e4e89SAndroid Build Coastguard Worker return err;
1510*de1e4e89SAndroid Build Coastguard Worker }
1511*de1e4e89SAndroid Build Coastguard Worker
cmd_dev_eswitch_set(struct dl * dl)1512*de1e4e89SAndroid Build Coastguard Worker static int cmd_dev_eswitch_set(struct dl *dl)
1513*de1e4e89SAndroid Build Coastguard Worker {
1514*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1515*de1e4e89SAndroid Build Coastguard Worker int err;
1516*de1e4e89SAndroid Build Coastguard Worker
1517*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_ESWITCH_SET,
1518*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
1519*de1e4e89SAndroid Build Coastguard Worker
1520*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE,
1521*de1e4e89SAndroid Build Coastguard Worker DL_OPT_ESWITCH_MODE |
1522*de1e4e89SAndroid Build Coastguard Worker DL_OPT_ESWITCH_INLINE_MODE |
1523*de1e4e89SAndroid Build Coastguard Worker DL_OPT_ESWITCH_ENCAP_MODE);
1524*de1e4e89SAndroid Build Coastguard Worker
1525*de1e4e89SAndroid Build Coastguard Worker if (err)
1526*de1e4e89SAndroid Build Coastguard Worker return err;
1527*de1e4e89SAndroid Build Coastguard Worker
1528*de1e4e89SAndroid Build Coastguard Worker if (dl->opts.present == 1) {
1529*de1e4e89SAndroid Build Coastguard Worker pr_err("Need to set at least one option\n");
1530*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
1531*de1e4e89SAndroid Build Coastguard Worker }
1532*de1e4e89SAndroid Build Coastguard Worker
1533*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
1534*de1e4e89SAndroid Build Coastguard Worker }
1535*de1e4e89SAndroid Build Coastguard Worker
cmd_dev_eswitch(struct dl * dl)1536*de1e4e89SAndroid Build Coastguard Worker static int cmd_dev_eswitch(struct dl *dl)
1537*de1e4e89SAndroid Build Coastguard Worker {
1538*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
1539*de1e4e89SAndroid Build Coastguard Worker cmd_dev_help();
1540*de1e4e89SAndroid Build Coastguard Worker return 0;
1541*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "set")) {
1542*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1543*de1e4e89SAndroid Build Coastguard Worker return cmd_dev_eswitch_set(dl);
1544*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show")) {
1545*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1546*de1e4e89SAndroid Build Coastguard Worker return cmd_dev_eswitch_show(dl);
1547*de1e4e89SAndroid Build Coastguard Worker }
1548*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
1549*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
1550*de1e4e89SAndroid Build Coastguard Worker }
1551*de1e4e89SAndroid Build Coastguard Worker
cmd_dev_show_cb(const struct nlmsghdr * nlh,void * data)1552*de1e4e89SAndroid Build Coastguard Worker static int cmd_dev_show_cb(const struct nlmsghdr *nlh, void *data)
1553*de1e4e89SAndroid Build Coastguard Worker {
1554*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
1555*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
1556*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
1557*de1e4e89SAndroid Build Coastguard Worker
1558*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
1559*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
1560*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
1561*de1e4e89SAndroid Build Coastguard Worker pr_out_dev(dl, tb);
1562*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
1563*de1e4e89SAndroid Build Coastguard Worker }
1564*de1e4e89SAndroid Build Coastguard Worker
cmd_dev_show(struct dl * dl)1565*de1e4e89SAndroid Build Coastguard Worker static int cmd_dev_show(struct dl *dl)
1566*de1e4e89SAndroid Build Coastguard Worker {
1567*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1568*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
1569*de1e4e89SAndroid Build Coastguard Worker int err;
1570*de1e4e89SAndroid Build Coastguard Worker
1571*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
1572*de1e4e89SAndroid Build Coastguard Worker flags |= NLM_F_DUMP;
1573*de1e4e89SAndroid Build Coastguard Worker
1574*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_GET, flags);
1575*de1e4e89SAndroid Build Coastguard Worker
1576*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) > 0) {
1577*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0);
1578*de1e4e89SAndroid Build Coastguard Worker if (err)
1579*de1e4e89SAndroid Build Coastguard Worker return err;
1580*de1e4e89SAndroid Build Coastguard Worker }
1581*de1e4e89SAndroid Build Coastguard Worker
1582*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "dev");
1583*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dev_show_cb, dl);
1584*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
1585*de1e4e89SAndroid Build Coastguard Worker return err;
1586*de1e4e89SAndroid Build Coastguard Worker }
1587*de1e4e89SAndroid Build Coastguard Worker
cmd_dev(struct dl * dl)1588*de1e4e89SAndroid Build Coastguard Worker static int cmd_dev(struct dl *dl)
1589*de1e4e89SAndroid Build Coastguard Worker {
1590*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help")) {
1591*de1e4e89SAndroid Build Coastguard Worker cmd_dev_help();
1592*de1e4e89SAndroid Build Coastguard Worker return 0;
1593*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show") ||
1594*de1e4e89SAndroid Build Coastguard Worker dl_argv_match(dl, "list") || dl_no_arg(dl)) {
1595*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1596*de1e4e89SAndroid Build Coastguard Worker return cmd_dev_show(dl);
1597*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "eswitch")) {
1598*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1599*de1e4e89SAndroid Build Coastguard Worker return cmd_dev_eswitch(dl);
1600*de1e4e89SAndroid Build Coastguard Worker }
1601*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
1602*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
1603*de1e4e89SAndroid Build Coastguard Worker }
1604*de1e4e89SAndroid Build Coastguard Worker
cmd_port_help(void)1605*de1e4e89SAndroid Build Coastguard Worker static void cmd_port_help(void)
1606*de1e4e89SAndroid Build Coastguard Worker {
1607*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink port show [ DEV/PORT_INDEX ]\n");
1608*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink port set DEV/PORT_INDEX [ type { eth | ib | auto} ]\n");
1609*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink port split DEV/PORT_INDEX count COUNT\n");
1610*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink port unsplit DEV/PORT_INDEX\n");
1611*de1e4e89SAndroid Build Coastguard Worker }
1612*de1e4e89SAndroid Build Coastguard Worker
port_type_name(uint32_t type)1613*de1e4e89SAndroid Build Coastguard Worker static const char *port_type_name(uint32_t type)
1614*de1e4e89SAndroid Build Coastguard Worker {
1615*de1e4e89SAndroid Build Coastguard Worker switch (type) {
1616*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_PORT_TYPE_NOTSET: return "notset";
1617*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_PORT_TYPE_AUTO: return "auto";
1618*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_PORT_TYPE_ETH: return "eth";
1619*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_PORT_TYPE_IB: return "ib";
1620*de1e4e89SAndroid Build Coastguard Worker default: return "<unknown type>";
1621*de1e4e89SAndroid Build Coastguard Worker }
1622*de1e4e89SAndroid Build Coastguard Worker }
1623*de1e4e89SAndroid Build Coastguard Worker
pr_out_port(struct dl * dl,struct nlattr ** tb)1624*de1e4e89SAndroid Build Coastguard Worker static void pr_out_port(struct dl *dl, struct nlattr **tb)
1625*de1e4e89SAndroid Build Coastguard Worker {
1626*de1e4e89SAndroid Build Coastguard Worker struct nlattr *pt_attr = tb[DEVLINK_ATTR_PORT_TYPE];
1627*de1e4e89SAndroid Build Coastguard Worker struct nlattr *dpt_attr = tb[DEVLINK_ATTR_PORT_DESIRED_TYPE];
1628*de1e4e89SAndroid Build Coastguard Worker
1629*de1e4e89SAndroid Build Coastguard Worker pr_out_port_handle_start(dl, tb, false);
1630*de1e4e89SAndroid Build Coastguard Worker if (pt_attr) {
1631*de1e4e89SAndroid Build Coastguard Worker uint16_t port_type = mnl_attr_get_u16(pt_attr);
1632*de1e4e89SAndroid Build Coastguard Worker
1633*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "type", port_type_name(port_type));
1634*de1e4e89SAndroid Build Coastguard Worker if (dpt_attr) {
1635*de1e4e89SAndroid Build Coastguard Worker uint16_t des_port_type = mnl_attr_get_u16(dpt_attr);
1636*de1e4e89SAndroid Build Coastguard Worker
1637*de1e4e89SAndroid Build Coastguard Worker if (port_type != des_port_type)
1638*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "des_type",
1639*de1e4e89SAndroid Build Coastguard Worker port_type_name(des_port_type));
1640*de1e4e89SAndroid Build Coastguard Worker }
1641*de1e4e89SAndroid Build Coastguard Worker }
1642*de1e4e89SAndroid Build Coastguard Worker if (tb[DEVLINK_ATTR_PORT_NETDEV_NAME])
1643*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "netdev",
1644*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_str(tb[DEVLINK_ATTR_PORT_NETDEV_NAME]));
1645*de1e4e89SAndroid Build Coastguard Worker if (tb[DEVLINK_ATTR_PORT_IBDEV_NAME])
1646*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "ibdev",
1647*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_str(tb[DEVLINK_ATTR_PORT_IBDEV_NAME]));
1648*de1e4e89SAndroid Build Coastguard Worker if (tb[DEVLINK_ATTR_PORT_SPLIT_GROUP])
1649*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "split_group",
1650*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_PORT_SPLIT_GROUP]));
1651*de1e4e89SAndroid Build Coastguard Worker pr_out_port_handle_end(dl);
1652*de1e4e89SAndroid Build Coastguard Worker }
1653*de1e4e89SAndroid Build Coastguard Worker
cmd_port_show_cb(const struct nlmsghdr * nlh,void * data)1654*de1e4e89SAndroid Build Coastguard Worker static int cmd_port_show_cb(const struct nlmsghdr *nlh, void *data)
1655*de1e4e89SAndroid Build Coastguard Worker {
1656*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
1657*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
1658*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
1659*de1e4e89SAndroid Build Coastguard Worker
1660*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
1661*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
1662*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_PORT_INDEX])
1663*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
1664*de1e4e89SAndroid Build Coastguard Worker pr_out_port(dl, tb);
1665*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
1666*de1e4e89SAndroid Build Coastguard Worker }
1667*de1e4e89SAndroid Build Coastguard Worker
cmd_port_show(struct dl * dl)1668*de1e4e89SAndroid Build Coastguard Worker static int cmd_port_show(struct dl *dl)
1669*de1e4e89SAndroid Build Coastguard Worker {
1670*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1671*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
1672*de1e4e89SAndroid Build Coastguard Worker int err;
1673*de1e4e89SAndroid Build Coastguard Worker
1674*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
1675*de1e4e89SAndroid Build Coastguard Worker flags |= NLM_F_DUMP;
1676*de1e4e89SAndroid Build Coastguard Worker
1677*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_GET, flags);
1678*de1e4e89SAndroid Build Coastguard Worker
1679*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) > 0) {
1680*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP, 0);
1681*de1e4e89SAndroid Build Coastguard Worker if (err)
1682*de1e4e89SAndroid Build Coastguard Worker return err;
1683*de1e4e89SAndroid Build Coastguard Worker }
1684*de1e4e89SAndroid Build Coastguard Worker
1685*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "port");
1686*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_port_show_cb, dl);
1687*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
1688*de1e4e89SAndroid Build Coastguard Worker return err;
1689*de1e4e89SAndroid Build Coastguard Worker }
1690*de1e4e89SAndroid Build Coastguard Worker
cmd_port_set(struct dl * dl)1691*de1e4e89SAndroid Build Coastguard Worker static int cmd_port_set(struct dl *dl)
1692*de1e4e89SAndroid Build Coastguard Worker {
1693*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1694*de1e4e89SAndroid Build Coastguard Worker int err;
1695*de1e4e89SAndroid Build Coastguard Worker
1696*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_SET,
1697*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
1698*de1e4e89SAndroid Build Coastguard Worker
1699*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP | DL_OPT_PORT_TYPE, 0);
1700*de1e4e89SAndroid Build Coastguard Worker if (err)
1701*de1e4e89SAndroid Build Coastguard Worker return err;
1702*de1e4e89SAndroid Build Coastguard Worker
1703*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
1704*de1e4e89SAndroid Build Coastguard Worker }
1705*de1e4e89SAndroid Build Coastguard Worker
cmd_port_split(struct dl * dl)1706*de1e4e89SAndroid Build Coastguard Worker static int cmd_port_split(struct dl *dl)
1707*de1e4e89SAndroid Build Coastguard Worker {
1708*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1709*de1e4e89SAndroid Build Coastguard Worker int err;
1710*de1e4e89SAndroid Build Coastguard Worker
1711*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_SPLIT,
1712*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
1713*de1e4e89SAndroid Build Coastguard Worker
1714*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP | DL_OPT_PORT_COUNT, 0);
1715*de1e4e89SAndroid Build Coastguard Worker if (err)
1716*de1e4e89SAndroid Build Coastguard Worker return err;
1717*de1e4e89SAndroid Build Coastguard Worker
1718*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
1719*de1e4e89SAndroid Build Coastguard Worker }
1720*de1e4e89SAndroid Build Coastguard Worker
cmd_port_unsplit(struct dl * dl)1721*de1e4e89SAndroid Build Coastguard Worker static int cmd_port_unsplit(struct dl *dl)
1722*de1e4e89SAndroid Build Coastguard Worker {
1723*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1724*de1e4e89SAndroid Build Coastguard Worker int err;
1725*de1e4e89SAndroid Build Coastguard Worker
1726*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_UNSPLIT,
1727*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
1728*de1e4e89SAndroid Build Coastguard Worker
1729*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP, 0);
1730*de1e4e89SAndroid Build Coastguard Worker if (err)
1731*de1e4e89SAndroid Build Coastguard Worker return err;
1732*de1e4e89SAndroid Build Coastguard Worker
1733*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
1734*de1e4e89SAndroid Build Coastguard Worker }
1735*de1e4e89SAndroid Build Coastguard Worker
cmd_port(struct dl * dl)1736*de1e4e89SAndroid Build Coastguard Worker static int cmd_port(struct dl *dl)
1737*de1e4e89SAndroid Build Coastguard Worker {
1738*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help")) {
1739*de1e4e89SAndroid Build Coastguard Worker cmd_port_help();
1740*de1e4e89SAndroid Build Coastguard Worker return 0;
1741*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show") ||
1742*de1e4e89SAndroid Build Coastguard Worker dl_argv_match(dl, "list") || dl_no_arg(dl)) {
1743*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1744*de1e4e89SAndroid Build Coastguard Worker return cmd_port_show(dl);
1745*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "set")) {
1746*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1747*de1e4e89SAndroid Build Coastguard Worker return cmd_port_set(dl);
1748*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "split")) {
1749*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1750*de1e4e89SAndroid Build Coastguard Worker return cmd_port_split(dl);
1751*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "unsplit")) {
1752*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1753*de1e4e89SAndroid Build Coastguard Worker return cmd_port_unsplit(dl);
1754*de1e4e89SAndroid Build Coastguard Worker }
1755*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
1756*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
1757*de1e4e89SAndroid Build Coastguard Worker }
1758*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_help(void)1759*de1e4e89SAndroid Build Coastguard Worker static void cmd_sb_help(void)
1760*de1e4e89SAndroid Build Coastguard Worker {
1761*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink sb show [ DEV [ sb SB_INDEX ] ]\n");
1762*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb pool show [ DEV [ sb SB_INDEX ] pool POOL_INDEX ]\n");
1763*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb pool set DEV [ sb SB_INDEX ] pool POOL_INDEX\n");
1764*de1e4e89SAndroid Build Coastguard Worker pr_err(" size POOL_SIZE thtype { static | dynamic }\n");
1765*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb port pool show [ DEV/PORT_INDEX [ sb SB_INDEX ]\n");
1766*de1e4e89SAndroid Build Coastguard Worker pr_err(" pool POOL_INDEX ]\n");
1767*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb port pool set DEV/PORT_INDEX [ sb SB_INDEX ]\n");
1768*de1e4e89SAndroid Build Coastguard Worker pr_err(" pool POOL_INDEX th THRESHOLD\n");
1769*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb tc bind show [ DEV/PORT_INDEX [ sb SB_INDEX ] tc TC_INDEX\n");
1770*de1e4e89SAndroid Build Coastguard Worker pr_err(" type { ingress | egress } ]\n");
1771*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb tc bind set DEV/PORT_INDEX [ sb SB_INDEX ] tc TC_INDEX\n");
1772*de1e4e89SAndroid Build Coastguard Worker pr_err(" type { ingress | egress } pool POOL_INDEX\n");
1773*de1e4e89SAndroid Build Coastguard Worker pr_err(" th THRESHOLD\n");
1774*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb occupancy show { DEV | DEV/PORT_INDEX } [ sb SB_INDEX ]\n");
1775*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb occupancy snapshot DEV [ sb SB_INDEX ]\n");
1776*de1e4e89SAndroid Build Coastguard Worker pr_err(" devlink sb occupancy clearmax DEV [ sb SB_INDEX ]\n");
1777*de1e4e89SAndroid Build Coastguard Worker }
1778*de1e4e89SAndroid Build Coastguard Worker
pr_out_sb(struct dl * dl,struct nlattr ** tb)1779*de1e4e89SAndroid Build Coastguard Worker static void pr_out_sb(struct dl *dl, struct nlattr **tb)
1780*de1e4e89SAndroid Build Coastguard Worker {
1781*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_start_arr(dl, tb);
1782*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "sb",
1783*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_INDEX]));
1784*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "size",
1785*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_SIZE]));
1786*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "ing_pools",
1787*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_INGRESS_POOL_COUNT]));
1788*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "eg_pools",
1789*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_EGRESS_POOL_COUNT]));
1790*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "ing_tcs",
1791*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_INGRESS_TC_COUNT]));
1792*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "eg_tcs",
1793*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_EGRESS_TC_COUNT]));
1794*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(dl);
1795*de1e4e89SAndroid Build Coastguard Worker }
1796*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_show_cb(const struct nlmsghdr * nlh,void * data)1797*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_show_cb(const struct nlmsghdr *nlh, void *data)
1798*de1e4e89SAndroid Build Coastguard Worker {
1799*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
1800*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
1801*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
1802*de1e4e89SAndroid Build Coastguard Worker
1803*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
1804*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
1805*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_INDEX] || !tb[DEVLINK_ATTR_SB_SIZE] ||
1806*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_INGRESS_POOL_COUNT] ||
1807*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_EGRESS_POOL_COUNT] ||
1808*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_INGRESS_TC_COUNT] ||
1809*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_EGRESS_TC_COUNT])
1810*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
1811*de1e4e89SAndroid Build Coastguard Worker pr_out_sb(dl, tb);
1812*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
1813*de1e4e89SAndroid Build Coastguard Worker }
1814*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_show(struct dl * dl)1815*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_show(struct dl *dl)
1816*de1e4e89SAndroid Build Coastguard Worker {
1817*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1818*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
1819*de1e4e89SAndroid Build Coastguard Worker int err;
1820*de1e4e89SAndroid Build Coastguard Worker
1821*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
1822*de1e4e89SAndroid Build Coastguard Worker flags |= NLM_F_DUMP;
1823*de1e4e89SAndroid Build Coastguard Worker
1824*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_GET, flags);
1825*de1e4e89SAndroid Build Coastguard Worker
1826*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) > 0) {
1827*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, DL_OPT_SB);
1828*de1e4e89SAndroid Build Coastguard Worker if (err)
1829*de1e4e89SAndroid Build Coastguard Worker return err;
1830*de1e4e89SAndroid Build Coastguard Worker }
1831*de1e4e89SAndroid Build Coastguard Worker
1832*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "sb");
1833*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_sb_show_cb, dl);
1834*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
1835*de1e4e89SAndroid Build Coastguard Worker return err;
1836*de1e4e89SAndroid Build Coastguard Worker }
1837*de1e4e89SAndroid Build Coastguard Worker
pool_type_name(uint8_t type)1838*de1e4e89SAndroid Build Coastguard Worker static const char *pool_type_name(uint8_t type)
1839*de1e4e89SAndroid Build Coastguard Worker {
1840*de1e4e89SAndroid Build Coastguard Worker switch (type) {
1841*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_SB_POOL_TYPE_INGRESS: return "ingress";
1842*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_SB_POOL_TYPE_EGRESS: return "egress";
1843*de1e4e89SAndroid Build Coastguard Worker default: return "<unknown type>";
1844*de1e4e89SAndroid Build Coastguard Worker }
1845*de1e4e89SAndroid Build Coastguard Worker }
1846*de1e4e89SAndroid Build Coastguard Worker
threshold_type_name(uint8_t type)1847*de1e4e89SAndroid Build Coastguard Worker static const char *threshold_type_name(uint8_t type)
1848*de1e4e89SAndroid Build Coastguard Worker {
1849*de1e4e89SAndroid Build Coastguard Worker switch (type) {
1850*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_SB_THRESHOLD_TYPE_STATIC: return "static";
1851*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC: return "dynamic";
1852*de1e4e89SAndroid Build Coastguard Worker default: return "<unknown type>";
1853*de1e4e89SAndroid Build Coastguard Worker }
1854*de1e4e89SAndroid Build Coastguard Worker }
1855*de1e4e89SAndroid Build Coastguard Worker
pr_out_sb_pool(struct dl * dl,struct nlattr ** tb)1856*de1e4e89SAndroid Build Coastguard Worker static void pr_out_sb_pool(struct dl *dl, struct nlattr **tb)
1857*de1e4e89SAndroid Build Coastguard Worker {
1858*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_start_arr(dl, tb);
1859*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "sb",
1860*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_INDEX]));
1861*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "pool",
1862*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_POOL_INDEX]));
1863*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "type",
1864*de1e4e89SAndroid Build Coastguard Worker pool_type_name(mnl_attr_get_u8(tb[DEVLINK_ATTR_SB_POOL_TYPE])));
1865*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "size",
1866*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_POOL_SIZE]));
1867*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "thtype",
1868*de1e4e89SAndroid Build Coastguard Worker threshold_type_name(mnl_attr_get_u8(tb[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])));
1869*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(dl);
1870*de1e4e89SAndroid Build Coastguard Worker }
1871*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_pool_show_cb(const struct nlmsghdr * nlh,void * data)1872*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_pool_show_cb(const struct nlmsghdr *nlh, void *data)
1873*de1e4e89SAndroid Build Coastguard Worker {
1874*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
1875*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
1876*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
1877*de1e4e89SAndroid Build Coastguard Worker
1878*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
1879*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
1880*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_INDEX] || !tb[DEVLINK_ATTR_SB_POOL_INDEX] ||
1881*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_POOL_TYPE] || !tb[DEVLINK_ATTR_SB_POOL_SIZE] ||
1882*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
1883*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
1884*de1e4e89SAndroid Build Coastguard Worker pr_out_sb_pool(dl, tb);
1885*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
1886*de1e4e89SAndroid Build Coastguard Worker }
1887*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_pool_show(struct dl * dl)1888*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_pool_show(struct dl *dl)
1889*de1e4e89SAndroid Build Coastguard Worker {
1890*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1891*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
1892*de1e4e89SAndroid Build Coastguard Worker int err;
1893*de1e4e89SAndroid Build Coastguard Worker
1894*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
1895*de1e4e89SAndroid Build Coastguard Worker flags |= NLM_F_DUMP;
1896*de1e4e89SAndroid Build Coastguard Worker
1897*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_POOL_GET, flags);
1898*de1e4e89SAndroid Build Coastguard Worker
1899*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) > 0) {
1900*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE | DL_OPT_SB_POOL,
1901*de1e4e89SAndroid Build Coastguard Worker DL_OPT_SB);
1902*de1e4e89SAndroid Build Coastguard Worker if (err)
1903*de1e4e89SAndroid Build Coastguard Worker return err;
1904*de1e4e89SAndroid Build Coastguard Worker }
1905*de1e4e89SAndroid Build Coastguard Worker
1906*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "pool");
1907*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_sb_pool_show_cb, dl);
1908*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
1909*de1e4e89SAndroid Build Coastguard Worker return err;
1910*de1e4e89SAndroid Build Coastguard Worker }
1911*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_pool_set(struct dl * dl)1912*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_pool_set(struct dl *dl)
1913*de1e4e89SAndroid Build Coastguard Worker {
1914*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1915*de1e4e89SAndroid Build Coastguard Worker int err;
1916*de1e4e89SAndroid Build Coastguard Worker
1917*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_POOL_SET,
1918*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
1919*de1e4e89SAndroid Build Coastguard Worker
1920*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE | DL_OPT_SB_POOL |
1921*de1e4e89SAndroid Build Coastguard Worker DL_OPT_SB_SIZE | DL_OPT_SB_THTYPE, DL_OPT_SB);
1922*de1e4e89SAndroid Build Coastguard Worker if (err)
1923*de1e4e89SAndroid Build Coastguard Worker return err;
1924*de1e4e89SAndroid Build Coastguard Worker
1925*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
1926*de1e4e89SAndroid Build Coastguard Worker }
1927*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_pool(struct dl * dl)1928*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_pool(struct dl *dl)
1929*de1e4e89SAndroid Build Coastguard Worker {
1930*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help")) {
1931*de1e4e89SAndroid Build Coastguard Worker cmd_sb_help();
1932*de1e4e89SAndroid Build Coastguard Worker return 0;
1933*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show") ||
1934*de1e4e89SAndroid Build Coastguard Worker dl_argv_match(dl, "list") || dl_no_arg(dl)) {
1935*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1936*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_pool_show(dl);
1937*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "set")) {
1938*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
1939*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_pool_set(dl);
1940*de1e4e89SAndroid Build Coastguard Worker }
1941*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
1942*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
1943*de1e4e89SAndroid Build Coastguard Worker }
1944*de1e4e89SAndroid Build Coastguard Worker
pr_out_sb_port_pool(struct dl * dl,struct nlattr ** tb)1945*de1e4e89SAndroid Build Coastguard Worker static void pr_out_sb_port_pool(struct dl *dl, struct nlattr **tb)
1946*de1e4e89SAndroid Build Coastguard Worker {
1947*de1e4e89SAndroid Build Coastguard Worker pr_out_port_handle_start_arr(dl, tb, true);
1948*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "sb",
1949*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_INDEX]));
1950*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "pool",
1951*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_POOL_INDEX]));
1952*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "threshold",
1953*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_THRESHOLD]));
1954*de1e4e89SAndroid Build Coastguard Worker pr_out_port_handle_end(dl);
1955*de1e4e89SAndroid Build Coastguard Worker }
1956*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_port_pool_show_cb(const struct nlmsghdr * nlh,void * data)1957*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_port_pool_show_cb(const struct nlmsghdr *nlh, void *data)
1958*de1e4e89SAndroid Build Coastguard Worker {
1959*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
1960*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
1961*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
1962*de1e4e89SAndroid Build Coastguard Worker
1963*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
1964*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
1965*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_PORT_INDEX] || !tb[DEVLINK_ATTR_SB_INDEX] ||
1966*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_POOL_INDEX] || !tb[DEVLINK_ATTR_SB_THRESHOLD])
1967*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
1968*de1e4e89SAndroid Build Coastguard Worker pr_out_sb_port_pool(dl, tb);
1969*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
1970*de1e4e89SAndroid Build Coastguard Worker }
1971*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_port_pool_show(struct dl * dl)1972*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_port_pool_show(struct dl *dl)
1973*de1e4e89SAndroid Build Coastguard Worker {
1974*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
1975*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
1976*de1e4e89SAndroid Build Coastguard Worker int err;
1977*de1e4e89SAndroid Build Coastguard Worker
1978*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
1979*de1e4e89SAndroid Build Coastguard Worker flags |= NLM_F_DUMP;
1980*de1e4e89SAndroid Build Coastguard Worker
1981*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_PORT_POOL_GET, flags);
1982*de1e4e89SAndroid Build Coastguard Worker
1983*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) > 0) {
1984*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl,
1985*de1e4e89SAndroid Build Coastguard Worker DL_OPT_HANDLEP | DL_OPT_SB_POOL,
1986*de1e4e89SAndroid Build Coastguard Worker DL_OPT_SB);
1987*de1e4e89SAndroid Build Coastguard Worker if (err)
1988*de1e4e89SAndroid Build Coastguard Worker return err;
1989*de1e4e89SAndroid Build Coastguard Worker }
1990*de1e4e89SAndroid Build Coastguard Worker
1991*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "port_pool");
1992*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_sb_port_pool_show_cb, dl);
1993*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
1994*de1e4e89SAndroid Build Coastguard Worker return 0;
1995*de1e4e89SAndroid Build Coastguard Worker }
1996*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_port_pool_set(struct dl * dl)1997*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_port_pool_set(struct dl *dl)
1998*de1e4e89SAndroid Build Coastguard Worker {
1999*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
2000*de1e4e89SAndroid Build Coastguard Worker int err;
2001*de1e4e89SAndroid Build Coastguard Worker
2002*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_PORT_POOL_SET,
2003*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
2004*de1e4e89SAndroid Build Coastguard Worker
2005*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP | DL_OPT_SB_POOL |
2006*de1e4e89SAndroid Build Coastguard Worker DL_OPT_SB_TH, DL_OPT_SB);
2007*de1e4e89SAndroid Build Coastguard Worker if (err)
2008*de1e4e89SAndroid Build Coastguard Worker return err;
2009*de1e4e89SAndroid Build Coastguard Worker
2010*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
2011*de1e4e89SAndroid Build Coastguard Worker }
2012*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_port_pool(struct dl * dl)2013*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_port_pool(struct dl *dl)
2014*de1e4e89SAndroid Build Coastguard Worker {
2015*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help")) {
2016*de1e4e89SAndroid Build Coastguard Worker cmd_sb_help();
2017*de1e4e89SAndroid Build Coastguard Worker return 0;
2018*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show") ||
2019*de1e4e89SAndroid Build Coastguard Worker dl_argv_match(dl, "list") || dl_no_arg(dl)) {
2020*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2021*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_port_pool_show(dl);
2022*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "set")) {
2023*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2024*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_port_pool_set(dl);
2025*de1e4e89SAndroid Build Coastguard Worker }
2026*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
2027*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
2028*de1e4e89SAndroid Build Coastguard Worker }
2029*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_port(struct dl * dl)2030*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_port(struct dl *dl)
2031*de1e4e89SAndroid Build Coastguard Worker {
2032*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
2033*de1e4e89SAndroid Build Coastguard Worker cmd_sb_help();
2034*de1e4e89SAndroid Build Coastguard Worker return 0;
2035*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "pool")) {
2036*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2037*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_port_pool(dl);
2038*de1e4e89SAndroid Build Coastguard Worker }
2039*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
2040*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
2041*de1e4e89SAndroid Build Coastguard Worker }
2042*de1e4e89SAndroid Build Coastguard Worker
pr_out_sb_tc_bind(struct dl * dl,struct nlattr ** tb)2043*de1e4e89SAndroid Build Coastguard Worker static void pr_out_sb_tc_bind(struct dl *dl, struct nlattr **tb)
2044*de1e4e89SAndroid Build Coastguard Worker {
2045*de1e4e89SAndroid Build Coastguard Worker pr_out_port_handle_start_arr(dl, tb, true);
2046*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "sb",
2047*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_INDEX]));
2048*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "tc",
2049*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_TC_INDEX]));
2050*de1e4e89SAndroid Build Coastguard Worker pr_out_str(dl, "type",
2051*de1e4e89SAndroid Build Coastguard Worker pool_type_name(mnl_attr_get_u8(tb[DEVLINK_ATTR_SB_POOL_TYPE])));
2052*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "pool",
2053*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_POOL_INDEX]));
2054*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(dl, "threshold",
2055*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_THRESHOLD]));
2056*de1e4e89SAndroid Build Coastguard Worker pr_out_port_handle_end(dl);
2057*de1e4e89SAndroid Build Coastguard Worker }
2058*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_tc_bind_show_cb(const struct nlmsghdr * nlh,void * data)2059*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_tc_bind_show_cb(const struct nlmsghdr *nlh, void *data)
2060*de1e4e89SAndroid Build Coastguard Worker {
2061*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
2062*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
2063*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
2064*de1e4e89SAndroid Build Coastguard Worker
2065*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
2066*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
2067*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_PORT_INDEX] || !tb[DEVLINK_ATTR_SB_INDEX] ||
2068*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_TC_INDEX] || !tb[DEVLINK_ATTR_SB_POOL_TYPE] ||
2069*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_POOL_INDEX] || !tb[DEVLINK_ATTR_SB_THRESHOLD])
2070*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
2071*de1e4e89SAndroid Build Coastguard Worker pr_out_sb_tc_bind(dl, tb);
2072*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
2073*de1e4e89SAndroid Build Coastguard Worker }
2074*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_tc_bind_show(struct dl * dl)2075*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_tc_bind_show(struct dl *dl)
2076*de1e4e89SAndroid Build Coastguard Worker {
2077*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
2078*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
2079*de1e4e89SAndroid Build Coastguard Worker int err;
2080*de1e4e89SAndroid Build Coastguard Worker
2081*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) == 0)
2082*de1e4e89SAndroid Build Coastguard Worker flags |= NLM_F_DUMP;
2083*de1e4e89SAndroid Build Coastguard Worker
2084*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_TC_POOL_BIND_GET, flags);
2085*de1e4e89SAndroid Build Coastguard Worker
2086*de1e4e89SAndroid Build Coastguard Worker if (dl_argc(dl) > 0) {
2087*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP | DL_OPT_SB_TC |
2088*de1e4e89SAndroid Build Coastguard Worker DL_OPT_SB_TYPE, DL_OPT_SB);
2089*de1e4e89SAndroid Build Coastguard Worker if (err)
2090*de1e4e89SAndroid Build Coastguard Worker return err;
2091*de1e4e89SAndroid Build Coastguard Worker }
2092*de1e4e89SAndroid Build Coastguard Worker
2093*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "tc_bind");
2094*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_sb_tc_bind_show_cb, dl);
2095*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
2096*de1e4e89SAndroid Build Coastguard Worker return err;
2097*de1e4e89SAndroid Build Coastguard Worker }
2098*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_tc_bind_set(struct dl * dl)2099*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_tc_bind_set(struct dl *dl)
2100*de1e4e89SAndroid Build Coastguard Worker {
2101*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
2102*de1e4e89SAndroid Build Coastguard Worker int err;
2103*de1e4e89SAndroid Build Coastguard Worker
2104*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_TC_POOL_BIND_SET,
2105*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
2106*de1e4e89SAndroid Build Coastguard Worker
2107*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP | DL_OPT_SB_TC |
2108*de1e4e89SAndroid Build Coastguard Worker DL_OPT_SB_TYPE | DL_OPT_SB_POOL | DL_OPT_SB_TH,
2109*de1e4e89SAndroid Build Coastguard Worker DL_OPT_SB);
2110*de1e4e89SAndroid Build Coastguard Worker if (err)
2111*de1e4e89SAndroid Build Coastguard Worker return err;
2112*de1e4e89SAndroid Build Coastguard Worker
2113*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
2114*de1e4e89SAndroid Build Coastguard Worker }
2115*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_tc_bind(struct dl * dl)2116*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_tc_bind(struct dl *dl)
2117*de1e4e89SAndroid Build Coastguard Worker {
2118*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help")) {
2119*de1e4e89SAndroid Build Coastguard Worker cmd_sb_help();
2120*de1e4e89SAndroid Build Coastguard Worker return 0;
2121*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show") ||
2122*de1e4e89SAndroid Build Coastguard Worker dl_argv_match(dl, "list") || dl_no_arg(dl)) {
2123*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2124*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_tc_bind_show(dl);
2125*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "set")) {
2126*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2127*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_tc_bind_set(dl);
2128*de1e4e89SAndroid Build Coastguard Worker }
2129*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
2130*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
2131*de1e4e89SAndroid Build Coastguard Worker }
2132*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_tc(struct dl * dl)2133*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_tc(struct dl *dl)
2134*de1e4e89SAndroid Build Coastguard Worker {
2135*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
2136*de1e4e89SAndroid Build Coastguard Worker cmd_sb_help();
2137*de1e4e89SAndroid Build Coastguard Worker return 0;
2138*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "bind")) {
2139*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2140*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_tc_bind(dl);
2141*de1e4e89SAndroid Build Coastguard Worker }
2142*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
2143*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
2144*de1e4e89SAndroid Build Coastguard Worker }
2145*de1e4e89SAndroid Build Coastguard Worker
2146*de1e4e89SAndroid Build Coastguard Worker struct occ_item {
2147*de1e4e89SAndroid Build Coastguard Worker struct list_head list;
2148*de1e4e89SAndroid Build Coastguard Worker uint32_t index;
2149*de1e4e89SAndroid Build Coastguard Worker uint32_t cur;
2150*de1e4e89SAndroid Build Coastguard Worker uint32_t max;
2151*de1e4e89SAndroid Build Coastguard Worker uint32_t bound_pool_index;
2152*de1e4e89SAndroid Build Coastguard Worker };
2153*de1e4e89SAndroid Build Coastguard Worker
2154*de1e4e89SAndroid Build Coastguard Worker struct occ_port {
2155*de1e4e89SAndroid Build Coastguard Worker struct list_head list;
2156*de1e4e89SAndroid Build Coastguard Worker char *bus_name;
2157*de1e4e89SAndroid Build Coastguard Worker char *dev_name;
2158*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index;
2159*de1e4e89SAndroid Build Coastguard Worker uint32_t sb_index;
2160*de1e4e89SAndroid Build Coastguard Worker struct list_head pool_list;
2161*de1e4e89SAndroid Build Coastguard Worker struct list_head ing_tc_list;
2162*de1e4e89SAndroid Build Coastguard Worker struct list_head eg_tc_list;
2163*de1e4e89SAndroid Build Coastguard Worker };
2164*de1e4e89SAndroid Build Coastguard Worker
2165*de1e4e89SAndroid Build Coastguard Worker struct occ_show {
2166*de1e4e89SAndroid Build Coastguard Worker struct dl *dl;
2167*de1e4e89SAndroid Build Coastguard Worker int err;
2168*de1e4e89SAndroid Build Coastguard Worker struct list_head port_list;
2169*de1e4e89SAndroid Build Coastguard Worker };
2170*de1e4e89SAndroid Build Coastguard Worker
occ_item_alloc(void)2171*de1e4e89SAndroid Build Coastguard Worker static struct occ_item *occ_item_alloc(void)
2172*de1e4e89SAndroid Build Coastguard Worker {
2173*de1e4e89SAndroid Build Coastguard Worker return calloc(1, sizeof(struct occ_item));
2174*de1e4e89SAndroid Build Coastguard Worker }
2175*de1e4e89SAndroid Build Coastguard Worker
occ_item_free(struct occ_item * occ_item)2176*de1e4e89SAndroid Build Coastguard Worker static void occ_item_free(struct occ_item *occ_item)
2177*de1e4e89SAndroid Build Coastguard Worker {
2178*de1e4e89SAndroid Build Coastguard Worker free(occ_item);
2179*de1e4e89SAndroid Build Coastguard Worker }
2180*de1e4e89SAndroid Build Coastguard Worker
occ_port_alloc(uint32_t port_index)2181*de1e4e89SAndroid Build Coastguard Worker static struct occ_port *occ_port_alloc(uint32_t port_index)
2182*de1e4e89SAndroid Build Coastguard Worker {
2183*de1e4e89SAndroid Build Coastguard Worker struct occ_port *occ_port;
2184*de1e4e89SAndroid Build Coastguard Worker
2185*de1e4e89SAndroid Build Coastguard Worker occ_port = calloc(1, sizeof(*occ_port));
2186*de1e4e89SAndroid Build Coastguard Worker if (!occ_port)
2187*de1e4e89SAndroid Build Coastguard Worker return NULL;
2188*de1e4e89SAndroid Build Coastguard Worker occ_port->port_index = port_index;
2189*de1e4e89SAndroid Build Coastguard Worker INIT_LIST_HEAD(&occ_port->pool_list);
2190*de1e4e89SAndroid Build Coastguard Worker INIT_LIST_HEAD(&occ_port->ing_tc_list);
2191*de1e4e89SAndroid Build Coastguard Worker INIT_LIST_HEAD(&occ_port->eg_tc_list);
2192*de1e4e89SAndroid Build Coastguard Worker return occ_port;
2193*de1e4e89SAndroid Build Coastguard Worker }
2194*de1e4e89SAndroid Build Coastguard Worker
occ_port_free(struct occ_port * occ_port)2195*de1e4e89SAndroid Build Coastguard Worker static void occ_port_free(struct occ_port *occ_port)
2196*de1e4e89SAndroid Build Coastguard Worker {
2197*de1e4e89SAndroid Build Coastguard Worker struct occ_item *occ_item, *tmp;
2198*de1e4e89SAndroid Build Coastguard Worker
2199*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_safe(occ_item, tmp, &occ_port->pool_list, list)
2200*de1e4e89SAndroid Build Coastguard Worker occ_item_free(occ_item);
2201*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_safe(occ_item, tmp, &occ_port->ing_tc_list, list)
2202*de1e4e89SAndroid Build Coastguard Worker occ_item_free(occ_item);
2203*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_safe(occ_item, tmp, &occ_port->eg_tc_list, list)
2204*de1e4e89SAndroid Build Coastguard Worker occ_item_free(occ_item);
2205*de1e4e89SAndroid Build Coastguard Worker }
2206*de1e4e89SAndroid Build Coastguard Worker
occ_show_alloc(struct dl * dl)2207*de1e4e89SAndroid Build Coastguard Worker static struct occ_show *occ_show_alloc(struct dl *dl)
2208*de1e4e89SAndroid Build Coastguard Worker {
2209*de1e4e89SAndroid Build Coastguard Worker struct occ_show *occ_show;
2210*de1e4e89SAndroid Build Coastguard Worker
2211*de1e4e89SAndroid Build Coastguard Worker occ_show = calloc(1, sizeof(*occ_show));
2212*de1e4e89SAndroid Build Coastguard Worker if (!occ_show)
2213*de1e4e89SAndroid Build Coastguard Worker return NULL;
2214*de1e4e89SAndroid Build Coastguard Worker occ_show->dl = dl;
2215*de1e4e89SAndroid Build Coastguard Worker INIT_LIST_HEAD(&occ_show->port_list);
2216*de1e4e89SAndroid Build Coastguard Worker return occ_show;
2217*de1e4e89SAndroid Build Coastguard Worker }
2218*de1e4e89SAndroid Build Coastguard Worker
occ_show_free(struct occ_show * occ_show)2219*de1e4e89SAndroid Build Coastguard Worker static void occ_show_free(struct occ_show *occ_show)
2220*de1e4e89SAndroid Build Coastguard Worker {
2221*de1e4e89SAndroid Build Coastguard Worker struct occ_port *occ_port, *tmp;
2222*de1e4e89SAndroid Build Coastguard Worker
2223*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_safe(occ_port, tmp, &occ_show->port_list, list)
2224*de1e4e89SAndroid Build Coastguard Worker occ_port_free(occ_port);
2225*de1e4e89SAndroid Build Coastguard Worker }
2226*de1e4e89SAndroid Build Coastguard Worker
occ_port_get(struct occ_show * occ_show,struct nlattr ** tb)2227*de1e4e89SAndroid Build Coastguard Worker static struct occ_port *occ_port_get(struct occ_show *occ_show,
2228*de1e4e89SAndroid Build Coastguard Worker struct nlattr **tb)
2229*de1e4e89SAndroid Build Coastguard Worker {
2230*de1e4e89SAndroid Build Coastguard Worker struct occ_port *occ_port;
2231*de1e4e89SAndroid Build Coastguard Worker uint32_t port_index;
2232*de1e4e89SAndroid Build Coastguard Worker
2233*de1e4e89SAndroid Build Coastguard Worker port_index = mnl_attr_get_u32(tb[DEVLINK_ATTR_PORT_INDEX]);
2234*de1e4e89SAndroid Build Coastguard Worker
2235*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_reverse(occ_port, &occ_show->port_list, list) {
2236*de1e4e89SAndroid Build Coastguard Worker if (occ_port->port_index == port_index)
2237*de1e4e89SAndroid Build Coastguard Worker return occ_port;
2238*de1e4e89SAndroid Build Coastguard Worker }
2239*de1e4e89SAndroid Build Coastguard Worker occ_port = occ_port_alloc(port_index);
2240*de1e4e89SAndroid Build Coastguard Worker if (!occ_port)
2241*de1e4e89SAndroid Build Coastguard Worker return NULL;
2242*de1e4e89SAndroid Build Coastguard Worker list_add_tail(&occ_port->list, &occ_show->port_list);
2243*de1e4e89SAndroid Build Coastguard Worker return occ_port;
2244*de1e4e89SAndroid Build Coastguard Worker }
2245*de1e4e89SAndroid Build Coastguard Worker
pr_out_occ_show_item_list(const char * label,struct list_head * list,bool bound_pool)2246*de1e4e89SAndroid Build Coastguard Worker static void pr_out_occ_show_item_list(const char *label, struct list_head *list,
2247*de1e4e89SAndroid Build Coastguard Worker bool bound_pool)
2248*de1e4e89SAndroid Build Coastguard Worker {
2249*de1e4e89SAndroid Build Coastguard Worker struct occ_item *occ_item;
2250*de1e4e89SAndroid Build Coastguard Worker int i = 1;
2251*de1e4e89SAndroid Build Coastguard Worker
2252*de1e4e89SAndroid Build Coastguard Worker pr_out_sp(7, " %s:", label);
2253*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(occ_item, list, list) {
2254*de1e4e89SAndroid Build Coastguard Worker if ((i - 1) % 4 == 0 && i != 1)
2255*de1e4e89SAndroid Build Coastguard Worker pr_out_sp(7, " ");
2256*de1e4e89SAndroid Build Coastguard Worker if (bound_pool)
2257*de1e4e89SAndroid Build Coastguard Worker pr_out_sp(7, "%2u(%u):", occ_item->index,
2258*de1e4e89SAndroid Build Coastguard Worker occ_item->bound_pool_index);
2259*de1e4e89SAndroid Build Coastguard Worker else
2260*de1e4e89SAndroid Build Coastguard Worker pr_out_sp(7, "%2u:", occ_item->index);
2261*de1e4e89SAndroid Build Coastguard Worker pr_out_sp(15, "%7u/%u", occ_item->cur, occ_item->max);
2262*de1e4e89SAndroid Build Coastguard Worker if (i++ % 4 == 0)
2263*de1e4e89SAndroid Build Coastguard Worker pr_out("\n");
2264*de1e4e89SAndroid Build Coastguard Worker }
2265*de1e4e89SAndroid Build Coastguard Worker if ((i - 1) % 4 != 0)
2266*de1e4e89SAndroid Build Coastguard Worker pr_out("\n");
2267*de1e4e89SAndroid Build Coastguard Worker }
2268*de1e4e89SAndroid Build Coastguard Worker
pr_out_json_occ_show_item_list(struct dl * dl,const char * label,struct list_head * list,bool bound_pool)2269*de1e4e89SAndroid Build Coastguard Worker static void pr_out_json_occ_show_item_list(struct dl *dl, const char *label,
2270*de1e4e89SAndroid Build Coastguard Worker struct list_head *list,
2271*de1e4e89SAndroid Build Coastguard Worker bool bound_pool)
2272*de1e4e89SAndroid Build Coastguard Worker {
2273*de1e4e89SAndroid Build Coastguard Worker struct occ_item *occ_item;
2274*de1e4e89SAndroid Build Coastguard Worker char buf[32];
2275*de1e4e89SAndroid Build Coastguard Worker
2276*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, label);
2277*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
2278*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(occ_item, list, list) {
2279*de1e4e89SAndroid Build Coastguard Worker sprintf(buf, "%u", occ_item->index);
2280*de1e4e89SAndroid Build Coastguard Worker jsonw_name(dl->jw, buf);
2281*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(dl->jw);
2282*de1e4e89SAndroid Build Coastguard Worker if (bound_pool)
2283*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(dl->jw, "bound_pool",
2284*de1e4e89SAndroid Build Coastguard Worker occ_item->bound_pool_index);
2285*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(dl->jw, "current", occ_item->cur);
2286*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(dl->jw, "max", occ_item->max);
2287*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(dl->jw);
2288*de1e4e89SAndroid Build Coastguard Worker }
2289*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(dl->jw);
2290*de1e4e89SAndroid Build Coastguard Worker }
2291*de1e4e89SAndroid Build Coastguard Worker
pr_out_occ_show_port(struct dl * dl,struct occ_port * occ_port)2292*de1e4e89SAndroid Build Coastguard Worker static void pr_out_occ_show_port(struct dl *dl, struct occ_port *occ_port)
2293*de1e4e89SAndroid Build Coastguard Worker {
2294*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
2295*de1e4e89SAndroid Build Coastguard Worker pr_out_json_occ_show_item_list(dl, "pool",
2296*de1e4e89SAndroid Build Coastguard Worker &occ_port->pool_list, false);
2297*de1e4e89SAndroid Build Coastguard Worker pr_out_json_occ_show_item_list(dl, "itc",
2298*de1e4e89SAndroid Build Coastguard Worker &occ_port->ing_tc_list, true);
2299*de1e4e89SAndroid Build Coastguard Worker pr_out_json_occ_show_item_list(dl, "etc",
2300*de1e4e89SAndroid Build Coastguard Worker &occ_port->eg_tc_list, true);
2301*de1e4e89SAndroid Build Coastguard Worker } else {
2302*de1e4e89SAndroid Build Coastguard Worker pr_out("\n");
2303*de1e4e89SAndroid Build Coastguard Worker pr_out_occ_show_item_list("pool", &occ_port->pool_list, false);
2304*de1e4e89SAndroid Build Coastguard Worker pr_out_occ_show_item_list("itc", &occ_port->ing_tc_list, true);
2305*de1e4e89SAndroid Build Coastguard Worker pr_out_occ_show_item_list("etc", &occ_port->eg_tc_list, true);
2306*de1e4e89SAndroid Build Coastguard Worker }
2307*de1e4e89SAndroid Build Coastguard Worker }
2308*de1e4e89SAndroid Build Coastguard Worker
pr_out_occ_show(struct occ_show * occ_show)2309*de1e4e89SAndroid Build Coastguard Worker static void pr_out_occ_show(struct occ_show *occ_show)
2310*de1e4e89SAndroid Build Coastguard Worker {
2311*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = occ_show->dl;
2312*de1e4e89SAndroid Build Coastguard Worker struct dl_opts *opts = &dl->opts;
2313*de1e4e89SAndroid Build Coastguard Worker struct occ_port *occ_port;
2314*de1e4e89SAndroid Build Coastguard Worker
2315*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(occ_port, &occ_show->port_list, list) {
2316*de1e4e89SAndroid Build Coastguard Worker __pr_out_port_handle_start(dl, opts->bus_name, opts->dev_name,
2317*de1e4e89SAndroid Build Coastguard Worker occ_port->port_index, true, false);
2318*de1e4e89SAndroid Build Coastguard Worker pr_out_occ_show_port(dl, occ_port);
2319*de1e4e89SAndroid Build Coastguard Worker pr_out_port_handle_end(dl);
2320*de1e4e89SAndroid Build Coastguard Worker }
2321*de1e4e89SAndroid Build Coastguard Worker }
2322*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ_port_pool_process(struct occ_show * occ_show,struct nlattr ** tb)2323*de1e4e89SAndroid Build Coastguard Worker static void cmd_sb_occ_port_pool_process(struct occ_show *occ_show,
2324*de1e4e89SAndroid Build Coastguard Worker struct nlattr **tb)
2325*de1e4e89SAndroid Build Coastguard Worker {
2326*de1e4e89SAndroid Build Coastguard Worker struct occ_port *occ_port;
2327*de1e4e89SAndroid Build Coastguard Worker struct occ_item *occ_item;
2328*de1e4e89SAndroid Build Coastguard Worker
2329*de1e4e89SAndroid Build Coastguard Worker if (occ_show->err || !dl_dump_filter(occ_show->dl, tb))
2330*de1e4e89SAndroid Build Coastguard Worker return;
2331*de1e4e89SAndroid Build Coastguard Worker
2332*de1e4e89SAndroid Build Coastguard Worker occ_port = occ_port_get(occ_show, tb);
2333*de1e4e89SAndroid Build Coastguard Worker if (!occ_port) {
2334*de1e4e89SAndroid Build Coastguard Worker occ_show->err = -ENOMEM;
2335*de1e4e89SAndroid Build Coastguard Worker return;
2336*de1e4e89SAndroid Build Coastguard Worker }
2337*de1e4e89SAndroid Build Coastguard Worker
2338*de1e4e89SAndroid Build Coastguard Worker occ_item = occ_item_alloc();
2339*de1e4e89SAndroid Build Coastguard Worker if (!occ_item) {
2340*de1e4e89SAndroid Build Coastguard Worker occ_show->err = -ENOMEM;
2341*de1e4e89SAndroid Build Coastguard Worker return;
2342*de1e4e89SAndroid Build Coastguard Worker }
2343*de1e4e89SAndroid Build Coastguard Worker occ_item->index = mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_POOL_INDEX]);
2344*de1e4e89SAndroid Build Coastguard Worker occ_item->cur = mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_OCC_CUR]);
2345*de1e4e89SAndroid Build Coastguard Worker occ_item->max = mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_OCC_MAX]);
2346*de1e4e89SAndroid Build Coastguard Worker list_add_tail(&occ_item->list, &occ_port->pool_list);
2347*de1e4e89SAndroid Build Coastguard Worker }
2348*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ_port_pool_process_cb(const struct nlmsghdr * nlh,void * data)2349*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_occ_port_pool_process_cb(const struct nlmsghdr *nlh, void *data)
2350*de1e4e89SAndroid Build Coastguard Worker {
2351*de1e4e89SAndroid Build Coastguard Worker struct occ_show *occ_show = data;
2352*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
2353*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
2354*de1e4e89SAndroid Build Coastguard Worker
2355*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
2356*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
2357*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_PORT_INDEX] || !tb[DEVLINK_ATTR_SB_INDEX] ||
2358*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_POOL_INDEX] ||
2359*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_OCC_CUR] || !tb[DEVLINK_ATTR_SB_OCC_MAX])
2360*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
2361*de1e4e89SAndroid Build Coastguard Worker cmd_sb_occ_port_pool_process(occ_show, tb);
2362*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
2363*de1e4e89SAndroid Build Coastguard Worker }
2364*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ_tc_pool_process(struct occ_show * occ_show,struct nlattr ** tb)2365*de1e4e89SAndroid Build Coastguard Worker static void cmd_sb_occ_tc_pool_process(struct occ_show *occ_show,
2366*de1e4e89SAndroid Build Coastguard Worker struct nlattr **tb)
2367*de1e4e89SAndroid Build Coastguard Worker {
2368*de1e4e89SAndroid Build Coastguard Worker struct occ_port *occ_port;
2369*de1e4e89SAndroid Build Coastguard Worker struct occ_item *occ_item;
2370*de1e4e89SAndroid Build Coastguard Worker uint8_t pool_type;
2371*de1e4e89SAndroid Build Coastguard Worker
2372*de1e4e89SAndroid Build Coastguard Worker if (occ_show->err || !dl_dump_filter(occ_show->dl, tb))
2373*de1e4e89SAndroid Build Coastguard Worker return;
2374*de1e4e89SAndroid Build Coastguard Worker
2375*de1e4e89SAndroid Build Coastguard Worker occ_port = occ_port_get(occ_show, tb);
2376*de1e4e89SAndroid Build Coastguard Worker if (!occ_port) {
2377*de1e4e89SAndroid Build Coastguard Worker occ_show->err = -ENOMEM;
2378*de1e4e89SAndroid Build Coastguard Worker return;
2379*de1e4e89SAndroid Build Coastguard Worker }
2380*de1e4e89SAndroid Build Coastguard Worker
2381*de1e4e89SAndroid Build Coastguard Worker occ_item = occ_item_alloc();
2382*de1e4e89SAndroid Build Coastguard Worker if (!occ_item) {
2383*de1e4e89SAndroid Build Coastguard Worker occ_show->err = -ENOMEM;
2384*de1e4e89SAndroid Build Coastguard Worker return;
2385*de1e4e89SAndroid Build Coastguard Worker }
2386*de1e4e89SAndroid Build Coastguard Worker occ_item->index = mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_TC_INDEX]);
2387*de1e4e89SAndroid Build Coastguard Worker occ_item->cur = mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_OCC_CUR]);
2388*de1e4e89SAndroid Build Coastguard Worker occ_item->max = mnl_attr_get_u32(tb[DEVLINK_ATTR_SB_OCC_MAX]);
2389*de1e4e89SAndroid Build Coastguard Worker occ_item->bound_pool_index =
2390*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u16(tb[DEVLINK_ATTR_SB_POOL_INDEX]);
2391*de1e4e89SAndroid Build Coastguard Worker pool_type = mnl_attr_get_u8(tb[DEVLINK_ATTR_SB_POOL_TYPE]);
2392*de1e4e89SAndroid Build Coastguard Worker if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS)
2393*de1e4e89SAndroid Build Coastguard Worker list_add_tail(&occ_item->list, &occ_port->ing_tc_list);
2394*de1e4e89SAndroid Build Coastguard Worker else if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS)
2395*de1e4e89SAndroid Build Coastguard Worker list_add_tail(&occ_item->list, &occ_port->eg_tc_list);
2396*de1e4e89SAndroid Build Coastguard Worker else
2397*de1e4e89SAndroid Build Coastguard Worker occ_item_free(occ_item);
2398*de1e4e89SAndroid Build Coastguard Worker }
2399*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ_tc_pool_process_cb(const struct nlmsghdr * nlh,void * data)2400*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_occ_tc_pool_process_cb(const struct nlmsghdr *nlh, void *data)
2401*de1e4e89SAndroid Build Coastguard Worker {
2402*de1e4e89SAndroid Build Coastguard Worker struct occ_show *occ_show = data;
2403*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
2404*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
2405*de1e4e89SAndroid Build Coastguard Worker
2406*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
2407*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
2408*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_PORT_INDEX] || !tb[DEVLINK_ATTR_SB_INDEX] ||
2409*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_TC_INDEX] || !tb[DEVLINK_ATTR_SB_POOL_TYPE] ||
2410*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_POOL_INDEX] ||
2411*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_SB_OCC_CUR] || !tb[DEVLINK_ATTR_SB_OCC_MAX])
2412*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
2413*de1e4e89SAndroid Build Coastguard Worker cmd_sb_occ_tc_pool_process(occ_show, tb);
2414*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
2415*de1e4e89SAndroid Build Coastguard Worker }
2416*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ_show(struct dl * dl)2417*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_occ_show(struct dl *dl)
2418*de1e4e89SAndroid Build Coastguard Worker {
2419*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
2420*de1e4e89SAndroid Build Coastguard Worker struct occ_show *occ_show;
2421*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP;
2422*de1e4e89SAndroid Build Coastguard Worker int err;
2423*de1e4e89SAndroid Build Coastguard Worker
2424*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP, DL_OPT_SB);
2425*de1e4e89SAndroid Build Coastguard Worker if (err)
2426*de1e4e89SAndroid Build Coastguard Worker return err;
2427*de1e4e89SAndroid Build Coastguard Worker
2428*de1e4e89SAndroid Build Coastguard Worker occ_show = occ_show_alloc(dl);
2429*de1e4e89SAndroid Build Coastguard Worker if (!occ_show)
2430*de1e4e89SAndroid Build Coastguard Worker return -ENOMEM;
2431*de1e4e89SAndroid Build Coastguard Worker
2432*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_PORT_POOL_GET, flags);
2433*de1e4e89SAndroid Build Coastguard Worker
2434*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh,
2435*de1e4e89SAndroid Build Coastguard Worker cmd_sb_occ_port_pool_process_cb, occ_show);
2436*de1e4e89SAndroid Build Coastguard Worker if (err)
2437*de1e4e89SAndroid Build Coastguard Worker goto out;
2438*de1e4e89SAndroid Build Coastguard Worker
2439*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_TC_POOL_BIND_GET, flags);
2440*de1e4e89SAndroid Build Coastguard Worker
2441*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh,
2442*de1e4e89SAndroid Build Coastguard Worker cmd_sb_occ_tc_pool_process_cb, occ_show);
2443*de1e4e89SAndroid Build Coastguard Worker if (err)
2444*de1e4e89SAndroid Build Coastguard Worker goto out;
2445*de1e4e89SAndroid Build Coastguard Worker
2446*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "occupancy");
2447*de1e4e89SAndroid Build Coastguard Worker pr_out_occ_show(occ_show);
2448*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
2449*de1e4e89SAndroid Build Coastguard Worker
2450*de1e4e89SAndroid Build Coastguard Worker out:
2451*de1e4e89SAndroid Build Coastguard Worker occ_show_free(occ_show);
2452*de1e4e89SAndroid Build Coastguard Worker return err;
2453*de1e4e89SAndroid Build Coastguard Worker }
2454*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ_snapshot(struct dl * dl)2455*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_occ_snapshot(struct dl *dl)
2456*de1e4e89SAndroid Build Coastguard Worker {
2457*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
2458*de1e4e89SAndroid Build Coastguard Worker int err;
2459*de1e4e89SAndroid Build Coastguard Worker
2460*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_OCC_SNAPSHOT,
2461*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
2462*de1e4e89SAndroid Build Coastguard Worker
2463*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, DL_OPT_SB);
2464*de1e4e89SAndroid Build Coastguard Worker if (err)
2465*de1e4e89SAndroid Build Coastguard Worker return err;
2466*de1e4e89SAndroid Build Coastguard Worker
2467*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
2468*de1e4e89SAndroid Build Coastguard Worker }
2469*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ_clearmax(struct dl * dl)2470*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_occ_clearmax(struct dl *dl)
2471*de1e4e89SAndroid Build Coastguard Worker {
2472*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
2473*de1e4e89SAndroid Build Coastguard Worker int err;
2474*de1e4e89SAndroid Build Coastguard Worker
2475*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_SB_OCC_MAX_CLEAR,
2476*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
2477*de1e4e89SAndroid Build Coastguard Worker
2478*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, DL_OPT_SB);
2479*de1e4e89SAndroid Build Coastguard Worker if (err)
2480*de1e4e89SAndroid Build Coastguard Worker return err;
2481*de1e4e89SAndroid Build Coastguard Worker
2482*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
2483*de1e4e89SAndroid Build Coastguard Worker }
2484*de1e4e89SAndroid Build Coastguard Worker
cmd_sb_occ(struct dl * dl)2485*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb_occ(struct dl *dl)
2486*de1e4e89SAndroid Build Coastguard Worker {
2487*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
2488*de1e4e89SAndroid Build Coastguard Worker cmd_sb_help();
2489*de1e4e89SAndroid Build Coastguard Worker return 0;
2490*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show") ||
2491*de1e4e89SAndroid Build Coastguard Worker dl_argv_match(dl, "list")) {
2492*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2493*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_occ_show(dl);
2494*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "snapshot")) {
2495*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2496*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_occ_snapshot(dl);
2497*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "clearmax")) {
2498*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2499*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_occ_clearmax(dl);
2500*de1e4e89SAndroid Build Coastguard Worker }
2501*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
2502*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
2503*de1e4e89SAndroid Build Coastguard Worker }
2504*de1e4e89SAndroid Build Coastguard Worker
cmd_sb(struct dl * dl)2505*de1e4e89SAndroid Build Coastguard Worker static int cmd_sb(struct dl *dl)
2506*de1e4e89SAndroid Build Coastguard Worker {
2507*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help")) {
2508*de1e4e89SAndroid Build Coastguard Worker cmd_sb_help();
2509*de1e4e89SAndroid Build Coastguard Worker return 0;
2510*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show") ||
2511*de1e4e89SAndroid Build Coastguard Worker dl_argv_match(dl, "list") || dl_no_arg(dl)) {
2512*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2513*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_show(dl);
2514*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "pool")) {
2515*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2516*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_pool(dl);
2517*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "port")) {
2518*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2519*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_port(dl);
2520*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "tc")) {
2521*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2522*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_tc(dl);
2523*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "occupancy")) {
2524*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2525*de1e4e89SAndroid Build Coastguard Worker return cmd_sb_occ(dl);
2526*de1e4e89SAndroid Build Coastguard Worker }
2527*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
2528*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
2529*de1e4e89SAndroid Build Coastguard Worker }
2530*de1e4e89SAndroid Build Coastguard Worker
cmd_name(uint8_t cmd)2531*de1e4e89SAndroid Build Coastguard Worker static const char *cmd_name(uint8_t cmd)
2532*de1e4e89SAndroid Build Coastguard Worker {
2533*de1e4e89SAndroid Build Coastguard Worker switch (cmd) {
2534*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_UNSPEC: return "unspec";
2535*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_GET: return "get";
2536*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_SET: return "set";
2537*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_NEW: return "new";
2538*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_DEL: return "del";
2539*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_GET: return "get";
2540*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_SET: return "set";
2541*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_NEW: return "net";
2542*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_DEL: return "del";
2543*de1e4e89SAndroid Build Coastguard Worker default: return "<unknown cmd>";
2544*de1e4e89SAndroid Build Coastguard Worker }
2545*de1e4e89SAndroid Build Coastguard Worker }
2546*de1e4e89SAndroid Build Coastguard Worker
cmd_obj(uint8_t cmd)2547*de1e4e89SAndroid Build Coastguard Worker static const char *cmd_obj(uint8_t cmd)
2548*de1e4e89SAndroid Build Coastguard Worker {
2549*de1e4e89SAndroid Build Coastguard Worker switch (cmd) {
2550*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_UNSPEC: return "unspec";
2551*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_GET:
2552*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_SET:
2553*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_NEW:
2554*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_DEL:
2555*de1e4e89SAndroid Build Coastguard Worker return "dev";
2556*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_GET:
2557*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_SET:
2558*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_NEW:
2559*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_DEL:
2560*de1e4e89SAndroid Build Coastguard Worker return "port";
2561*de1e4e89SAndroid Build Coastguard Worker default: return "<unknown obj>";
2562*de1e4e89SAndroid Build Coastguard Worker }
2563*de1e4e89SAndroid Build Coastguard Worker }
2564*de1e4e89SAndroid Build Coastguard Worker
pr_out_mon_header(uint8_t cmd)2565*de1e4e89SAndroid Build Coastguard Worker static void pr_out_mon_header(uint8_t cmd)
2566*de1e4e89SAndroid Build Coastguard Worker {
2567*de1e4e89SAndroid Build Coastguard Worker pr_out("[%s,%s] ", cmd_obj(cmd), cmd_name(cmd));
2568*de1e4e89SAndroid Build Coastguard Worker }
2569*de1e4e89SAndroid Build Coastguard Worker
cmd_filter_check(struct dl * dl,uint8_t cmd)2570*de1e4e89SAndroid Build Coastguard Worker static bool cmd_filter_check(struct dl *dl, uint8_t cmd)
2571*de1e4e89SAndroid Build Coastguard Worker {
2572*de1e4e89SAndroid Build Coastguard Worker const char *obj = cmd_obj(cmd);
2573*de1e4e89SAndroid Build Coastguard Worker unsigned int index = 0;
2574*de1e4e89SAndroid Build Coastguard Worker const char *cur_obj;
2575*de1e4e89SAndroid Build Coastguard Worker
2576*de1e4e89SAndroid Build Coastguard Worker if (dl_no_arg(dl))
2577*de1e4e89SAndroid Build Coastguard Worker return true;
2578*de1e4e89SAndroid Build Coastguard Worker while ((cur_obj = dl_argv_index(dl, index++))) {
2579*de1e4e89SAndroid Build Coastguard Worker if (strcmp(cur_obj, obj) == 0 || strcmp(cur_obj, "all") == 0)
2580*de1e4e89SAndroid Build Coastguard Worker return true;
2581*de1e4e89SAndroid Build Coastguard Worker }
2582*de1e4e89SAndroid Build Coastguard Worker return false;
2583*de1e4e89SAndroid Build Coastguard Worker }
2584*de1e4e89SAndroid Build Coastguard Worker
cmd_mon_show_cb(const struct nlmsghdr * nlh,void * data)2585*de1e4e89SAndroid Build Coastguard Worker static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
2586*de1e4e89SAndroid Build Coastguard Worker {
2587*de1e4e89SAndroid Build Coastguard Worker struct dl *dl = data;
2588*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
2589*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
2590*de1e4e89SAndroid Build Coastguard Worker uint8_t cmd = genl->cmd;
2591*de1e4e89SAndroid Build Coastguard Worker
2592*de1e4e89SAndroid Build Coastguard Worker if (!cmd_filter_check(dl, cmd))
2593*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
2594*de1e4e89SAndroid Build Coastguard Worker
2595*de1e4e89SAndroid Build Coastguard Worker switch (cmd) {
2596*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_GET: /* fall through */
2597*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_SET: /* fall through */
2598*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_NEW: /* fall through */
2599*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_DEL:
2600*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
2601*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
2602*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
2603*de1e4e89SAndroid Build Coastguard Worker pr_out_mon_header(genl->cmd);
2604*de1e4e89SAndroid Build Coastguard Worker pr_out_dev(dl, tb);
2605*de1e4e89SAndroid Build Coastguard Worker break;
2606*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_GET: /* fall through */
2607*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_SET: /* fall through */
2608*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_NEW: /* fall through */
2609*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_CMD_PORT_DEL:
2610*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
2611*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
2612*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_PORT_INDEX])
2613*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
2614*de1e4e89SAndroid Build Coastguard Worker pr_out_mon_header(genl->cmd);
2615*de1e4e89SAndroid Build Coastguard Worker pr_out_port(dl, tb);
2616*de1e4e89SAndroid Build Coastguard Worker break;
2617*de1e4e89SAndroid Build Coastguard Worker }
2618*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
2619*de1e4e89SAndroid Build Coastguard Worker }
2620*de1e4e89SAndroid Build Coastguard Worker
cmd_mon_show(struct dl * dl)2621*de1e4e89SAndroid Build Coastguard Worker static int cmd_mon_show(struct dl *dl)
2622*de1e4e89SAndroid Build Coastguard Worker {
2623*de1e4e89SAndroid Build Coastguard Worker int err;
2624*de1e4e89SAndroid Build Coastguard Worker unsigned int index = 0;
2625*de1e4e89SAndroid Build Coastguard Worker const char *cur_obj;
2626*de1e4e89SAndroid Build Coastguard Worker
2627*de1e4e89SAndroid Build Coastguard Worker while ((cur_obj = dl_argv_index(dl, index++))) {
2628*de1e4e89SAndroid Build Coastguard Worker if (strcmp(cur_obj, "all") != 0 &&
2629*de1e4e89SAndroid Build Coastguard Worker strcmp(cur_obj, "dev") != 0 &&
2630*de1e4e89SAndroid Build Coastguard Worker strcmp(cur_obj, "port") != 0) {
2631*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown object \"%s\"\n", cur_obj);
2632*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
2633*de1e4e89SAndroid Build Coastguard Worker }
2634*de1e4e89SAndroid Build Coastguard Worker }
2635*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_group_add(dl->nlg, DEVLINK_GENL_MCGRP_CONFIG_NAME);
2636*de1e4e89SAndroid Build Coastguard Worker if (err)
2637*de1e4e89SAndroid Build Coastguard Worker return err;
2638*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_recv_run(dl->nlg, cmd_mon_show_cb, dl);
2639*de1e4e89SAndroid Build Coastguard Worker if (err)
2640*de1e4e89SAndroid Build Coastguard Worker return err;
2641*de1e4e89SAndroid Build Coastguard Worker return 0;
2642*de1e4e89SAndroid Build Coastguard Worker }
2643*de1e4e89SAndroid Build Coastguard Worker
cmd_mon_help(void)2644*de1e4e89SAndroid Build Coastguard Worker static void cmd_mon_help(void)
2645*de1e4e89SAndroid Build Coastguard Worker {
2646*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink monitor [ all | OBJECT-LIST ]\n"
2647*de1e4e89SAndroid Build Coastguard Worker "where OBJECT-LIST := { dev | port }\n");
2648*de1e4e89SAndroid Build Coastguard Worker }
2649*de1e4e89SAndroid Build Coastguard Worker
cmd_mon(struct dl * dl)2650*de1e4e89SAndroid Build Coastguard Worker static int cmd_mon(struct dl *dl)
2651*de1e4e89SAndroid Build Coastguard Worker {
2652*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help")) {
2653*de1e4e89SAndroid Build Coastguard Worker cmd_mon_help();
2654*de1e4e89SAndroid Build Coastguard Worker return 0;
2655*de1e4e89SAndroid Build Coastguard Worker } else if (dl_no_arg(dl)) {
2656*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
2657*de1e4e89SAndroid Build Coastguard Worker return cmd_mon_show(dl);
2658*de1e4e89SAndroid Build Coastguard Worker }
2659*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
2660*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
2661*de1e4e89SAndroid Build Coastguard Worker }
2662*de1e4e89SAndroid Build Coastguard Worker
2663*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field {
2664*de1e4e89SAndroid Build Coastguard Worker char *name;
2665*de1e4e89SAndroid Build Coastguard Worker unsigned int id;
2666*de1e4e89SAndroid Build Coastguard Worker unsigned int bitwidth;
2667*de1e4e89SAndroid Build Coastguard Worker enum devlink_dpipe_field_mapping_type mapping_type;
2668*de1e4e89SAndroid Build Coastguard Worker };
2669*de1e4e89SAndroid Build Coastguard Worker
2670*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header {
2671*de1e4e89SAndroid Build Coastguard Worker struct list_head list;
2672*de1e4e89SAndroid Build Coastguard Worker char *name;
2673*de1e4e89SAndroid Build Coastguard Worker unsigned int id;
2674*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field *fields;
2675*de1e4e89SAndroid Build Coastguard Worker unsigned int fields_count;
2676*de1e4e89SAndroid Build Coastguard Worker };
2677*de1e4e89SAndroid Build Coastguard Worker
2678*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx {
2679*de1e4e89SAndroid Build Coastguard Worker struct dl *dl;
2680*de1e4e89SAndroid Build Coastguard Worker int err;
2681*de1e4e89SAndroid Build Coastguard Worker struct list_head global_headers;
2682*de1e4e89SAndroid Build Coastguard Worker struct list_head local_headers;
2683*de1e4e89SAndroid Build Coastguard Worker bool print_headers;
2684*de1e4e89SAndroid Build Coastguard Worker };
2685*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_alloc(unsigned int fields_count)2686*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_header *dpipe_header_alloc(unsigned int fields_count)
2687*de1e4e89SAndroid Build Coastguard Worker {
2688*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header;
2689*de1e4e89SAndroid Build Coastguard Worker
2690*de1e4e89SAndroid Build Coastguard Worker header = calloc(1, sizeof(struct dpipe_header));
2691*de1e4e89SAndroid Build Coastguard Worker if (!header)
2692*de1e4e89SAndroid Build Coastguard Worker return NULL;
2693*de1e4e89SAndroid Build Coastguard Worker header->fields = calloc(fields_count, sizeof(struct dpipe_field));
2694*de1e4e89SAndroid Build Coastguard Worker if (!header->fields)
2695*de1e4e89SAndroid Build Coastguard Worker goto err_fields_alloc;
2696*de1e4e89SAndroid Build Coastguard Worker header->fields_count = fields_count;
2697*de1e4e89SAndroid Build Coastguard Worker return header;
2698*de1e4e89SAndroid Build Coastguard Worker
2699*de1e4e89SAndroid Build Coastguard Worker err_fields_alloc:
2700*de1e4e89SAndroid Build Coastguard Worker free(header);
2701*de1e4e89SAndroid Build Coastguard Worker return NULL;
2702*de1e4e89SAndroid Build Coastguard Worker }
2703*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_free(struct dpipe_header * header)2704*de1e4e89SAndroid Build Coastguard Worker static void dpipe_header_free(struct dpipe_header *header)
2705*de1e4e89SAndroid Build Coastguard Worker {
2706*de1e4e89SAndroid Build Coastguard Worker free(header->fields);
2707*de1e4e89SAndroid Build Coastguard Worker free(header);
2708*de1e4e89SAndroid Build Coastguard Worker }
2709*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_clear(struct dpipe_header * header)2710*de1e4e89SAndroid Build Coastguard Worker static void dpipe_header_clear(struct dpipe_header *header)
2711*de1e4e89SAndroid Build Coastguard Worker {
2712*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field *field;
2713*de1e4e89SAndroid Build Coastguard Worker int i;
2714*de1e4e89SAndroid Build Coastguard Worker
2715*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < header->fields_count; i++) {
2716*de1e4e89SAndroid Build Coastguard Worker field = &header->fields[i];
2717*de1e4e89SAndroid Build Coastguard Worker free(field->name);
2718*de1e4e89SAndroid Build Coastguard Worker }
2719*de1e4e89SAndroid Build Coastguard Worker free(header->name);
2720*de1e4e89SAndroid Build Coastguard Worker }
2721*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_add(struct dpipe_ctx * ctx,struct dpipe_header * header,bool global)2722*de1e4e89SAndroid Build Coastguard Worker static void dpipe_header_add(struct dpipe_ctx *ctx,
2723*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header, bool global)
2724*de1e4e89SAndroid Build Coastguard Worker {
2725*de1e4e89SAndroid Build Coastguard Worker if (global)
2726*de1e4e89SAndroid Build Coastguard Worker list_add(&header->list, &ctx->global_headers);
2727*de1e4e89SAndroid Build Coastguard Worker else
2728*de1e4e89SAndroid Build Coastguard Worker list_add(&header->list, &ctx->local_headers);
2729*de1e4e89SAndroid Build Coastguard Worker }
2730*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_del(struct dpipe_header * header)2731*de1e4e89SAndroid Build Coastguard Worker static void dpipe_header_del(struct dpipe_header *header)
2732*de1e4e89SAndroid Build Coastguard Worker {
2733*de1e4e89SAndroid Build Coastguard Worker list_del(&header->list);
2734*de1e4e89SAndroid Build Coastguard Worker }
2735*de1e4e89SAndroid Build Coastguard Worker
dpipe_ctx_alloc(struct dl * dl)2736*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_ctx *dpipe_ctx_alloc(struct dl *dl)
2737*de1e4e89SAndroid Build Coastguard Worker {
2738*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx;
2739*de1e4e89SAndroid Build Coastguard Worker
2740*de1e4e89SAndroid Build Coastguard Worker ctx = calloc(1, sizeof(struct dpipe_ctx));
2741*de1e4e89SAndroid Build Coastguard Worker if (!ctx)
2742*de1e4e89SAndroid Build Coastguard Worker return NULL;
2743*de1e4e89SAndroid Build Coastguard Worker ctx->dl = dl;
2744*de1e4e89SAndroid Build Coastguard Worker INIT_LIST_HEAD(&ctx->global_headers);
2745*de1e4e89SAndroid Build Coastguard Worker INIT_LIST_HEAD(&ctx->local_headers);
2746*de1e4e89SAndroid Build Coastguard Worker return ctx;
2747*de1e4e89SAndroid Build Coastguard Worker }
2748*de1e4e89SAndroid Build Coastguard Worker
dpipe_ctx_free(struct dpipe_ctx * ctx)2749*de1e4e89SAndroid Build Coastguard Worker static void dpipe_ctx_free(struct dpipe_ctx *ctx)
2750*de1e4e89SAndroid Build Coastguard Worker {
2751*de1e4e89SAndroid Build Coastguard Worker free(ctx);
2752*de1e4e89SAndroid Build Coastguard Worker }
2753*de1e4e89SAndroid Build Coastguard Worker
dpipe_ctx_clear(struct dpipe_ctx * ctx)2754*de1e4e89SAndroid Build Coastguard Worker static void dpipe_ctx_clear(struct dpipe_ctx *ctx)
2755*de1e4e89SAndroid Build Coastguard Worker {
2756*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header, *tmp;
2757*de1e4e89SAndroid Build Coastguard Worker
2758*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_safe(header, tmp, &ctx->global_headers,
2759*de1e4e89SAndroid Build Coastguard Worker list) {
2760*de1e4e89SAndroid Build Coastguard Worker dpipe_header_del(header);
2761*de1e4e89SAndroid Build Coastguard Worker dpipe_header_clear(header);
2762*de1e4e89SAndroid Build Coastguard Worker dpipe_header_free(header);
2763*de1e4e89SAndroid Build Coastguard Worker }
2764*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry_safe(header, tmp, &ctx->local_headers,
2765*de1e4e89SAndroid Build Coastguard Worker list) {
2766*de1e4e89SAndroid Build Coastguard Worker dpipe_header_del(header);
2767*de1e4e89SAndroid Build Coastguard Worker dpipe_header_clear(header);
2768*de1e4e89SAndroid Build Coastguard Worker dpipe_header_free(header);
2769*de1e4e89SAndroid Build Coastguard Worker }
2770*de1e4e89SAndroid Build Coastguard Worker }
2771*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_id2s(struct dpipe_ctx * ctx,uint32_t header_id,bool global)2772*de1e4e89SAndroid Build Coastguard Worker static const char *dpipe_header_id2s(struct dpipe_ctx *ctx,
2773*de1e4e89SAndroid Build Coastguard Worker uint32_t header_id, bool global)
2774*de1e4e89SAndroid Build Coastguard Worker {
2775*de1e4e89SAndroid Build Coastguard Worker struct list_head *header_list;
2776*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header;
2777*de1e4e89SAndroid Build Coastguard Worker
2778*de1e4e89SAndroid Build Coastguard Worker if (global)
2779*de1e4e89SAndroid Build Coastguard Worker header_list = &ctx->global_headers;
2780*de1e4e89SAndroid Build Coastguard Worker else
2781*de1e4e89SAndroid Build Coastguard Worker header_list = &ctx->local_headers;
2782*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(header, header_list, list) {
2783*de1e4e89SAndroid Build Coastguard Worker if (header->id != header_id)
2784*de1e4e89SAndroid Build Coastguard Worker continue;
2785*de1e4e89SAndroid Build Coastguard Worker return header->name;
2786*de1e4e89SAndroid Build Coastguard Worker }
2787*de1e4e89SAndroid Build Coastguard Worker return NULL;
2788*de1e4e89SAndroid Build Coastguard Worker }
2789*de1e4e89SAndroid Build Coastguard Worker
dpipe_field_id2s(struct dpipe_ctx * ctx,uint32_t header_id,uint32_t field_id,bool global)2790*de1e4e89SAndroid Build Coastguard Worker static const char *dpipe_field_id2s(struct dpipe_ctx *ctx,
2791*de1e4e89SAndroid Build Coastguard Worker uint32_t header_id,
2792*de1e4e89SAndroid Build Coastguard Worker uint32_t field_id, bool global)
2793*de1e4e89SAndroid Build Coastguard Worker {
2794*de1e4e89SAndroid Build Coastguard Worker struct list_head *header_list;
2795*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header;
2796*de1e4e89SAndroid Build Coastguard Worker
2797*de1e4e89SAndroid Build Coastguard Worker if (global)
2798*de1e4e89SAndroid Build Coastguard Worker header_list = &ctx->global_headers;
2799*de1e4e89SAndroid Build Coastguard Worker else
2800*de1e4e89SAndroid Build Coastguard Worker header_list = &ctx->local_headers;
2801*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(header, header_list, list) {
2802*de1e4e89SAndroid Build Coastguard Worker if (header->id != header_id)
2803*de1e4e89SAndroid Build Coastguard Worker continue;
2804*de1e4e89SAndroid Build Coastguard Worker return header->fields[field_id].name;
2805*de1e4e89SAndroid Build Coastguard Worker }
2806*de1e4e89SAndroid Build Coastguard Worker return NULL;
2807*de1e4e89SAndroid Build Coastguard Worker }
2808*de1e4e89SAndroid Build Coastguard Worker
2809*de1e4e89SAndroid Build Coastguard Worker static const char *
dpipe_field_mapping_e2s(enum devlink_dpipe_field_mapping_type mapping_type)2810*de1e4e89SAndroid Build Coastguard Worker dpipe_field_mapping_e2s(enum devlink_dpipe_field_mapping_type mapping_type)
2811*de1e4e89SAndroid Build Coastguard Worker {
2812*de1e4e89SAndroid Build Coastguard Worker switch (mapping_type) {
2813*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE:
2814*de1e4e89SAndroid Build Coastguard Worker return NULL;
2815*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX:
2816*de1e4e89SAndroid Build Coastguard Worker return "ifindex";
2817*de1e4e89SAndroid Build Coastguard Worker default:
2818*de1e4e89SAndroid Build Coastguard Worker return "<unknown>";
2819*de1e4e89SAndroid Build Coastguard Worker }
2820*de1e4e89SAndroid Build Coastguard Worker }
2821*de1e4e89SAndroid Build Coastguard Worker
2822*de1e4e89SAndroid Build Coastguard Worker static const char *
dpipe_mapping_get(struct dpipe_ctx * ctx,uint32_t header_id,uint32_t field_id,bool global)2823*de1e4e89SAndroid Build Coastguard Worker dpipe_mapping_get(struct dpipe_ctx *ctx, uint32_t header_id,
2824*de1e4e89SAndroid Build Coastguard Worker uint32_t field_id, bool global)
2825*de1e4e89SAndroid Build Coastguard Worker {
2826*de1e4e89SAndroid Build Coastguard Worker enum devlink_dpipe_field_mapping_type mapping_type;
2827*de1e4e89SAndroid Build Coastguard Worker struct list_head *header_list;
2828*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header;
2829*de1e4e89SAndroid Build Coastguard Worker
2830*de1e4e89SAndroid Build Coastguard Worker if (global)
2831*de1e4e89SAndroid Build Coastguard Worker header_list = &ctx->global_headers;
2832*de1e4e89SAndroid Build Coastguard Worker else
2833*de1e4e89SAndroid Build Coastguard Worker header_list = &ctx->local_headers;
2834*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(header, header_list, list) {
2835*de1e4e89SAndroid Build Coastguard Worker if (header->id != header_id)
2836*de1e4e89SAndroid Build Coastguard Worker continue;
2837*de1e4e89SAndroid Build Coastguard Worker mapping_type = header->fields[field_id].mapping_type;
2838*de1e4e89SAndroid Build Coastguard Worker return dpipe_field_mapping_e2s(mapping_type);
2839*de1e4e89SAndroid Build Coastguard Worker }
2840*de1e4e89SAndroid Build Coastguard Worker return NULL;
2841*de1e4e89SAndroid Build Coastguard Worker }
2842*de1e4e89SAndroid Build Coastguard Worker
pr_out_dpipe_fields(struct dpipe_ctx * ctx,struct dpipe_field * fields,unsigned int field_count)2843*de1e4e89SAndroid Build Coastguard Worker static void pr_out_dpipe_fields(struct dpipe_ctx *ctx,
2844*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field *fields,
2845*de1e4e89SAndroid Build Coastguard Worker unsigned int field_count)
2846*de1e4e89SAndroid Build Coastguard Worker {
2847*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field *field;
2848*de1e4e89SAndroid Build Coastguard Worker int i;
2849*de1e4e89SAndroid Build Coastguard Worker
2850*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < field_count; i++) {
2851*de1e4e89SAndroid Build Coastguard Worker field = &fields[i];
2852*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_start(ctx->dl);
2853*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "name", field->name);
2854*de1e4e89SAndroid Build Coastguard Worker if (ctx->dl->verbose)
2855*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, "id", field->id);
2856*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, "bitwidth", field->bitwidth);
2857*de1e4e89SAndroid Build Coastguard Worker if (field->mapping_type)
2858*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "mapping_type",
2859*de1e4e89SAndroid Build Coastguard Worker dpipe_field_mapping_e2s(field->mapping_type));
2860*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
2861*de1e4e89SAndroid Build Coastguard Worker }
2862*de1e4e89SAndroid Build Coastguard Worker }
2863*de1e4e89SAndroid Build Coastguard Worker
2864*de1e4e89SAndroid Build Coastguard Worker static void
pr_out_dpipe_header(struct dpipe_ctx * ctx,struct nlattr ** tb,struct dpipe_header * header,bool global)2865*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_header(struct dpipe_ctx *ctx, struct nlattr **tb,
2866*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header, bool global)
2867*de1e4e89SAndroid Build Coastguard Worker {
2868*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_start_arr(ctx->dl, tb);
2869*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "name", header->name);
2870*de1e4e89SAndroid Build Coastguard Worker if (ctx->dl->verbose) {
2871*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, "id", header->id);
2872*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "global",
2873*de1e4e89SAndroid Build Coastguard Worker global ? "true" : "false");
2874*de1e4e89SAndroid Build Coastguard Worker }
2875*de1e4e89SAndroid Build Coastguard Worker pr_out_array_start(ctx->dl, "field");
2876*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_fields(ctx, header->fields,
2877*de1e4e89SAndroid Build Coastguard Worker header->fields_count);
2878*de1e4e89SAndroid Build Coastguard Worker pr_out_array_end(ctx->dl);
2879*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(ctx->dl);
2880*de1e4e89SAndroid Build Coastguard Worker }
2881*de1e4e89SAndroid Build Coastguard Worker
pr_out_dpipe_headers(struct dpipe_ctx * ctx,struct nlattr ** tb)2882*de1e4e89SAndroid Build Coastguard Worker static void pr_out_dpipe_headers(struct dpipe_ctx *ctx,
2883*de1e4e89SAndroid Build Coastguard Worker struct nlattr **tb)
2884*de1e4e89SAndroid Build Coastguard Worker {
2885*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header;
2886*de1e4e89SAndroid Build Coastguard Worker
2887*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(header, &ctx->local_headers, list)
2888*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_header(ctx, tb, header, false);
2889*de1e4e89SAndroid Build Coastguard Worker
2890*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(header, &ctx->global_headers, list)
2891*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_header(ctx, tb, header, true);
2892*de1e4e89SAndroid Build Coastguard Worker }
2893*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_field_get(struct nlattr * nl,struct dpipe_field * field)2894*de1e4e89SAndroid Build Coastguard Worker static int dpipe_header_field_get(struct nlattr *nl, struct dpipe_field *field)
2895*de1e4e89SAndroid Build Coastguard Worker {
2896*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_field[DEVLINK_ATTR_MAX + 1] = {};
2897*de1e4e89SAndroid Build Coastguard Worker const char *name;
2898*de1e4e89SAndroid Build Coastguard Worker int err;
2899*de1e4e89SAndroid Build Coastguard Worker
2900*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_field);
2901*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
2902*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
2903*de1e4e89SAndroid Build Coastguard Worker if (!nla_field[DEVLINK_ATTR_DPIPE_FIELD_ID] ||
2904*de1e4e89SAndroid Build Coastguard Worker !nla_field[DEVLINK_ATTR_DPIPE_FIELD_NAME] ||
2905*de1e4e89SAndroid Build Coastguard Worker !nla_field[DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] ||
2906*de1e4e89SAndroid Build Coastguard Worker !nla_field[DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE])
2907*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
2908*de1e4e89SAndroid Build Coastguard Worker
2909*de1e4e89SAndroid Build Coastguard Worker name = mnl_attr_get_str(nla_field[DEVLINK_ATTR_DPIPE_FIELD_NAME]);
2910*de1e4e89SAndroid Build Coastguard Worker field->id = mnl_attr_get_u32(nla_field[DEVLINK_ATTR_DPIPE_FIELD_ID]);
2911*de1e4e89SAndroid Build Coastguard Worker field->bitwidth = mnl_attr_get_u32(nla_field[DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH]);
2912*de1e4e89SAndroid Build Coastguard Worker field->name = strdup(name);
2913*de1e4e89SAndroid Build Coastguard Worker if (!field->name)
2914*de1e4e89SAndroid Build Coastguard Worker return -ENOMEM;
2915*de1e4e89SAndroid Build Coastguard Worker field->mapping_type = mnl_attr_get_u32(nla_field[DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE]);
2916*de1e4e89SAndroid Build Coastguard Worker return 0;
2917*de1e4e89SAndroid Build Coastguard Worker }
2918*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_fields_get(struct nlattr * nla_fields,struct dpipe_field * fields)2919*de1e4e89SAndroid Build Coastguard Worker static int dpipe_header_fields_get(struct nlattr *nla_fields,
2920*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field *fields)
2921*de1e4e89SAndroid Build Coastguard Worker {
2922*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_field;
2923*de1e4e89SAndroid Build Coastguard Worker int count = 0;
2924*de1e4e89SAndroid Build Coastguard Worker int err;
2925*de1e4e89SAndroid Build Coastguard Worker
2926*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_field, nla_fields) {
2927*de1e4e89SAndroid Build Coastguard Worker err = dpipe_header_field_get(nla_field, &fields[count]);
2928*de1e4e89SAndroid Build Coastguard Worker if (err)
2929*de1e4e89SAndroid Build Coastguard Worker return err;
2930*de1e4e89SAndroid Build Coastguard Worker count++;
2931*de1e4e89SAndroid Build Coastguard Worker }
2932*de1e4e89SAndroid Build Coastguard Worker return 0;
2933*de1e4e89SAndroid Build Coastguard Worker }
2934*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_field_count_get(struct nlattr * nla_fields)2935*de1e4e89SAndroid Build Coastguard Worker static unsigned int dpipe_header_field_count_get(struct nlattr *nla_fields)
2936*de1e4e89SAndroid Build Coastguard Worker {
2937*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_field;
2938*de1e4e89SAndroid Build Coastguard Worker unsigned int count = 0;
2939*de1e4e89SAndroid Build Coastguard Worker
2940*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_field, nla_fields)
2941*de1e4e89SAndroid Build Coastguard Worker count++;
2942*de1e4e89SAndroid Build Coastguard Worker return count;
2943*de1e4e89SAndroid Build Coastguard Worker }
2944*de1e4e89SAndroid Build Coastguard Worker
dpipe_header_get(struct dpipe_ctx * ctx,struct nlattr * nl)2945*de1e4e89SAndroid Build Coastguard Worker static int dpipe_header_get(struct dpipe_ctx *ctx, struct nlattr *nl)
2946*de1e4e89SAndroid Build Coastguard Worker {
2947*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_header[DEVLINK_ATTR_MAX + 1] = {};
2948*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header *header;
2949*de1e4e89SAndroid Build Coastguard Worker unsigned int fields_count;
2950*de1e4e89SAndroid Build Coastguard Worker const char *header_name;
2951*de1e4e89SAndroid Build Coastguard Worker bool global;
2952*de1e4e89SAndroid Build Coastguard Worker int err;
2953*de1e4e89SAndroid Build Coastguard Worker
2954*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_header);
2955*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
2956*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
2957*de1e4e89SAndroid Build Coastguard Worker
2958*de1e4e89SAndroid Build Coastguard Worker if (!nla_header[DEVLINK_ATTR_DPIPE_HEADER_NAME] ||
2959*de1e4e89SAndroid Build Coastguard Worker !nla_header[DEVLINK_ATTR_DPIPE_HEADER_ID] ||
2960*de1e4e89SAndroid Build Coastguard Worker !nla_header[DEVLINK_ATTR_DPIPE_HEADER_FIELDS])
2961*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
2962*de1e4e89SAndroid Build Coastguard Worker
2963*de1e4e89SAndroid Build Coastguard Worker fields_count = dpipe_header_field_count_get(nla_header[DEVLINK_ATTR_DPIPE_HEADER_FIELDS]);
2964*de1e4e89SAndroid Build Coastguard Worker header = dpipe_header_alloc(fields_count);
2965*de1e4e89SAndroid Build Coastguard Worker if (!header)
2966*de1e4e89SAndroid Build Coastguard Worker return -ENOMEM;
2967*de1e4e89SAndroid Build Coastguard Worker
2968*de1e4e89SAndroid Build Coastguard Worker header_name = mnl_attr_get_str(nla_header[DEVLINK_ATTR_DPIPE_HEADER_NAME]);
2969*de1e4e89SAndroid Build Coastguard Worker header->name = strdup(header_name);
2970*de1e4e89SAndroid Build Coastguard Worker header->id = mnl_attr_get_u32(nla_header[DEVLINK_ATTR_DPIPE_HEADER_ID]);
2971*de1e4e89SAndroid Build Coastguard Worker header->fields_count = fields_count;
2972*de1e4e89SAndroid Build Coastguard Worker global = !!mnl_attr_get_u8(nla_header[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]);
2973*de1e4e89SAndroid Build Coastguard Worker
2974*de1e4e89SAndroid Build Coastguard Worker err = dpipe_header_fields_get(nla_header[DEVLINK_ATTR_DPIPE_HEADER_FIELDS],
2975*de1e4e89SAndroid Build Coastguard Worker header->fields);
2976*de1e4e89SAndroid Build Coastguard Worker if (err)
2977*de1e4e89SAndroid Build Coastguard Worker goto err_field_get;
2978*de1e4e89SAndroid Build Coastguard Worker dpipe_header_add(ctx, header, global);
2979*de1e4e89SAndroid Build Coastguard Worker return 0;
2980*de1e4e89SAndroid Build Coastguard Worker
2981*de1e4e89SAndroid Build Coastguard Worker err_field_get:
2982*de1e4e89SAndroid Build Coastguard Worker dpipe_header_free(header);
2983*de1e4e89SAndroid Build Coastguard Worker return err;
2984*de1e4e89SAndroid Build Coastguard Worker }
2985*de1e4e89SAndroid Build Coastguard Worker
dpipe_headers_get(struct dpipe_ctx * ctx,struct nlattr ** tb)2986*de1e4e89SAndroid Build Coastguard Worker static int dpipe_headers_get(struct dpipe_ctx *ctx, struct nlattr **tb)
2987*de1e4e89SAndroid Build Coastguard Worker {
2988*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_headers = tb[DEVLINK_ATTR_DPIPE_HEADERS];
2989*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_header;
2990*de1e4e89SAndroid Build Coastguard Worker int err;
2991*de1e4e89SAndroid Build Coastguard Worker
2992*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_header, nla_headers) {
2993*de1e4e89SAndroid Build Coastguard Worker err = dpipe_header_get(ctx, nla_header);
2994*de1e4e89SAndroid Build Coastguard Worker if (err)
2995*de1e4e89SAndroid Build Coastguard Worker return err;
2996*de1e4e89SAndroid Build Coastguard Worker }
2997*de1e4e89SAndroid Build Coastguard Worker return 0;
2998*de1e4e89SAndroid Build Coastguard Worker }
2999*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_header_cb(const struct nlmsghdr * nlh,void * data)3000*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_header_cb(const struct nlmsghdr *nlh, void *data)
3001*de1e4e89SAndroid Build Coastguard Worker {
3002*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx = data;
3003*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
3004*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
3005*de1e4e89SAndroid Build Coastguard Worker int err;
3006*de1e4e89SAndroid Build Coastguard Worker
3007*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
3008*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
3009*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_DPIPE_HEADERS])
3010*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
3011*de1e4e89SAndroid Build Coastguard Worker err = dpipe_headers_get(ctx, tb);
3012*de1e4e89SAndroid Build Coastguard Worker if (err) {
3013*de1e4e89SAndroid Build Coastguard Worker ctx->err = err;
3014*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
3015*de1e4e89SAndroid Build Coastguard Worker }
3016*de1e4e89SAndroid Build Coastguard Worker
3017*de1e4e89SAndroid Build Coastguard Worker if (ctx->print_headers)
3018*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_headers(ctx, tb);
3019*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
3020*de1e4e89SAndroid Build Coastguard Worker }
3021*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_headers_show(struct dl * dl)3022*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_headers_show(struct dl *dl)
3023*de1e4e89SAndroid Build Coastguard Worker {
3024*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
3025*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx;
3026*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
3027*de1e4e89SAndroid Build Coastguard Worker int err;
3028*de1e4e89SAndroid Build Coastguard Worker
3029*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_HEADERS_GET, flags);
3030*de1e4e89SAndroid Build Coastguard Worker
3031*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE, 0);
3032*de1e4e89SAndroid Build Coastguard Worker if (err)
3033*de1e4e89SAndroid Build Coastguard Worker return err;
3034*de1e4e89SAndroid Build Coastguard Worker
3035*de1e4e89SAndroid Build Coastguard Worker ctx = dpipe_ctx_alloc(dl);
3036*de1e4e89SAndroid Build Coastguard Worker if (!ctx)
3037*de1e4e89SAndroid Build Coastguard Worker return -ENOMEM;
3038*de1e4e89SAndroid Build Coastguard Worker
3039*de1e4e89SAndroid Build Coastguard Worker ctx->print_headers = true;
3040*de1e4e89SAndroid Build Coastguard Worker
3041*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "header");
3042*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_header_cb, ctx);
3043*de1e4e89SAndroid Build Coastguard Worker if (err)
3044*de1e4e89SAndroid Build Coastguard Worker pr_err("error get headers %s\n", strerror(ctx->err));
3045*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
3046*de1e4e89SAndroid Build Coastguard Worker
3047*de1e4e89SAndroid Build Coastguard Worker dpipe_ctx_clear(ctx);
3048*de1e4e89SAndroid Build Coastguard Worker dpipe_ctx_free(ctx);
3049*de1e4e89SAndroid Build Coastguard Worker return err;
3050*de1e4e89SAndroid Build Coastguard Worker }
3051*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_header_help(void)3052*de1e4e89SAndroid Build Coastguard Worker static void cmd_dpipe_header_help(void)
3053*de1e4e89SAndroid Build Coastguard Worker {
3054*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink dpipe headers show DEV\n");
3055*de1e4e89SAndroid Build Coastguard Worker }
3056*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_header(struct dl * dl)3057*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_header(struct dl *dl)
3058*de1e4e89SAndroid Build Coastguard Worker {
3059*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
3060*de1e4e89SAndroid Build Coastguard Worker cmd_dpipe_header_help();
3061*de1e4e89SAndroid Build Coastguard Worker return 0;
3062*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show")) {
3063*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3064*de1e4e89SAndroid Build Coastguard Worker return cmd_dpipe_headers_show(dl);
3065*de1e4e89SAndroid Build Coastguard Worker }
3066*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
3067*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
3068*de1e4e89SAndroid Build Coastguard Worker }
3069*de1e4e89SAndroid Build Coastguard Worker
3070*de1e4e89SAndroid Build Coastguard Worker static const char
dpipe_action_type_e2s(enum devlink_dpipe_action_type action_type)3071*de1e4e89SAndroid Build Coastguard Worker *dpipe_action_type_e2s(enum devlink_dpipe_action_type action_type)
3072*de1e4e89SAndroid Build Coastguard Worker {
3073*de1e4e89SAndroid Build Coastguard Worker switch (action_type) {
3074*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY:
3075*de1e4e89SAndroid Build Coastguard Worker return "field_modify";
3076*de1e4e89SAndroid Build Coastguard Worker default:
3077*de1e4e89SAndroid Build Coastguard Worker return "<unknown>";
3078*de1e4e89SAndroid Build Coastguard Worker }
3079*de1e4e89SAndroid Build Coastguard Worker }
3080*de1e4e89SAndroid Build Coastguard Worker
3081*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info {
3082*de1e4e89SAndroid Build Coastguard Worker uint32_t header_id;
3083*de1e4e89SAndroid Build Coastguard Worker uint32_t field_id;
3084*de1e4e89SAndroid Build Coastguard Worker bool header_global;
3085*de1e4e89SAndroid Build Coastguard Worker };
3086*de1e4e89SAndroid Build Coastguard Worker
3087*de1e4e89SAndroid Build Coastguard Worker struct dpipe_action {
3088*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info info;
3089*de1e4e89SAndroid Build Coastguard Worker uint32_t type;
3090*de1e4e89SAndroid Build Coastguard Worker };
3091*de1e4e89SAndroid Build Coastguard Worker
pr_out_dpipe_action(struct dpipe_action * action,struct dpipe_ctx * ctx)3092*de1e4e89SAndroid Build Coastguard Worker static void pr_out_dpipe_action(struct dpipe_action *action,
3093*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx)
3094*de1e4e89SAndroid Build Coastguard Worker {
3095*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info *op_info = &action->info;
3096*de1e4e89SAndroid Build Coastguard Worker const char *mapping;
3097*de1e4e89SAndroid Build Coastguard Worker
3098*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "type",
3099*de1e4e89SAndroid Build Coastguard Worker dpipe_action_type_e2s(action->type));
3100*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "header",
3101*de1e4e89SAndroid Build Coastguard Worker dpipe_header_id2s(ctx, op_info->header_id,
3102*de1e4e89SAndroid Build Coastguard Worker op_info->header_global));
3103*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "field",
3104*de1e4e89SAndroid Build Coastguard Worker dpipe_field_id2s(ctx, op_info->header_id,
3105*de1e4e89SAndroid Build Coastguard Worker op_info->field_id,
3106*de1e4e89SAndroid Build Coastguard Worker op_info->header_global));
3107*de1e4e89SAndroid Build Coastguard Worker mapping = dpipe_mapping_get(ctx, op_info->header_id,
3108*de1e4e89SAndroid Build Coastguard Worker op_info->field_id,
3109*de1e4e89SAndroid Build Coastguard Worker op_info->header_global);
3110*de1e4e89SAndroid Build Coastguard Worker if (mapping)
3111*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "mapping", mapping);
3112*de1e4e89SAndroid Build Coastguard Worker }
3113*de1e4e89SAndroid Build Coastguard Worker
dpipe_action_parse(struct dpipe_action * action,struct nlattr * nl)3114*de1e4e89SAndroid Build Coastguard Worker static int dpipe_action_parse(struct dpipe_action *action, struct nlattr *nl)
3115*de1e4e89SAndroid Build Coastguard Worker {
3116*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_action[DEVLINK_ATTR_MAX + 1] = {};
3117*de1e4e89SAndroid Build Coastguard Worker int err;
3118*de1e4e89SAndroid Build Coastguard Worker
3119*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_action);
3120*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
3121*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3122*de1e4e89SAndroid Build Coastguard Worker
3123*de1e4e89SAndroid Build Coastguard Worker if (!nla_action[DEVLINK_ATTR_DPIPE_ACTION_TYPE] ||
3124*de1e4e89SAndroid Build Coastguard Worker !nla_action[DEVLINK_ATTR_DPIPE_HEADER_INDEX] ||
3125*de1e4e89SAndroid Build Coastguard Worker !nla_action[DEVLINK_ATTR_DPIPE_HEADER_ID] ||
3126*de1e4e89SAndroid Build Coastguard Worker !nla_action[DEVLINK_ATTR_DPIPE_FIELD_ID]) {
3127*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3128*de1e4e89SAndroid Build Coastguard Worker }
3129*de1e4e89SAndroid Build Coastguard Worker
3130*de1e4e89SAndroid Build Coastguard Worker action->type = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_ACTION_TYPE]);
3131*de1e4e89SAndroid Build Coastguard Worker action->info.header_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_HEADER_ID]);
3132*de1e4e89SAndroid Build Coastguard Worker action->info.field_id = mnl_attr_get_u32(nla_action[DEVLINK_ATTR_DPIPE_FIELD_ID]);
3133*de1e4e89SAndroid Build Coastguard Worker action->info.header_global = !!mnl_attr_get_u8(nla_action[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]);
3134*de1e4e89SAndroid Build Coastguard Worker
3135*de1e4e89SAndroid Build Coastguard Worker return 0;
3136*de1e4e89SAndroid Build Coastguard Worker }
3137*de1e4e89SAndroid Build Coastguard Worker
dpipe_table_actions_show(struct dpipe_ctx * ctx,struct nlattr * nla_actions)3138*de1e4e89SAndroid Build Coastguard Worker static int dpipe_table_actions_show(struct dpipe_ctx *ctx,
3139*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_actions)
3140*de1e4e89SAndroid Build Coastguard Worker {
3141*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_action;
3142*de1e4e89SAndroid Build Coastguard Worker struct dpipe_action action;
3143*de1e4e89SAndroid Build Coastguard Worker
3144*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_action, nla_actions) {
3145*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_start(ctx->dl);
3146*de1e4e89SAndroid Build Coastguard Worker if (dpipe_action_parse(&action, nla_action))
3147*de1e4e89SAndroid Build Coastguard Worker goto err_action_parse;
3148*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_action(&action, ctx);
3149*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3150*de1e4e89SAndroid Build Coastguard Worker }
3151*de1e4e89SAndroid Build Coastguard Worker return 0;
3152*de1e4e89SAndroid Build Coastguard Worker
3153*de1e4e89SAndroid Build Coastguard Worker err_action_parse:
3154*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3155*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3156*de1e4e89SAndroid Build Coastguard Worker }
3157*de1e4e89SAndroid Build Coastguard Worker
3158*de1e4e89SAndroid Build Coastguard Worker static const char *
dpipe_match_type_e2s(enum devlink_dpipe_match_type match_type)3159*de1e4e89SAndroid Build Coastguard Worker dpipe_match_type_e2s(enum devlink_dpipe_match_type match_type)
3160*de1e4e89SAndroid Build Coastguard Worker {
3161*de1e4e89SAndroid Build Coastguard Worker switch (match_type) {
3162*de1e4e89SAndroid Build Coastguard Worker case DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT:
3163*de1e4e89SAndroid Build Coastguard Worker return "field_exact";
3164*de1e4e89SAndroid Build Coastguard Worker default:
3165*de1e4e89SAndroid Build Coastguard Worker return "<unknown>";
3166*de1e4e89SAndroid Build Coastguard Worker }
3167*de1e4e89SAndroid Build Coastguard Worker }
3168*de1e4e89SAndroid Build Coastguard Worker
3169*de1e4e89SAndroid Build Coastguard Worker struct dpipe_match {
3170*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info info;
3171*de1e4e89SAndroid Build Coastguard Worker uint32_t type;
3172*de1e4e89SAndroid Build Coastguard Worker };
3173*de1e4e89SAndroid Build Coastguard Worker
pr_out_dpipe_match(struct dpipe_match * match,struct dpipe_ctx * ctx)3174*de1e4e89SAndroid Build Coastguard Worker static void pr_out_dpipe_match(struct dpipe_match *match,
3175*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx)
3176*de1e4e89SAndroid Build Coastguard Worker {
3177*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info *op_info = &match->info;
3178*de1e4e89SAndroid Build Coastguard Worker const char *mapping;
3179*de1e4e89SAndroid Build Coastguard Worker
3180*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "type",
3181*de1e4e89SAndroid Build Coastguard Worker dpipe_match_type_e2s(match->type));
3182*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "header",
3183*de1e4e89SAndroid Build Coastguard Worker dpipe_header_id2s(ctx, op_info->header_id,
3184*de1e4e89SAndroid Build Coastguard Worker op_info->header_global));
3185*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "field",
3186*de1e4e89SAndroid Build Coastguard Worker dpipe_field_id2s(ctx, op_info->header_id,
3187*de1e4e89SAndroid Build Coastguard Worker op_info->field_id,
3188*de1e4e89SAndroid Build Coastguard Worker op_info->header_global));
3189*de1e4e89SAndroid Build Coastguard Worker mapping = dpipe_mapping_get(ctx, op_info->header_id,
3190*de1e4e89SAndroid Build Coastguard Worker op_info->field_id,
3191*de1e4e89SAndroid Build Coastguard Worker op_info->header_global);
3192*de1e4e89SAndroid Build Coastguard Worker if (mapping)
3193*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "mapping", mapping);
3194*de1e4e89SAndroid Build Coastguard Worker }
3195*de1e4e89SAndroid Build Coastguard Worker
dpipe_match_parse(struct dpipe_match * match,struct nlattr * nl)3196*de1e4e89SAndroid Build Coastguard Worker static int dpipe_match_parse(struct dpipe_match *match,
3197*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nl)
3198*de1e4e89SAndroid Build Coastguard Worker
3199*de1e4e89SAndroid Build Coastguard Worker {
3200*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_match[DEVLINK_ATTR_MAX + 1] = {};
3201*de1e4e89SAndroid Build Coastguard Worker int err;
3202*de1e4e89SAndroid Build Coastguard Worker
3203*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_match);
3204*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
3205*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3206*de1e4e89SAndroid Build Coastguard Worker
3207*de1e4e89SAndroid Build Coastguard Worker if (!nla_match[DEVLINK_ATTR_DPIPE_MATCH_TYPE] ||
3208*de1e4e89SAndroid Build Coastguard Worker !nla_match[DEVLINK_ATTR_DPIPE_HEADER_INDEX] ||
3209*de1e4e89SAndroid Build Coastguard Worker !nla_match[DEVLINK_ATTR_DPIPE_HEADER_ID] ||
3210*de1e4e89SAndroid Build Coastguard Worker !nla_match[DEVLINK_ATTR_DPIPE_FIELD_ID]) {
3211*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3212*de1e4e89SAndroid Build Coastguard Worker }
3213*de1e4e89SAndroid Build Coastguard Worker
3214*de1e4e89SAndroid Build Coastguard Worker match->type = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_MATCH_TYPE]);
3215*de1e4e89SAndroid Build Coastguard Worker match->info.header_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_HEADER_ID]);
3216*de1e4e89SAndroid Build Coastguard Worker match->info.field_id = mnl_attr_get_u32(nla_match[DEVLINK_ATTR_DPIPE_FIELD_ID]);
3217*de1e4e89SAndroid Build Coastguard Worker match->info.header_global = !!mnl_attr_get_u8(nla_match[DEVLINK_ATTR_DPIPE_HEADER_GLOBAL]);
3218*de1e4e89SAndroid Build Coastguard Worker
3219*de1e4e89SAndroid Build Coastguard Worker return 0;
3220*de1e4e89SAndroid Build Coastguard Worker }
3221*de1e4e89SAndroid Build Coastguard Worker
dpipe_table_matches_show(struct dpipe_ctx * ctx,struct nlattr * nla_matches)3222*de1e4e89SAndroid Build Coastguard Worker static int dpipe_table_matches_show(struct dpipe_ctx *ctx,
3223*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_matches)
3224*de1e4e89SAndroid Build Coastguard Worker {
3225*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_match;
3226*de1e4e89SAndroid Build Coastguard Worker struct dpipe_match match;
3227*de1e4e89SAndroid Build Coastguard Worker
3228*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_match, nla_matches) {
3229*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_start(ctx->dl);
3230*de1e4e89SAndroid Build Coastguard Worker if (dpipe_match_parse(&match, nla_match))
3231*de1e4e89SAndroid Build Coastguard Worker goto err_match_parse;
3232*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_match(&match, ctx);
3233*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3234*de1e4e89SAndroid Build Coastguard Worker }
3235*de1e4e89SAndroid Build Coastguard Worker return 0;
3236*de1e4e89SAndroid Build Coastguard Worker
3237*de1e4e89SAndroid Build Coastguard Worker err_match_parse:
3238*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3239*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3240*de1e4e89SAndroid Build Coastguard Worker }
3241*de1e4e89SAndroid Build Coastguard Worker
dpipe_table_show(struct dpipe_ctx * ctx,struct nlattr * nl)3242*de1e4e89SAndroid Build Coastguard Worker static int dpipe_table_show(struct dpipe_ctx *ctx, struct nlattr *nl)
3243*de1e4e89SAndroid Build Coastguard Worker {
3244*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_table[DEVLINK_ATTR_MAX + 1] = {};
3245*de1e4e89SAndroid Build Coastguard Worker bool counters_enabled;
3246*de1e4e89SAndroid Build Coastguard Worker const char *name;
3247*de1e4e89SAndroid Build Coastguard Worker uint32_t size;
3248*de1e4e89SAndroid Build Coastguard Worker int err;
3249*de1e4e89SAndroid Build Coastguard Worker
3250*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_table);
3251*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
3252*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3253*de1e4e89SAndroid Build Coastguard Worker
3254*de1e4e89SAndroid Build Coastguard Worker if (!nla_table[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
3255*de1e4e89SAndroid Build Coastguard Worker !nla_table[DEVLINK_ATTR_DPIPE_TABLE_SIZE] ||
3256*de1e4e89SAndroid Build Coastguard Worker !nla_table[DEVLINK_ATTR_DPIPE_TABLE_ACTIONS] ||
3257*de1e4e89SAndroid Build Coastguard Worker !nla_table[DEVLINK_ATTR_DPIPE_TABLE_MATCHES] ||
3258*de1e4e89SAndroid Build Coastguard Worker !nla_table[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]) {
3259*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3260*de1e4e89SAndroid Build Coastguard Worker }
3261*de1e4e89SAndroid Build Coastguard Worker
3262*de1e4e89SAndroid Build Coastguard Worker name = mnl_attr_get_str(nla_table[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3263*de1e4e89SAndroid Build Coastguard Worker size = mnl_attr_get_u32(nla_table[DEVLINK_ATTR_DPIPE_TABLE_SIZE]);
3264*de1e4e89SAndroid Build Coastguard Worker counters_enabled = !!mnl_attr_get_u8(nla_table[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
3265*de1e4e89SAndroid Build Coastguard Worker
3266*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "name", name);
3267*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, "size", size);
3268*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, "counters_enabled",
3269*de1e4e89SAndroid Build Coastguard Worker counters_enabled ? "true" : "false");
3270*de1e4e89SAndroid Build Coastguard Worker
3271*de1e4e89SAndroid Build Coastguard Worker pr_out_array_start(ctx->dl, "match");
3272*de1e4e89SAndroid Build Coastguard Worker if (dpipe_table_matches_show(ctx, nla_table[DEVLINK_ATTR_DPIPE_TABLE_MATCHES]))
3273*de1e4e89SAndroid Build Coastguard Worker goto err_matches_show;
3274*de1e4e89SAndroid Build Coastguard Worker pr_out_array_end(ctx->dl);
3275*de1e4e89SAndroid Build Coastguard Worker
3276*de1e4e89SAndroid Build Coastguard Worker pr_out_array_start(ctx->dl, "action");
3277*de1e4e89SAndroid Build Coastguard Worker if (dpipe_table_actions_show(ctx, nla_table[DEVLINK_ATTR_DPIPE_TABLE_ACTIONS]))
3278*de1e4e89SAndroid Build Coastguard Worker goto err_actions_show;
3279*de1e4e89SAndroid Build Coastguard Worker pr_out_array_end(ctx->dl);
3280*de1e4e89SAndroid Build Coastguard Worker
3281*de1e4e89SAndroid Build Coastguard Worker return 0;
3282*de1e4e89SAndroid Build Coastguard Worker
3283*de1e4e89SAndroid Build Coastguard Worker err_actions_show:
3284*de1e4e89SAndroid Build Coastguard Worker err_matches_show:
3285*de1e4e89SAndroid Build Coastguard Worker pr_out_array_end(ctx->dl);
3286*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3287*de1e4e89SAndroid Build Coastguard Worker }
3288*de1e4e89SAndroid Build Coastguard Worker
dpipe_tables_show(struct dpipe_ctx * ctx,struct nlattr ** tb)3289*de1e4e89SAndroid Build Coastguard Worker static int dpipe_tables_show(struct dpipe_ctx *ctx, struct nlattr **tb)
3290*de1e4e89SAndroid Build Coastguard Worker {
3291*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_tables = tb[DEVLINK_ATTR_DPIPE_TABLES];
3292*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_table;
3293*de1e4e89SAndroid Build Coastguard Worker
3294*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_table, nla_tables) {
3295*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_start_arr(ctx->dl, tb);
3296*de1e4e89SAndroid Build Coastguard Worker if (dpipe_table_show(ctx, nla_table))
3297*de1e4e89SAndroid Build Coastguard Worker goto err_table_show;
3298*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(ctx->dl);
3299*de1e4e89SAndroid Build Coastguard Worker }
3300*de1e4e89SAndroid Build Coastguard Worker return 0;
3301*de1e4e89SAndroid Build Coastguard Worker
3302*de1e4e89SAndroid Build Coastguard Worker err_table_show:
3303*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(ctx->dl);
3304*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3305*de1e4e89SAndroid Build Coastguard Worker }
3306*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_table_show_cb(const struct nlmsghdr * nlh,void * data)3307*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_table_show_cb(const struct nlmsghdr *nlh, void *data)
3308*de1e4e89SAndroid Build Coastguard Worker {
3309*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx = data;
3310*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
3311*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
3312*de1e4e89SAndroid Build Coastguard Worker
3313*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
3314*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
3315*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_DPIPE_TABLES])
3316*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
3317*de1e4e89SAndroid Build Coastguard Worker
3318*de1e4e89SAndroid Build Coastguard Worker if (dpipe_tables_show(ctx, tb))
3319*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
3320*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
3321*de1e4e89SAndroid Build Coastguard Worker }
3322*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_table_show(struct dl * dl)3323*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_table_show(struct dl *dl)
3324*de1e4e89SAndroid Build Coastguard Worker {
3325*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
3326*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx;
3327*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST;
3328*de1e4e89SAndroid Build Coastguard Worker int err;
3329*de1e4e89SAndroid Build Coastguard Worker
3330*de1e4e89SAndroid Build Coastguard Worker ctx = dpipe_ctx_alloc(dl);
3331*de1e4e89SAndroid Build Coastguard Worker if (!ctx)
3332*de1e4e89SAndroid Build Coastguard Worker return -ENOMEM;
3333*de1e4e89SAndroid Build Coastguard Worker
3334*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse(dl, DL_OPT_HANDLE, DL_OPT_DPIPE_TABLE_NAME);
3335*de1e4e89SAndroid Build Coastguard Worker if (err)
3336*de1e4e89SAndroid Build Coastguard Worker goto out;
3337*de1e4e89SAndroid Build Coastguard Worker
3338*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_HEADERS_GET, flags);
3339*de1e4e89SAndroid Build Coastguard Worker dl_opts_put(nlh, dl);
3340*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_header_cb, ctx);
3341*de1e4e89SAndroid Build Coastguard Worker if (err) {
3342*de1e4e89SAndroid Build Coastguard Worker pr_err("error get headers %s\n", strerror(ctx->err));
3343*de1e4e89SAndroid Build Coastguard Worker goto out;
3344*de1e4e89SAndroid Build Coastguard Worker }
3345*de1e4e89SAndroid Build Coastguard Worker
3346*de1e4e89SAndroid Build Coastguard Worker flags = NLM_F_REQUEST | NLM_F_ACK;
3347*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_TABLE_GET, flags);
3348*de1e4e89SAndroid Build Coastguard Worker dl_opts_put(nlh, dl);
3349*de1e4e89SAndroid Build Coastguard Worker
3350*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "table");
3351*de1e4e89SAndroid Build Coastguard Worker _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_table_show_cb, ctx);
3352*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
3353*de1e4e89SAndroid Build Coastguard Worker out:
3354*de1e4e89SAndroid Build Coastguard Worker dpipe_ctx_clear(ctx);
3355*de1e4e89SAndroid Build Coastguard Worker dpipe_ctx_free(ctx);
3356*de1e4e89SAndroid Build Coastguard Worker return err;
3357*de1e4e89SAndroid Build Coastguard Worker }
3358*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_table_set(struct dl * dl)3359*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_table_set(struct dl *dl)
3360*de1e4e89SAndroid Build Coastguard Worker {
3361*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
3362*de1e4e89SAndroid Build Coastguard Worker int err;
3363*de1e4e89SAndroid Build Coastguard Worker
3364*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
3365*de1e4e89SAndroid Build Coastguard Worker NLM_F_REQUEST | NLM_F_ACK);
3366*de1e4e89SAndroid Build Coastguard Worker
3367*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse_put(nlh, dl,
3368*de1e4e89SAndroid Build Coastguard Worker DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME |
3369*de1e4e89SAndroid Build Coastguard Worker DL_OPT_DPIPE_TABLE_COUNTERS, 0);
3370*de1e4e89SAndroid Build Coastguard Worker if (err)
3371*de1e4e89SAndroid Build Coastguard Worker return err;
3372*de1e4e89SAndroid Build Coastguard Worker
3373*de1e4e89SAndroid Build Coastguard Worker return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
3374*de1e4e89SAndroid Build Coastguard Worker }
3375*de1e4e89SAndroid Build Coastguard Worker
3376*de1e4e89SAndroid Build Coastguard Worker enum dpipe_value_type {
3377*de1e4e89SAndroid Build Coastguard Worker DPIPE_VALUE_TYPE_VALUE,
3378*de1e4e89SAndroid Build Coastguard Worker DPIPE_VALUE_TYPE_MASK,
3379*de1e4e89SAndroid Build Coastguard Worker };
3380*de1e4e89SAndroid Build Coastguard Worker
3381*de1e4e89SAndroid Build Coastguard Worker static const char *
dpipe_value_type_e2s(enum dpipe_value_type type)3382*de1e4e89SAndroid Build Coastguard Worker dpipe_value_type_e2s(enum dpipe_value_type type)
3383*de1e4e89SAndroid Build Coastguard Worker {
3384*de1e4e89SAndroid Build Coastguard Worker switch (type) {
3385*de1e4e89SAndroid Build Coastguard Worker case DPIPE_VALUE_TYPE_VALUE:
3386*de1e4e89SAndroid Build Coastguard Worker return "value";
3387*de1e4e89SAndroid Build Coastguard Worker case DPIPE_VALUE_TYPE_MASK:
3388*de1e4e89SAndroid Build Coastguard Worker return "value_mask";
3389*de1e4e89SAndroid Build Coastguard Worker default:
3390*de1e4e89SAndroid Build Coastguard Worker return "<unknown>";
3391*de1e4e89SAndroid Build Coastguard Worker }
3392*de1e4e89SAndroid Build Coastguard Worker }
3393*de1e4e89SAndroid Build Coastguard Worker
3394*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field_printer {
3395*de1e4e89SAndroid Build Coastguard Worker unsigned int field_id;
3396*de1e4e89SAndroid Build Coastguard Worker void (*printer)(struct dpipe_ctx *, enum dpipe_value_type, void *);
3397*de1e4e89SAndroid Build Coastguard Worker };
3398*de1e4e89SAndroid Build Coastguard Worker
3399*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header_printer {
3400*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field_printer *printers;
3401*de1e4e89SAndroid Build Coastguard Worker unsigned int printers_count;
3402*de1e4e89SAndroid Build Coastguard Worker unsigned int header_id;
3403*de1e4e89SAndroid Build Coastguard Worker };
3404*de1e4e89SAndroid Build Coastguard Worker
dpipe_field_printer_ipv4_addr(struct dpipe_ctx * ctx,enum dpipe_value_type type,void * value)3405*de1e4e89SAndroid Build Coastguard Worker static void dpipe_field_printer_ipv4_addr(struct dpipe_ctx *ctx,
3406*de1e4e89SAndroid Build Coastguard Worker enum dpipe_value_type type,
3407*de1e4e89SAndroid Build Coastguard Worker void *value)
3408*de1e4e89SAndroid Build Coastguard Worker {
3409*de1e4e89SAndroid Build Coastguard Worker struct in_addr ip_addr;
3410*de1e4e89SAndroid Build Coastguard Worker
3411*de1e4e89SAndroid Build Coastguard Worker ip_addr.s_addr = htonl(*(uint32_t *)value);
3412*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, dpipe_value_type_e2s(type), inet_ntoa(ip_addr));
3413*de1e4e89SAndroid Build Coastguard Worker }
3414*de1e4e89SAndroid Build Coastguard Worker
3415*de1e4e89SAndroid Build Coastguard Worker static void
dpipe_field_printer_ethernet_addr(struct dpipe_ctx * ctx,enum dpipe_value_type type,void * value)3416*de1e4e89SAndroid Build Coastguard Worker dpipe_field_printer_ethernet_addr(struct dpipe_ctx *ctx,
3417*de1e4e89SAndroid Build Coastguard Worker enum dpipe_value_type type,
3418*de1e4e89SAndroid Build Coastguard Worker void *value)
3419*de1e4e89SAndroid Build Coastguard Worker {
3420*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, dpipe_value_type_e2s(type),
3421*de1e4e89SAndroid Build Coastguard Worker ether_ntoa((struct ether_addr *)value));
3422*de1e4e89SAndroid Build Coastguard Worker }
3423*de1e4e89SAndroid Build Coastguard Worker
dpipe_field_printer_ipv6_addr(struct dpipe_ctx * ctx,enum dpipe_value_type type,void * value)3424*de1e4e89SAndroid Build Coastguard Worker static void dpipe_field_printer_ipv6_addr(struct dpipe_ctx *ctx,
3425*de1e4e89SAndroid Build Coastguard Worker enum dpipe_value_type type,
3426*de1e4e89SAndroid Build Coastguard Worker void *value)
3427*de1e4e89SAndroid Build Coastguard Worker {
3428*de1e4e89SAndroid Build Coastguard Worker char str[INET6_ADDRSTRLEN];
3429*de1e4e89SAndroid Build Coastguard Worker
3430*de1e4e89SAndroid Build Coastguard Worker inet_ntop(AF_INET6, value, str, INET6_ADDRSTRLEN);
3431*de1e4e89SAndroid Build Coastguard Worker pr_out_str(ctx->dl, dpipe_value_type_e2s(type), str);
3432*de1e4e89SAndroid Build Coastguard Worker }
3433*de1e4e89SAndroid Build Coastguard Worker
3434*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_field_printer dpipe_field_printers_ipv4[] = {
3435*de1e4e89SAndroid Build Coastguard Worker {
3436*de1e4e89SAndroid Build Coastguard Worker .printer = dpipe_field_printer_ipv4_addr,
3437*de1e4e89SAndroid Build Coastguard Worker .field_id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
3438*de1e4e89SAndroid Build Coastguard Worker }
3439*de1e4e89SAndroid Build Coastguard Worker };
3440*de1e4e89SAndroid Build Coastguard Worker
3441*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_header_printer dpipe_header_printer_ipv4 = {
3442*de1e4e89SAndroid Build Coastguard Worker .printers = dpipe_field_printers_ipv4,
3443*de1e4e89SAndroid Build Coastguard Worker .printers_count = ARRAY_SIZE(dpipe_field_printers_ipv4),
3444*de1e4e89SAndroid Build Coastguard Worker .header_id = DEVLINK_DPIPE_HEADER_IPV4,
3445*de1e4e89SAndroid Build Coastguard Worker };
3446*de1e4e89SAndroid Build Coastguard Worker
3447*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_field_printer dpipe_field_printers_ethernet[] = {
3448*de1e4e89SAndroid Build Coastguard Worker {
3449*de1e4e89SAndroid Build Coastguard Worker .printer = dpipe_field_printer_ethernet_addr,
3450*de1e4e89SAndroid Build Coastguard Worker .field_id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
3451*de1e4e89SAndroid Build Coastguard Worker },
3452*de1e4e89SAndroid Build Coastguard Worker };
3453*de1e4e89SAndroid Build Coastguard Worker
3454*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_header_printer dpipe_header_printer_ethernet = {
3455*de1e4e89SAndroid Build Coastguard Worker .printers = dpipe_field_printers_ethernet,
3456*de1e4e89SAndroid Build Coastguard Worker .printers_count = ARRAY_SIZE(dpipe_field_printers_ethernet),
3457*de1e4e89SAndroid Build Coastguard Worker .header_id = DEVLINK_DPIPE_HEADER_ETHERNET,
3458*de1e4e89SAndroid Build Coastguard Worker };
3459*de1e4e89SAndroid Build Coastguard Worker
3460*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_field_printer dpipe_field_printers_ipv6[] = {
3461*de1e4e89SAndroid Build Coastguard Worker {
3462*de1e4e89SAndroid Build Coastguard Worker .printer = dpipe_field_printer_ipv6_addr,
3463*de1e4e89SAndroid Build Coastguard Worker .field_id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
3464*de1e4e89SAndroid Build Coastguard Worker }
3465*de1e4e89SAndroid Build Coastguard Worker };
3466*de1e4e89SAndroid Build Coastguard Worker
3467*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_header_printer dpipe_header_printer_ipv6 = {
3468*de1e4e89SAndroid Build Coastguard Worker .printers = dpipe_field_printers_ipv6,
3469*de1e4e89SAndroid Build Coastguard Worker .printers_count = ARRAY_SIZE(dpipe_field_printers_ipv6),
3470*de1e4e89SAndroid Build Coastguard Worker .header_id = DEVLINK_DPIPE_HEADER_IPV6,
3471*de1e4e89SAndroid Build Coastguard Worker };
3472*de1e4e89SAndroid Build Coastguard Worker
3473*de1e4e89SAndroid Build Coastguard Worker static struct dpipe_header_printer *dpipe_header_printers[] = {
3474*de1e4e89SAndroid Build Coastguard Worker &dpipe_header_printer_ipv4,
3475*de1e4e89SAndroid Build Coastguard Worker &dpipe_header_printer_ethernet,
3476*de1e4e89SAndroid Build Coastguard Worker &dpipe_header_printer_ipv6,
3477*de1e4e89SAndroid Build Coastguard Worker };
3478*de1e4e89SAndroid Build Coastguard Worker
dpipe_print_prot_header(struct dpipe_ctx * ctx,struct dpipe_op_info * info,enum dpipe_value_type type,void * value)3479*de1e4e89SAndroid Build Coastguard Worker static int dpipe_print_prot_header(struct dpipe_ctx *ctx,
3480*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info *info,
3481*de1e4e89SAndroid Build Coastguard Worker enum dpipe_value_type type,
3482*de1e4e89SAndroid Build Coastguard Worker void *value)
3483*de1e4e89SAndroid Build Coastguard Worker {
3484*de1e4e89SAndroid Build Coastguard Worker unsigned int header_printers_count = ARRAY_SIZE(dpipe_header_printers);
3485*de1e4e89SAndroid Build Coastguard Worker struct dpipe_header_printer *header_printer;
3486*de1e4e89SAndroid Build Coastguard Worker struct dpipe_field_printer *field_printer;
3487*de1e4e89SAndroid Build Coastguard Worker unsigned int field_printers_count;
3488*de1e4e89SAndroid Build Coastguard Worker int j;
3489*de1e4e89SAndroid Build Coastguard Worker int i;
3490*de1e4e89SAndroid Build Coastguard Worker
3491*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < header_printers_count; i++) {
3492*de1e4e89SAndroid Build Coastguard Worker header_printer = dpipe_header_printers[i];
3493*de1e4e89SAndroid Build Coastguard Worker if (header_printer->header_id != info->header_id)
3494*de1e4e89SAndroid Build Coastguard Worker continue;
3495*de1e4e89SAndroid Build Coastguard Worker field_printers_count = header_printer->printers_count;
3496*de1e4e89SAndroid Build Coastguard Worker for (j = 0; j < field_printers_count; j++) {
3497*de1e4e89SAndroid Build Coastguard Worker field_printer = &header_printer->printers[j];
3498*de1e4e89SAndroid Build Coastguard Worker if (field_printer->field_id != info->field_id)
3499*de1e4e89SAndroid Build Coastguard Worker continue;
3500*de1e4e89SAndroid Build Coastguard Worker field_printer->printer(ctx, type, value);
3501*de1e4e89SAndroid Build Coastguard Worker return 0;
3502*de1e4e89SAndroid Build Coastguard Worker }
3503*de1e4e89SAndroid Build Coastguard Worker }
3504*de1e4e89SAndroid Build Coastguard Worker
3505*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3506*de1e4e89SAndroid Build Coastguard Worker }
3507*de1e4e89SAndroid Build Coastguard Worker
__pr_out_entry_value(struct dpipe_ctx * ctx,void * value,unsigned int value_len,struct dpipe_op_info * info,enum dpipe_value_type type)3508*de1e4e89SAndroid Build Coastguard Worker static void __pr_out_entry_value(struct dpipe_ctx *ctx,
3509*de1e4e89SAndroid Build Coastguard Worker void *value,
3510*de1e4e89SAndroid Build Coastguard Worker unsigned int value_len,
3511*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info *info,
3512*de1e4e89SAndroid Build Coastguard Worker enum dpipe_value_type type)
3513*de1e4e89SAndroid Build Coastguard Worker {
3514*de1e4e89SAndroid Build Coastguard Worker if (info->header_global &&
3515*de1e4e89SAndroid Build Coastguard Worker !dpipe_print_prot_header(ctx, info, type, value))
3516*de1e4e89SAndroid Build Coastguard Worker return;
3517*de1e4e89SAndroid Build Coastguard Worker
3518*de1e4e89SAndroid Build Coastguard Worker if (value_len == sizeof(uint32_t)) {
3519*de1e4e89SAndroid Build Coastguard Worker uint32_t *value_32 = value;
3520*de1e4e89SAndroid Build Coastguard Worker
3521*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, dpipe_value_type_e2s(type), *value_32);
3522*de1e4e89SAndroid Build Coastguard Worker }
3523*de1e4e89SAndroid Build Coastguard Worker }
3524*de1e4e89SAndroid Build Coastguard Worker
pr_out_dpipe_entry_value(struct dpipe_ctx * ctx,struct nlattr ** nla_match_value,struct dpipe_op_info * info)3525*de1e4e89SAndroid Build Coastguard Worker static void pr_out_dpipe_entry_value(struct dpipe_ctx *ctx,
3526*de1e4e89SAndroid Build Coastguard Worker struct nlattr **nla_match_value,
3527*de1e4e89SAndroid Build Coastguard Worker struct dpipe_op_info *info)
3528*de1e4e89SAndroid Build Coastguard Worker {
3529*de1e4e89SAndroid Build Coastguard Worker void *value, *value_mask;
3530*de1e4e89SAndroid Build Coastguard Worker uint32_t value_mapping;
3531*de1e4e89SAndroid Build Coastguard Worker uint16_t value_len;
3532*de1e4e89SAndroid Build Coastguard Worker bool mask, mapping;
3533*de1e4e89SAndroid Build Coastguard Worker
3534*de1e4e89SAndroid Build Coastguard Worker mask = !!nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MASK];
3535*de1e4e89SAndroid Build Coastguard Worker mapping = !!nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MAPPING];
3536*de1e4e89SAndroid Build Coastguard Worker
3537*de1e4e89SAndroid Build Coastguard Worker value_len = mnl_attr_get_payload_len(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]);
3538*de1e4e89SAndroid Build Coastguard Worker value = mnl_attr_get_payload(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]);
3539*de1e4e89SAndroid Build Coastguard Worker
3540*de1e4e89SAndroid Build Coastguard Worker if (mapping) {
3541*de1e4e89SAndroid Build Coastguard Worker value_mapping = mnl_attr_get_u32(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE_MAPPING]);
3542*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, "mapping_value", value_mapping);
3543*de1e4e89SAndroid Build Coastguard Worker }
3544*de1e4e89SAndroid Build Coastguard Worker
3545*de1e4e89SAndroid Build Coastguard Worker if (mask) {
3546*de1e4e89SAndroid Build Coastguard Worker value_mask = mnl_attr_get_payload(nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]);
3547*de1e4e89SAndroid Build Coastguard Worker __pr_out_entry_value(ctx, value_mask, value_len, info,
3548*de1e4e89SAndroid Build Coastguard Worker DPIPE_VALUE_TYPE_MASK);
3549*de1e4e89SAndroid Build Coastguard Worker }
3550*de1e4e89SAndroid Build Coastguard Worker
3551*de1e4e89SAndroid Build Coastguard Worker __pr_out_entry_value(ctx, value, value_len, info, DPIPE_VALUE_TYPE_VALUE);
3552*de1e4e89SAndroid Build Coastguard Worker }
3553*de1e4e89SAndroid Build Coastguard Worker
dpipe_entry_match_value_show(struct dpipe_ctx * ctx,struct nlattr * nl)3554*de1e4e89SAndroid Build Coastguard Worker static int dpipe_entry_match_value_show(struct dpipe_ctx *ctx,
3555*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nl)
3556*de1e4e89SAndroid Build Coastguard Worker {
3557*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_match_value[DEVLINK_ATTR_MAX + 1] = {};
3558*de1e4e89SAndroid Build Coastguard Worker struct dpipe_match match;
3559*de1e4e89SAndroid Build Coastguard Worker int err;
3560*de1e4e89SAndroid Build Coastguard Worker
3561*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_match_value);
3562*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
3563*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3564*de1e4e89SAndroid Build Coastguard Worker
3565*de1e4e89SAndroid Build Coastguard Worker if (!nla_match_value[DEVLINK_ATTR_DPIPE_MATCH] ||
3566*de1e4e89SAndroid Build Coastguard Worker !nla_match_value[DEVLINK_ATTR_DPIPE_VALUE]) {
3567*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3568*de1e4e89SAndroid Build Coastguard Worker }
3569*de1e4e89SAndroid Build Coastguard Worker
3570*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_start(ctx->dl);
3571*de1e4e89SAndroid Build Coastguard Worker if (dpipe_match_parse(&match,
3572*de1e4e89SAndroid Build Coastguard Worker nla_match_value[DEVLINK_ATTR_DPIPE_MATCH]))
3573*de1e4e89SAndroid Build Coastguard Worker goto err_match_parse;
3574*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_match(&match, ctx);
3575*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_entry_value(ctx, nla_match_value, &match.info);
3576*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3577*de1e4e89SAndroid Build Coastguard Worker
3578*de1e4e89SAndroid Build Coastguard Worker return 0;
3579*de1e4e89SAndroid Build Coastguard Worker
3580*de1e4e89SAndroid Build Coastguard Worker err_match_parse:
3581*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3582*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3583*de1e4e89SAndroid Build Coastguard Worker }
3584*de1e4e89SAndroid Build Coastguard Worker
dpipe_entry_action_value_show(struct dpipe_ctx * ctx,struct nlattr * nl)3585*de1e4e89SAndroid Build Coastguard Worker static int dpipe_entry_action_value_show(struct dpipe_ctx *ctx,
3586*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nl)
3587*de1e4e89SAndroid Build Coastguard Worker {
3588*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_action_value[DEVLINK_ATTR_MAX + 1] = {};
3589*de1e4e89SAndroid Build Coastguard Worker struct dpipe_action action;
3590*de1e4e89SAndroid Build Coastguard Worker int err;
3591*de1e4e89SAndroid Build Coastguard Worker
3592*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_action_value);
3593*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
3594*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3595*de1e4e89SAndroid Build Coastguard Worker
3596*de1e4e89SAndroid Build Coastguard Worker if (!nla_action_value[DEVLINK_ATTR_DPIPE_ACTION] ||
3597*de1e4e89SAndroid Build Coastguard Worker !nla_action_value[DEVLINK_ATTR_DPIPE_VALUE]) {
3598*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3599*de1e4e89SAndroid Build Coastguard Worker }
3600*de1e4e89SAndroid Build Coastguard Worker
3601*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_start(ctx->dl);
3602*de1e4e89SAndroid Build Coastguard Worker if (dpipe_action_parse(&action,
3603*de1e4e89SAndroid Build Coastguard Worker nla_action_value[DEVLINK_ATTR_DPIPE_ACTION]))
3604*de1e4e89SAndroid Build Coastguard Worker goto err_action_parse;
3605*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_action(&action, ctx);
3606*de1e4e89SAndroid Build Coastguard Worker pr_out_dpipe_entry_value(ctx, nla_action_value, &action.info);
3607*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3608*de1e4e89SAndroid Build Coastguard Worker
3609*de1e4e89SAndroid Build Coastguard Worker return 0;
3610*de1e4e89SAndroid Build Coastguard Worker
3611*de1e4e89SAndroid Build Coastguard Worker err_action_parse:
3612*de1e4e89SAndroid Build Coastguard Worker pr_out_entry_end(ctx->dl);
3613*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3614*de1e4e89SAndroid Build Coastguard Worker }
3615*de1e4e89SAndroid Build Coastguard Worker
3616*de1e4e89SAndroid Build Coastguard Worker static int
dpipe_tables_action_values_show(struct dpipe_ctx * ctx,struct nlattr * nla_action_values)3617*de1e4e89SAndroid Build Coastguard Worker dpipe_tables_action_values_show(struct dpipe_ctx *ctx,
3618*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_action_values)
3619*de1e4e89SAndroid Build Coastguard Worker {
3620*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_action_value;
3621*de1e4e89SAndroid Build Coastguard Worker
3622*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_action_value, nla_action_values) {
3623*de1e4e89SAndroid Build Coastguard Worker if (dpipe_entry_action_value_show(ctx, nla_action_value))
3624*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3625*de1e4e89SAndroid Build Coastguard Worker }
3626*de1e4e89SAndroid Build Coastguard Worker return 0;
3627*de1e4e89SAndroid Build Coastguard Worker }
3628*de1e4e89SAndroid Build Coastguard Worker
3629*de1e4e89SAndroid Build Coastguard Worker static int
dpipe_tables_match_values_show(struct dpipe_ctx * ctx,struct nlattr * nla_match_values)3630*de1e4e89SAndroid Build Coastguard Worker dpipe_tables_match_values_show(struct dpipe_ctx *ctx,
3631*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_match_values)
3632*de1e4e89SAndroid Build Coastguard Worker {
3633*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_match_value;
3634*de1e4e89SAndroid Build Coastguard Worker
3635*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_match_value, nla_match_values) {
3636*de1e4e89SAndroid Build Coastguard Worker if (dpipe_entry_match_value_show(ctx, nla_match_value))
3637*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3638*de1e4e89SAndroid Build Coastguard Worker }
3639*de1e4e89SAndroid Build Coastguard Worker return 0;
3640*de1e4e89SAndroid Build Coastguard Worker }
3641*de1e4e89SAndroid Build Coastguard Worker
dpipe_entry_show(struct dpipe_ctx * ctx,struct nlattr * nl)3642*de1e4e89SAndroid Build Coastguard Worker static int dpipe_entry_show(struct dpipe_ctx *ctx, struct nlattr *nl)
3643*de1e4e89SAndroid Build Coastguard Worker {
3644*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_entry[DEVLINK_ATTR_MAX + 1] = {};
3645*de1e4e89SAndroid Build Coastguard Worker uint32_t entry_index;
3646*de1e4e89SAndroid Build Coastguard Worker uint64_t counter;
3647*de1e4e89SAndroid Build Coastguard Worker int err;
3648*de1e4e89SAndroid Build Coastguard Worker
3649*de1e4e89SAndroid Build Coastguard Worker err = mnl_attr_parse_nested(nl, attr_cb, nla_entry);
3650*de1e4e89SAndroid Build Coastguard Worker if (err != MNL_CB_OK)
3651*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3652*de1e4e89SAndroid Build Coastguard Worker
3653*de1e4e89SAndroid Build Coastguard Worker if (!nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_INDEX] ||
3654*de1e4e89SAndroid Build Coastguard Worker !nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES] ||
3655*de1e4e89SAndroid Build Coastguard Worker !nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES]) {
3656*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3657*de1e4e89SAndroid Build Coastguard Worker }
3658*de1e4e89SAndroid Build Coastguard Worker
3659*de1e4e89SAndroid Build Coastguard Worker entry_index = mnl_attr_get_u32(nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_INDEX]);
3660*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, "index", entry_index);
3661*de1e4e89SAndroid Build Coastguard Worker
3662*de1e4e89SAndroid Build Coastguard Worker if (nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_COUNTER]) {
3663*de1e4e89SAndroid Build Coastguard Worker counter = mnl_attr_get_u64(nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_COUNTER]);
3664*de1e4e89SAndroid Build Coastguard Worker pr_out_uint(ctx->dl, "counter", counter);
3665*de1e4e89SAndroid Build Coastguard Worker }
3666*de1e4e89SAndroid Build Coastguard Worker
3667*de1e4e89SAndroid Build Coastguard Worker pr_out_array_start(ctx->dl, "match_value");
3668*de1e4e89SAndroid Build Coastguard Worker if (dpipe_tables_match_values_show(ctx,
3669*de1e4e89SAndroid Build Coastguard Worker nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES]))
3670*de1e4e89SAndroid Build Coastguard Worker goto err_match_values_show;
3671*de1e4e89SAndroid Build Coastguard Worker pr_out_array_end(ctx->dl);
3672*de1e4e89SAndroid Build Coastguard Worker
3673*de1e4e89SAndroid Build Coastguard Worker pr_out_array_start(ctx->dl, "action_value");
3674*de1e4e89SAndroid Build Coastguard Worker if (dpipe_tables_action_values_show(ctx,
3675*de1e4e89SAndroid Build Coastguard Worker nla_entry[DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES]))
3676*de1e4e89SAndroid Build Coastguard Worker goto err_action_values_show;
3677*de1e4e89SAndroid Build Coastguard Worker pr_out_array_end(ctx->dl);
3678*de1e4e89SAndroid Build Coastguard Worker return 0;
3679*de1e4e89SAndroid Build Coastguard Worker
3680*de1e4e89SAndroid Build Coastguard Worker err_action_values_show:
3681*de1e4e89SAndroid Build Coastguard Worker err_match_values_show:
3682*de1e4e89SAndroid Build Coastguard Worker pr_out_array_end(ctx->dl);
3683*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3684*de1e4e89SAndroid Build Coastguard Worker }
3685*de1e4e89SAndroid Build Coastguard Worker
dpipe_table_entries_show(struct dpipe_ctx * ctx,struct nlattr ** tb)3686*de1e4e89SAndroid Build Coastguard Worker static int dpipe_table_entries_show(struct dpipe_ctx *ctx, struct nlattr **tb)
3687*de1e4e89SAndroid Build Coastguard Worker {
3688*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_entries = tb[DEVLINK_ATTR_DPIPE_ENTRIES];
3689*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nla_entry;
3690*de1e4e89SAndroid Build Coastguard Worker
3691*de1e4e89SAndroid Build Coastguard Worker mnl_attr_for_each_nested(nla_entry, nla_entries) {
3692*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_start_arr(ctx->dl, tb);
3693*de1e4e89SAndroid Build Coastguard Worker if (dpipe_entry_show(ctx, nla_entry))
3694*de1e4e89SAndroid Build Coastguard Worker goto err_entry_show;
3695*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(ctx->dl);
3696*de1e4e89SAndroid Build Coastguard Worker }
3697*de1e4e89SAndroid Build Coastguard Worker return 0;
3698*de1e4e89SAndroid Build Coastguard Worker
3699*de1e4e89SAndroid Build Coastguard Worker err_entry_show:
3700*de1e4e89SAndroid Build Coastguard Worker pr_out_handle_end(ctx->dl);
3701*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
3702*de1e4e89SAndroid Build Coastguard Worker }
3703*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_table_entry_dump_cb(const struct nlmsghdr * nlh,void * data)3704*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_table_entry_dump_cb(const struct nlmsghdr *nlh, void *data)
3705*de1e4e89SAndroid Build Coastguard Worker {
3706*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx = data;
3707*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
3708*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
3709*de1e4e89SAndroid Build Coastguard Worker
3710*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
3711*de1e4e89SAndroid Build Coastguard Worker if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
3712*de1e4e89SAndroid Build Coastguard Worker !tb[DEVLINK_ATTR_DPIPE_ENTRIES])
3713*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
3714*de1e4e89SAndroid Build Coastguard Worker
3715*de1e4e89SAndroid Build Coastguard Worker if (dpipe_table_entries_show(ctx, tb))
3716*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
3717*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
3718*de1e4e89SAndroid Build Coastguard Worker }
3719*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_table_dump(struct dl * dl)3720*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_table_dump(struct dl *dl)
3721*de1e4e89SAndroid Build Coastguard Worker {
3722*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
3723*de1e4e89SAndroid Build Coastguard Worker struct dpipe_ctx *ctx;
3724*de1e4e89SAndroid Build Coastguard Worker uint16_t flags = NLM_F_REQUEST;
3725*de1e4e89SAndroid Build Coastguard Worker int err;
3726*de1e4e89SAndroid Build Coastguard Worker
3727*de1e4e89SAndroid Build Coastguard Worker ctx = dpipe_ctx_alloc(dl);
3728*de1e4e89SAndroid Build Coastguard Worker if (!ctx)
3729*de1e4e89SAndroid Build Coastguard Worker return -ENOMEM;
3730*de1e4e89SAndroid Build Coastguard Worker
3731*de1e4e89SAndroid Build Coastguard Worker err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_DPIPE_TABLE_NAME, 0);
3732*de1e4e89SAndroid Build Coastguard Worker if (err)
3733*de1e4e89SAndroid Build Coastguard Worker goto out;
3734*de1e4e89SAndroid Build Coastguard Worker
3735*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_HEADERS_GET, flags);
3736*de1e4e89SAndroid Build Coastguard Worker dl_opts_put(nlh, dl);
3737*de1e4e89SAndroid Build Coastguard Worker err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_header_cb, ctx);
3738*de1e4e89SAndroid Build Coastguard Worker if (err) {
3739*de1e4e89SAndroid Build Coastguard Worker pr_err("error get headers %s\n", strerror(ctx->err));
3740*de1e4e89SAndroid Build Coastguard Worker goto out;
3741*de1e4e89SAndroid Build Coastguard Worker }
3742*de1e4e89SAndroid Build Coastguard Worker
3743*de1e4e89SAndroid Build Coastguard Worker flags = NLM_F_REQUEST | NLM_F_ACK;
3744*de1e4e89SAndroid Build Coastguard Worker nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_ENTRIES_GET, flags);
3745*de1e4e89SAndroid Build Coastguard Worker dl_opts_put(nlh, dl);
3746*de1e4e89SAndroid Build Coastguard Worker
3747*de1e4e89SAndroid Build Coastguard Worker pr_out_section_start(dl, "table_entry");
3748*de1e4e89SAndroid Build Coastguard Worker _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_dpipe_table_entry_dump_cb, ctx);
3749*de1e4e89SAndroid Build Coastguard Worker pr_out_section_end(dl);
3750*de1e4e89SAndroid Build Coastguard Worker out:
3751*de1e4e89SAndroid Build Coastguard Worker dpipe_ctx_clear(ctx);
3752*de1e4e89SAndroid Build Coastguard Worker dpipe_ctx_free(ctx);
3753*de1e4e89SAndroid Build Coastguard Worker return err;
3754*de1e4e89SAndroid Build Coastguard Worker }
3755*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_table_help(void)3756*de1e4e89SAndroid Build Coastguard Worker static void cmd_dpipe_table_help(void)
3757*de1e4e89SAndroid Build Coastguard Worker {
3758*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink dpipe table [ OBJECT-LIST ]\n"
3759*de1e4e89SAndroid Build Coastguard Worker "where OBJECT-LIST := { show | set | dump }\n");
3760*de1e4e89SAndroid Build Coastguard Worker }
3761*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_table(struct dl * dl)3762*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe_table(struct dl *dl)
3763*de1e4e89SAndroid Build Coastguard Worker {
3764*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
3765*de1e4e89SAndroid Build Coastguard Worker cmd_dpipe_table_help();
3766*de1e4e89SAndroid Build Coastguard Worker return 0;
3767*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "show")) {
3768*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3769*de1e4e89SAndroid Build Coastguard Worker return cmd_dpipe_table_show(dl);
3770*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "set")) {
3771*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3772*de1e4e89SAndroid Build Coastguard Worker return cmd_dpipe_table_set(dl);
3773*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "dump")) {
3774*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3775*de1e4e89SAndroid Build Coastguard Worker return cmd_dpipe_table_dump(dl);
3776*de1e4e89SAndroid Build Coastguard Worker }
3777*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
3778*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
3779*de1e4e89SAndroid Build Coastguard Worker }
3780*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe_help(void)3781*de1e4e89SAndroid Build Coastguard Worker static void cmd_dpipe_help(void)
3782*de1e4e89SAndroid Build Coastguard Worker {
3783*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink dpipe [ OBJECT-LIST ]\n"
3784*de1e4e89SAndroid Build Coastguard Worker "where OBJECT-LIST := { header | table }\n");
3785*de1e4e89SAndroid Build Coastguard Worker }
3786*de1e4e89SAndroid Build Coastguard Worker
cmd_dpipe(struct dl * dl)3787*de1e4e89SAndroid Build Coastguard Worker static int cmd_dpipe(struct dl *dl)
3788*de1e4e89SAndroid Build Coastguard Worker {
3789*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
3790*de1e4e89SAndroid Build Coastguard Worker cmd_dpipe_help();
3791*de1e4e89SAndroid Build Coastguard Worker return 0;
3792*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "header")) {
3793*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3794*de1e4e89SAndroid Build Coastguard Worker return cmd_dpipe_header(dl);
3795*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "table")) {
3796*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3797*de1e4e89SAndroid Build Coastguard Worker return cmd_dpipe_table(dl);
3798*de1e4e89SAndroid Build Coastguard Worker }
3799*de1e4e89SAndroid Build Coastguard Worker pr_err("Command \"%s\" not found\n", dl_argv(dl));
3800*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
3801*de1e4e89SAndroid Build Coastguard Worker }
3802*de1e4e89SAndroid Build Coastguard Worker
help(void)3803*de1e4e89SAndroid Build Coastguard Worker static void help(void)
3804*de1e4e89SAndroid Build Coastguard Worker {
3805*de1e4e89SAndroid Build Coastguard Worker pr_err("Usage: devlink [ OPTIONS ] OBJECT { COMMAND | help }\n"
3806*de1e4e89SAndroid Build Coastguard Worker " devlink [ -f[orce] ] -b[atch] filename\n"
3807*de1e4e89SAndroid Build Coastguard Worker "where OBJECT := { dev | port | sb | monitor | dpipe }\n"
3808*de1e4e89SAndroid Build Coastguard Worker " OPTIONS := { -V[ersion] | -n[no-nice-names] | -j[json] | -p[pretty] | -v[verbose] }\n");
3809*de1e4e89SAndroid Build Coastguard Worker }
3810*de1e4e89SAndroid Build Coastguard Worker
dl_cmd(struct dl * dl,int argc,char ** argv)3811*de1e4e89SAndroid Build Coastguard Worker static int dl_cmd(struct dl *dl, int argc, char **argv)
3812*de1e4e89SAndroid Build Coastguard Worker {
3813*de1e4e89SAndroid Build Coastguard Worker dl->argc = argc;
3814*de1e4e89SAndroid Build Coastguard Worker dl->argv = argv;
3815*de1e4e89SAndroid Build Coastguard Worker
3816*de1e4e89SAndroid Build Coastguard Worker if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
3817*de1e4e89SAndroid Build Coastguard Worker help();
3818*de1e4e89SAndroid Build Coastguard Worker return 0;
3819*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "dev")) {
3820*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3821*de1e4e89SAndroid Build Coastguard Worker return cmd_dev(dl);
3822*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "port")) {
3823*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3824*de1e4e89SAndroid Build Coastguard Worker return cmd_port(dl);
3825*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "sb")) {
3826*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3827*de1e4e89SAndroid Build Coastguard Worker return cmd_sb(dl);
3828*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "monitor")) {
3829*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3830*de1e4e89SAndroid Build Coastguard Worker return cmd_mon(dl);
3831*de1e4e89SAndroid Build Coastguard Worker } else if (dl_argv_match(dl, "dpipe")) {
3832*de1e4e89SAndroid Build Coastguard Worker dl_arg_inc(dl);
3833*de1e4e89SAndroid Build Coastguard Worker return cmd_dpipe(dl);
3834*de1e4e89SAndroid Build Coastguard Worker }
3835*de1e4e89SAndroid Build Coastguard Worker pr_err("Object \"%s\" not found\n", dl_argv(dl));
3836*de1e4e89SAndroid Build Coastguard Worker return -ENOENT;
3837*de1e4e89SAndroid Build Coastguard Worker }
3838*de1e4e89SAndroid Build Coastguard Worker
dl_init(struct dl * dl)3839*de1e4e89SAndroid Build Coastguard Worker static int dl_init(struct dl *dl)
3840*de1e4e89SAndroid Build Coastguard Worker {
3841*de1e4e89SAndroid Build Coastguard Worker int err;
3842*de1e4e89SAndroid Build Coastguard Worker
3843*de1e4e89SAndroid Build Coastguard Worker dl->nlg = mnlg_socket_open(DEVLINK_GENL_NAME, DEVLINK_GENL_VERSION);
3844*de1e4e89SAndroid Build Coastguard Worker if (!dl->nlg) {
3845*de1e4e89SAndroid Build Coastguard Worker pr_err("Failed to connect to devlink Netlink\n");
3846*de1e4e89SAndroid Build Coastguard Worker return -errno;
3847*de1e4e89SAndroid Build Coastguard Worker }
3848*de1e4e89SAndroid Build Coastguard Worker
3849*de1e4e89SAndroid Build Coastguard Worker err = ifname_map_init(dl);
3850*de1e4e89SAndroid Build Coastguard Worker if (err) {
3851*de1e4e89SAndroid Build Coastguard Worker pr_err("Failed to create index map\n");
3852*de1e4e89SAndroid Build Coastguard Worker goto err_ifname_map_create;
3853*de1e4e89SAndroid Build Coastguard Worker }
3854*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output) {
3855*de1e4e89SAndroid Build Coastguard Worker dl->jw = jsonw_new(stdout);
3856*de1e4e89SAndroid Build Coastguard Worker if (!dl->jw) {
3857*de1e4e89SAndroid Build Coastguard Worker pr_err("Failed to create JSON writer\n");
3858*de1e4e89SAndroid Build Coastguard Worker goto err_json_new;
3859*de1e4e89SAndroid Build Coastguard Worker }
3860*de1e4e89SAndroid Build Coastguard Worker jsonw_pretty(dl->jw, dl->pretty_output);
3861*de1e4e89SAndroid Build Coastguard Worker }
3862*de1e4e89SAndroid Build Coastguard Worker return 0;
3863*de1e4e89SAndroid Build Coastguard Worker
3864*de1e4e89SAndroid Build Coastguard Worker err_json_new:
3865*de1e4e89SAndroid Build Coastguard Worker ifname_map_fini(dl);
3866*de1e4e89SAndroid Build Coastguard Worker err_ifname_map_create:
3867*de1e4e89SAndroid Build Coastguard Worker mnlg_socket_close(dl->nlg);
3868*de1e4e89SAndroid Build Coastguard Worker return err;
3869*de1e4e89SAndroid Build Coastguard Worker }
3870*de1e4e89SAndroid Build Coastguard Worker
dl_fini(struct dl * dl)3871*de1e4e89SAndroid Build Coastguard Worker static void dl_fini(struct dl *dl)
3872*de1e4e89SAndroid Build Coastguard Worker {
3873*de1e4e89SAndroid Build Coastguard Worker if (dl->json_output)
3874*de1e4e89SAndroid Build Coastguard Worker jsonw_destroy(&dl->jw);
3875*de1e4e89SAndroid Build Coastguard Worker ifname_map_fini(dl);
3876*de1e4e89SAndroid Build Coastguard Worker mnlg_socket_close(dl->nlg);
3877*de1e4e89SAndroid Build Coastguard Worker }
3878*de1e4e89SAndroid Build Coastguard Worker
dl_alloc(void)3879*de1e4e89SAndroid Build Coastguard Worker static struct dl *dl_alloc(void)
3880*de1e4e89SAndroid Build Coastguard Worker {
3881*de1e4e89SAndroid Build Coastguard Worker struct dl *dl;
3882*de1e4e89SAndroid Build Coastguard Worker
3883*de1e4e89SAndroid Build Coastguard Worker dl = calloc(1, sizeof(*dl));
3884*de1e4e89SAndroid Build Coastguard Worker if (!dl)
3885*de1e4e89SAndroid Build Coastguard Worker return NULL;
3886*de1e4e89SAndroid Build Coastguard Worker return dl;
3887*de1e4e89SAndroid Build Coastguard Worker }
3888*de1e4e89SAndroid Build Coastguard Worker
dl_free(struct dl * dl)3889*de1e4e89SAndroid Build Coastguard Worker static void dl_free(struct dl *dl)
3890*de1e4e89SAndroid Build Coastguard Worker {
3891*de1e4e89SAndroid Build Coastguard Worker free(dl);
3892*de1e4e89SAndroid Build Coastguard Worker }
3893*de1e4e89SAndroid Build Coastguard Worker
dl_batch(struct dl * dl,const char * name,bool force)3894*de1e4e89SAndroid Build Coastguard Worker static int dl_batch(struct dl *dl, const char *name, bool force)
3895*de1e4e89SAndroid Build Coastguard Worker {
3896*de1e4e89SAndroid Build Coastguard Worker char *line = NULL;
3897*de1e4e89SAndroid Build Coastguard Worker size_t len = 0;
3898*de1e4e89SAndroid Build Coastguard Worker int ret = EXIT_SUCCESS;
3899*de1e4e89SAndroid Build Coastguard Worker
3900*de1e4e89SAndroid Build Coastguard Worker if (name && strcmp(name, "-") != 0) {
3901*de1e4e89SAndroid Build Coastguard Worker if (freopen(name, "r", stdin) == NULL) {
3902*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
3903*de1e4e89SAndroid Build Coastguard Worker "Cannot open file \"%s\" for reading: %s\n",
3904*de1e4e89SAndroid Build Coastguard Worker name, strerror(errno));
3905*de1e4e89SAndroid Build Coastguard Worker return EXIT_FAILURE;
3906*de1e4e89SAndroid Build Coastguard Worker }
3907*de1e4e89SAndroid Build Coastguard Worker }
3908*de1e4e89SAndroid Build Coastguard Worker
3909*de1e4e89SAndroid Build Coastguard Worker cmdlineno = 0;
3910*de1e4e89SAndroid Build Coastguard Worker while (getcmdline(&line, &len, stdin) != -1) {
3911*de1e4e89SAndroid Build Coastguard Worker char *largv[100];
3912*de1e4e89SAndroid Build Coastguard Worker int largc;
3913*de1e4e89SAndroid Build Coastguard Worker
3914*de1e4e89SAndroid Build Coastguard Worker largc = makeargs(line, largv, 100);
3915*de1e4e89SAndroid Build Coastguard Worker if (!largc)
3916*de1e4e89SAndroid Build Coastguard Worker continue; /* blank line */
3917*de1e4e89SAndroid Build Coastguard Worker
3918*de1e4e89SAndroid Build Coastguard Worker if (dl_cmd(dl, largc, largv)) {
3919*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Command failed %s:%d\n",
3920*de1e4e89SAndroid Build Coastguard Worker name, cmdlineno);
3921*de1e4e89SAndroid Build Coastguard Worker ret = EXIT_FAILURE;
3922*de1e4e89SAndroid Build Coastguard Worker if (!force)
3923*de1e4e89SAndroid Build Coastguard Worker break;
3924*de1e4e89SAndroid Build Coastguard Worker }
3925*de1e4e89SAndroid Build Coastguard Worker }
3926*de1e4e89SAndroid Build Coastguard Worker
3927*de1e4e89SAndroid Build Coastguard Worker if (line)
3928*de1e4e89SAndroid Build Coastguard Worker free(line);
3929*de1e4e89SAndroid Build Coastguard Worker
3930*de1e4e89SAndroid Build Coastguard Worker return ret;
3931*de1e4e89SAndroid Build Coastguard Worker }
3932*de1e4e89SAndroid Build Coastguard Worker
main(int argc,char ** argv)3933*de1e4e89SAndroid Build Coastguard Worker int main(int argc, char **argv)
3934*de1e4e89SAndroid Build Coastguard Worker {
3935*de1e4e89SAndroid Build Coastguard Worker static const struct option long_options[] = {
3936*de1e4e89SAndroid Build Coastguard Worker { "Version", no_argument, NULL, 'V' },
3937*de1e4e89SAndroid Build Coastguard Worker { "force", no_argument, NULL, 'f' },
3938*de1e4e89SAndroid Build Coastguard Worker { "batch", required_argument, NULL, 'b' },
3939*de1e4e89SAndroid Build Coastguard Worker { "no-nice-names", no_argument, NULL, 'n' },
3940*de1e4e89SAndroid Build Coastguard Worker { "json", no_argument, NULL, 'j' },
3941*de1e4e89SAndroid Build Coastguard Worker { "pretty", no_argument, NULL, 'p' },
3942*de1e4e89SAndroid Build Coastguard Worker { "verbose", no_argument, NULL, 'v' },
3943*de1e4e89SAndroid Build Coastguard Worker { NULL, 0, NULL, 0 }
3944*de1e4e89SAndroid Build Coastguard Worker };
3945*de1e4e89SAndroid Build Coastguard Worker const char *batch_file = NULL;
3946*de1e4e89SAndroid Build Coastguard Worker bool force = false;
3947*de1e4e89SAndroid Build Coastguard Worker struct dl *dl;
3948*de1e4e89SAndroid Build Coastguard Worker int opt;
3949*de1e4e89SAndroid Build Coastguard Worker int err;
3950*de1e4e89SAndroid Build Coastguard Worker int ret;
3951*de1e4e89SAndroid Build Coastguard Worker
3952*de1e4e89SAndroid Build Coastguard Worker dl = dl_alloc();
3953*de1e4e89SAndroid Build Coastguard Worker if (!dl) {
3954*de1e4e89SAndroid Build Coastguard Worker pr_err("Failed to allocate memory for devlink\n");
3955*de1e4e89SAndroid Build Coastguard Worker return EXIT_FAILURE;
3956*de1e4e89SAndroid Build Coastguard Worker }
3957*de1e4e89SAndroid Build Coastguard Worker
3958*de1e4e89SAndroid Build Coastguard Worker while ((opt = getopt_long(argc, argv, "Vfb:njpv",
3959*de1e4e89SAndroid Build Coastguard Worker long_options, NULL)) >= 0) {
3960*de1e4e89SAndroid Build Coastguard Worker
3961*de1e4e89SAndroid Build Coastguard Worker switch (opt) {
3962*de1e4e89SAndroid Build Coastguard Worker case 'V':
3963*de1e4e89SAndroid Build Coastguard Worker printf("devlink utility, iproute2-ss%s\n", SNAPSHOT);
3964*de1e4e89SAndroid Build Coastguard Worker ret = EXIT_SUCCESS;
3965*de1e4e89SAndroid Build Coastguard Worker goto dl_free;
3966*de1e4e89SAndroid Build Coastguard Worker case 'f':
3967*de1e4e89SAndroid Build Coastguard Worker force = true;
3968*de1e4e89SAndroid Build Coastguard Worker break;
3969*de1e4e89SAndroid Build Coastguard Worker case 'b':
3970*de1e4e89SAndroid Build Coastguard Worker batch_file = optarg;
3971*de1e4e89SAndroid Build Coastguard Worker break;
3972*de1e4e89SAndroid Build Coastguard Worker case 'n':
3973*de1e4e89SAndroid Build Coastguard Worker dl->no_nice_names = true;
3974*de1e4e89SAndroid Build Coastguard Worker break;
3975*de1e4e89SAndroid Build Coastguard Worker case 'j':
3976*de1e4e89SAndroid Build Coastguard Worker dl->json_output = true;
3977*de1e4e89SAndroid Build Coastguard Worker break;
3978*de1e4e89SAndroid Build Coastguard Worker case 'p':
3979*de1e4e89SAndroid Build Coastguard Worker dl->pretty_output = true;
3980*de1e4e89SAndroid Build Coastguard Worker break;
3981*de1e4e89SAndroid Build Coastguard Worker case 'v':
3982*de1e4e89SAndroid Build Coastguard Worker dl->verbose = true;
3983*de1e4e89SAndroid Build Coastguard Worker break;
3984*de1e4e89SAndroid Build Coastguard Worker default:
3985*de1e4e89SAndroid Build Coastguard Worker pr_err("Unknown option.\n");
3986*de1e4e89SAndroid Build Coastguard Worker help();
3987*de1e4e89SAndroid Build Coastguard Worker ret = EXIT_FAILURE;
3988*de1e4e89SAndroid Build Coastguard Worker goto dl_free;
3989*de1e4e89SAndroid Build Coastguard Worker }
3990*de1e4e89SAndroid Build Coastguard Worker }
3991*de1e4e89SAndroid Build Coastguard Worker
3992*de1e4e89SAndroid Build Coastguard Worker argc -= optind;
3993*de1e4e89SAndroid Build Coastguard Worker argv += optind;
3994*de1e4e89SAndroid Build Coastguard Worker
3995*de1e4e89SAndroid Build Coastguard Worker err = dl_init(dl);
3996*de1e4e89SAndroid Build Coastguard Worker if (err) {
3997*de1e4e89SAndroid Build Coastguard Worker ret = EXIT_FAILURE;
3998*de1e4e89SAndroid Build Coastguard Worker goto dl_free;
3999*de1e4e89SAndroid Build Coastguard Worker }
4000*de1e4e89SAndroid Build Coastguard Worker
4001*de1e4e89SAndroid Build Coastguard Worker if (batch_file)
4002*de1e4e89SAndroid Build Coastguard Worker err = dl_batch(dl, batch_file, force);
4003*de1e4e89SAndroid Build Coastguard Worker else
4004*de1e4e89SAndroid Build Coastguard Worker err = dl_cmd(dl, argc, argv);
4005*de1e4e89SAndroid Build Coastguard Worker
4006*de1e4e89SAndroid Build Coastguard Worker if (err) {
4007*de1e4e89SAndroid Build Coastguard Worker ret = EXIT_FAILURE;
4008*de1e4e89SAndroid Build Coastguard Worker goto dl_fini;
4009*de1e4e89SAndroid Build Coastguard Worker }
4010*de1e4e89SAndroid Build Coastguard Worker
4011*de1e4e89SAndroid Build Coastguard Worker ret = EXIT_SUCCESS;
4012*de1e4e89SAndroid Build Coastguard Worker
4013*de1e4e89SAndroid Build Coastguard Worker dl_fini:
4014*de1e4e89SAndroid Build Coastguard Worker dl_fini(dl);
4015*de1e4e89SAndroid Build Coastguard Worker dl_free:
4016*de1e4e89SAndroid Build Coastguard Worker dl_free(dl);
4017*de1e4e89SAndroid Build Coastguard Worker
4018*de1e4e89SAndroid Build Coastguard Worker return ret;
4019*de1e4e89SAndroid Build Coastguard Worker }
4020