iproute2/dcb/dcb_apptrust.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   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        /* Check that selector is encapsulated in the right attribute */
 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        /* No trusted selectors ? */
 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