Blame dcb/dcb_dcbx.c

Packit Bot 867fae
// SPDX-License-Identifier: GPL-2.0+
Packit Bot 867fae
Packit Bot 867fae
#include <errno.h>
Packit Bot 867fae
#include <inttypes.h>
Packit Bot 867fae
#include <stdio.h>
Packit Bot 867fae
#include <linux/dcbnl.h>
Packit Bot 867fae
Packit Bot 867fae
#include "dcb.h"
Packit Bot 867fae
#include "utils.h"
Packit Bot 867fae
Packit Bot 867fae
static void dcb_dcbx_help_set(void)
Packit Bot 867fae
{
Packit Bot 867fae
	fprintf(stderr,
Packit Bot 867fae
		"Usage: dcb dcbx set dev STRING\n"
Packit Bot 867fae
		"           [ host | lld-managed ]\n"
Packit Bot 867fae
		"           [ cee | ieee ] [ static ]\n"
Packit Bot 867fae
		"\n"
Packit Bot 867fae
	);
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
static void dcb_dcbx_help_show(void)
Packit Bot 867fae
{
Packit Bot 867fae
	fprintf(stderr,
Packit Bot 867fae
		"Usage: dcb dcbx show dev STRING\n"
Packit Bot 867fae
		"\n"
Packit Bot 867fae
	);
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
static void dcb_dcbx_help(void)
Packit Bot 867fae
{
Packit Bot 867fae
	fprintf(stderr,
Packit Bot 867fae
		"Usage: dcb dcbx help\n"
Packit Bot 867fae
		"\n"
Packit Bot 867fae
	);
Packit Bot 867fae
	dcb_dcbx_help_show();
Packit Bot 867fae
	dcb_dcbx_help_set();
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
struct dcb_dcbx_flag {
Packit Bot 867fae
	__u8 value;
Packit Bot 867fae
	const char *key_fp;
Packit Bot 867fae
	const char *key_json;
Packit Bot 867fae
};
Packit Bot 867fae
Packit Bot 867fae
static struct dcb_dcbx_flag dcb_dcbx_flags[] = {
Packit Bot 867fae
	{DCB_CAP_DCBX_HOST, "host"},
Packit Bot 867fae
	{DCB_CAP_DCBX_LLD_MANAGED, "lld-managed", "lld_managed"},
Packit Bot 867fae
	{DCB_CAP_DCBX_VER_CEE, "cee"},
Packit Bot 867fae
	{DCB_CAP_DCBX_VER_IEEE, "ieee"},
Packit Bot 867fae
	{DCB_CAP_DCBX_STATIC, "static"},
Packit Bot 867fae
};
Packit Bot 867fae
Packit Bot 867fae
static void dcb_dcbx_print(__u8 dcbx)
Packit Bot 867fae
{
Packit Bot 867fae
	int bit;
Packit Bot 867fae
	int i;
Packit Bot 867fae
Packit Bot 867fae
	while ((bit = ffs(dcbx))) {
Packit Bot 867fae
		bool found = false;
Packit Bot 867fae
Packit Bot 867fae
		bit--;
Packit Bot 867fae
		for (i = 0; i < ARRAY_SIZE(dcb_dcbx_flags); i++) {
Packit Bot 867fae
			struct dcb_dcbx_flag *flag = &dcb_dcbx_flags[i];
Packit Bot 867fae
Packit Bot 867fae
			if (flag->value == 1 << bit) {
Packit Bot 867fae
				print_bool(PRINT_JSON, flag->key_json ?: flag->key_fp,
Packit Bot 867fae
					   NULL, true);
Packit Bot 867fae
				print_string(PRINT_FP, NULL, "%s ", flag->key_fp);
Packit Bot 867fae
				found = true;
Packit Bot 867fae
				break;
Packit Bot 867fae
			}
Packit Bot 867fae
		}
Packit Bot 867fae
Packit Bot 867fae
		if (!found)
Packit Bot 867fae
			fprintf(stderr, "Unknown DCBX bit %#x.\n", 1 << bit);
Packit Bot 867fae
Packit Bot 867fae
		dcbx &= ~(1 << bit);
Packit Bot 867fae
	}
Packit Bot 867fae
Packit Bot 867fae
	print_nl();
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
static int dcb_dcbx_get(struct dcb *dcb, const char *dev, __u8 *dcbx)
Packit Bot 867fae
{
Packit Bot 867fae
	__u16 payload_len;
Packit Bot 867fae
	void *payload;
Packit Bot 867fae
	int err;
Packit Bot 867fae
Packit Bot 867fae
	err = dcb_get_attribute_bare(dcb, DCB_CMD_IEEE_GET, dev, DCB_ATTR_DCBX,
Packit Bot 867fae
				     &payload, &payload_len);
Packit Bot 867fae
	if (err != 0)
Packit Bot 867fae
		return err;
Packit Bot 867fae
Packit Bot 867fae
	if (payload_len != 1) {
Packit Bot 867fae
		fprintf(stderr, "DCB_ATTR_DCBX payload has size %d, expected 1.\n",
Packit Bot 867fae
			payload_len);
Packit Bot 867fae
		return -EINVAL;
Packit Bot 867fae
	}
Packit Bot 867fae
	*dcbx = *(__u8 *) payload;
Packit Bot 867fae
	return 0;
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
static int dcb_dcbx_set(struct dcb *dcb, const char *dev, __u8 dcbx)
Packit Bot 867fae
{
Packit Bot 867fae
	return dcb_set_attribute_bare(dcb, DCB_CMD_SDCBX, dev, DCB_ATTR_DCBX,
Packit Bot 867fae
				      &dcbx, 1, DCB_ATTR_DCBX);
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
static int dcb_cmd_dcbx_set(struct dcb *dcb, const char *dev, int argc, char **argv)
Packit Bot 867fae
{
Packit Bot 867fae
	__u8 dcbx = 0;
Packit Bot 867fae
	__u8 i;
Packit Bot 867fae
Packit Bot 867fae
	if (!argc) {
Packit Bot 867fae
		dcb_dcbx_help_set();
Packit Bot 867fae
		return 0;
Packit Bot 867fae
	}
Packit Bot 867fae
Packit Bot 867fae
	do {
Packit Bot 867fae
		if (matches(*argv, "help") == 0) {
Packit Bot 867fae
			dcb_dcbx_help_set();
Packit Bot 867fae
			return 0;
Packit Bot 867fae
		}
Packit Bot 867fae
Packit Bot 867fae
		for (i = 0; i < ARRAY_SIZE(dcb_dcbx_flags); i++) {
Packit Bot 867fae
			struct dcb_dcbx_flag *flag = &dcb_dcbx_flags[i];
Packit Bot 867fae
Packit Bot 867fae
			if (matches(*argv, flag->key_fp) == 0) {
Packit Bot 867fae
				dcbx |= flag->value;
Packit Bot 867fae
				NEXT_ARG_FWD();
Packit Bot 867fae
				goto next;
Packit Bot 867fae
			}
Packit Bot 867fae
		}
Packit Bot 867fae
Packit Bot 867fae
		fprintf(stderr, "What is \"%s\"?\n", *argv);
Packit Bot 867fae
		dcb_dcbx_help_set();
Packit Bot 867fae
		return -EINVAL;
Packit Bot 867fae
Packit Bot 867fae
next:
Packit Bot 867fae
		;
Packit Bot 867fae
	} while (argc > 0);
Packit Bot 867fae
Packit Bot 867fae
	return dcb_dcbx_set(dcb, dev, dcbx);
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
static int dcb_cmd_dcbx_show(struct dcb *dcb, const char *dev, int argc, char **argv)
Packit Bot 867fae
{
Packit Bot 867fae
	__u8 dcbx;
Packit Bot 867fae
	int ret;
Packit Bot 867fae
Packit Bot 867fae
	ret = dcb_dcbx_get(dcb, dev, &dcbx);
Packit Bot 867fae
	if (ret != 0)
Packit Bot 867fae
		return ret;
Packit Bot 867fae
Packit Bot 867fae
	while (argc > 0) {
Packit Bot 867fae
		if (matches(*argv, "help") == 0) {
Packit Bot 867fae
			dcb_dcbx_help_show();
Packit Bot 867fae
			return 0;
Packit Bot 867fae
		} else {
Packit Bot 867fae
			fprintf(stderr, "What is \"%s\"?\n", *argv);
Packit Bot 867fae
			dcb_dcbx_help_show();
Packit Bot 867fae
			return -EINVAL;
Packit Bot 867fae
		}
Packit Bot 867fae
Packit Bot 867fae
		NEXT_ARG_FWD();
Packit Bot 867fae
	}
Packit Bot 867fae
Packit Bot 867fae
	open_json_object(NULL);
Packit Bot 867fae
	dcb_dcbx_print(dcbx);
Packit Bot 867fae
	close_json_object();
Packit Bot 867fae
	return 0;
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
int dcb_cmd_dcbx(struct dcb *dcb, int argc, char **argv)
Packit Bot 867fae
{
Packit Bot 867fae
	if (!argc || matches(*argv, "help") == 0) {
Packit Bot 867fae
		dcb_dcbx_help();
Packit Bot 867fae
		return 0;
Packit Bot 867fae
	} else if (matches(*argv, "show") == 0) {
Packit Bot 867fae
		NEXT_ARG_FWD();
Packit Bot 867fae
		return dcb_cmd_parse_dev(dcb, argc, argv,
Packit Bot 867fae
					 dcb_cmd_dcbx_show, dcb_dcbx_help_show);
Packit Bot 867fae
	} else if (matches(*argv, "set") == 0) {
Packit Bot 867fae
		NEXT_ARG_FWD();
Packit Bot 867fae
		return dcb_cmd_parse_dev(dcb, argc, argv,
Packit Bot 867fae
					 dcb_cmd_dcbx_set, dcb_dcbx_help_set);
Packit Bot 867fae
	} else {
Packit Bot 867fae
		fprintf(stderr, "What is \"%s\"?\n", *argv);
Packit Bot 867fae
		dcb_dcbx_help();
Packit Bot 867fae
		return -EINVAL;
Packit Bot 867fae
	}
Packit Bot 867fae
}