/* SPDX-License-Identifier: GPL-2.0 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/if_bridge.h>
#include <string.h>
#include <stdbool.h>

#include "json_print.h"
#include "libnetlink.h"
#include "utils.h"
#include "br_common.h"

static unsigned int filter_index;

static const char *port_states[] = {
	[BR_STATE_DISABLED] = "disabled",
	[BR_STATE_LISTENING] = "listening",
	[BR_STATE_LEARNING] = "learning",
	[BR_STATE_FORWARDING] = "forwarding",
	[BR_STATE_BLOCKING] = "blocking",
};

static const char *hw_mode[] = {
	"VEB", "VEPA"
};

static void print_link_flags(FILE *fp, unsigned int flags, unsigned int mdown)
{
	open_json_array(PRINT_ANY, is_json_context() ? "flags" : "<");
	if (flags & IFF_UP && !(flags & IFF_RUNNING))
		print_string(PRINT_ANY, NULL,
			     flags ? "%s," : "%s", "NO-CARRIER");
	flags &= ~IFF_RUNNING;

#define _PF(f) if (flags&IFF_##f) {					\
		flags &= ~IFF_##f ;					\
		print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); }
	_PF(LOOPBACK);
	_PF(BROADCAST);
	_PF(POINTOPOINT);
	_PF(MULTICAST);
	_PF(NOARP);
	_PF(ALLMULTI);
	_PF(PROMISC);
	_PF(MASTER);
	_PF(SLAVE);
	_PF(DEBUG);
	_PF(DYNAMIC);
	_PF(AUTOMEDIA);
	_PF(PORTSEL);
	_PF(NOTRAILERS);
	_PF(UP);
	_PF(LOWER_UP);
	_PF(DORMANT);
	_PF(ECHO);
#undef _PF
	if (flags)
		print_hex(PRINT_ANY, NULL, "%x", flags);
	if (mdown)
		print_string(PRINT_ANY, NULL, ",%s", "M-DOWN");
	close_json_array(PRINT_ANY, "> ");
}

static void print_portstate(__u8 state)
{
	if (state <= BR_STATE_BLOCKING)
		print_string(PRINT_ANY, "state",
			     "state %s ", port_states[state]);
	else
		print_uint(PRINT_ANY, "state",
			     "state (%d) ", state);
}

static void print_onoff(FILE *fp, const char *flag, __u8 val)
{
	if (is_json_context())
		print_bool(PRINT_JSON, flag, NULL, val);
	else
		fprintf(fp, "%s %s ", flag, val ? "on" : "off");
}

static void print_hwmode(__u16 mode)
{
	if (mode >= ARRAY_SIZE(hw_mode))
		print_0xhex(PRINT_ANY, "hwmode",
			    "hwmode %#llx ", mode);
	else
		print_string(PRINT_ANY, "hwmode",
			     "hwmode %s ", hw_mode[mode]);
}

static void print_protinfo(FILE *fp, struct rtattr *attr)
{
	if (attr->rta_type & NLA_F_NESTED) {
		struct rtattr *prtb[IFLA_BRPORT_MAX + 1];

		parse_rtattr_nested(prtb, IFLA_BRPORT_MAX, attr);

		if (prtb[IFLA_BRPORT_STATE])
			print_portstate(rta_getattr_u8(prtb[IFLA_BRPORT_STATE]));

		if (prtb[IFLA_BRPORT_PRIORITY])
			print_uint(PRINT_ANY, "priority",
				   "priority %u ",
				   rta_getattr_u16(prtb[IFLA_BRPORT_PRIORITY]));

		if (prtb[IFLA_BRPORT_COST])
			print_uint(PRINT_ANY, "cost",
				   "cost %u ",
				   rta_getattr_u32(prtb[IFLA_BRPORT_COST]));

		if (!show_details)
			return;

		if (!is_json_context())
			fprintf(fp, "%s    ", _SL_);

		if (prtb[IFLA_BRPORT_MODE])
			print_onoff(fp, "hairpin",
				    rta_getattr_u8(prtb[IFLA_BRPORT_MODE]));
		if (prtb[IFLA_BRPORT_GUARD])
			print_onoff(fp, "guard",
				    rta_getattr_u8(prtb[IFLA_BRPORT_GUARD]));
		if (prtb[IFLA_BRPORT_PROTECT])
			print_onoff(fp, "root_block",
				    rta_getattr_u8(prtb[IFLA_BRPORT_PROTECT]));
		if (prtb[IFLA_BRPORT_FAST_LEAVE])
			print_onoff(fp, "fastleave",
				    rta_getattr_u8(prtb[IFLA_BRPORT_FAST_LEAVE]));
		if (prtb[IFLA_BRPORT_LEARNING])
			print_onoff(fp, "learning",
				    rta_getattr_u8(prtb[IFLA_BRPORT_LEARNING]));
		if (prtb[IFLA_BRPORT_LEARNING_SYNC])
			print_onoff(fp, "learning_sync",
				    rta_getattr_u8(prtb[IFLA_BRPORT_LEARNING_SYNC]));
		if (prtb[IFLA_BRPORT_UNICAST_FLOOD])
			print_onoff(fp, "flood",
				    rta_getattr_u8(prtb[IFLA_BRPORT_UNICAST_FLOOD]));
		if (prtb[IFLA_BRPORT_MCAST_FLOOD])
			print_onoff(fp, "mcast_flood",
				    rta_getattr_u8(prtb[IFLA_BRPORT_MCAST_FLOOD]));
		if (prtb[IFLA_BRPORT_MCAST_TO_UCAST])
			print_onoff(fp, "mcast_to_unicast",
				    rta_getattr_u8(prtb[IFLA_BRPORT_MCAST_TO_UCAST]));
		if (prtb[IFLA_BRPORT_NEIGH_SUPPRESS])
			print_onoff(fp, "neigh_suppress",
				    rta_getattr_u8(prtb[IFLA_BRPORT_NEIGH_SUPPRESS]));
		if (prtb[IFLA_BRPORT_VLAN_TUNNEL])
			print_onoff(fp, "vlan_tunnel",
				    rta_getattr_u8(prtb[IFLA_BRPORT_VLAN_TUNNEL]));

		if (prtb[IFLA_BRPORT_BACKUP_PORT]) {
			int ifidx;

			ifidx = rta_getattr_u32(prtb[IFLA_BRPORT_BACKUP_PORT]);
			print_string(PRINT_ANY,
				     "backup_port", "backup_port %s ",
				     ll_index_to_name(ifidx));
		}

		if (prtb[IFLA_BRPORT_ISOLATED])
			print_onoff(fp, "isolated",
				    rta_getattr_u8(prtb[IFLA_BRPORT_ISOLATED]));
	} else
		print_portstate(rta_getattr_u8(attr));
}


/*
 * This is reported by HW devices that have some bridging
 * capabilities.
 */
