/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2010-2013 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @ingroup link
 * @defgroup bridge Bridging
 *
 * @details
 * @{
 */

#include "nl-default.h"

#include <linux/if_bridge.h>

#include <netlink/netlink.h>
#include <netlink/attr.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/link/bridge.h>

#include "nl-route.h"
#include "link-api.h"
#include "nl-priv-dynamic-core/nl-core.h"

#define VLAN_VID_MASK           0x0fff /* VLAN Identifier */

/** @cond SKIP */
#define BRIDGE_ATTR_PORT_STATE		(1 << 0)
#define BRIDGE_ATTR_PRIORITY		(1 << 1)
#define BRIDGE_ATTR_COST		(1 << 2)
#define BRIDGE_ATTR_FLAGS		(1 << 3)
#define BRIDGE_ATTR_PORT_VLAN           (1 << 4)
#define BRIDGE_ATTR_HWMODE		(1 << 5)
#define BRIDGE_ATTR_SELF		(1 << 6)

#define PRIV_FLAG_NEW_ATTRS		(1 << 0)

struct bridge_data
{
	uint8_t			b_port_state;
	uint8_t			b_priv_flags; /* internal flags */
	uint16_t		b_hwmode;
	uint16_t		b_priority;
	uint16_t		b_self; /* here for comparison reasons */
	uint32_t		b_cost;
	uint32_t		b_flags;
	uint32_t		b_flags_mask;
	uint32_t                ce_mask; /* HACK to support attr macros */
	struct rtnl_link_bridge_vlan vlan_info;
};

static void set_bit(unsigned nr, uint32_t *addr)
{
	if (nr < RTNL_LINK_BRIDGE_VLAN_BITMAP_MAX)
		addr[nr / 32] |= (((uint32_t) 1) << (nr % 32));
}

static int find_next_bit(int i, uint32_t x)
{
	int j;

	if (i >= 32)
		return -1;

	/* find first bit */
	if (i < 0)
		return __builtin_ffs(x);

	/* mask off prior finds to get next */
	j = __builtin_ffs(x >> i);
	return j ? j + i : 0;
}

static struct rtnl_link_af_ops bridge_ops;

#define IS_BRIDGE_LINK_ASSERT(link) \
	if (!rtnl_link_is_bridge(link)) { \
		APPBUG("A function was expecting a link object of type bridge."); \
		return -NLE_OPNOTSUPP; \
	}

static inline struct bridge_data *bridge_data(struct rtnl_link *link)
{
	return rtnl_link_af_data(link, &bridge_ops);
}

static void *bridge_alloc(struct rtnl_link *link)
{
	return calloc(1, sizeof(struct bridge_data));
}

static void *bridge_clone(struct rtnl_link *link, void *data)
{
	struct bridge_data *bd;

	if ((bd = bridge_alloc(link)))
		memcpy(bd, data, sizeof(*bd));

	return bd;
}

static void bridge_free(struct rtnl_link *link, void *data)
{
	free(data);
}

static struct nla_policy br_attrs_policy[IFLA_BRPORT_MAX+1] = {
	[IFLA_BRPORT_STATE]		= { .type = NLA_U8 },
	[IFLA_BRPORT_PRIORITY]		= { .type = NLA_U16 },
	[IFLA_BRPORT_COST]		= { .type = NLA_U32 },
	[IFLA_BRPORT_MODE]		= { .type = NLA_U8 },
	[IFLA_BRPORT_GUARD]		= { .type = NLA_U8 },
	[IFLA_BRPORT_PROTECT]		= { .type = NLA_U8 },
	[IFLA_BRPORT_FAST_LEAVE]	= { .type = NLA_U8 },
	[IFLA_BRPORT_LEARNING]		= { .type = NLA_U8 },
	[IFLA_BRPORT_LEARNING_SYNC]	= { .type = NLA_U8 },
	[IFLA_BRPORT_UNICAST_FLOOD]	= { .type = NLA_U8 },
};

static void check_flag(struct rtnl_link *link, struct nlattr *attrs[],
		       int type, int flag)
{
	if (attrs[type] && nla_get_u8(attrs[type]))
		rtnl_link_bridge_set_flags(link, flag);
}

static int bridge_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
				 void *data)
{
	struct bridge_data *bd = data;
	struct nlattr *br_attrs[IFLA_BRPORT_MAX+1];
	int err;

	/* Backwards compatibility */
	if (!nla_is_nested(attr)) {
		if (nla_len(attr) < 1)
			return -NLE_RANGE;

		bd->b_port_state = nla_get_u8(attr);
		bd->ce_mask |= BRIDGE_ATTR_PORT_STATE;

		return 0;
	}

	if ((err = nla_parse_nested(br_attrs, IFLA_BRPORT_MAX, attr,
	     br_attrs_policy)) < 0)
		return err;

	bd->b_priv_flags |= PRIV_FLAG_NEW_ATTRS;

	if (br_attrs[IFLA_BRPORT_STATE]) {
		bd->b_port_state = nla_get_u8(br_attrs[IFLA_BRPORT_STATE]);
		bd->ce_mask |= BRIDGE_ATTR_PORT_STATE;
	}

	if (br_attrs[IFLA_BRPORT_PRIORITY]) {
		bd->b_priority = nla_get_u16(br_attrs[IFLA_BRPORT_PRIORITY]);
		bd->ce_mask |= BRIDGE_ATTR_PRIORITY;
	}

	if (br_attrs[IFLA_BRPORT_COST]) {
		bd->b_cost = nla_get_u32(br_attrs[IFLA_BRPORT_COST]);
		bd->ce_mask |= BRIDGE_ATTR_COST;
	}

	check_flag(link, br_attrs, IFLA_BRPORT_MODE, RTNL_BRIDGE_HAIRPIN_MODE);
	check_flag(link, br_attrs, IFLA_BRPORT_GUARD, RTNL_BRIDGE_BPDU_GUARD);
	check_flag(link, br_attrs, IFLA_BRPORT_PROTECT, RTNL_BRIDGE_ROOT_BLOCK);
	check_flag(link, br_attrs, IFLA_BRPORT_FAST_LEAVE, RTNL_BRIDGE_FAST_LEAVE);
	check_flag(link, br_attrs, IFLA_BRPORT_UNICAST_FLOOD,
	           RTNL_BRIDGE_UNICAST_FLOOD);
	check_flag(link, br_attrs, IFLA_BRPORT_LEARNING, RTNL_BRIDGE_LEARNING);
	check_flag(link, br_attrs, IFLA_BRPORT_LEARNING_SYNC,
	           RTNL_BRIDGE_LEARNING_SYNC);

	return 0;
}

