1
2
3#include <errno.h>
4#include <linux/dcbnl.h>
5
6#include "dcb.h"
7#include "utils.h"
8
9static void dcb_apptrust_help_set(void)
10{
11 fprintf(stderr,
12 "Usage: dcb apptrust set dev STRING\n"
13 " [ order [ ethtype | stream-port | dgram-port | port | dscp | pcp ] ]\n"
14 "\n");
15}
16
17static void dcb_apptrust_help_show(void)
18{
19 fprintf(stderr, "Usage: dcb apptrust show dev STRING\n"
20 " [ order ]\n"
21 "\n");
22}
23
24static void dcb_apptrust_help(void)
25{
26 fprintf(stderr, "Usage: dcb apptrust help\n"
27 "\n");
28 dcb_apptrust_help_show();
29 dcb_apptrust_help_set();
30}
31
32static const char *const selector_names[] = {
33 [IEEE_8021QAZ_APP_SEL_ETHERTYPE] = "ethtype",
34 [IEEE_8021QAZ_APP_SEL_STREAM] = "stream-port",
35 [IEEE_8021QAZ_APP_SEL_DGRAM] = "dgram-port",
36 [IEEE_8021QAZ_APP_SEL_ANY] = "port",
37 [IEEE_8021QAZ_APP_SEL_DSCP] = "dscp",
38 [DCB_APP_SEL_PCP] = "pcp",
39};
40
41struct dcb_apptrust_table {
42 __u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1];
43 int nselectors;
44};
45
46static bool dcb_apptrust_contains(const struct dcb_apptrust_table *table,
47 __u8 selector)
48{
49 int i;
50
51 for (i = 0; i < table->nselectors; i++)
52 if (table->selectors[i] == selector)
53 return true;
54
55 return false;
56}
57
58static void dcb_apptrust_print_order(const struct dcb_apptrust_table *table)
59{
60 const char *str;
61 __u8 selector;
62 int i;
63
64 open_json_array(PRINT_JSON, "order");
65 print_string(PRINT_FP, NULL, "order: ", NULL);
66
67 for (i = 0; i < table->nselectors; i++) {
68 selector = table->selectors[i];
69 str = selector_names[selector];
70 print_string(PRINT_ANY, NULL, "%s ", str);
71 }
72 print_nl();
73
74 close_json_array(PRINT_JSON, "order");
75}
76
77static void dcb_apptrust_print(const struct dcb_apptrust_table *table)
78{
79 dcb_apptrust_print_order(table);
80 print_nl();
81}
82
83static int dcb_apptrust_get_cb(const struct nlattr *attr, void *data)
84{
85 struct dcb_apptrust_table *table = data;
86 uint16_t type;
87 __u8 selector;
88
89 type = mnl_attr_get_type(attr);
90
91 if (!dcb_app_attr_type_validate(type)) {
92 fprintf(stderr,
93 "Unknown attribute in DCB_ATTR_IEEE_APP_TRUST_TABLE: %d\n",
94 type);
95 return MNL_CB_OK;
96 }
97
98 if (mnl_attr_get_payload_len(attr) < 1) {
99 fprintf(stderr,
100 "DCB_ATTR_IEEE_APP_TRUST payload expected to have size %zd, not %d\n",
101 sizeof(struct dcb_app), mnl_attr_get_payload_len(attr));
102 return MNL_CB_OK;
103 }
104
105 selector = mnl_attr_get_u8(attr);
106
107
108 if (!dcb_app_selector_validate(type, selector)) {
109 fprintf(stderr, "Wrong type for selector: %s\n",
110 selector_names[selector]);
111 return MNL_CB_OK;
112 }
113
114 table->selectors[table->nselectors++] = selector;
115
116 return MNL_CB_OK;
117}
118
119static int dcb_apptrust_get(struct dcb *dcb, const char *dev,
120 struct dcb_apptrust_table *table)
121{
122 uint16_t payload_len;
123 void *payload;
124 int ret;
125
126 ret = dcb_get_attribute_va(dcb, dev, DCB_ATTR_DCB_APP_TRUST_TABLE,
127 &payload, &payload_len);
128 if (ret != 0)
129 return ret;
130
131 ret = mnl_attr_parse_payload(payload, payload_len, dcb_apptrust_get_cb,
132 table);
133 if (ret != MNL_CB_OK)
134 return -EINVAL;
135
136 return 0;
137}
138
139static int dcb_apptrust_set_cb(struct dcb *dcb, struct nlmsghdr *nlh,
140 void *data)
141{
142 const struct dcb_apptrust_table *table = data;
143 enum ieee_attrs_app type;
144 struct nlattr *nest;
145 int i;
146
147 nest = mnl_attr_nest_start(nlh, DCB_ATTR_DCB_APP_TRUST_TABLE);
148
149 for (i = 0; i < table->nselectors; i++) {
150 type = dcb_app_attr_type_get(table->selectors[i]);
151 mnl_attr_put_u8(nlh, type, table->selectors[i]);
152 }
153
154 mnl_attr_nest_end(nlh, nest);
155
156 return 0;
157}
158
159static int dcb_apptrust_set(struct dcb *dcb, const char *dev,
160 const struct dcb_apptrust_table *table)
161{
162 return dcb_set_attribute_va(dcb, DCB_CMD_IEEE_SET, dev,
163 &dcb_apptrust_set_cb, (void *)table);
164}
165
166static __u8 dcb_apptrust_parse_selector(const char *selector, int *err)
167{
168 int i;
169
170 for (i = 0; i < ARRAY_SIZE(selector_names); i++) {
171 if (selector_names[i] &&
172 strcmp(selector, selector_names[i]) == 0) {
173 *err = 0;
174 return i;
175 }
176 }
177
178 *err = -EINVAL;
179 return 0;
180}
181
182static int dcb_apptrust_parse_selector_list(int *argcp, char ***argvp,
183 struct dcb_apptrust_table *table)
184{
185 int argc = *argcp, err;
186 char **argv = *argvp;
187 __u8 selector;
188
189
190 if (argc == 0)
191 goto out;
192
193 while (argc > 0) {
194 selector = dcb_apptrust_parse_selector(*argv, &err);
195 if (err < 0)
196 goto out;
197
198 if (table->nselectors > IEEE_8021QAZ_APP_SEL_MAX)
199 return -ERANGE;
200
201 if (dcb_apptrust_contains(table, selector)) {
202 fprintf(stderr, "Duplicate selector: %s\n",
203 selector_names[selector]);
204 return -EINVAL;
205 }
206
207 table->selectors[table->nselectors++] = selector;
208
209 NEXT_ARG_FWD();
210 }
211
212out:
213 *argcp = argc;
214 *argvp = argv;
215
216 return 0;
217}
218
219static int dcb_cmd_apptrust_set(struct dcb *dcb, const char *dev, int argc,
220 char **argv)
221{
222 struct dcb_apptrust_table table = { 0 };
223 int ret;
224
225 if (!argc) {
226 dcb_apptrust_help_set();
227 return 0;
228 }
229
230 do {
231 if (strcmp(*argv, "help") == 0) {
232 dcb_apptrust_help_set();
233 return 0;
234 } else if (strcmp(*argv, "order") == 0) {
235 NEXT_ARG_FWD();
236 ret = dcb_apptrust_parse_selector_list(&argc, &argv,
237 &table);
238 if (ret < 0) {
239 fprintf(stderr, "Invalid list of selectors\n");
240 return -EINVAL;
241 }
242 } else {
243 fprintf(stderr, "What is \"%s\"?\n", *argv);
244 dcb_apptrust_help_set();
245 return -EINVAL;
246 }
247 } while (argc > 0);
248
249 return dcb_apptrust_set(dcb, dev, &table);
250}
251
252static int dcb_cmd_apptrust_show(struct dcb *dcb, const char *dev, int argc,
253 char **argv)
254{
255 struct dcb_apptrust_table table = { 0 };
256 int ret;
257
258 ret = dcb_apptrust_get(dcb, dev, &table);
259 if (ret)
260 return ret;
261
262 open_json_object(NULL);
263
264 if (!argc) {
265 dcb_apptrust_print(&table);
266 goto out;
267 }
268
269 do {
270 if (strcmp(*argv, "help") == 0) {
271 dcb_apptrust_help_show();
272 return 0;
273 } else if (strcmp(*argv, "order") == 0) {
274 dcb_apptrust_print_order(&table);
275 } else {
276 fprintf(stderr, "What is \"%s\"?\n", *argv);
277 dcb_apptrust_help_show();
278 return -EINVAL;
279 }
280
281 NEXT_ARG_FWD();
282 } while (argc > 0);
283
284out:
285 close_json_object();
286 return 0;
287}
288
289int dcb_cmd_apptrust(struct dcb *dcb, int argc, char **argv)
290{
291 if (!argc || strcmp(*argv, "help") == 0) {
292 dcb_apptrust_help();
293 return 0;
294 } else if (strcmp(*argv, "show") == 0) {
295 NEXT_ARG_FWD();
296 return dcb_cmd_parse_dev(dcb, argc, argv, dcb_cmd_apptrust_show,
297 dcb_apptrust_help_show);
298 } else if (strcmp(*argv, "set") == 0) {
299 NEXT_ARG_FWD();
300 return dcb_cmd_parse_dev(dcb, argc, argv, dcb_cmd_apptrust_set,
301 dcb_apptrust_help_set);
302 } else {
303 fprintf(stderr, "What is \"%s\"?\n", *argv);
304 dcb_apptrust_help();
305 return -EINVAL;
306 }
307}
308