static void print_af_spec(struct rtattr *attr, int ifindex)
{
	struct rtattr *aftb[IFLA_BRIDGE_MAX+1];

	parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, attr);

	if (aftb[IFLA_BRIDGE_MODE])
		print_hwmode(rta_getattr_u16(aftb[IFLA_BRIDGE_MODE]));

	if (!show_details)
		return;

	if (aftb[IFLA_BRIDGE_VLAN_INFO])
		print_vlan_info(aftb[IFLA_BRIDGE_VLAN_INFO], ifindex);
}

int print_linkinfo(struct nlmsghdr *n, void *arg)
{
	FILE *fp = arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr *tb[IFLA_MAX+1];
	unsigned int m_flag = 0;
	int len = n->nlmsg_len;
	const char *name;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0) {
		fprintf(stderr, "Message too short!\n");
		return -1;
	}

	if (!(ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_UNSPEC))
		return 0;

	if (filter_index && filter_index != ifi->ifi_index)
		return 0;

	parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);

	name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
	if (!name)
		return -1;

	open_json_object(NULL);
	if (n->nlmsg_type == RTM_DELLINK)
		print_bool(PRINT_ANY, "deleted", "Deleted ", true);

	print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
	m_flag = print_name_and_link("%s: ", name, tb);
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		print_int(PRINT_ANY,
			  "mtu", "mtu %u ",
			  rta_getattr_u32(tb[IFLA_MTU]));

	if (tb[IFLA_MASTER]) {
		int master = rta_getattr_u32(tb[IFLA_MASTER]);

		print_string(PRINT_ANY, "master", "master %s ",
			     ll_index_to_name(master));
	}

	if (tb[IFLA_PROTINFO])
		print_protinfo(fp, tb[IFLA_PROTINFO]);

	if (tb[IFLA_AF_SPEC])
		print_af_spec(tb[IFLA_AF_SPEC], ifi->ifi_index);

	print_string(PRINT_FP, NULL, "%s", "\n");
	close_json_object();
	fflush(fp);
	return 0;
}

