// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2020, Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <net/ip_tunnels.h>

#include "br_private.h"
#include "br_private_tunnel.h"

static bool __vlan_tun_put(struct sk_buff *skb, const struct net_bridge_vlan *v)
{
	__be32 tid = tunnel_id_to_key32(v->tinfo.tunnel_id);
	struct nlattr *nest;

	if (!v->tinfo.tunnel_dst)
		return true;

	nest = nla_nest_start(skb, BRIDGE_VLANDB_ENTRY_TUNNEL_INFO);
	if (!nest)
		return false;
	if (nla_put_u32(skb, BRIDGE_VLANDB_TINFO_ID, be32_to_cpu(tid))) {
		nla_nest_cancel(skb, nest);
		return false;
	}
	nla_nest_end(skb, nest);

	return true;
}

static bool __vlan_tun_can_enter_range(const struct net_bridge_vlan *v_curr,
				       const struct net_bridge_vlan *range_end)
{
	return (!v_curr->tinfo.tunnel_dst && !range_end->tinfo.tunnel_dst) ||
	       vlan_tunid_inrange(v_curr, range_end);
}

/* check if the options' state of v_curr allow it to enter the range */
bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr,
			   const struct net_bridge_vlan *range_end)
{
	u8 range_mc_rtr = br_vlan_multicast_router(range_end);
	u8 curr_mc_rtr = br_vlan_multicast_router(v_curr);

	if (v_curr->state != range_end->state)
		return false;

	if (!__vlan_tun_can_enter_range(v_curr, range_end))
		return false;

	if (curr_mc_rtr != range_mc_rtr)
		return false;

	/* Check user-visible priv_flags that affect output */
	if ((v_curr->priv_flags ^ range_end->priv_flags) &
	    (BR_VLFLAG_NEIGH_SUPPRESS_ENABLED | BR_VLFLAG_MCAST_ENABLED |
	     BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED))
		return false;

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	if (!br_vlan_is_master(v_curr) &&
	    !br_multicast_port_ctx_vlan_disabled(&v_curr->port_mcast_ctx) &&
	    !br_multicast_port_ctx_options_equal(&v_curr->port_mcast_ctx,
						 &range_end->port_mcast_ctx))
		return false;
#endif

	return true;
}

bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v,
		       const struct net_bridge_port *p)
{
	if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_STATE, br_vlan_get_state(v)) ||
	    !__vlan_tun_put(skb, v) ||
	    nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS,
		       !!(v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED)) ||
	    nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_NEIGH_FORWARD_GRAT,
		       !!(v->priv_flags & BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED)))
		return false;

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
		       br_vlan_multicast_router(v)))
		return false;
	if (p && !br_multicast_port_ctx_vlan_disabled(&v->port_mcast_ctx) &&
	    (nla_put_u32(skb, BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS,
			 br_multicast_ngroups_get(&v->port_mcast_ctx)) ||
	     nla_put_u32(skb, BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS,
			 br_multicast_ngroups_get_max(&v->port_mcast_ctx))))
		return false;
#endif

	return true;
}

size_t br_vlan_opts_nl_size(void)
{
	return nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_STATE */
	       + nla_total_size(0) /* BRIDGE_VLANDB_ENTRY_TUNNEL_INFO */
	       + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_TINFO_ID */
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	       + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_MCAST_ROUTER */
	       + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS */
	       + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS */
#endif
	       + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS */
	       + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_NEIGH_FORWARD_GRAT */
	       + 0;
}

static int br_vlan_modify_state(struct net_bridge_vlan_group *vg,
				struct net_bridge_vlan *v,
				u8 state,
				bool *changed,
				struct netlink_ext_ack *extack)
{
	struct net_bridge *br;

	ASSERT_RTNL();

	if (state > BR_STATE_BLOCKING) {
		NL_SET_ERR_MSG_MOD(extack, "Invalid vlan state");
		return -EINVAL;
	}

