/*
 * iplink_macvlan.c	macvlan/macvtap device support
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 *
 * Authors:     Patrick McHardy <kaber@trash.net>
 *		Arnd Bergmann <arnd@arndb.de>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/if_link.h>
#include <linux/if_ether.h>

#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"

#define pfx_err(lu, ...) {               \
	fprintf(stderr, "%s: ", lu->id); \
	fprintf(stderr, __VA_ARGS__);    \
	fprintf(stderr, "\n");           \
}

static void print_explain(struct link_util *lu, FILE *f)
{
	fprintf(f,
		"Usage: ... %s mode MODE [flag MODE_FLAG] MODE_OPTS\n"
		"\n"
		"MODE: private | vepa | bridge | passthru | source\n"
		"MODE_FLAG: null | nopromisc\n"
		"MODE_OPTS: for mode \"source\":\n"
		"\tmacaddr { { add | del } <macaddr> | set [ <macaddr> [ <macaddr>  ... ] ] | flush }\n",
		lu->id
	);
}

static void explain(struct link_util *lu)
{
	print_explain(lu, stderr);
}


static int mode_arg(const char *arg)
{
	fprintf(stderr,
		"Error: argument of \"mode\" must be \"private\", \"vepa\", \"bridge\", \"passthru\" or \"source\", not \"%s\"\n",
		arg);
	return -1;
}

static int flag_arg(const char *arg)
{
	fprintf(stderr,
		"Error: argument of \"flag\" must be \"nopromisc\" or \"null\", not \"%s\"\n",
		arg);
	return -1;
}

static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
			  struct nlmsghdr *n)
{
	__u32 mode = 0;
	__u16 flags = 0;
	__u32 mac_mode = 0;
	int has_flags = 0;
	char mac[ETH_ALEN];
	struct rtattr *nmac;

	while (argc > 0) {
		if (matches(*argv, "mode") == 0) {
			NEXT_ARG();

			if (strcmp(*argv, "private") == 0)
				mode = MACVLAN_MODE_PRIVATE;
			else if (strcmp(*argv, "vepa") == 0)
				mode = MACVLAN_MODE_VEPA;
			else if (strcmp(*argv, "bridge") == 0)
				mode = MACVLAN_MODE_BRIDGE;
			else if (strcmp(*argv, "passthru") == 0)
				mode = MACVLAN_MODE_PASSTHRU;
			else if (strcmp(*argv, "source") == 0)
				mode = MACVLAN_MODE_SOURCE;
			else
				return mode_arg(*argv);
		} else if (matches(*argv, "flag") == 0) {
			NEXT_ARG();

			if (strcmp(*argv, "nopromisc") == 0)
				flags |= MACVLAN_FLAG_NOPROMISC;
			else if (strcmp(*argv, "null") == 0)
				flags |= 0;
			else
				return flag_arg(*argv);

			has_flags = 1;

		} else if (matches(*argv, "macaddr") == 0) {
			NEXT_ARG();

			if (strcmp(*argv, "add") == 0) {
				mac_mode = MACVLAN_MACADDR_ADD;
			} else if (strcmp(*argv, "del") == 0) {
				mac_mode = MACVLAN_MACADDR_DEL;
			} else if (strcmp(*argv, "set") == 0) {
				mac_mode = MACVLAN_MACADDR_SET;
			} else if (strcmp(*argv, "flush") == 0) {
				mac_mode = MACVLAN_MACADDR_FLUSH;
			} else {
				explain(lu);
				return -1;
			}

			addattr32(n, 1024, IFLA_MACVLAN_MACADDR_MODE, mac_mode);

			if (mac_mode == MACVLAN_MACADDR_ADD ||
			    mac_mode == MACVLAN_MACADDR_DEL) {
				NEXT_ARG();

				if (ll_addr_a2n(mac, sizeof(mac),
						*argv) != ETH_ALEN)
					return -1;

				addattr_l(n, 1024, IFLA_MACVLAN_MACADDR, &mac,
					  ETH_ALEN);
			}

			if (mac_mode == MACVLAN_MACADDR_SET) {
				nmac = addattr_nest(n, 1024,
						    IFLA_MACVLAN_MACADDR_DATA);
				while (NEXT_ARG_OK()) {
					NEXT_ARG_FWD();

					if (ll_addr_a2n(mac, sizeof(mac),
							*argv) != ETH_ALEN) {
						PREV_ARG();
						break;
					}

					addattr_l(n, 1024, IFLA_MACVLAN_MACADDR,
						  &mac, ETH_ALEN);
				}
				addattr_nest_end(n, nmac);
			}
		} else if (matches(*argv, "nopromisc") == 0) {
			flags |= MACVLAN_FLAG_NOPROMISC;
			has_flags = 1;
		} else if (matches(*argv, "help") == 0) {
			explain(lu);
			return -1;
		} else {
			pfx_err(lu, "unknown option \"%s\"?", *argv);
			explain(lu);
			return -1;
		}
		argc--, argv++;
	}

	if (mode)
		addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);

	if (has_flags) {
		if (flags & MACVLAN_FLAG_NOPROMISC &&
		    mode != MACVLAN_MODE_PASSTHRU) {
			pfx_err(lu, "nopromisc flag only valid in passthru mode");
			explain(lu);
			return -1;
		}
		addattr16(n, 1024, IFLA_MACVLAN_FLAGS, flags);
	}
	return 0;
}

static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
	__u32 mode;
	__u16 flags;
	__u32 count;
	unsigned char *addr;
	int len;
	struct rtattr *rta;

	if (!tb)
		return;

	if (!tb[IFLA_MACVLAN_MODE] ||
	    RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
		return;

	mode = rta_getattr_u32(tb[IFLA_MACVLAN_MODE]);
	print_string(PRINT_ANY,
		     "mode",
		     "mode %s ",
		     mode == MACVLAN_MODE_PRIVATE ? "private"
		     : mode == MACVLAN_MODE_VEPA    ? "vepa"
		     : mode == MACVLAN_MODE_BRIDGE  ? "bridge"
		     : mode == MACVLAN_MODE_PASSTHRU  ? "passthru"
		     : mode == MACVLAN_MODE_SOURCE  ? "source"
		     :				 "unknown");

	if (!tb[IFLA_MACVLAN_FLAGS] ||
	    RTA_PAYLOAD(tb[IFLA_MACVLAN_FLAGS]) < sizeof(__u16))
		flags = 0;
	else
		flags = rta_getattr_u16(tb[IFLA_MACVLAN_FLAGS]);

	if (flags & MACVLAN_FLAG_NOPROMISC)
		print_bool(PRINT_ANY, "nopromisc", "nopromisc ", true);

	/* in source mode, there are more options to print */

	if (mode != MACVLAN_MODE_SOURCE)
		return;

	if (!tb[IFLA_MACVLAN_MACADDR_COUNT] ||
	    RTA_PAYLOAD(tb[IFLA_MACVLAN_MACADDR_COUNT]) < sizeof(__u32))
		return;

	count = rta_getattr_u32(tb[IFLA_MACVLAN_MACADDR_COUNT]);
	print_int(PRINT_ANY, "macaddr_count", "remotes (%d) ", count);

	if (!tb[IFLA_MACVLAN_MACADDR_DATA])
		return;

	rta = RTA_DATA(tb[IFLA_MACVLAN_MACADDR_DATA]);
	len = RTA_PAYLOAD(tb[IFLA_MACVLAN_MACADDR_DATA]);

	open_json_array(PRINT_JSON, "macaddr_data");
	for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
		if (rta->rta_type != IFLA_MACVLAN_MACADDR ||
		    RTA_PAYLOAD(rta) < 6)
			continue;
		addr = RTA_DATA(rta);
		if (is_json_context()) {
			SPRINT_BUF(b1);

			snprintf(b1, sizeof(b1),
				 "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", addr[0],
				 addr[1], addr[2], addr[3], addr[4], addr[5]);
			print_string(PRINT_JSON, NULL, NULL, b1);
		} else {
			fprintf(f, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x ", addr[0],
				addr[1], addr[2], addr[3], addr[4], addr[5]);
		}
	}
	close_json_array(PRINT_JSON, NULL);
}

static void macvlan_print_help(struct link_util *lu, int argc, char **argv,
			       FILE *f)
{
	print_explain(lu, f);
}

struct link_util macvlan_link_util = {
	.id		= "macvlan",
	.maxattr	= IFLA_MACVLAN_MAX,
	.parse_opt	= macvlan_parse_opt,
	.print_opt	= macvlan_print_opt,
	.print_help	= macvlan_print_help,
};

struct link_util macvtap_link_util = {
	.id		= "macvtap",
	.maxattr	= IFLA_MACVLAN_MAX,
	.parse_opt	= macvlan_parse_opt,
	.print_opt	= macvlan_print_opt,
	.print_help	= macvlan_print_help,
};