static int bridge_parse_af_full(struct rtnl_link *link, struct nlattr *attr_full,
                                void *data)
{
	struct bridge_data *bd = data;
	struct bridge_vlan_info *vinfo = NULL;
	uint16_t vid_range_start = 0;
	uint16_t vid_range_flags = -1;

	struct nlattr *attr;
	int remaining;

	nla_for_each_nested(attr, attr_full, remaining) {

		if (nla_type(attr) == IFLA_BRIDGE_MODE) {
			bd->b_hwmode = nla_get_u16(attr);
			bd->ce_mask |= BRIDGE_ATTR_HWMODE;
			continue;
		} else if (nla_type(attr) != IFLA_BRIDGE_VLAN_INFO)
			continue;

		if (nla_len(attr) != sizeof(struct bridge_vlan_info))
			return -EINVAL;

		vinfo = nla_data(attr);
		if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK)
			return -EINVAL;


		if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
			vid_range_start = vinfo->vid;
			vid_range_flags = (vinfo->flags ^ BRIDGE_VLAN_INFO_RANGE_BEGIN);
			continue;
		}

		if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) {
			/* sanity check the range flags */
			if (vid_range_flags != (vinfo->flags ^ BRIDGE_VLAN_INFO_RANGE_END)) {
				NL_DBG(1, "VLAN range flags differ; can not handle it.\n");
				return -EINVAL;
			}
		} else {
			vid_range_start = vinfo->vid;
		}

		for (; vid_range_start <= vinfo->vid; vid_range_start++) {
			if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
				bd->vlan_info.pvid = vinfo->vid;

			if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
				set_bit(vid_range_start, bd->vlan_info.untagged_bitmap);

			set_bit(vid_range_start, bd->vlan_info.vlan_bitmap);
			bd->ce_mask |= BRIDGE_ATTR_PORT_VLAN;
		}

		vid_range_flags = -1;
	}

	return 0;
}

