Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <uapi/linux/mrp_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include "br_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include "br_private_mrp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) static const struct nla_policy br_mrp_policy[IFLA_BRIDGE_MRP_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 	[IFLA_BRIDGE_MRP_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 	[IFLA_BRIDGE_MRP_INSTANCE]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 	[IFLA_BRIDGE_MRP_PORT_STATE]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 	[IFLA_BRIDGE_MRP_PORT_ROLE]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	[IFLA_BRIDGE_MRP_RING_STATE]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	[IFLA_BRIDGE_MRP_RING_ROLE]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	[IFLA_BRIDGE_MRP_START_TEST]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	[IFLA_BRIDGE_MRP_IN_ROLE]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	[IFLA_BRIDGE_MRP_IN_STATE]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	[IFLA_BRIDGE_MRP_START_IN_TEST]	= { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) br_mrp_instance_policy[IFLA_BRIDGE_MRP_INSTANCE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	[IFLA_BRIDGE_MRP_INSTANCE_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	[IFLA_BRIDGE_MRP_INSTANCE_RING_ID]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	[IFLA_BRIDGE_MRP_INSTANCE_PRIO]		= { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static int br_mrp_instance_parse(struct net_bridge *br, struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 				 int cmd, struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct nlattr *tb[IFLA_BRIDGE_MRP_INSTANCE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct br_mrp_instance inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_INSTANCE_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			       br_mrp_instance_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	if (!tb[IFLA_BRIDGE_MRP_INSTANCE_RING_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	    !tb[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	    !tb[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		NL_SET_ERR_MSG_MOD(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 				   "Missing attribute: RING_ID or P_IFINDEX or S_IFINDEX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	memset(&inst, 0, sizeof(inst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	inst.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_RING_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	inst.p_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	inst.s_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	inst.prio = MRP_DEFAULT_PRIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	if (tb[IFLA_BRIDGE_MRP_INSTANCE_PRIO])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		inst.prio = nla_get_u16(tb[IFLA_BRIDGE_MRP_INSTANCE_PRIO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (cmd == RTM_SETLINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		return br_mrp_add(br, &inst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		return br_mrp_del(br, &inst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) br_mrp_port_state_policy[IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	[IFLA_BRIDGE_MRP_PORT_STATE_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	[IFLA_BRIDGE_MRP_PORT_STATE_STATE]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static int br_mrp_port_state_parse(struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				   struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 				   struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct nlattr *tb[IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	enum br_mrp_port_state_type state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_PORT_STATE_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			       br_mrp_port_state_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (!tb[IFLA_BRIDGE_MRP_PORT_STATE_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		NL_SET_ERR_MSG_MOD(extack, "Missing attribute: STATE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	state = nla_get_u32(tb[IFLA_BRIDGE_MRP_PORT_STATE_STATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	return br_mrp_set_port_state(p, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) br_mrp_port_role_policy[IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	[IFLA_BRIDGE_MRP_PORT_ROLE_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int br_mrp_port_role_parse(struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				  struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 				  struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct nlattr *tb[IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	enum br_mrp_port_role_type role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_PORT_ROLE_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			       br_mrp_port_role_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (!tb[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		NL_SET_ERR_MSG_MOD(extack, "Missing attribute: ROLE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	role = nla_get_u32(tb[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	return br_mrp_set_port_role(p, role);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) br_mrp_ring_state_policy[IFLA_BRIDGE_MRP_RING_STATE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	[IFLA_BRIDGE_MRP_RING_STATE_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	[IFLA_BRIDGE_MRP_RING_STATE_RING_ID]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	[IFLA_BRIDGE_MRP_RING_STATE_STATE]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int br_mrp_ring_state_parse(struct net_bridge *br, struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				   struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	struct nlattr *tb[IFLA_BRIDGE_MRP_RING_STATE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	struct br_mrp_ring_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_RING_STATE_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			       br_mrp_ring_state_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (!tb[IFLA_BRIDGE_MRP_RING_STATE_RING_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	    !tb[IFLA_BRIDGE_MRP_RING_STATE_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		NL_SET_ERR_MSG_MOD(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 				   "Missing attribute: RING_ID or STATE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	memset(&state, 0x0, sizeof(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	state.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_STATE_RING_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	state.ring_state = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_STATE_STATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	return br_mrp_set_ring_state(br, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) br_mrp_ring_role_policy[IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	[IFLA_BRIDGE_MRP_RING_ROLE_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static int br_mrp_ring_role_parse(struct net_bridge *br, struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 				  struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	struct nlattr *tb[IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	struct br_mrp_ring_role role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_RING_ROLE_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			       br_mrp_ring_role_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (!tb[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	    !tb[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		NL_SET_ERR_MSG_MOD(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 				   "Missing attribute: RING_ID or ROLE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	memset(&role, 0x0, sizeof(role));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	role.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	role.ring_role = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	return br_mrp_set_ring_role(br, &role);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) br_mrp_start_test_policy[IFLA_BRIDGE_MRP_START_TEST_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	[IFLA_BRIDGE_MRP_START_TEST_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	[IFLA_BRIDGE_MRP_START_TEST_RING_ID]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	[IFLA_BRIDGE_MRP_START_TEST_INTERVAL]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	[IFLA_BRIDGE_MRP_START_TEST_PERIOD]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	[IFLA_BRIDGE_MRP_START_TEST_MONITOR]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int br_mrp_start_test_parse(struct net_bridge *br, struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 				   struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	struct nlattr *tb[IFLA_BRIDGE_MRP_START_TEST_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	struct br_mrp_start_test test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_START_TEST_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			       br_mrp_start_test_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (!tb[IFLA_BRIDGE_MRP_START_TEST_RING_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	    !tb[IFLA_BRIDGE_MRP_START_TEST_INTERVAL] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	    !tb[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	    !tb[IFLA_BRIDGE_MRP_START_TEST_PERIOD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		NL_SET_ERR_MSG_MOD(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 				   "Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	memset(&test, 0x0, sizeof(test));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	test.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_RING_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	test.interval = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	test.max_miss = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	test.period = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_PERIOD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	test.monitor = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (tb[IFLA_BRIDGE_MRP_START_TEST_MONITOR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		test.monitor =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_MONITOR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	return br_mrp_start_test(br, &test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) br_mrp_in_state_policy[IFLA_BRIDGE_MRP_IN_STATE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	[IFLA_BRIDGE_MRP_IN_STATE_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	[IFLA_BRIDGE_MRP_IN_STATE_IN_ID]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	[IFLA_BRIDGE_MRP_IN_STATE_STATE]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int br_mrp_in_state_parse(struct net_bridge *br, struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				 struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	struct nlattr *tb[IFLA_BRIDGE_MRP_IN_STATE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	struct br_mrp_in_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_IN_STATE_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			       br_mrp_in_state_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (!tb[IFLA_BRIDGE_MRP_IN_STATE_IN_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	    !tb[IFLA_BRIDGE_MRP_IN_STATE_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		NL_SET_ERR_MSG_MOD(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				   "Missing attribute: IN_ID or STATE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	memset(&state, 0x0, sizeof(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	state.in_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_STATE_IN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	state.in_state = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_STATE_STATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return br_mrp_set_in_state(br, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) br_mrp_in_role_policy[IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	[IFLA_BRIDGE_MRP_IN_ROLE_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID]		= { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]		= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int br_mrp_in_role_parse(struct net_bridge *br, struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 				struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	struct nlattr *tb[IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	struct br_mrp_in_role role;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_IN_ROLE_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			       br_mrp_in_role_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if (!tb[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	    !tb[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	    !tb[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	    !tb[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		NL_SET_ERR_MSG_MOD(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 				   "Missing attribute: RING_ID or ROLE or IN_ID or I_IFINDEX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	memset(&role, 0x0, sizeof(role));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	role.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	role.in_id = nla_get_u16(tb[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	role.i_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	role.in_role = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	return br_mrp_set_in_role(br, &role);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) br_mrp_start_in_test_policy[IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	[IFLA_BRIDGE_MRP_START_IN_TEST_UNSPEC]	= { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int br_mrp_start_in_test_parse(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				      struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 				      struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	struct nlattr *tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	struct br_mrp_start_in_test test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_START_IN_TEST_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			       br_mrp_start_in_test_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (!tb[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	    !tb[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	    !tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	    !tb[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		NL_SET_ERR_MSG_MOD(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				   "Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	memset(&test, 0x0, sizeof(test));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	test.in_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	test.interval = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	test.max_miss = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	test.period = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	return br_mrp_start_in_test(br, &test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	struct nlattr *tb[IFLA_BRIDGE_MRP_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	/* When this function is called for a port then the br pointer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	 * invalid, therefor set the br to point correctly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		br = p->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (br->stp_enabled != BR_NO_STP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		NL_SET_ERR_MSG_MOD(extack, "MRP can't be enabled if STP is already enabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			       br_mrp_policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	if (tb[IFLA_BRIDGE_MRP_INSTANCE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		err = br_mrp_instance_parse(br, tb[IFLA_BRIDGE_MRP_INSTANCE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 					    cmd, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	if (tb[IFLA_BRIDGE_MRP_PORT_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		err = br_mrp_port_state_parse(p, tb[IFLA_BRIDGE_MRP_PORT_STATE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 					      extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	if (tb[IFLA_BRIDGE_MRP_PORT_ROLE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		err = br_mrp_port_role_parse(p, tb[IFLA_BRIDGE_MRP_PORT_ROLE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 					     extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	if (tb[IFLA_BRIDGE_MRP_RING_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		err = br_mrp_ring_state_parse(br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 					      tb[IFLA_BRIDGE_MRP_RING_STATE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 					      extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (tb[IFLA_BRIDGE_MRP_RING_ROLE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		err = br_mrp_ring_role_parse(br, tb[IFLA_BRIDGE_MRP_RING_ROLE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 					     extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (tb[IFLA_BRIDGE_MRP_START_TEST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		err = br_mrp_start_test_parse(br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 					      tb[IFLA_BRIDGE_MRP_START_TEST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 					      extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	if (tb[IFLA_BRIDGE_MRP_IN_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		err = br_mrp_in_state_parse(br, tb[IFLA_BRIDGE_MRP_IN_STATE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 					    extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (tb[IFLA_BRIDGE_MRP_IN_ROLE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		err = br_mrp_in_role_parse(br, tb[IFLA_BRIDGE_MRP_IN_ROLE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 					   extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	if (tb[IFLA_BRIDGE_MRP_START_IN_TEST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		err = br_mrp_start_in_test_parse(br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 						 tb[IFLA_BRIDGE_MRP_START_IN_TEST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 						 extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	struct nlattr *tb, *mrp_tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	struct br_mrp *mrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	mrp_tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	if (!mrp_tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	list_for_each_entry_rcu(mrp, &br->mrp_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		struct net_bridge_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		if (!tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			goto nla_info_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 				mrp->ring_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		p = rcu_dereference(mrp->p_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_P_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 				     p->dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		p = rcu_dereference(mrp->s_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_S_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 				     p->dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		p = rcu_dereference(mrp->i_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_I_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 				     p->dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		if (nla_put_u16(skb, IFLA_BRIDGE_MRP_INFO_PRIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 				mrp->prio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				mrp->ring_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ROLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 				mrp->ring_role))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 				mrp->test_interval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MAX_MISS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				mrp->test_max_miss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MONITOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 				mrp->test_monitor))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				mrp->in_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_ROLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 				mrp->in_role))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_TEST_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				mrp->in_test_interval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_TEST_MAX_MISS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 				mrp->in_test_max_miss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		nla_nest_end(skb, tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	nla_nest_end(skb, mrp_tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	nla_nest_cancel(skb, tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) nla_info_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	nla_nest_cancel(skb, mrp_tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int br_mrp_ring_port_open(struct net_device *dev, u8 loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	struct net_bridge_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	p = br_port_get_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	if (loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		p->flags |= BR_MRP_LOST_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		p->flags &= ~BR_MRP_LOST_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	br_ifinfo_notify(RTM_NEWLINK, NULL, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int br_mrp_in_port_open(struct net_device *dev, u8 loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	struct net_bridge_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	p = br_port_get_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	if (loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		p->flags |= BR_MRP_LOST_IN_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		p->flags &= ~BR_MRP_LOST_IN_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	br_ifinfo_notify(RTM_NEWLINK, NULL, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }