1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright 2022 NXP 3 */ 4 #include <linux/netdevice.h> 5 #include <net/rtnetlink.h> 6 7 #include "dsa_priv.h" 8 9 static const struct nla_policy dsa_policy[IFLA_DSA_MAX + 1] = { 10 [IFLA_DSA_MASTER] = { .type = NLA_U32 }, 11 }; 12 13 static int dsa_changelink(struct net_device *dev, struct nlattr *tb[], 14 struct nlattr *data[], 15 struct netlink_ext_ack *extack) 16 { 17 int err; 18 19 if (!data) 20 return 0; 21 22 if (data[IFLA_DSA_MASTER]) { 23 u32 ifindex = nla_get_u32(data[IFLA_DSA_MASTER]); 24 struct net_device *master; 25 26 master = __dev_get_by_index(dev_net(dev), ifindex); 27 if (!master) 28 return -EINVAL; 29 30 err = dsa_slave_change_master(dev, master, extack); 31 if (err) 32 return err; 33 } 34 35 return 0; 36 } 37 38 static size_t dsa_get_size(const struct net_device *dev) 39 { 40 return nla_total_size(sizeof(u32)) + /* IFLA_DSA_MASTER */ 41 0; 42 } 43 44 static int dsa_fill_info(struct sk_buff *skb, const struct net_device *dev) 45 { 46 struct net_device *master = dsa_slave_to_master(dev); 47 48 if (nla_put_u32(skb, IFLA_DSA_MASTER, master->ifindex)) 49 return -EMSGSIZE; 50 51 return 0; 52 } 53 54 struct rtnl_link_ops dsa_link_ops __read_mostly = { 55 .kind = "dsa", 56 .priv_size = sizeof(struct dsa_port), 57 .maxtype = IFLA_DSA_MAX, 58 .policy = dsa_policy, 59 .changelink = dsa_changelink, 60 .get_size = dsa_get_size, 61 .fill_info = dsa_fill_info, 62 }; 63