xref: /openbmc/linux/net/bridge/br_mrp_netlink.c (revision cdd38c5f1ce4398ec58fec95904b75824daab7b5)
19a9f26e8SHoratiu Vultur // SPDX-License-Identifier: GPL-2.0-or-later
29a9f26e8SHoratiu Vultur 
39a9f26e8SHoratiu Vultur #include <net/genetlink.h>
49a9f26e8SHoratiu Vultur 
59a9f26e8SHoratiu Vultur #include <uapi/linux/mrp_bridge.h>
69a9f26e8SHoratiu Vultur #include "br_private.h"
79a9f26e8SHoratiu Vultur #include "br_private_mrp.h"
89a9f26e8SHoratiu Vultur 
94d02b8f0SHoratiu Vultur static const struct nla_policy br_mrp_policy[IFLA_BRIDGE_MRP_MAX + 1] = {
104d02b8f0SHoratiu Vultur 	[IFLA_BRIDGE_MRP_UNSPEC]	= { .type = NLA_REJECT },
1120f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_INSTANCE]	= { .type = NLA_NESTED },
1220f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_PORT_STATE]	= { .type = NLA_NESTED },
1320f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_PORT_ROLE]	= { .type = NLA_NESTED },
1420f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_STATE]	= { .type = NLA_NESTED },
1520f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_ROLE]	= { .type = NLA_NESTED },
1620f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_TEST]	= { .type = NLA_NESTED },
177ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_ROLE]	= { .type = NLA_NESTED },
187ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_STATE]	= { .type = NLA_NESTED },
197ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_IN_TEST]	= { .type = NLA_NESTED },
204d02b8f0SHoratiu Vultur };
214d02b8f0SHoratiu Vultur 
2220f6a05eSHoratiu Vultur static const struct nla_policy
2320f6a05eSHoratiu Vultur br_mrp_instance_policy[IFLA_BRIDGE_MRP_INSTANCE_MAX + 1] = {
2420f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_INSTANCE_UNSPEC]	= { .type = NLA_REJECT },
2520f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_INSTANCE_RING_ID]	= { .type = NLA_U32 },
2620f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX]	= { .type = NLA_U32 },
2720f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]	= { .type = NLA_U32 },
284b3a61b0SHoratiu Vultur 	[IFLA_BRIDGE_MRP_INSTANCE_PRIO]		= { .type = NLA_U16 },
2920f6a05eSHoratiu Vultur };
3020f6a05eSHoratiu Vultur 
br_mrp_instance_parse(struct net_bridge * br,struct nlattr * attr,int cmd,struct netlink_ext_ack * extack)3120f6a05eSHoratiu Vultur static int br_mrp_instance_parse(struct net_bridge *br, struct nlattr *attr,
3220f6a05eSHoratiu Vultur 				 int cmd, struct netlink_ext_ack *extack)
3320f6a05eSHoratiu Vultur {
3420f6a05eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_INSTANCE_MAX + 1];
3520f6a05eSHoratiu Vultur 	struct br_mrp_instance inst;
3620f6a05eSHoratiu Vultur 	int err;
3720f6a05eSHoratiu Vultur 
3820f6a05eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_INSTANCE_MAX, attr,
3920f6a05eSHoratiu Vultur 			       br_mrp_instance_policy, extack);
4020f6a05eSHoratiu Vultur 	if (err)
4120f6a05eSHoratiu Vultur 		return err;
4220f6a05eSHoratiu Vultur 
4320f6a05eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_INSTANCE_RING_ID] ||
4420f6a05eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX] ||
4520f6a05eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]) {
4620f6a05eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack,
4720f6a05eSHoratiu Vultur 				   "Missing attribute: RING_ID or P_IFINDEX or S_IFINDEX");
4820f6a05eSHoratiu Vultur 		return -EINVAL;
4920f6a05eSHoratiu Vultur 	}
5020f6a05eSHoratiu Vultur 
5120f6a05eSHoratiu Vultur 	memset(&inst, 0, sizeof(inst));
5220f6a05eSHoratiu Vultur 
5320f6a05eSHoratiu Vultur 	inst.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_RING_ID]);
5420f6a05eSHoratiu Vultur 	inst.p_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX]);
5520f6a05eSHoratiu Vultur 	inst.s_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]);
564b3a61b0SHoratiu Vultur 	inst.prio = MRP_DEFAULT_PRIO;
574b3a61b0SHoratiu Vultur 
584b3a61b0SHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_INSTANCE_PRIO])
594b3a61b0SHoratiu Vultur 		inst.prio = nla_get_u16(tb[IFLA_BRIDGE_MRP_INSTANCE_PRIO]);
6020f6a05eSHoratiu Vultur 
6120f6a05eSHoratiu Vultur 	if (cmd == RTM_SETLINK)
6220f6a05eSHoratiu Vultur 		return br_mrp_add(br, &inst);
6320f6a05eSHoratiu Vultur 	else
6420f6a05eSHoratiu Vultur 		return br_mrp_del(br, &inst);
6520f6a05eSHoratiu Vultur 
6620f6a05eSHoratiu Vultur 	return 0;
6720f6a05eSHoratiu Vultur }
6820f6a05eSHoratiu Vultur 
6920f6a05eSHoratiu Vultur static const struct nla_policy
7020f6a05eSHoratiu Vultur br_mrp_port_state_policy[IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1] = {
7120f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_PORT_STATE_UNSPEC]	= { .type = NLA_REJECT },
7220f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_PORT_STATE_STATE]	= { .type = NLA_U32 },
7320f6a05eSHoratiu Vultur };
7420f6a05eSHoratiu Vultur 
br_mrp_port_state_parse(struct net_bridge_port * p,struct nlattr * attr,struct netlink_ext_ack * extack)7520f6a05eSHoratiu Vultur static int br_mrp_port_state_parse(struct net_bridge_port *p,
7620f6a05eSHoratiu Vultur 				   struct nlattr *attr,
7720f6a05eSHoratiu Vultur 				   struct netlink_ext_ack *extack)
7820f6a05eSHoratiu Vultur {
7920f6a05eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1];
8020f6a05eSHoratiu Vultur 	enum br_mrp_port_state_type state;
8120f6a05eSHoratiu Vultur 	int err;
8220f6a05eSHoratiu Vultur 
8320f6a05eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_PORT_STATE_MAX, attr,
8420f6a05eSHoratiu Vultur 			       br_mrp_port_state_policy, extack);
8520f6a05eSHoratiu Vultur 	if (err)
8620f6a05eSHoratiu Vultur 		return err;
8720f6a05eSHoratiu Vultur 
8820f6a05eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_PORT_STATE_STATE]) {
8920f6a05eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack, "Missing attribute: STATE");
9020f6a05eSHoratiu Vultur 		return -EINVAL;
9120f6a05eSHoratiu Vultur 	}
9220f6a05eSHoratiu Vultur 
9320f6a05eSHoratiu Vultur 	state = nla_get_u32(tb[IFLA_BRIDGE_MRP_PORT_STATE_STATE]);
9420f6a05eSHoratiu Vultur 
9520f6a05eSHoratiu Vultur 	return br_mrp_set_port_state(p, state);
9620f6a05eSHoratiu Vultur }
9720f6a05eSHoratiu Vultur 
9820f6a05eSHoratiu Vultur static const struct nla_policy
9920f6a05eSHoratiu Vultur br_mrp_port_role_policy[IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1] = {
10020f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_PORT_ROLE_UNSPEC]	= { .type = NLA_REJECT },
10120f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]	= { .type = NLA_U32 },
10220f6a05eSHoratiu Vultur };
10320f6a05eSHoratiu Vultur 
br_mrp_port_role_parse(struct net_bridge_port * p,struct nlattr * attr,struct netlink_ext_ack * extack)10420f6a05eSHoratiu Vultur static int br_mrp_port_role_parse(struct net_bridge_port *p,
10520f6a05eSHoratiu Vultur 				  struct nlattr *attr,
10620f6a05eSHoratiu Vultur 				  struct netlink_ext_ack *extack)
10720f6a05eSHoratiu Vultur {
10820f6a05eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1];
10920f6a05eSHoratiu Vultur 	enum br_mrp_port_role_type role;
11020f6a05eSHoratiu Vultur 	int err;
11120f6a05eSHoratiu Vultur 
11220f6a05eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_PORT_ROLE_MAX, attr,
11320f6a05eSHoratiu Vultur 			       br_mrp_port_role_policy, extack);
11420f6a05eSHoratiu Vultur 	if (err)
11520f6a05eSHoratiu Vultur 		return err;
11620f6a05eSHoratiu Vultur 
11720f6a05eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]) {
11820f6a05eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack, "Missing attribute: ROLE");
11920f6a05eSHoratiu Vultur 		return -EINVAL;
12020f6a05eSHoratiu Vultur 	}
12120f6a05eSHoratiu Vultur 
12220f6a05eSHoratiu Vultur 	role = nla_get_u32(tb[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]);
12320f6a05eSHoratiu Vultur 
12420f6a05eSHoratiu Vultur 	return br_mrp_set_port_role(p, role);
12520f6a05eSHoratiu Vultur }
12620f6a05eSHoratiu Vultur 
12720f6a05eSHoratiu Vultur static const struct nla_policy
12820f6a05eSHoratiu Vultur br_mrp_ring_state_policy[IFLA_BRIDGE_MRP_RING_STATE_MAX + 1] = {
12920f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_STATE_UNSPEC]	= { .type = NLA_REJECT },
13020f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_STATE_RING_ID]	= { .type = NLA_U32 },
13120f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_STATE_STATE]	= { .type = NLA_U32 },
13220f6a05eSHoratiu Vultur };
13320f6a05eSHoratiu Vultur 
br_mrp_ring_state_parse(struct net_bridge * br,struct nlattr * attr,struct netlink_ext_ack * extack)13420f6a05eSHoratiu Vultur static int br_mrp_ring_state_parse(struct net_bridge *br, struct nlattr *attr,
13520f6a05eSHoratiu Vultur 				   struct netlink_ext_ack *extack)
13620f6a05eSHoratiu Vultur {
13720f6a05eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_RING_STATE_MAX + 1];
13820f6a05eSHoratiu Vultur 	struct br_mrp_ring_state state;
13920f6a05eSHoratiu Vultur 	int err;
14020f6a05eSHoratiu Vultur 
14120f6a05eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_RING_STATE_MAX, attr,
14220f6a05eSHoratiu Vultur 			       br_mrp_ring_state_policy, extack);
14320f6a05eSHoratiu Vultur 	if (err)
14420f6a05eSHoratiu Vultur 		return err;
14520f6a05eSHoratiu Vultur 
14620f6a05eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_RING_STATE_RING_ID] ||
14720f6a05eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_RING_STATE_STATE]) {
14820f6a05eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack,
14920f6a05eSHoratiu Vultur 				   "Missing attribute: RING_ID or STATE");
15020f6a05eSHoratiu Vultur 		return -EINVAL;
15120f6a05eSHoratiu Vultur 	}
15220f6a05eSHoratiu Vultur 
15320f6a05eSHoratiu Vultur 	memset(&state, 0x0, sizeof(state));
15420f6a05eSHoratiu Vultur 
15520f6a05eSHoratiu Vultur 	state.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_STATE_RING_ID]);
15620f6a05eSHoratiu Vultur 	state.ring_state = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_STATE_STATE]);
15720f6a05eSHoratiu Vultur 
15820f6a05eSHoratiu Vultur 	return br_mrp_set_ring_state(br, &state);
15920f6a05eSHoratiu Vultur }
16020f6a05eSHoratiu Vultur 
16120f6a05eSHoratiu Vultur static const struct nla_policy
16220f6a05eSHoratiu Vultur br_mrp_ring_role_policy[IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1] = {
16320f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_ROLE_UNSPEC]	= { .type = NLA_REJECT },
16420f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID]	= { .type = NLA_U32 },
16520f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]	= { .type = NLA_U32 },
16620f6a05eSHoratiu Vultur };
16720f6a05eSHoratiu Vultur 
br_mrp_ring_role_parse(struct net_bridge * br,struct nlattr * attr,struct netlink_ext_ack * extack)16820f6a05eSHoratiu Vultur static int br_mrp_ring_role_parse(struct net_bridge *br, struct nlattr *attr,
16920f6a05eSHoratiu Vultur 				  struct netlink_ext_ack *extack)
17020f6a05eSHoratiu Vultur {
17120f6a05eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1];
17220f6a05eSHoratiu Vultur 	struct br_mrp_ring_role role;
17320f6a05eSHoratiu Vultur 	int err;
17420f6a05eSHoratiu Vultur 
17520f6a05eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_RING_ROLE_MAX, attr,
17620f6a05eSHoratiu Vultur 			       br_mrp_ring_role_policy, extack);
17720f6a05eSHoratiu Vultur 	if (err)
17820f6a05eSHoratiu Vultur 		return err;
17920f6a05eSHoratiu Vultur 
18020f6a05eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID] ||
18120f6a05eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]) {
18220f6a05eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack,
18320f6a05eSHoratiu Vultur 				   "Missing attribute: RING_ID or ROLE");
18420f6a05eSHoratiu Vultur 		return -EINVAL;
18520f6a05eSHoratiu Vultur 	}
18620f6a05eSHoratiu Vultur 
18720f6a05eSHoratiu Vultur 	memset(&role, 0x0, sizeof(role));
18820f6a05eSHoratiu Vultur 
18920f6a05eSHoratiu Vultur 	role.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID]);
19020f6a05eSHoratiu Vultur 	role.ring_role = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]);
19120f6a05eSHoratiu Vultur 
19220f6a05eSHoratiu Vultur 	return br_mrp_set_ring_role(br, &role);
19320f6a05eSHoratiu Vultur }
19420f6a05eSHoratiu Vultur 
19520f6a05eSHoratiu Vultur static const struct nla_policy
19620f6a05eSHoratiu Vultur br_mrp_start_test_policy[IFLA_BRIDGE_MRP_START_TEST_MAX + 1] = {
19720f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_TEST_UNSPEC]	= { .type = NLA_REJECT },
19820f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_TEST_RING_ID]	= { .type = NLA_U32 },
19920f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_TEST_INTERVAL]	= { .type = NLA_U32 },
20020f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS]	= { .type = NLA_U32 },
20120f6a05eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_TEST_PERIOD]	= { .type = NLA_U32 },
202c6676e7dSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_TEST_MONITOR]	= { .type = NLA_U32 },
20320f6a05eSHoratiu Vultur };
20420f6a05eSHoratiu Vultur 
br_mrp_start_test_parse(struct net_bridge * br,struct nlattr * attr,struct netlink_ext_ack * extack)20520f6a05eSHoratiu Vultur static int br_mrp_start_test_parse(struct net_bridge *br, struct nlattr *attr,
20620f6a05eSHoratiu Vultur 				   struct netlink_ext_ack *extack)
20720f6a05eSHoratiu Vultur {
20820f6a05eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_START_TEST_MAX + 1];
20920f6a05eSHoratiu Vultur 	struct br_mrp_start_test test;
21020f6a05eSHoratiu Vultur 	int err;
21120f6a05eSHoratiu Vultur 
21220f6a05eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_START_TEST_MAX, attr,
21320f6a05eSHoratiu Vultur 			       br_mrp_start_test_policy, extack);
21420f6a05eSHoratiu Vultur 	if (err)
21520f6a05eSHoratiu Vultur 		return err;
21620f6a05eSHoratiu Vultur 
21720f6a05eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_START_TEST_RING_ID] ||
21820f6a05eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_START_TEST_INTERVAL] ||
21920f6a05eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS] ||
22020f6a05eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_START_TEST_PERIOD]) {
22120f6a05eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack,
22220f6a05eSHoratiu Vultur 				   "Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD");
22320f6a05eSHoratiu Vultur 		return -EINVAL;
22420f6a05eSHoratiu Vultur 	}
22520f6a05eSHoratiu Vultur 
22620f6a05eSHoratiu Vultur 	memset(&test, 0x0, sizeof(test));
22720f6a05eSHoratiu Vultur 
22820f6a05eSHoratiu Vultur 	test.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_RING_ID]);
22920f6a05eSHoratiu Vultur 	test.interval = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_INTERVAL]);
23020f6a05eSHoratiu Vultur 	test.max_miss = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS]);
23120f6a05eSHoratiu Vultur 	test.period = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_PERIOD]);
232c6676e7dSHoratiu Vultur 	test.monitor = false;
233c6676e7dSHoratiu Vultur 
234c6676e7dSHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_START_TEST_MONITOR])
235c6676e7dSHoratiu Vultur 		test.monitor =
236c6676e7dSHoratiu Vultur 			nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_MONITOR]);
23720f6a05eSHoratiu Vultur 
23820f6a05eSHoratiu Vultur 	return br_mrp_start_test(br, &test);
23920f6a05eSHoratiu Vultur }
24020f6a05eSHoratiu Vultur 
2417ab1748eSHoratiu Vultur static const struct nla_policy
2427ab1748eSHoratiu Vultur br_mrp_in_state_policy[IFLA_BRIDGE_MRP_IN_STATE_MAX + 1] = {
2437ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_STATE_UNSPEC]	= { .type = NLA_REJECT },
2447ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_STATE_IN_ID]	= { .type = NLA_U32 },
2457ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_STATE_STATE]	= { .type = NLA_U32 },
2467ab1748eSHoratiu Vultur };
2477ab1748eSHoratiu Vultur 
br_mrp_in_state_parse(struct net_bridge * br,struct nlattr * attr,struct netlink_ext_ack * extack)2487ab1748eSHoratiu Vultur static int br_mrp_in_state_parse(struct net_bridge *br, struct nlattr *attr,
2497ab1748eSHoratiu Vultur 				 struct netlink_ext_ack *extack)
2507ab1748eSHoratiu Vultur {
2517ab1748eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_IN_STATE_MAX + 1];
2527ab1748eSHoratiu Vultur 	struct br_mrp_in_state state;
2537ab1748eSHoratiu Vultur 	int err;
2547ab1748eSHoratiu Vultur 
2557ab1748eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_IN_STATE_MAX, attr,
2567ab1748eSHoratiu Vultur 			       br_mrp_in_state_policy, extack);
2577ab1748eSHoratiu Vultur 	if (err)
2587ab1748eSHoratiu Vultur 		return err;
2597ab1748eSHoratiu Vultur 
2607ab1748eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_IN_STATE_IN_ID] ||
2617ab1748eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_IN_STATE_STATE]) {
2627ab1748eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack,
2637ab1748eSHoratiu Vultur 				   "Missing attribute: IN_ID or STATE");
2647ab1748eSHoratiu Vultur 		return -EINVAL;
2657ab1748eSHoratiu Vultur 	}
2667ab1748eSHoratiu Vultur 
2677ab1748eSHoratiu Vultur 	memset(&state, 0x0, sizeof(state));
2687ab1748eSHoratiu Vultur 
2697ab1748eSHoratiu Vultur 	state.in_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_STATE_IN_ID]);
2707ab1748eSHoratiu Vultur 	state.in_state = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_STATE_STATE]);
2717ab1748eSHoratiu Vultur 
2727ab1748eSHoratiu Vultur 	return br_mrp_set_in_state(br, &state);
2737ab1748eSHoratiu Vultur }
2747ab1748eSHoratiu Vultur 
2757ab1748eSHoratiu Vultur static const struct nla_policy
2767ab1748eSHoratiu Vultur br_mrp_in_role_policy[IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1] = {
2777ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_ROLE_UNSPEC]	= { .type = NLA_REJECT },
2787ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID]	= { .type = NLA_U32 },
2797ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID]		= { .type = NLA_U16 },
2807ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]		= { .type = NLA_U32 },
2817ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX]	= { .type = NLA_U32 },
2827ab1748eSHoratiu Vultur };
2837ab1748eSHoratiu Vultur 
br_mrp_in_role_parse(struct net_bridge * br,struct nlattr * attr,struct netlink_ext_ack * extack)2847ab1748eSHoratiu Vultur static int br_mrp_in_role_parse(struct net_bridge *br, struct nlattr *attr,
2857ab1748eSHoratiu Vultur 				struct netlink_ext_ack *extack)
2867ab1748eSHoratiu Vultur {
2877ab1748eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1];
2887ab1748eSHoratiu Vultur 	struct br_mrp_in_role role;
2897ab1748eSHoratiu Vultur 	int err;
2907ab1748eSHoratiu Vultur 
2917ab1748eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_IN_ROLE_MAX, attr,
2927ab1748eSHoratiu Vultur 			       br_mrp_in_role_policy, extack);
2937ab1748eSHoratiu Vultur 	if (err)
2947ab1748eSHoratiu Vultur 		return err;
2957ab1748eSHoratiu Vultur 
2967ab1748eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID] ||
2977ab1748eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID] ||
2987ab1748eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX] ||
2997ab1748eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]) {
3007ab1748eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack,
3017ab1748eSHoratiu Vultur 				   "Missing attribute: RING_ID or ROLE or IN_ID or I_IFINDEX");
3027ab1748eSHoratiu Vultur 		return -EINVAL;
3037ab1748eSHoratiu Vultur 	}
3047ab1748eSHoratiu Vultur 
3057ab1748eSHoratiu Vultur 	memset(&role, 0x0, sizeof(role));
3067ab1748eSHoratiu Vultur 
3077ab1748eSHoratiu Vultur 	role.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID]);
3087ab1748eSHoratiu Vultur 	role.in_id = nla_get_u16(tb[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID]);
3097ab1748eSHoratiu Vultur 	role.i_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX]);
3107ab1748eSHoratiu Vultur 	role.in_role = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]);
3117ab1748eSHoratiu Vultur 
3127ab1748eSHoratiu Vultur 	return br_mrp_set_in_role(br, &role);
3137ab1748eSHoratiu Vultur }
3147ab1748eSHoratiu Vultur 
3157ab1748eSHoratiu Vultur static const struct nla_policy
3167ab1748eSHoratiu Vultur br_mrp_start_in_test_policy[IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1] = {
3177ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_IN_TEST_UNSPEC]	= { .type = NLA_REJECT },
3187ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID]	= { .type = NLA_U32 },
3197ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL]	= { .type = NLA_U32 },
3207ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS]	= { .type = NLA_U32 },
3217ab1748eSHoratiu Vultur 	[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]	= { .type = NLA_U32 },
3227ab1748eSHoratiu Vultur };
3237ab1748eSHoratiu Vultur 
br_mrp_start_in_test_parse(struct net_bridge * br,struct nlattr * attr,struct netlink_ext_ack * extack)3247ab1748eSHoratiu Vultur static int br_mrp_start_in_test_parse(struct net_bridge *br,
3257ab1748eSHoratiu Vultur 				      struct nlattr *attr,
3267ab1748eSHoratiu Vultur 				      struct netlink_ext_ack *extack)
3277ab1748eSHoratiu Vultur {
3287ab1748eSHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1];
3297ab1748eSHoratiu Vultur 	struct br_mrp_start_in_test test;
3307ab1748eSHoratiu Vultur 	int err;
3317ab1748eSHoratiu Vultur 
3327ab1748eSHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_START_IN_TEST_MAX, attr,
3337ab1748eSHoratiu Vultur 			       br_mrp_start_in_test_policy, extack);
3347ab1748eSHoratiu Vultur 	if (err)
3357ab1748eSHoratiu Vultur 		return err;
3367ab1748eSHoratiu Vultur 
3377ab1748eSHoratiu Vultur 	if (!tb[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID] ||
3387ab1748eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL] ||
3397ab1748eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS] ||
3407ab1748eSHoratiu Vultur 	    !tb[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]) {
3417ab1748eSHoratiu Vultur 		NL_SET_ERR_MSG_MOD(extack,
3427ab1748eSHoratiu Vultur 				   "Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD");
3437ab1748eSHoratiu Vultur 		return -EINVAL;
3447ab1748eSHoratiu Vultur 	}
3457ab1748eSHoratiu Vultur 
3467ab1748eSHoratiu Vultur 	memset(&test, 0x0, sizeof(test));
3477ab1748eSHoratiu Vultur 
3487ab1748eSHoratiu Vultur 	test.in_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID]);
3497ab1748eSHoratiu Vultur 	test.interval = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL]);
3507ab1748eSHoratiu Vultur 	test.max_miss = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS]);
3517ab1748eSHoratiu Vultur 	test.period = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]);
3527ab1748eSHoratiu Vultur 
3537ab1748eSHoratiu Vultur 	return br_mrp_start_in_test(br, &test);
3547ab1748eSHoratiu Vultur }
3557ab1748eSHoratiu Vultur 
br_mrp_parse(struct net_bridge * br,struct net_bridge_port * p,struct nlattr * attr,int cmd,struct netlink_ext_ack * extack)3564d02b8f0SHoratiu Vultur int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
3574d02b8f0SHoratiu Vultur 		 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack)
3584d02b8f0SHoratiu Vultur {
3594d02b8f0SHoratiu Vultur 	struct nlattr *tb[IFLA_BRIDGE_MRP_MAX + 1];
3604d02b8f0SHoratiu Vultur 	int err;
3614d02b8f0SHoratiu Vultur 
362617504c6SHoratiu Vultur 	/* When this function is called for a port then the br pointer is
363617504c6SHoratiu Vultur 	 * invalid, therefor set the br to point correctly
364617504c6SHoratiu Vultur 	 */
365617504c6SHoratiu Vultur 	if (p)
366617504c6SHoratiu Vultur 		br = p->br;
367617504c6SHoratiu Vultur 
3684d02b8f0SHoratiu Vultur 	if (br->stp_enabled != BR_NO_STP) {
369c75a33c8SJacob Keller 		NL_SET_ERR_MSG_MOD(extack, "MRP can't be enabled if STP is already enabled");
3704d02b8f0SHoratiu Vultur 		return -EINVAL;
3714d02b8f0SHoratiu Vultur 	}
3724d02b8f0SHoratiu Vultur 
3734d02b8f0SHoratiu Vultur 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_MAX, attr,
3744d02b8f0SHoratiu Vultur 			       br_mrp_policy, extack);
3754d02b8f0SHoratiu Vultur 	if (err)
3764d02b8f0SHoratiu Vultur 		return err;
3774d02b8f0SHoratiu Vultur 
3784d02b8f0SHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_INSTANCE]) {
37920f6a05eSHoratiu Vultur 		err = br_mrp_instance_parse(br, tb[IFLA_BRIDGE_MRP_INSTANCE],
38020f6a05eSHoratiu Vultur 					    cmd, extack);
3814d02b8f0SHoratiu Vultur 		if (err)
3824d02b8f0SHoratiu Vultur 			return err;
3834d02b8f0SHoratiu Vultur 	}
3844d02b8f0SHoratiu Vultur 
3854d02b8f0SHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_PORT_STATE]) {
38620f6a05eSHoratiu Vultur 		err = br_mrp_port_state_parse(p, tb[IFLA_BRIDGE_MRP_PORT_STATE],
38720f6a05eSHoratiu Vultur 					      extack);
3884d02b8f0SHoratiu Vultur 		if (err)
3894d02b8f0SHoratiu Vultur 			return err;
3904d02b8f0SHoratiu Vultur 	}
3914d02b8f0SHoratiu Vultur 
3924d02b8f0SHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_PORT_ROLE]) {
39320f6a05eSHoratiu Vultur 		err = br_mrp_port_role_parse(p, tb[IFLA_BRIDGE_MRP_PORT_ROLE],
39420f6a05eSHoratiu Vultur 					     extack);
3954d02b8f0SHoratiu Vultur 		if (err)
3964d02b8f0SHoratiu Vultur 			return err;
3974d02b8f0SHoratiu Vultur 	}
3984d02b8f0SHoratiu Vultur 
3994d02b8f0SHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_RING_STATE]) {
40020f6a05eSHoratiu Vultur 		err = br_mrp_ring_state_parse(br,
40120f6a05eSHoratiu Vultur 					      tb[IFLA_BRIDGE_MRP_RING_STATE],
40220f6a05eSHoratiu Vultur 					      extack);
4034d02b8f0SHoratiu Vultur 		if (err)
4044d02b8f0SHoratiu Vultur 			return err;
4054d02b8f0SHoratiu Vultur 	}
4064d02b8f0SHoratiu Vultur 
4074d02b8f0SHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_RING_ROLE]) {
40820f6a05eSHoratiu Vultur 		err = br_mrp_ring_role_parse(br, tb[IFLA_BRIDGE_MRP_RING_ROLE],
40920f6a05eSHoratiu Vultur 					     extack);
4104d02b8f0SHoratiu Vultur 		if (err)
4114d02b8f0SHoratiu Vultur 			return err;
4124d02b8f0SHoratiu Vultur 	}
4134d02b8f0SHoratiu Vultur 
4144d02b8f0SHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_START_TEST]) {
41520f6a05eSHoratiu Vultur 		err = br_mrp_start_test_parse(br,
41620f6a05eSHoratiu Vultur 					      tb[IFLA_BRIDGE_MRP_START_TEST],
41720f6a05eSHoratiu Vultur 					      extack);
4184d02b8f0SHoratiu Vultur 		if (err)
4194d02b8f0SHoratiu Vultur 			return err;
4204d02b8f0SHoratiu Vultur 	}
4214d02b8f0SHoratiu Vultur 
4227ab1748eSHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_IN_STATE]) {
4237ab1748eSHoratiu Vultur 		err = br_mrp_in_state_parse(br, tb[IFLA_BRIDGE_MRP_IN_STATE],
4247ab1748eSHoratiu Vultur 					    extack);
4257ab1748eSHoratiu Vultur 		if (err)
4267ab1748eSHoratiu Vultur 			return err;
4277ab1748eSHoratiu Vultur 	}
4287ab1748eSHoratiu Vultur 
4297ab1748eSHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_IN_ROLE]) {
4307ab1748eSHoratiu Vultur 		err = br_mrp_in_role_parse(br, tb[IFLA_BRIDGE_MRP_IN_ROLE],
4317ab1748eSHoratiu Vultur 					   extack);
4327ab1748eSHoratiu Vultur 		if (err)
4337ab1748eSHoratiu Vultur 			return err;
4347ab1748eSHoratiu Vultur 	}
4357ab1748eSHoratiu Vultur 
4367ab1748eSHoratiu Vultur 	if (tb[IFLA_BRIDGE_MRP_START_IN_TEST]) {
4377ab1748eSHoratiu Vultur 		err = br_mrp_start_in_test_parse(br,
4387ab1748eSHoratiu Vultur 						 tb[IFLA_BRIDGE_MRP_START_IN_TEST],
4397ab1748eSHoratiu Vultur 						 extack);
4407ab1748eSHoratiu Vultur 		if (err)
4417ab1748eSHoratiu Vultur 			return err;
4427ab1748eSHoratiu Vultur 	}
4437ab1748eSHoratiu Vultur 
4444d02b8f0SHoratiu Vultur 	return 0;
4454d02b8f0SHoratiu Vultur }
4464d02b8f0SHoratiu Vultur 
br_mrp_fill_info(struct sk_buff * skb,struct net_bridge * br)447df42ef22SHoratiu Vultur int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
448df42ef22SHoratiu Vultur {
449df42ef22SHoratiu Vultur 	struct nlattr *tb, *mrp_tb;
450df42ef22SHoratiu Vultur 	struct br_mrp *mrp;
451df42ef22SHoratiu Vultur 
452df42ef22SHoratiu Vultur 	mrp_tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP);
453df42ef22SHoratiu Vultur 	if (!mrp_tb)
454df42ef22SHoratiu Vultur 		return -EMSGSIZE;
455df42ef22SHoratiu Vultur 
456*0169b820SHoratiu Vultur 	hlist_for_each_entry_rcu(mrp, &br->mrp_list, list) {
457df42ef22SHoratiu Vultur 		struct net_bridge_port *p;
458df42ef22SHoratiu Vultur 
459df42ef22SHoratiu Vultur 		tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP_INFO);
460df42ef22SHoratiu Vultur 		if (!tb)
461df42ef22SHoratiu Vultur 			goto nla_info_failure;
462df42ef22SHoratiu Vultur 
463df42ef22SHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ID,
464df42ef22SHoratiu Vultur 				mrp->ring_id))
465df42ef22SHoratiu Vultur 			goto nla_put_failure;
466df42ef22SHoratiu Vultur 
467df42ef22SHoratiu Vultur 		p = rcu_dereference(mrp->p_port);
468df42ef22SHoratiu Vultur 		if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_P_IFINDEX,
469df42ef22SHoratiu Vultur 				     p->dev->ifindex))
470df42ef22SHoratiu Vultur 			goto nla_put_failure;
471df42ef22SHoratiu Vultur 
472df42ef22SHoratiu Vultur 		p = rcu_dereference(mrp->s_port);
473df42ef22SHoratiu Vultur 		if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_S_IFINDEX,
474df42ef22SHoratiu Vultur 				     p->dev->ifindex))
475df42ef22SHoratiu Vultur 			goto nla_put_failure;
476df42ef22SHoratiu Vultur 
4774fc4871fSHoratiu Vultur 		p = rcu_dereference(mrp->i_port);
4784fc4871fSHoratiu Vultur 		if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_I_IFINDEX,
4794fc4871fSHoratiu Vultur 				     p->dev->ifindex))
4804fc4871fSHoratiu Vultur 			goto nla_put_failure;
4814fc4871fSHoratiu Vultur 
482df42ef22SHoratiu Vultur 		if (nla_put_u16(skb, IFLA_BRIDGE_MRP_INFO_PRIO,
483df42ef22SHoratiu Vultur 				mrp->prio))
484df42ef22SHoratiu Vultur 			goto nla_put_failure;
485df42ef22SHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_STATE,
486df42ef22SHoratiu Vultur 				mrp->ring_state))
487df42ef22SHoratiu Vultur 			goto nla_put_failure;
488df42ef22SHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ROLE,
489df42ef22SHoratiu Vultur 				mrp->ring_role))
490df42ef22SHoratiu Vultur 			goto nla_put_failure;
491df42ef22SHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_INTERVAL,
492df42ef22SHoratiu Vultur 				mrp->test_interval))
493df42ef22SHoratiu Vultur 			goto nla_put_failure;
494df42ef22SHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MAX_MISS,
495df42ef22SHoratiu Vultur 				mrp->test_max_miss))
496df42ef22SHoratiu Vultur 			goto nla_put_failure;
497df42ef22SHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MONITOR,
498df42ef22SHoratiu Vultur 				mrp->test_monitor))
499df42ef22SHoratiu Vultur 			goto nla_put_failure;
500df42ef22SHoratiu Vultur 
5014fc4871fSHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_STATE,
5024fc4871fSHoratiu Vultur 				mrp->in_state))
5034fc4871fSHoratiu Vultur 			goto nla_put_failure;
5044fc4871fSHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_ROLE,
5054fc4871fSHoratiu Vultur 				mrp->in_role))
5064fc4871fSHoratiu Vultur 			goto nla_put_failure;
5074fc4871fSHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_TEST_INTERVAL,
5084fc4871fSHoratiu Vultur 				mrp->in_test_interval))
5094fc4871fSHoratiu Vultur 			goto nla_put_failure;
5104fc4871fSHoratiu Vultur 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_TEST_MAX_MISS,
5114fc4871fSHoratiu Vultur 				mrp->in_test_max_miss))
5124fc4871fSHoratiu Vultur 			goto nla_put_failure;
5134fc4871fSHoratiu Vultur 
514df42ef22SHoratiu Vultur 		nla_nest_end(skb, tb);
515df42ef22SHoratiu Vultur 	}
516df42ef22SHoratiu Vultur 	nla_nest_end(skb, mrp_tb);
517df42ef22SHoratiu Vultur 
518df42ef22SHoratiu Vultur 	return 0;
519df42ef22SHoratiu Vultur 
520df42ef22SHoratiu Vultur nla_put_failure:
521df42ef22SHoratiu Vultur 	nla_nest_cancel(skb, tb);
522df42ef22SHoratiu Vultur 
523df42ef22SHoratiu Vultur nla_info_failure:
524df42ef22SHoratiu Vultur 	nla_nest_cancel(skb, mrp_tb);
525df42ef22SHoratiu Vultur 
526df42ef22SHoratiu Vultur 	return -EMSGSIZE;
527df42ef22SHoratiu Vultur }
528df42ef22SHoratiu Vultur 
br_mrp_ring_port_open(struct net_device * dev,u8 loc)5294cc625c6SHoratiu Vultur int br_mrp_ring_port_open(struct net_device *dev, u8 loc)
5309a9f26e8SHoratiu Vultur {
5319a9f26e8SHoratiu Vultur 	struct net_bridge_port *p;
5329a9f26e8SHoratiu Vultur 	int err = 0;
5339a9f26e8SHoratiu Vultur 
5349a9f26e8SHoratiu Vultur 	p = br_port_get_rcu(dev);
5359a9f26e8SHoratiu Vultur 	if (!p) {
5369a9f26e8SHoratiu Vultur 		err = -EINVAL;
5379a9f26e8SHoratiu Vultur 		goto out;
5389a9f26e8SHoratiu Vultur 	}
5399a9f26e8SHoratiu Vultur 
5409a9f26e8SHoratiu Vultur 	if (loc)
5419a9f26e8SHoratiu Vultur 		p->flags |= BR_MRP_LOST_CONT;
5429a9f26e8SHoratiu Vultur 	else
5439a9f26e8SHoratiu Vultur 		p->flags &= ~BR_MRP_LOST_CONT;
5449a9f26e8SHoratiu Vultur 
5459a9f26e8SHoratiu Vultur 	br_ifinfo_notify(RTM_NEWLINK, NULL, p);
5469a9f26e8SHoratiu Vultur 
5479a9f26e8SHoratiu Vultur out:
5489a9f26e8SHoratiu Vultur 	return err;
5499a9f26e8SHoratiu Vultur }
5504139d4b5SHoratiu Vultur 
br_mrp_in_port_open(struct net_device * dev,u8 loc)5514139d4b5SHoratiu Vultur int br_mrp_in_port_open(struct net_device *dev, u8 loc)
5524139d4b5SHoratiu Vultur {
5534139d4b5SHoratiu Vultur 	struct net_bridge_port *p;
5544139d4b5SHoratiu Vultur 	int err = 0;
5554139d4b5SHoratiu Vultur 
5564139d4b5SHoratiu Vultur 	p = br_port_get_rcu(dev);
5574139d4b5SHoratiu Vultur 	if (!p) {
5584139d4b5SHoratiu Vultur 		err = -EINVAL;
5594139d4b5SHoratiu Vultur 		goto out;
5604139d4b5SHoratiu Vultur 	}
5614139d4b5SHoratiu Vultur 
5624139d4b5SHoratiu Vultur 	if (loc)
5634139d4b5SHoratiu Vultur 		p->flags |= BR_MRP_LOST_IN_CONT;
5644139d4b5SHoratiu Vultur 	else
5654139d4b5SHoratiu Vultur 		p->flags &= ~BR_MRP_LOST_IN_CONT;
5664139d4b5SHoratiu Vultur 
5674139d4b5SHoratiu Vultur 	br_ifinfo_notify(RTM_NEWLINK, NULL, p);
5684139d4b5SHoratiu Vultur 
5694139d4b5SHoratiu Vultur out:
5704139d4b5SHoratiu Vultur 	return err;
5714139d4b5SHoratiu Vultur }
572