static int bridge_fill_af(struct rtnl_link *link, struct nl_msg *msg,
		   void *data)
{
	struct bridge_data *bd = data;

	if ((bd->ce_mask & BRIDGE_ATTR_SELF)||(bd->ce_mask & BRIDGE_ATTR_HWMODE))
		NLA_PUT_U16(msg, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF);

	if (bd->ce_mask & BRIDGE_ATTR_HWMODE)
		NLA_PUT_U16(msg, IFLA_BRIDGE_MODE, bd->b_hwmode);

	return 0;

nla_put_failure:
	return -NLE_MSGSIZE;
}

static int bridge_fill_pi(struct rtnl_link *link, struct nl_msg *msg,
		   void *data)
{
	struct bridge_data *bd = data;

	if (bd->ce_mask & BRIDGE_ATTR_FLAGS) {
		if (bd->b_flags_mask & RTNL_BRIDGE_BPDU_GUARD) {
			NLA_PUT_U8(msg, IFLA_BRPORT_GUARD,
						bd->b_flags & RTNL_BRIDGE_BPDU_GUARD);
		}
		if (bd->b_flags_mask & RTNL_BRIDGE_HAIRPIN_MODE) {
			NLA_PUT_U8(msg, IFLA_BRPORT_MODE,
			           bd->b_flags & RTNL_BRIDGE_HAIRPIN_MODE);
		}
		if (bd->b_flags_mask & RTNL_BRIDGE_FAST_LEAVE) {
			NLA_PUT_U8(msg, IFLA_BRPORT_FAST_LEAVE,
			           bd->b_flags & RTNL_BRIDGE_FAST_LEAVE);
		}
		if (bd->b_flags_mask & RTNL_BRIDGE_ROOT_BLOCK) {
			NLA_PUT_U8(msg, IFLA_BRPORT_PROTECT,
			           bd->b_flags & RTNL_BRIDGE_ROOT_BLOCK);
		}
		if (bd->b_flags_mask & RTNL_BRIDGE_UNICAST_FLOOD) {
			NLA_PUT_U8(msg, IFLA_BRPORT_UNICAST_FLOOD,
			           bd->b_flags & RTNL_BRIDGE_UNICAST_FLOOD);
		}
		if (bd->b_flags_mask & RTNL_BRIDGE_LEARNING) {
			NLA_PUT_U8(msg, IFLA_BRPORT_LEARNING,
			           bd->b_flags & RTNL_BRIDGE_LEARNING);
		}
		if (bd->b_flags_mask & RTNL_BRIDGE_LEARNING_SYNC) {
			NLA_PUT_U8(msg, IFLA_BRPORT_LEARNING_SYNC,
			           bd->b_flags & RTNL_BRIDGE_LEARNING_SYNC);
		}
	}

	if (bd->ce_mask & BRIDGE_ATTR_COST)
		NLA_PUT_U32(msg, IFLA_BRPORT_COST, bd->b_cost);

	if (bd->ce_mask & BRIDGE_ATTR_PRIORITY)
		NLA_PUT_U16(msg, IFLA_BRPORT_PRIORITY, bd->b_priority);

	if (bd->ce_mask & BRIDGE_ATTR_PORT_STATE)
		NLA_PUT_U8(msg, IFLA_BRPORT_STATE, bd->b_port_state);

	return 0;

nla_put_failure:
	return -NLE_MSGSIZE;
}