	if (br_vlan_is_brentry(v))
		br = v->br;
	else
		br = v->port->br;

	if (br->stp_enabled == BR_KERNEL_STP) {
		NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state when using kernel STP");
		return -EBUSY;
	}

	if (br_opt_get(br, BROPT_MST_ENABLED)) {
		NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state directly when MST is enabled");
		return -EBUSY;
	}

	if (v->state == state)
		return 0;

	if (v->vid == br_get_pvid(vg))
		br_vlan_set_pvid_state(vg, state);

	br_vlan_set_state(v, state);
	*changed = true;

	return 0;
}

static const struct nla_policy br_vlandb_tinfo_pol[BRIDGE_VLANDB_TINFO_MAX + 1] = {
	[BRIDGE_VLANDB_TINFO_ID]	= { .type = NLA_U32 },
	[BRIDGE_VLANDB_TINFO_CMD]	= { .type = NLA_U32 },
};

static int br_vlan_modify_tunnel(const struct net_bridge_port *p,
				 struct net_bridge_vlan *v,
				 struct nlattr **tb,
				 bool *changed,
				 struct netlink_ext_ack *extack)
{
	struct nlattr *tun_tb[BRIDGE_VLANDB_TINFO_MAX + 1], *attr;
	struct bridge_vlan_info *vinfo;
	u32 tun_id = 0;
	int cmd, err;

	if (!p) {
		NL_SET_ERR_MSG_MOD(extack, "Can't modify tunnel mapping of non-port vlans");
		return -EINVAL;
	}
	if (!test_bit(BR_VLAN_TUNNEL_BIT, &p->flags)) {
		NL_SET_ERR_MSG_MOD(extack, "Port doesn't have tunnel flag set");
		return -EINVAL;
	}

	attr = tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO];
	err = nla_parse_nested(tun_tb, BRIDGE_VLANDB_TINFO_MAX, attr,
			       br_vlandb_tinfo_pol, extack);
	if (err)
		return err;

	if (!tun_tb[BRIDGE_VLANDB_TINFO_CMD]) {
		NL_SET_ERR_MSG_MOD(extack, "Missing tunnel command attribute");
		return -ENOENT;
	}
	cmd = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_CMD]);
	switch (cmd) {
	case RTM_SETLINK:
		if (!tun_tb[BRIDGE_VLANDB_TINFO_ID]) {
			NL_SET_ERR_MSG_MOD(extack, "Missing tunnel id attribute");
			return -ENOENT;
		}
		/* when working on vlan ranges this is the starting tunnel id */
		tun_id = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_ID]);
		/* vlan info attr is guaranteed by br_vlan_rtm_process_one */
		vinfo = nla_data(tb[BRIDGE_VLANDB_ENTRY_INFO]);
		/* tunnel ids are mapped to each vlan in increasing order,
		 * the starting vlan is in BRIDGE_VLANDB_ENTRY_INFO and v is the
		 * current vlan, so we compute: tun_id + v - vinfo->vid
		 */
		tun_id += v->vid - vinfo->vid;
		break;
	case RTM_DELLINK:
		break;
	default:
		NL_SET_ERR_MSG_MOD(extack, "Unsupported tunnel command");
		return -EINVAL;
	}

	return br_vlan_tunnel_info(p, cmd, v->vid, tun_id, changed);
}

static int br_vlan_process_one_opts(const struct net_bridge *br,
				    const struct net_bridge_port *p,
				    struct net_bridge_vlan_group *vg,
				    struct net_bridge_vlan *v,
				    struct nlattr **tb,
				    bool *changed,
				    struct netlink_ext_ack *extack)
{
	int err;