static void usage(void)
{
	fprintf(stderr,
		"Usage: bridge link set dev DEV [ cost COST ] [ priority PRIO ] [ state STATE ]\n"
		"                               [ guard {on | off} ]\n"
		"                               [ hairpin {on | off} ]\n"
		"                               [ fastleave {on | off} ]\n"
		"                               [ root_block {on | off} ]\n"
		"                               [ learning {on | off} ]\n"
		"                               [ learning_sync {on | off} ]\n"
		"                               [ flood {on | off} ]\n"
		"                               [ mcast_flood {on | off} ]\n"
		"                               [ mcast_to_unicast {on | off} ]\n"
		"                               [ neigh_suppress {on | off} ]\n"
		"                               [ vlan_tunnel {on | off} ]\n"
		"                               [ isolated {on | off} ]\n"
		"                               [ hwmode {vepa | veb} ]\n"
		"                               [ backup_port DEVICE ] [ nobackup_port ]\n"
		"                               [ self ] [ master ]\n"
		"       bridge link show [dev DEV]\n");
	exit(-1);
}

static bool on_off(char *arg, __s8 *attr, char *val)
{
	if (strcmp(val, "on") == 0)
		*attr = 1;
	else if (strcmp(val, "off") == 0)
		*attr = 0;
	else {
		fprintf(stderr,
			"Error: argument of \"%s\" must be \"on\" or \"off\"\n",
			arg);
		return false;
	}

	return true;
}