static int bridge_override_rtm(struct rtnl_link *link) {
        struct bridge_data *bd;

        if (!rtnl_link_is_bridge(link))
                return 0;

        bd = bridge_data(link);

        if (bd->ce_mask & BRIDGE_ATTR_FLAGS)
                return 1;

        return 0;
}

static int bridge_get_af(struct nl_msg *msg, uint32_t *ext_filter_mask)
{
	*ext_filter_mask |= RTEXT_FILTER_BRVLAN;
	return 0;
}

static void dump_bitmap(struct nl_dump_params *p, const uint32_t *b)
{
	int i = -1, j, k;
	int start = -1, prev = -1;
	int done, found = 0;

	for (k = 0; k < RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN; k++) {
		int base_bit;
		uint32_t a = b[k];

		base_bit = k * 32;
		i = -1;
		done = 0;
		while (!done) {
			j = find_next_bit(i, a);
			if (j > 0) {
				/* first hit of any bit */
				if (start < 0 && prev < 0) {
					start = prev = j - 1 + base_bit;
					goto next;
				}
				/* this bit is a continuation of prior bits */
				if (j - 2 + base_bit == prev) {
					prev++;
					goto next;
				}
			} else
				done = 1;

			if (start >= 0) {
				found++;
				if (done && k < RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN - 1)
					break;

				nl_dump(p, " %d", start);
				if (start != prev)
					nl_dump(p, "-%d", prev);

				if (done)
					break;
			}
			if (j > 0)
				start = prev = j - 1 + base_bit;
next:
			i = j;
		}
	}
	if (!found)
		nl_dump(p, " <none>");

	return;
}

static void rtnl_link_bridge_dump_vlans(struct nl_dump_params *p,
					struct bridge_data *bd)
{
	nl_dump(p, "pvid %u", bd->vlan_info.pvid);

	nl_dump(p, "   all vlans:");
	dump_bitmap(p, bd->vlan_info.vlan_bitmap);

	nl_dump(p, "   untagged vlans:");
	dump_bitmap(p, bd->vlan_info.untagged_bitmap);
}

static void bridge_dump_details(struct rtnl_link *link,
				struct nl_dump_params *p, void *data)
{
	struct bridge_data *bd = data;

	nl_dump_line(p, "    bridge: ");

	if (bd->ce_mask & BRIDGE_ATTR_PORT_STATE)
		nl_dump(p, "port-state %u ", bd->b_port_state);

	if (bd->ce_mask & BRIDGE_ATTR_PRIORITY)
		nl_dump(p, "prio %u ", bd->b_priority);

	if (bd->ce_mask & BRIDGE_ATTR_COST)
		nl_dump(p, "cost %u ", bd->b_cost);

	if (bd->ce_mask & BRIDGE_ATTR_HWMODE) {
		char hbuf[32];

		rtnl_link_bridge_hwmode2str(bd->b_hwmode, hbuf, sizeof(hbuf));
		nl_dump(p, "hwmode %s", hbuf);
	}

	if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN)
		rtnl_link_bridge_dump_vlans(p, bd);

	if (bd->ce_mask & BRIDGE_ATTR_FLAGS) {
		char buf[256];

		rtnl_link_bridge_flags2str(bd->b_flags & bd->b_flags_mask,
					   buf, sizeof(buf));
		nl_dump(p, "%s", buf);
	}

	nl_dump(p, "\n");
}