	*changed = false;
	if (tb[BRIDGE_VLANDB_ENTRY_STATE]) {
		u8 state = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_STATE]);

		err = br_vlan_modify_state(vg, v, state, changed, extack);
		if (err)
			return err;
	}
	if (tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO]) {
		err = br_vlan_modify_tunnel(p, v, tb, changed, extack);
		if (err)
			return err;
	}

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	if (tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]) {
		u8 val;

		val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]);
		err = br_multicast_set_vlan_router(v, val);
		if (err)
			return err;
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS]) {
		u32 val;

		if (!p) {
			NL_SET_ERR_MSG_MOD(extack, "Can't set mcast_max_groups for non-port vlans");
			return -EINVAL;
		}
		if (br_multicast_port_ctx_vlan_disabled(&v->port_mcast_ctx)) {
			NL_SET_ERR_MSG_MOD(extack, "Multicast snooping disabled on this VLAN");
			return -EINVAL;
		}

		val = nla_get_u32(tb[BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS]);
		br_multicast_ngroups_set_max(&v->port_mcast_ctx, val);
		*changed = true;
	}
#endif

	if (tb[BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS]) {
		bool enabled = v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED;
		bool val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS]);

		if (!p) {
			NL_SET_ERR_MSG_MOD(extack, "Can't set neigh_suppress for non-port vlans");
			return -EINVAL;
		}

		if (val != enabled) {
			v->priv_flags ^= BR_VLFLAG_NEIGH_SUPPRESS_ENABLED;
			*changed = true;
		}
	}

	if (tb[BRIDGE_VLANDB_ENTRY_NEIGH_FORWARD_GRAT]) {
		bool enabled = v->priv_flags & BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED;
		bool val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_NEIGH_FORWARD_GRAT]);

		if (!p) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Can't set neigh_forward_grat for non-port vlans");
			return -EINVAL;
		}

		if (val != enabled) {
			v->priv_flags ^= BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED;
			*changed = true;
		}
	}

	return 0;
}

int br_vlan_process_options(const struct net_bridge *br,
			    const struct net_bridge_port *p,
			    struct net_bridge_vlan *range_start,
			    struct net_bridge_vlan *range_end,
			    struct nlattr **tb,
			    struct netlink_ext_ack *extack)
{
	struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL;
	struct net_bridge_vlan_group *vg;
	int vid, err = 0;
	u16 pvid;

	if (p)
		vg = nbp_vlan_group(p);
	else
		vg = br_vlan_group(br);

	if (!range_start || !br_vlan_should_use(range_start)) {
		NL_SET_ERR_MSG_MOD(extack, "Vlan range start doesn't exist, can't process options");
		return -ENOENT;
	}
	if (!range_end || !br_vlan_should_use(range_end)) {
		NL_SET_ERR_MSG_MOD(extack, "Vlan range end doesn't exist, can't process options");
		return -ENOENT;
	}

	pvid = br_get_pvid(vg);
	for (vid = range_start->vid; vid <= range_end->vid; vid++) {
		bool changed = false;

		v = br_vlan_find(vg, vid);
		if (!v || !br_vlan_should_use(v)) {
			NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process options");
			err = -ENOENT;
			break;
		}

		err = br_vlan_process_one_opts(br, p, vg, v, tb, &changed,
					       extack);
		if (err)
			break;

		if (changed) {
			/* vlan options changed, check for range */
			if (!curr_start) {
				curr_start = v;
				curr_end = v;
				continue;
			}

			if (!br_vlan_can_enter_range(v, curr_end, pvid)) {
				br_vlan_notify(br, p, curr_start->vid,
					       curr_end->vid, RTM_NEWVLAN);
				curr_start = v;
			}
			curr_end = v;
		} else {
			/* nothing changed and nothing to notify yet */
			if (!curr_start)
				continue;

			br_vlan_notify(br, p, curr_start->vid, curr_end->vid,
				       RTM_NEWVLAN);
			curr_start = NULL;
			curr_end = NULL;
		}
	}
	if (curr_start)
		br_vlan_notify(br, p, curr_start->vid, curr_end->vid,
			       RTM_NEWVLAN);

	return err;
}

bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
					 const struct net_bridge_vlan *r_end)
{
	return v_curr->vid - r_end->vid == 1 &&
		v_curr->msti == r_end->msti &&
	       ((v_curr->priv_flags ^ r_end->priv_flags) &
		BR_VLFLAG_GLOBAL_MCAST_ENABLED) == 0 &&
		br_multicast_ctx_options_equal(&v_curr->br_mcast_ctx,
					       &r_end->br_mcast_ctx);
}

bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
			      const struct net_bridge_vlan *v_opts)
{
	struct nlattr *nest2 __maybe_unused;
	u64 clockval __maybe_unused;
	struct nlattr *nest;

	nest = nla_nest_start(skb, BRIDGE_VLANDB_GLOBAL_OPTIONS);
	if (!nest)
		return false;

	if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_ID, vid))
		goto out_err;

	if (vid_range && vid < vid_range &&
	    nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_RANGE, vid_range))
		goto out_err;

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING,
		       !!(v_opts->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)) ||
	    nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION,
		       v_opts->br_mcast_ctx.multicast_igmp_version) ||
	    nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
			v_opts->br_mcast_ctx.multicast_last_member_count) ||
	    nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
			v_opts->br_mcast_ctx.multicast_startup_query_count) ||
	    nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
		       v_opts->br_mcast_ctx.multicast_querier) ||
	    br_multicast_dump_querier_state(skb, &v_opts->br_mcast_ctx,
					    BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE))
		goto out_err;

	clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval);
	if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
			      clockval, BRIDGE_VLANDB_GOPTS_PAD))
		goto out_err;
	clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_membership_interval);
	if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
			      clockval, BRIDGE_VLANDB_GOPTS_PAD))
		goto out_err;
	clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_querier_interval);
	if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
			      clockval, BRIDGE_VLANDB_GOPTS_PAD))
		goto out_err;
	clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_interval);
	if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
			      clockval, BRIDGE_VLANDB_GOPTS_PAD))
		goto out_err;
	clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_response_interval);
	if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
			      clockval, BRIDGE_VLANDB_GOPTS_PAD))
		goto out_err;
	clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_startup_query_interval);
	if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
			      clockval, BRIDGE_VLANDB_GOPTS_PAD))
		goto out_err;

	if (br_rports_have_mc_router(&v_opts->br_mcast_ctx)) {
		nest2 = nla_nest_start(skb,
				       BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS);
		if (!nest2)
			goto out_err;

		rcu_read_lock();
		if (br_rports_fill_info(skb, &v_opts->br_mcast_ctx)) {
			rcu_read_unlock();
			nla_nest_cancel(skb, nest2);
			goto out_err;
		}
		rcu_read_unlock();

		nla_nest_end(skb, nest2);
	}

#if IS_ENABLED(CONFIG_IPV6)
	if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
		       v_opts->br_mcast_ctx.multicast_mld_version))
		goto out_err;
#endif
#endif

	if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_MSTI, v_opts->msti))
		goto out_err;

	nla_nest_end(skb, nest);

	return true;

out_err:
	nla_nest_cancel(skb, nest);
	return false;
}

static size_t rtnl_vlan_global_opts_nlmsg_size(const struct net_bridge_vlan *v)
{
	return NLMSG_ALIGN(sizeof(struct br_vlan_msg))
		+ nla_total_size(0) /* BRIDGE_VLANDB_GLOBAL_OPTIONS */
		+ nla_total_size(sizeof(u16)) /* BRIDGE_VLANDB_GOPTS_ID */
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
		+ nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING */
		+ nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION */
		+ nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION */
		+ nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT */
		+ nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT */
		+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL */
		+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL */
		+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL */
		+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL */
		+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL */
		+ nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL */
		+ nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER */
		+ br_multicast_querier_state_size() /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE */
		+ nla_total_size(0) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS */
		+ br_rports_size(&v->br_mcast_ctx) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS */
#endif
		+ nla_total_size(sizeof(u16)) /* BRIDGE_VLANDB_GOPTS_MSTI */
		+ nla_total_size(sizeof(u16)); /* BRIDGE_VLANDB_GOPTS_RANGE */
}

