2020-04-26 16:22:05 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
# include <net/genetlink.h>
# include <uapi/linux/mrp_bridge.h>
# include "br_private.h"
# include "br_private_mrp.h"
2020-04-26 16:22:06 +03:00
static const struct nla_policy br_mrp_policy [ IFLA_BRIDGE_MRP_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_UNSPEC ] = { . type = NLA_REJECT } ,
2020-05-27 15:34:30 +03:00
[ IFLA_BRIDGE_MRP_INSTANCE ] = { . type = NLA_NESTED } ,
[ IFLA_BRIDGE_MRP_PORT_STATE ] = { . type = NLA_NESTED } ,
[ IFLA_BRIDGE_MRP_PORT_ROLE ] = { . type = NLA_NESTED } ,
[ IFLA_BRIDGE_MRP_RING_STATE ] = { . type = NLA_NESTED } ,
[ IFLA_BRIDGE_MRP_RING_ROLE ] = { . type = NLA_NESTED } ,
[ IFLA_BRIDGE_MRP_START_TEST ] = { . type = NLA_NESTED } ,
2020-07-14 10:34:55 +03:00
[ IFLA_BRIDGE_MRP_IN_ROLE ] = { . type = NLA_NESTED } ,
[ IFLA_BRIDGE_MRP_IN_STATE ] = { . type = NLA_NESTED } ,
[ IFLA_BRIDGE_MRP_START_IN_TEST ] = { . type = NLA_NESTED } ,
2020-04-26 16:22:06 +03:00
} ;
2020-05-27 15:34:30 +03:00
static const struct nla_policy
br_mrp_instance_policy [ IFLA_BRIDGE_MRP_INSTANCE_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_INSTANCE_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_INSTANCE_RING_ID ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX ] = { . type = NLA_U32 } ,
2020-05-30 21:09:47 +03:00
[ IFLA_BRIDGE_MRP_INSTANCE_PRIO ] = { . type = NLA_U16 } ,
2020-05-27 15:34:30 +03:00
} ;
static int br_mrp_instance_parse ( struct net_bridge * br , struct nlattr * attr ,
int cmd , struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_INSTANCE_MAX + 1 ] ;
struct br_mrp_instance inst ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_INSTANCE_MAX , attr ,
br_mrp_instance_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_INSTANCE_RING_ID ] | |
! tb [ IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX ] | |
! tb [ IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX ] ) {
NL_SET_ERR_MSG_MOD ( extack ,
" Missing attribute: RING_ID or P_IFINDEX or S_IFINDEX " ) ;
return - EINVAL ;
}
memset ( & inst , 0 , sizeof ( inst ) ) ;
inst . ring_id = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_INSTANCE_RING_ID ] ) ;
inst . p_ifindex = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX ] ) ;
inst . s_ifindex = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX ] ) ;
2020-05-30 21:09:47 +03:00
inst . prio = MRP_DEFAULT_PRIO ;
if ( tb [ IFLA_BRIDGE_MRP_INSTANCE_PRIO ] )
inst . prio = nla_get_u16 ( tb [ IFLA_BRIDGE_MRP_INSTANCE_PRIO ] ) ;
2020-05-27 15:34:30 +03:00
if ( cmd = = RTM_SETLINK )
return br_mrp_add ( br , & inst ) ;
else
return br_mrp_del ( br , & inst ) ;
return 0 ;
}
static const struct nla_policy
br_mrp_port_state_policy [ IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_PORT_STATE_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_PORT_STATE_STATE ] = { . type = NLA_U32 } ,
} ;
static int br_mrp_port_state_parse ( struct net_bridge_port * p ,
struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1 ] ;
enum br_mrp_port_state_type state ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_PORT_STATE_MAX , attr ,
br_mrp_port_state_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_PORT_STATE_STATE ] ) {
NL_SET_ERR_MSG_MOD ( extack , " Missing attribute: STATE " ) ;
return - EINVAL ;
}
state = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_PORT_STATE_STATE ] ) ;
return br_mrp_set_port_state ( p , state ) ;
}
static const struct nla_policy
br_mrp_port_role_policy [ IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_PORT_ROLE_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_PORT_ROLE_ROLE ] = { . type = NLA_U32 } ,
} ;
static int br_mrp_port_role_parse ( struct net_bridge_port * p ,
struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1 ] ;
enum br_mrp_port_role_type role ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_PORT_ROLE_MAX , attr ,
br_mrp_port_role_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_PORT_ROLE_ROLE ] ) {
NL_SET_ERR_MSG_MOD ( extack , " Missing attribute: ROLE " ) ;
return - EINVAL ;
}
role = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_PORT_ROLE_ROLE ] ) ;
return br_mrp_set_port_role ( p , role ) ;
}
static const struct nla_policy
br_mrp_ring_state_policy [ IFLA_BRIDGE_MRP_RING_STATE_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_RING_STATE_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_RING_STATE_RING_ID ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_RING_STATE_STATE ] = { . type = NLA_U32 } ,
} ;
static int br_mrp_ring_state_parse ( struct net_bridge * br , struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_RING_STATE_MAX + 1 ] ;
struct br_mrp_ring_state state ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_RING_STATE_MAX , attr ,
br_mrp_ring_state_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_RING_STATE_RING_ID ] | |
! tb [ IFLA_BRIDGE_MRP_RING_STATE_STATE ] ) {
NL_SET_ERR_MSG_MOD ( extack ,
" Missing attribute: RING_ID or STATE " ) ;
return - EINVAL ;
}
memset ( & state , 0x0 , sizeof ( state ) ) ;
state . ring_id = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_RING_STATE_RING_ID ] ) ;
state . ring_state = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_RING_STATE_STATE ] ) ;
return br_mrp_set_ring_state ( br , & state ) ;
}
static const struct nla_policy
br_mrp_ring_role_policy [ IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_RING_ROLE_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_RING_ROLE_RING_ID ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_RING_ROLE_ROLE ] = { . type = NLA_U32 } ,
} ;
static int br_mrp_ring_role_parse ( struct net_bridge * br , struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1 ] ;
struct br_mrp_ring_role role ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_RING_ROLE_MAX , attr ,
br_mrp_ring_role_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_RING_ROLE_RING_ID ] | |
! tb [ IFLA_BRIDGE_MRP_RING_ROLE_ROLE ] ) {
NL_SET_ERR_MSG_MOD ( extack ,
" Missing attribute: RING_ID or ROLE " ) ;
return - EINVAL ;
}
memset ( & role , 0x0 , sizeof ( role ) ) ;
role . ring_id = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_RING_ROLE_RING_ID ] ) ;
role . ring_role = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_RING_ROLE_ROLE ] ) ;
return br_mrp_set_ring_role ( br , & role ) ;
}
static const struct nla_policy
br_mrp_start_test_policy [ IFLA_BRIDGE_MRP_START_TEST_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_START_TEST_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_START_TEST_RING_ID ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_START_TEST_INTERVAL ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_START_TEST_MAX_MISS ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_START_TEST_PERIOD ] = { . type = NLA_U32 } ,
2020-05-30 21:09:48 +03:00
[ IFLA_BRIDGE_MRP_START_TEST_MONITOR ] = { . type = NLA_U32 } ,
2020-05-27 15:34:30 +03:00
} ;
static int br_mrp_start_test_parse ( struct net_bridge * br , struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_START_TEST_MAX + 1 ] ;
struct br_mrp_start_test test ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_START_TEST_MAX , attr ,
br_mrp_start_test_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_START_TEST_RING_ID ] | |
! tb [ IFLA_BRIDGE_MRP_START_TEST_INTERVAL ] | |
! tb [ IFLA_BRIDGE_MRP_START_TEST_MAX_MISS ] | |
! tb [ IFLA_BRIDGE_MRP_START_TEST_PERIOD ] ) {
NL_SET_ERR_MSG_MOD ( extack ,
" Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD " ) ;
return - EINVAL ;
}
memset ( & test , 0x0 , sizeof ( test ) ) ;
test . ring_id = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_TEST_RING_ID ] ) ;
test . interval = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_TEST_INTERVAL ] ) ;
test . max_miss = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_TEST_MAX_MISS ] ) ;
test . period = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_TEST_PERIOD ] ) ;
2020-05-30 21:09:48 +03:00
test . monitor = false ;
if ( tb [ IFLA_BRIDGE_MRP_START_TEST_MONITOR ] )
test . monitor =
nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_TEST_MONITOR ] ) ;
2020-05-27 15:34:30 +03:00
return br_mrp_start_test ( br , & test ) ;
}
2020-07-14 10:34:55 +03:00
static const struct nla_policy
br_mrp_in_state_policy [ IFLA_BRIDGE_MRP_IN_STATE_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_IN_STATE_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_IN_STATE_IN_ID ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_IN_STATE_STATE ] = { . type = NLA_U32 } ,
} ;
static int br_mrp_in_state_parse ( struct net_bridge * br , struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_IN_STATE_MAX + 1 ] ;
struct br_mrp_in_state state ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_IN_STATE_MAX , attr ,
br_mrp_in_state_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_IN_STATE_IN_ID ] | |
! tb [ IFLA_BRIDGE_MRP_IN_STATE_STATE ] ) {
NL_SET_ERR_MSG_MOD ( extack ,
" Missing attribute: IN_ID or STATE " ) ;
return - EINVAL ;
}
memset ( & state , 0x0 , sizeof ( state ) ) ;
state . in_id = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_IN_STATE_IN_ID ] ) ;
state . in_state = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_IN_STATE_STATE ] ) ;
return br_mrp_set_in_state ( br , & state ) ;
}
static const struct nla_policy
br_mrp_in_role_policy [ IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_IN_ROLE_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_IN_ROLE_RING_ID ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_IN_ROLE_IN_ID ] = { . type = NLA_U16 } ,
[ IFLA_BRIDGE_MRP_IN_ROLE_ROLE ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX ] = { . type = NLA_U32 } ,
} ;
static int br_mrp_in_role_parse ( struct net_bridge * br , struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1 ] ;
struct br_mrp_in_role role ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_IN_ROLE_MAX , attr ,
br_mrp_in_role_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_IN_ROLE_RING_ID ] | |
! tb [ IFLA_BRIDGE_MRP_IN_ROLE_IN_ID ] | |
! tb [ IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX ] | |
! tb [ IFLA_BRIDGE_MRP_IN_ROLE_ROLE ] ) {
NL_SET_ERR_MSG_MOD ( extack ,
" Missing attribute: RING_ID or ROLE or IN_ID or I_IFINDEX " ) ;
return - EINVAL ;
}
memset ( & role , 0x0 , sizeof ( role ) ) ;
role . ring_id = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_IN_ROLE_RING_ID ] ) ;
role . in_id = nla_get_u16 ( tb [ IFLA_BRIDGE_MRP_IN_ROLE_IN_ID ] ) ;
role . i_ifindex = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX ] ) ;
role . in_role = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_IN_ROLE_ROLE ] ) ;
return br_mrp_set_in_role ( br , & role ) ;
}
static const struct nla_policy
br_mrp_start_in_test_policy [ IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1 ] = {
[ IFLA_BRIDGE_MRP_START_IN_TEST_UNSPEC ] = { . type = NLA_REJECT } ,
[ IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS ] = { . type = NLA_U32 } ,
[ IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD ] = { . type = NLA_U32 } ,
} ;
static int br_mrp_start_in_test_parse ( struct net_bridge * br ,
struct nlattr * attr ,
struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1 ] ;
struct br_mrp_start_in_test test ;
int err ;
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_START_IN_TEST_MAX , attr ,
br_mrp_start_in_test_policy , extack ) ;
if ( err )
return err ;
if ( ! tb [ IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID ] | |
! tb [ IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL ] | |
! tb [ IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS ] | |
! tb [ IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD ] ) {
NL_SET_ERR_MSG_MOD ( extack ,
" Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD " ) ;
return - EINVAL ;
}
memset ( & test , 0x0 , sizeof ( test ) ) ;
test . in_id = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID ] ) ;
test . interval = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL ] ) ;
test . max_miss = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS ] ) ;
test . period = nla_get_u32 ( tb [ IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD ] ) ;
return br_mrp_start_in_test ( br , & test ) ;
}
2020-04-26 16:22:06 +03:00
int br_mrp_parse ( struct net_bridge * br , struct net_bridge_port * p ,
struct nlattr * attr , int cmd , struct netlink_ext_ack * extack )
{
struct nlattr * tb [ IFLA_BRIDGE_MRP_MAX + 1 ] ;
int err ;
2020-05-25 12:55:41 +03:00
/* When this function is called for a port then the br pointer is
* invalid , therefor set the br to point correctly
*/
if ( p )
br = p - > br ;
2020-04-26 16:22:06 +03:00
if ( br - > stp_enabled ! = BR_NO_STP ) {
2020-05-07 03:58:27 +03:00
NL_SET_ERR_MSG_MOD ( extack , " MRP can't be enabled if STP is already enabled " ) ;
2020-04-26 16:22:06 +03:00
return - EINVAL ;
}
err = nla_parse_nested ( tb , IFLA_BRIDGE_MRP_MAX , attr ,
br_mrp_policy , extack ) ;
if ( err )
return err ;
if ( tb [ IFLA_BRIDGE_MRP_INSTANCE ] ) {
2020-05-27 15:34:30 +03:00
err = br_mrp_instance_parse ( br , tb [ IFLA_BRIDGE_MRP_INSTANCE ] ,
cmd , extack ) ;
2020-04-26 16:22:06 +03:00
if ( err )
return err ;
}
if ( tb [ IFLA_BRIDGE_MRP_PORT_STATE ] ) {
2020-05-27 15:34:30 +03:00
err = br_mrp_port_state_parse ( p , tb [ IFLA_BRIDGE_MRP_PORT_STATE ] ,
extack ) ;
2020-04-26 16:22:06 +03:00
if ( err )
return err ;
}
if ( tb [ IFLA_BRIDGE_MRP_PORT_ROLE ] ) {
2020-05-27 15:34:30 +03:00
err = br_mrp_port_role_parse ( p , tb [ IFLA_BRIDGE_MRP_PORT_ROLE ] ,
extack ) ;
2020-04-26 16:22:06 +03:00
if ( err )
return err ;
}
if ( tb [ IFLA_BRIDGE_MRP_RING_STATE ] ) {
2020-05-27 15:34:30 +03:00
err = br_mrp_ring_state_parse ( br ,
tb [ IFLA_BRIDGE_MRP_RING_STATE ] ,
extack ) ;
2020-04-26 16:22:06 +03:00
if ( err )
return err ;
}
if ( tb [ IFLA_BRIDGE_MRP_RING_ROLE ] ) {
2020-05-27 15:34:30 +03:00
err = br_mrp_ring_role_parse ( br , tb [ IFLA_BRIDGE_MRP_RING_ROLE ] ,
extack ) ;
2020-04-26 16:22:06 +03:00
if ( err )
return err ;
}
if ( tb [ IFLA_BRIDGE_MRP_START_TEST ] ) {
2020-05-27 15:34:30 +03:00
err = br_mrp_start_test_parse ( br ,
tb [ IFLA_BRIDGE_MRP_START_TEST ] ,
extack ) ;
2020-04-26 16:22:06 +03:00
if ( err )
return err ;
}
2020-07-14 10:34:55 +03:00
if ( tb [ IFLA_BRIDGE_MRP_IN_STATE ] ) {
err = br_mrp_in_state_parse ( br , tb [ IFLA_BRIDGE_MRP_IN_STATE ] ,
extack ) ;
if ( err )
return err ;
}
if ( tb [ IFLA_BRIDGE_MRP_IN_ROLE ] ) {
err = br_mrp_in_role_parse ( br , tb [ IFLA_BRIDGE_MRP_IN_ROLE ] ,
extack ) ;
if ( err )
return err ;
}
if ( tb [ IFLA_BRIDGE_MRP_START_IN_TEST ] ) {
err = br_mrp_start_in_test_parse ( br ,
tb [ IFLA_BRIDGE_MRP_START_IN_TEST ] ,
extack ) ;
if ( err )
return err ;
}
2020-04-26 16:22:06 +03:00
return 0 ;
}
2020-07-02 11:13:06 +03:00
int br_mrp_fill_info ( struct sk_buff * skb , struct net_bridge * br )
{
struct nlattr * tb , * mrp_tb ;
struct br_mrp * mrp ;
mrp_tb = nla_nest_start_noflag ( skb , IFLA_BRIDGE_MRP ) ;
if ( ! mrp_tb )
return - EMSGSIZE ;
2020-11-07 00:50:49 +03:00
hlist_for_each_entry_rcu ( mrp , & br - > mrp_list , list ) {
2020-07-02 11:13:06 +03:00
struct net_bridge_port * p ;
tb = nla_nest_start_noflag ( skb , IFLA_BRIDGE_MRP_INFO ) ;
if ( ! tb )
goto nla_info_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_RING_ID ,
mrp - > ring_id ) )
goto nla_put_failure ;
p = rcu_dereference ( mrp - > p_port ) ;
if ( p & & nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_P_IFINDEX ,
p - > dev - > ifindex ) )
goto nla_put_failure ;
p = rcu_dereference ( mrp - > s_port ) ;
if ( p & & nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_S_IFINDEX ,
p - > dev - > ifindex ) )
goto nla_put_failure ;
2020-07-14 10:34:57 +03:00
p = rcu_dereference ( mrp - > i_port ) ;
if ( p & & nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_I_IFINDEX ,
p - > dev - > ifindex ) )
goto nla_put_failure ;
2020-07-02 11:13:06 +03:00
if ( nla_put_u16 ( skb , IFLA_BRIDGE_MRP_INFO_PRIO ,
mrp - > prio ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_RING_STATE ,
mrp - > ring_state ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_RING_ROLE ,
mrp - > ring_role ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_TEST_INTERVAL ,
mrp - > test_interval ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_TEST_MAX_MISS ,
mrp - > test_max_miss ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_TEST_MONITOR ,
mrp - > test_monitor ) )
goto nla_put_failure ;
2020-07-14 10:34:57 +03:00
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_IN_STATE ,
mrp - > in_state ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_IN_ROLE ,
mrp - > in_role ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_IN_TEST_INTERVAL ,
mrp - > in_test_interval ) )
goto nla_put_failure ;
if ( nla_put_u32 ( skb , IFLA_BRIDGE_MRP_INFO_IN_TEST_MAX_MISS ,
mrp - > in_test_max_miss ) )
goto nla_put_failure ;
2020-07-02 11:13:06 +03:00
nla_nest_end ( skb , tb ) ;
}
nla_nest_end ( skb , mrp_tb ) ;
return 0 ;
nla_put_failure :
nla_nest_cancel ( skb , tb ) ;
nla_info_failure :
nla_nest_cancel ( skb , mrp_tb ) ;
return - EMSGSIZE ;
}
2020-07-14 10:34:51 +03:00
int br_mrp_ring_port_open ( struct net_device * dev , u8 loc )
2020-04-26 16:22:05 +03:00
{
struct net_bridge_port * p ;
int err = 0 ;
p = br_port_get_rcu ( dev ) ;
if ( ! p ) {
err = - EINVAL ;
goto out ;
}
if ( loc )
p - > flags | = BR_MRP_LOST_CONT ;
else
p - > flags & = ~ BR_MRP_LOST_CONT ;
br_ifinfo_notify ( RTM_NEWLINK , NULL , p ) ;
out :
return err ;
}
2020-07-14 10:34:52 +03:00
int br_mrp_in_port_open ( struct net_device * dev , u8 loc )
{
struct net_bridge_port * p ;
int err = 0 ;
p = br_port_get_rcu ( dev ) ;
if ( ! p ) {
err = - EINVAL ;
goto out ;
}
if ( loc )
p - > flags | = BR_MRP_LOST_IN_CONT ;
else
p - > flags & = ~ BR_MRP_LOST_IN_CONT ;
br_ifinfo_notify ( RTM_NEWLINK , NULL , p ) ;
out :
return err ;
}