static int bridge_compare(struct rtnl_link *_a, struct rtnl_link *_b,
			  int family, uint32_t attrs, int flags)
{
	struct bridge_data *a = bridge_data(_a);
	struct bridge_data *b = bridge_data(_b);
	int diff = 0;

#define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
	diff |= _DIFF(BRIDGE_ATTR_PORT_STATE,
		      a->b_port_state != b->b_port_state);
	diff |= _DIFF(BRIDGE_ATTR_PRIORITY, a->b_priority != b->b_priority);
	diff |= _DIFF(BRIDGE_ATTR_COST, a->b_cost != b->b_cost);
	diff |= _DIFF(BRIDGE_ATTR_PORT_VLAN,
		      memcmp(&a->vlan_info, &b->vlan_info,
			     sizeof(struct rtnl_link_bridge_vlan)));
	diff |= _DIFF(BRIDGE_ATTR_HWMODE, a->b_hwmode != b->b_hwmode);
	diff |= _DIFF(BRIDGE_ATTR_SELF, a->b_self != b->b_self);

	if (flags & LOOSE_COMPARISON)
		diff |= _DIFF(BRIDGE_ATTR_FLAGS,
			      (a->b_flags ^ b->b_flags) & b->b_flags_mask);
	else
		diff |= _DIFF(BRIDGE_ATTR_FLAGS, a->b_flags != b->b_flags);
#undef _DIFF

	return diff;
}
/** @endcond */

/**
 * Allocate link object of type bridge
 *
 * @return Allocated link object or NULL.
 */
struct rtnl_link *rtnl_link_bridge_alloc(void)
{
	struct rtnl_link *link;

	if (!(link = rtnl_link_alloc()))
		return NULL;

	if (rtnl_link_set_type(link, "bridge") < 0) {
		rtnl_link_put(link);
		return NULL;
	}

	return link;
}

/**
 * Create a new kernel bridge device
 * @arg sk              netlink socket
 * @arg name            name of the bridge device or NULL
 *
 * Creates a new bridge device in the kernel. If no name is
 * provided, the kernel will automatically pick a name of the
 * form "type%d" (e.g. bridge0, vlan1, etc.)
 *
 * @return 0 on success or a negative error code
*/
int rtnl_link_bridge_add(struct nl_sock *sk, const char *name)
{
	int err;
	struct rtnl_link *link;

	if (!(link = rtnl_link_bridge_alloc()))
		return -NLE_NOMEM;

	if(name)
		rtnl_link_set_name(link, name);

	err = rtnl_link_add(sk, link, NLM_F_CREATE);
	rtnl_link_put(link);

	return err;
}

/**
 * Check if a link is a bridge
 * @arg link		Link object
 *
 * @return 1 if the link is a bridge, 0 otherwise.
 */
int rtnl_link_is_bridge(struct rtnl_link *link)
{
	return link->l_family == AF_BRIDGE &&
	       link->l_af_ops == &bridge_ops;
}

/**
 * Check if bridge has extended information
 * @arg link		Link object of type bridge
 *
 * Checks if the bridge object has been constructed based on
 * information that is only available in newer kernels. This
 * affectes the following functions:
 *  - rtnl_link_bridge_get_cost()
 *  - rtnl_link_bridge_get_priority()
 *  - rtnl_link_bridge_get_flags()
 *
 * @return 1 if extended information is available, otherwise 0 is returned.
 */
int rtnl_link_bridge_has_ext_info(struct rtnl_link *link)
{
	struct bridge_data *bd;

	if (!rtnl_link_is_bridge(link))
		return 0;

	bd = bridge_data(link);
	return !!(bd->b_priv_flags & PRIV_FLAG_NEW_ATTRS);
}

/**
 * Set Spanning Tree Protocol (STP) port state
 * @arg link		Link object of type bridge
 * @arg state		New STP port state
 *
 * The value of state must be one of the following:
 *   - BR_STATE_DISABLED
 *   - BR_STATE_LISTENING
 *   - BR_STATE_LEARNING
 *   - BR_STATE_FORWARDING
 *   - BR_STATE_BLOCKING
 *
 * @see rtnl_link_bridge_get_port_state()
 *
 * @return 0 on success or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 * @retval -NLE_INVAL Invalid state value (0..BR_STATE_BLOCKING)
 */