static void br_vlan_global_opts_notify(const struct net_bridge *br,
				       u16 vid, u16 vid_range)
{
	struct net_bridge_vlan *v;
	struct br_vlan_msg *bvm;
	struct nlmsghdr *nlh;
	struct sk_buff *skb;
	int err = -ENOBUFS;

	/* right now notifications are done only with rtnl held */
	ASSERT_RTNL();

	/* need to find the vlan due to flags/options */
	v = br_vlan_find(br_vlan_group(br), vid);
	if (!v)
		return;

	skb = nlmsg_new(rtnl_vlan_global_opts_nlmsg_size(v), GFP_KERNEL);
	if (!skb)
		goto out_err;

	err = -EMSGSIZE;
	nlh = nlmsg_put(skb, 0, 0, RTM_NEWVLAN, sizeof(*bvm), 0);
	if (!nlh)
		goto out_err;
	bvm = nlmsg_data(nlh);
	memset(bvm, 0, sizeof(*bvm));
	bvm->family = AF_BRIDGE;
	bvm->ifindex = br->dev->ifindex;

	if (!br_vlan_global_opts_fill(skb, vid, vid_range, v))
		goto out_err;

	nlmsg_end(skb, nlh);
	rtnl_notify(skb, dev_net(br->dev), 0, RTNLGRP_BRVLAN, NULL, GFP_KERNEL);
	return;

out_err:
	rtnl_set_sk_err(dev_net(br->dev), RTNLGRP_BRVLAN, err);
	kfree_skb(skb);
}

static int br_vlan_process_global_one_opts(const struct net_bridge *br,
					   struct net_bridge_vlan_group *vg,
					   struct net_bridge_vlan *v,
					   struct nlattr **tb,
					   bool *changed,
					   struct netlink_ext_ack *extack)
{
	int err __maybe_unused;

	*changed = false;
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]) {
		u8 mc_snooping;

		mc_snooping = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]);
		if (br_multicast_toggle_global_vlan(v, !!mc_snooping))
			*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) {
		u8 ver;

		ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]);
		err = br_multicast_set_igmp_version(&v->br_mcast_ctx, ver);
		if (err)
			return err;
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]) {
		u32 cnt;

		cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]);
		v->br_mcast_ctx.multicast_last_member_count = cnt;
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]) {
		u32 cnt;

		cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]);
		v->br_mcast_ctx.multicast_startup_query_count = cnt;
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]) {
		u64 val;

		val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]);
		v->br_mcast_ctx.multicast_last_member_interval = clock_t_to_jiffies(val);
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]) {
		u64 val;

		val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]);
		v->br_mcast_ctx.multicast_membership_interval = clock_t_to_jiffies(val);
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]) {
		u64 val;

		val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]);
		v->br_mcast_ctx.multicast_querier_interval = clock_t_to_jiffies(val);
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]) {
		u64 val;

		val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]);
		br_multicast_set_query_intvl(&v->br_mcast_ctx, val);
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) {
		u64 val;

		val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]);
		v->br_mcast_ctx.multicast_query_response_interval = clock_t_to_jiffies(val);
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]) {
		u64 val;

		val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]);
		br_multicast_set_startup_query_intvl(&v->br_mcast_ctx, val);
		*changed = true;
	}
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {
		u8 val;

		val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]);
		err = br_multicast_set_querier(&v->br_mcast_ctx, val);
		if (err)
			return err;
		*changed = true;
	}
#if IS_ENABLED(CONFIG_IPV6)
	if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
		u8 ver;

		ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]);
		err = br_multicast_set_mld_version(&v->br_mcast_ctx, ver);
		if (err)
			return err;
		*changed = true;
	}
#endif
#endif
	if (tb[BRIDGE_VLANDB_GOPTS_MSTI]) {
		u16 msti;

		msti = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_MSTI]);
		err = br_mst_vlan_set_msti(v, msti);
		if (err)
			return err;
		*changed = true;
	}

	return 0;
}