static int brlink_modify(int argc, char **argv)
{
	struct {
		struct nlmsghdr  n;
		struct ifinfomsg ifm;
		char             buf[512];
	} req = {
		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
		.n.nlmsg_flags = NLM_F_REQUEST,
		.n.nlmsg_type = RTM_SETLINK,
		.ifm.ifi_family = PF_BRIDGE,
	};
	char *d = NULL;
	int backup_port_idx = -1;
	__s8 neigh_suppress = -1;
	__s8 learning = -1;
	__s8 learning_sync = -1;
	__s8 flood = -1;
	__s8 vlan_tunnel = -1;
	__s8 mcast_flood = -1;
	__s8 mcast_to_unicast = -1;
	__s8 isolated = -1;
	__s8 hairpin = -1;
	__s8 bpdu_guard = -1;
	__s8 fast_leave = -1;
	__s8 root_block = -1;
	__u32 cost = 0;
	__s16 priority = -1;
	__s8 state = -1;
	__s16 mode = -1;
	__u16 flags = 0;
	struct rtattr *nest;

	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			d = *argv;
		} else if (strcmp(*argv, "guard") == 0) {
			NEXT_ARG();
			if (!on_off("guard", &bpdu_guard, *argv))
				return -1;
		} else if (strcmp(*argv, "hairpin") == 0) {
			NEXT_ARG();
			if (!on_off("hairpin", &hairpin, *argv))
				return -1;
		} else if (strcmp(*argv, "fastleave") == 0) {
			NEXT_ARG();
			if (!on_off("fastleave", &fast_leave, *argv))
				return -1;
		} else if (strcmp(*argv, "root_block") == 0) {
			NEXT_ARG();
			if (!on_off("root_block", &root_block, *argv))
				return -1;
		} else if (strcmp(*argv, "learning") == 0) {
			NEXT_ARG();
			if (!on_off("learning", &learning, *argv))
				return -1;
		} else if (strcmp(*argv, "learning_sync") == 0) {
			NEXT_ARG();
			if (!on_off("learning_sync", &learning_sync, *argv))
				return -1;
		} else if (strcmp(*argv, "flood") == 0) {
			NEXT_ARG();
			if (!on_off("flood", &flood, *argv))
				return -1;
		} else if (strcmp(*argv, "mcast_flood") == 0) {
			NEXT_ARG();
			if (!on_off("mcast_flood", &mcast_flood, *argv))
				return -1;
		} else if (strcmp(*argv, "mcast_to_unicast") == 0) {
			NEXT_ARG();
			if (!on_off("mcast_to_unicast", &mcast_to_unicast, *argv))
				return -1;
		} else if (strcmp(*argv, "cost") == 0) {
			NEXT_ARG();
			cost = atoi(*argv);
		} else if (strcmp(*argv, "priority") == 0) {
			NEXT_ARG();
			priority = atoi(*argv);
		} else if (strcmp(*argv, "state") == 0) {
			NEXT_ARG();
			char *endptr;
			size_t nstates = ARRAY_SIZE(port_states);

			state = strtol(*argv, &endptr, 10);
			if (!(**argv != '\0' && *endptr == '\0')) {
				for (state = 0; state < nstates; state++)
					if (strcmp(port_states[state], *argv) == 0)
						break;
				if (state == nstates) {
					fprintf(stderr,
						"Error: invalid STP port state\n");
					return -1;
				}
			}
		} else if (strcmp(*argv, "hwmode") == 0) {
			NEXT_ARG();
			flags = BRIDGE_FLAGS_SELF;
			if (strcmp(*argv, "vepa") == 0)
				mode = BRIDGE_MODE_VEPA;
			else if (strcmp(*argv, "veb") == 0)
				mode = BRIDGE_MODE_VEB;
			else {
				fprintf(stderr,
					"Mode argument must be \"vepa\" or \"veb\".\n");
				return -1;
			}
		} else if (strcmp(*argv, "self") == 0) {
			flags |= BRIDGE_FLAGS_SELF;
		} else if (strcmp(*argv, "master") == 0) {
			flags |= BRIDGE_FLAGS_MASTER;
		} else if (strcmp(*argv, "neigh_suppress") == 0) {
			NEXT_ARG();
			if (!on_off("neigh_suppress", &neigh_suppress,
				    *argv))
				return -1;
		} else if (strcmp(*argv, "vlan_tunnel") == 0) {
			NEXT_ARG();
			if (!on_off("vlan_tunnel", &vlan_tunnel,
				    *argv))
				return -1;
		} else if (strcmp(*argv, "isolated") == 0) {
			NEXT_ARG();
			if (!on_off("isolated", &isolated, *argv))
				return -1;
		} else if (strcmp(*argv, "backup_port") == 0) {
			NEXT_ARG();
			backup_port_idx = ll_name_to_index(*argv);
			if (!backup_port_idx) {
				fprintf(stderr, "Error: device %s does not exist\n",
					*argv);
				return -1;
			}
		} else if (strcmp(*argv, "nobackup_port") == 0) {
			backup_port_idx = 0;
		} else {
			usage();
		}
		argc--; argv++;
	}
	if (d == NULL) {
		fprintf(stderr, "Device is a required argument.\n");
		return -1;
	}


	req.ifm.ifi_index = ll_name_to_index(d);
	if (req.ifm.ifi_index == 0) {
		fprintf(stderr, "Cannot find bridge device \"%s\"\n", d);
		return -1;
	}

	/* Nested PROTINFO attribute.  Contains: port flags, cost, priority and
	 * state.
	 */
	nest = addattr_nest(&req.n, sizeof(req),
			    IFLA_PROTINFO | NLA_F_NESTED);
	/* Flags first */
	if (bpdu_guard >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_GUARD, bpdu_guard);
	if (hairpin >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_MODE, hairpin);
	if (fast_leave >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_FAST_LEAVE,
			 fast_leave);
	if (root_block >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_PROTECT, root_block);
	if (flood >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_UNICAST_FLOOD, flood);
	if (mcast_flood >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_MCAST_FLOOD,
			 mcast_flood);
	if (mcast_to_unicast >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_MCAST_TO_UCAST,
			 mcast_to_unicast);
	if (learning >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_LEARNING, learning);
	if (learning_sync >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_LEARNING_SYNC,
			 learning_sync);

	if (cost > 0)
		addattr32(&req.n, sizeof(req), IFLA_BRPORT_COST, cost);

	if (priority >= 0)
		addattr16(&req.n, sizeof(req), IFLA_BRPORT_PRIORITY, priority);

	if (state >= 0)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_STATE, state);

	if (neigh_suppress != -1)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_NEIGH_SUPPRESS,
			 neigh_suppress);
	if (vlan_tunnel != -1)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_VLAN_TUNNEL,
			 vlan_tunnel);
	if (isolated != -1)
		addattr8(&req.n, sizeof(req), IFLA_BRPORT_ISOLATED, isolated);

	if (backup_port_idx != -1)
		addattr32(&req.n, sizeof(req), IFLA_BRPORT_BACKUP_PORT,
			  backup_port_idx);

	addattr_nest_end(&req.n, nest);

	/* IFLA_AF_SPEC nested attribute. Contains IFLA_BRIDGE_FLAGS that
	 * designates master or self operation and IFLA_BRIDGE_MODE
	 * for hw 'vepa' or 'veb' operation modes. The hwmodes are
	 * only valid in 'self' mode on some devices so far.
	 */
	if (mode >= 0 || flags > 0) {
		nest = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC);

		if (flags > 0)
			addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags);

		if (mode >= 0)
			addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MODE, mode);

		addattr_nest_end(&req.n, nest);
	}

	if (rtnl_talk(&rth, &req.n, NULL) < 0)
		return -1;

	return 0;
}

static int brlink_show(int argc, char **argv)
{
	char *filter_dev = NULL;

	while (argc > 0) {
		if (strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			if (filter_dev)
				duparg("dev", *argv);
			filter_dev = *argv;
		}
		argc--; argv++;
	}

	if (filter_dev) {
		filter_index = ll_name_to_index(filter_dev);
		if (!filter_index)
			return nodev(filter_dev);
	}

	if (show_details) {
		if (rtnl_linkdump_req_filter(&rth, PF_BRIDGE,
					     (compress_vlans ?
					      RTEXT_FILTER_BRVLAN_COMPRESSED :
					      RTEXT_FILTER_BRVLAN)) < 0) {
			perror("Cannon send dump request");
			exit(1);
		}
	} else {
		if (rtnl_linkdump_req(&rth, PF_BRIDGE) < 0) {
			perror("Cannon send dump request");
			exit(1);
		}
	}

	new_json_obj(json);
	if (rtnl_dump_filter(&rth, print_linkinfo, stdout) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	delete_json_obj();
	fflush(stdout);
	return 0;
}

int do_link(int argc, char **argv)
{
	ll_init_map(&rth);
	if (argc > 0) {
		if (matches(*argv, "set") == 0 ||
		    matches(*argv, "change") == 0)
			return brlink_modify(argc-1, argv+1);
		if (matches(*argv, "show") == 0 ||
		    matches(*argv, "lst") == 0 ||
		    matches(*argv, "list") == 0)
			return brlink_show(argc-1, argv+1);
		if (matches(*argv, "help") == 0)
			usage();
	} else
		return brlink_show(0, NULL);

	fprintf(stderr, "Command \"%s\" is unknown, try \"bridge link help\".\n", *argv);
	exit(-1);
}