int rtnl_link_bridge_set_port_state(struct rtnl_link *link, uint8_t state)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	if (state > BR_STATE_BLOCKING)
		return -NLE_INVAL;

	bd->b_port_state = state;
	bd->ce_mask |= BRIDGE_ATTR_PORT_STATE;

	return 0;
}

/**
 * Get Spanning Tree Protocol (STP) port state
 * @arg link		Link object of type bridge
 *
 * @see rtnl_link_bridge_set_port_state()
 *
 * @return The STP port state or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 */
int rtnl_link_bridge_get_port_state(struct rtnl_link *link)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	return bd->b_port_state;
}

/**
 * Set priority
 * @arg link		Link object of type bridge
 * @arg prio		Bridge priority
 *
 * @see rtnl_link_bridge_get_priority()
 *
 * @return 0 on success or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 */
int rtnl_link_bridge_set_priority(struct rtnl_link *link, uint16_t prio)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	bd->b_priority = prio;
	bd->ce_mask |= BRIDGE_ATTR_PRIORITY;

	return 0;
}

/**
 * Get priority
 * @arg link		Link object of type bridge
 *
 * @see rtnl_link_bridge_set_priority()
 *
 * @return 0 on success or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 */
int rtnl_link_bridge_get_priority(struct rtnl_link *link)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	return bd->b_priority;
}

/**
 * Set Spanning Tree Protocol (STP) path cost
 * @arg link		Link object of type bridge
 * @arg cost		New STP path cost value
 *
 * @see rtnl_link_bridge_get_cost()
 *
 * @return The bridge priority or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 */
int rtnl_link_bridge_set_cost(struct rtnl_link *link, uint32_t cost)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	bd->b_cost = cost;
	bd->ce_mask |= BRIDGE_ATTR_COST;

	return 0;
}

/**
 * Get Spanning Tree Protocol (STP) path cost
 * @arg link		Link object of type bridge
 * @arg cost		Pointer to store STP cost value
 *
 * @see rtnl_link_bridge_set_cost()
 *
 * @return 0 on success or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 * @retval -NLE_INVAL `cost` is not a valid pointer
 */
int rtnl_link_bridge_get_cost(struct rtnl_link *link, uint32_t *cost)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	if (!cost)
		return -NLE_INVAL;

	*cost = bd->b_cost;

	return 0;
}

/**
 * Unset flags
 * @arg link		Link object of type bridge
 * @arg flags		Bridging flags to unset
 *
 * @see rtnl_link_bridge_set_flags()
 * @see rtnl_link_bridge_get_flags()
 *
 * @return 0 on success or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 */
int rtnl_link_bridge_unset_flags(struct rtnl_link *link, unsigned int flags)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	bd->b_flags_mask |= flags;
	bd->b_flags &= ~flags;
	bd->ce_mask |= BRIDGE_ATTR_FLAGS;

	return 0;
}

/**
 * Set flags
 * @arg link		Link object of type bridge
 * @arg flags		Bridging flags to set
 *
 * Valid flags are:
 *   - RTNL_BRIDGE_HAIRPIN_MODE
 *   - RTNL_BRIDGE_BPDU_GUARD
 *   - RTNL_BRIDGE_ROOT_BLOCK
 *   - RTNL_BRIDGE_FAST_LEAVE
 *   - RTNL_BRIDGE_UNICAST_FLOOD
 *   - RTNL_BRIDGE_LEARNING
 *   - RTNL_BRIDGE_LEARNING_SYNC
 *
 * @see rtnl_link_bridge_unset_flags()
 * @see rtnl_link_bridge_get_flags()
 *
 * @return 0 on success or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 */
int rtnl_link_bridge_set_flags(struct rtnl_link *link, unsigned int flags)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	bd->b_flags_mask |= flags;
	bd->b_flags |= flags;
	bd->ce_mask |= BRIDGE_ATTR_FLAGS;

	return 0;
}

/**
 * Get flags
 * @arg link		Link object of type bridge
 *
 * @see rtnl_link_bridge_set_flags()
 * @see rtnl_link_bridge_unset_flags()
 *
 * @return Flags or a negative error code.
 * @retval -NLE_OPNOTSUPP Link is not a bridge
 */
int rtnl_link_bridge_get_flags(struct rtnl_link *link)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	return bd->b_flags;
}

/**
 * Set link change type to self
 * @arg link		Link Object of type bridge
 *
 * This will set the bridge change flag to self, meaning that changes to
 * be applied with this link object will be applied directly to the physical
 * device in a bridge instead of the virtual device.
 *
 * @return 0 on success or negative error code
 * @return -NLE_OPNOTSUP Link is not a bridge
 */
int rtnl_link_bridge_set_self(struct rtnl_link *link)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	bd->b_self |= 1;
	bd->ce_mask |= BRIDGE_ATTR_SELF;

	return 0;
}

/**
 * Get hardware mode
 * @arg link            Link object of type bridge
 * @arg hwmode          Output argument.
 *
 * @see rtnl_link_bridge_set_hwmode()
 *
 * @return 0 if hardware mode is present and returned in hwmode
 * @return -NLE_NOATTR if hardware mode is not present
 * @return -NLE_OPNOTSUP Link is not a bridge
 */
int rtnl_link_bridge_get_hwmode(struct rtnl_link *link, uint16_t *hwmode)
{
	struct bridge_data *bd = bridge_data(link);

	IS_BRIDGE_LINK_ASSERT(link);

	if (!(bd->ce_mask & BRIDGE_ATTR_HWMODE))
		return -NLE_NOATTR;

	*hwmode = bd->b_hwmode;
	return 0;
}

/**
 * Set hardware mode
 * @arg link		Link object of type bridge
 * @arg hwmode		Hardware mode to set on link
 *
 * This will set the hardware mode of a link when it supports hardware
 * offloads for bridging.
 * @see rtnl_link_bridge_get_hwmode()
 *
 * Valid modes are:
 *   - RTNL_BRIDGE_HWMODE_VEB
 *   - RTNL_BRIDGE_HWMODE_VEPA
 *
 * When setting hardware mode, the change type will be set to self.
 * @see rtnl_link_bridge_set_self()
 *
 * @return 0 on success or negative error code
 * @return -NLE_OPNOTSUP Link is not a bridge
 * @return -NLE_INVAL when specified hwmode is unsupported.
 */
int rtnl_link_bridge_set_hwmode(struct rtnl_link *link, uint16_t hwmode)
{
	int err;
	struct bridge_data *bd = bridge_data(link);

	if (hwmode > RTNL_BRIDGE_HWMODE_MAX)
		return -NLE_INVAL;

	if ((err = rtnl_link_bridge_set_self(link)) < 0)
		return err;

	bd->b_hwmode = hwmode;
	bd->ce_mask |= BRIDGE_ATTR_HWMODE;

	return 0;
}


static const struct trans_tbl bridge_flags[] = {
	__ADD(RTNL_BRIDGE_HAIRPIN_MODE, hairpin_mode),
	__ADD(RTNL_BRIDGE_BPDU_GUARD, 	bpdu_guard),
	__ADD(RTNL_BRIDGE_ROOT_BLOCK,	root_block),
	__ADD(RTNL_BRIDGE_FAST_LEAVE,	fast_leave),
	__ADD(RTNL_BRIDGE_UNICAST_FLOOD,	flood),
	__ADD(RTNL_BRIDGE_LEARNING,			learning),
	__ADD(RTNL_BRIDGE_LEARNING_SYNC,	learning_sync),
};

/**
 * @name Flag Translation
 * @{
 */

char *rtnl_link_bridge_flags2str(int flags, char *buf, size_t len)
{
	return __flags2str(flags, buf, len, bridge_flags, ARRAY_SIZE(bridge_flags));
}

int rtnl_link_bridge_str2flags(const char *name)
{
	return __str2flags(name, bridge_flags, ARRAY_SIZE(bridge_flags));
}