static const struct nla_policy br_vlan_db_gpol[BRIDGE_VLANDB_GOPTS_MAX + 1] = {
	[BRIDGE_VLANDB_GOPTS_ID]	= { .type = NLA_U16 },
	[BRIDGE_VLANDB_GOPTS_RANGE]	= { .type = NLA_U16 },
	[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]	= { .type = NLA_U8 },
	[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]	= { .type = NLA_U8 },
	[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]	= { .type = NLA_U64 },
	[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]	= { .type = NLA_U8 },
	[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]	= { .type = NLA_U8 },
	[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]	= { .type = NLA_U32 },
	[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]	= { .type = NLA_U32 },
	[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]	= { .type = NLA_U64 },
	[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]	= { .type = NLA_U64 },
	[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]	= { .type = NLA_U64 },
	[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]	= { .type = NLA_U64 },
	[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL] = { .type = NLA_U64 },
	[BRIDGE_VLANDB_GOPTS_MSTI] = NLA_POLICY_MAX(NLA_U16, VLAN_N_VID - 1),
};

int br_vlan_rtm_process_global_options(struct net_device *dev,
				       const struct nlattr *attr,
				       int cmd,
				       struct netlink_ext_ack *extack)
{
	struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL;
	struct nlattr *tb[BRIDGE_VLANDB_GOPTS_MAX + 1];
	struct net_bridge_vlan_group *vg;
	u16 vid, vid_range = 0;
	struct net_bridge *br;
	int err = 0;

	if (cmd != RTM_NEWVLAN) {
		NL_SET_ERR_MSG_MOD(extack, "Global vlan options support only set operation");
		return -EINVAL;
	}
	if (!netif_is_bridge_master(dev)) {
		NL_SET_ERR_MSG_MOD(extack, "Global vlan options can only be set on bridge device");
		return -EINVAL;
	}
	br = netdev_priv(dev);
	vg = br_vlan_group(br);
	if (WARN_ON(!vg))
		return -ENODEV;

	err = nla_parse_nested(tb, BRIDGE_VLANDB_GOPTS_MAX, attr,
			       br_vlan_db_gpol, extack);
	if (err)
		return err;

	if (!tb[BRIDGE_VLANDB_GOPTS_ID]) {
		NL_SET_ERR_MSG_MOD(extack, "Missing vlan entry id");
		return -EINVAL;
	}
	vid = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_ID]);
	if (!br_vlan_valid_id(vid, extack))
		return -EINVAL;

	if (tb[BRIDGE_VLANDB_GOPTS_RANGE]) {
		vid_range = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_RANGE]);
		if (!br_vlan_valid_id(vid_range, extack))
			return -EINVAL;
		if (vid >= vid_range) {
			NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id");
			return -EINVAL;
		}
	} else {
		vid_range = vid;
	}

	for (; vid <= vid_range; vid++) {
		bool changed = false;

		v = br_vlan_find(vg, vid);
		if (!v) {
			NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process global options");
			err = -ENOENT;
			break;
		}

		err = br_vlan_process_global_one_opts(br, vg, v, tb, &changed,
						      extack);
		if (err)
			break;

		if (changed) {
			/* vlan options changed, check for range */
			if (!curr_start) {
				curr_start = v;
				curr_end = v;
				continue;
			}

			if (!br_vlan_global_opts_can_enter_range(v, curr_end)) {
				br_vlan_global_opts_notify(br, curr_start->vid,
							   curr_end->vid);
				curr_start = v;
			}
			curr_end = v;
		} else {
			/* nothing changed and nothing to notify yet */
			if (!curr_start)
				continue;

			br_vlan_global_opts_notify(br, curr_start->vid,
						   curr_end->vid);
			curr_start = NULL;
			curr_end = NULL;
		}
	}
	if (curr_start)
		br_vlan_global_opts_notify(br, curr_start->vid, curr_end->vid);

	return err;
}
