2022-09-11 04:06:59 +03:00
// SPDX-License-Identifier: GPL-2.0
/* Copyright 2022 NXP
*/
# include <linux/netdevice.h>
# include <net/rtnetlink.h>
2022-11-21 15:55:55 +02:00
# include "netlink.h"
2023-10-23 11:17:28 -07:00
# include "user.h"
2022-09-11 04:06:59 +03:00
static const struct nla_policy dsa_policy [ IFLA_DSA_MAX + 1 ] = {
2023-10-23 11:17:29 -07:00
[ IFLA_DSA_CONDUIT ] = { . type = NLA_U32 } ,
2022-09-11 04:06:59 +03:00
} ;
static int dsa_changelink ( struct net_device * dev , struct nlattr * tb [ ] ,
struct nlattr * data [ ] ,
struct netlink_ext_ack * extack )
{
int err ;
if ( ! data )
return 0 ;
2023-10-23 11:17:29 -07:00
if ( data [ IFLA_DSA_CONDUIT ] ) {
u32 ifindex = nla_get_u32 ( data [ IFLA_DSA_CONDUIT ] ) ;
2023-10-23 11:17:28 -07:00
struct net_device * conduit ;
2022-09-11 04:06:59 +03:00
2023-10-23 11:17:28 -07:00
conduit = __dev_get_by_index ( dev_net ( dev ) , ifindex ) ;
if ( ! conduit )
2022-09-11 04:06:59 +03:00
return - EINVAL ;
2023-10-23 11:17:28 -07:00
err = dsa_user_change_conduit ( dev , conduit , extack ) ;
2022-09-11 04:06:59 +03:00
if ( err )
return err ;
}
return 0 ;
}
static size_t dsa_get_size ( const struct net_device * dev )
{
2023-10-23 11:17:29 -07:00
return nla_total_size ( sizeof ( u32 ) ) + /* IFLA_DSA_CONDUIT */
2022-09-11 04:06:59 +03:00
0 ;
}
static int dsa_fill_info ( struct sk_buff * skb , const struct net_device * dev )
{
2023-10-23 11:17:28 -07:00
struct net_device * conduit = dsa_user_to_conduit ( dev ) ;
2022-09-11 04:06:59 +03:00
2023-10-23 11:17:29 -07:00
if ( nla_put_u32 ( skb , IFLA_DSA_CONDUIT , conduit - > ifindex ) )
2022-09-11 04:06:59 +03:00
return - EMSGSIZE ;
return 0 ;
}
struct rtnl_link_ops dsa_link_ops __read_mostly = {
. kind = " dsa " ,
. priv_size = sizeof ( struct dsa_port ) ,
. maxtype = IFLA_DSA_MAX ,
. policy = dsa_policy ,
. changelink = dsa_changelink ,
. get_size = dsa_get_size ,
. fill_info = dsa_fill_info ,
2022-09-21 21:54:28 +03:00
. netns_refund = true ,
2022-09-11 04:06:59 +03:00
} ;