/** @} */

static const struct trans_tbl port_states[] = {
	__ADD(BR_STATE_DISABLED, disabled),
	__ADD(BR_STATE_LISTENING, listening),
	__ADD(BR_STATE_LEARNING, learning),
	__ADD(BR_STATE_FORWARDING, forwarding),
	__ADD(BR_STATE_BLOCKING, blocking),
};

/**
 * @name Port State Translation
 * @{
 */

char *rtnl_link_bridge_portstate2str(int st, char *buf, size_t len)
{
	return __type2str(st, buf, len, port_states, ARRAY_SIZE(port_states));
}

int rtnl_link_bridge_str2portstate(const char *name)
{
	return __str2type(name, port_states, ARRAY_SIZE(port_states));
}

/** @} */

static const struct trans_tbl hw_modes[] = {
	__ADD(RTNL_BRIDGE_HWMODE_VEB, veb),
	__ADD(RTNL_BRIDGE_HWMODE_VEPA, vepa),
	__ADD(RTNL_BRIDGE_HWMODE_UNDEF, undef),
};

/**
 * @name Hardware Mode Translation
 * @{
 */

char *rtnl_link_bridge_hwmode2str(uint16_t st, char *buf, size_t len) {
	return __type2str(st, buf, len, hw_modes, ARRAY_SIZE(hw_modes));
}

uint16_t rtnl_link_bridge_str2hwmode(const char *name)
{
	return __str2type(name, hw_modes, ARRAY_SIZE(hw_modes));
}

/** @} */

int rtnl_link_bridge_pvid(struct rtnl_link *link)
{
	struct bridge_data *bd;

	IS_BRIDGE_LINK_ASSERT(link);

	bd = link->l_af_data[AF_BRIDGE];
	if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN)
		return (int) bd->vlan_info.pvid;

	return -EINVAL;
}

int rtnl_link_bridge_has_vlan(struct rtnl_link *link)
{
	struct bridge_data *bd;
	int i;

	IS_BRIDGE_LINK_ASSERT(link);

	bd = link->l_af_data[AF_BRIDGE];
	if (bd->ce_mask & BRIDGE_ATTR_PORT_VLAN) {
		if (bd->vlan_info.pvid)
			return 1;

		for (i = 0; i < RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN; ++i) {
			if (bd->vlan_info.vlan_bitmap[i] ||
			    bd->vlan_info.untagged_bitmap[i])
				return 1;
		}
	}
	return 0;
}

struct rtnl_link_bridge_vlan *rtnl_link_bridge_get_port_vlan(struct rtnl_link *link)
{
	struct bridge_data *data;

	if (!rtnl_link_is_bridge(link))
		return NULL;

	data = link->l_af_data[AF_BRIDGE];
	if (data && (data->ce_mask & BRIDGE_ATTR_PORT_VLAN))
		return &data->vlan_info;

	return NULL;
}

static struct rtnl_link_af_ops bridge_ops = {
	.ao_family			= AF_BRIDGE,
	.ao_alloc			= &bridge_alloc,
	.ao_clone			= &bridge_clone,
	.ao_free			= &bridge_free,
	.ao_parse_protinfo		= &bridge_parse_protinfo,
	.ao_dump[NL_DUMP_DETAILS]	= &bridge_dump_details,
	.ao_compare			= &bridge_compare,
	.ao_parse_af_full		= &bridge_parse_af_full,
	.ao_get_af			= &bridge_get_af,
	.ao_fill_af			= &bridge_fill_af,
	.ao_fill_pi			= &bridge_fill_pi,
	.ao_fill_pi_flags	= NLA_F_NESTED,
	.ao_override_rtm		= &bridge_override_rtm,
	.ao_fill_af_no_nest	= 1,
};

static void _nl_init bridge_init(void)
{
	rtnl_link_af_register(&bridge_ops);
}

static void _nl_exit bridge_exit(void)
{
	rtnl_link_af_unregister(&bridge_ops);
}

/** @} */
