// SPDX-License-Identifier: GPL-2.0 /* Copyright 2022 NXP */ #include #include #include "netlink.h" #include "user.h" static const struct nla_policy dsa_policy[IFLA_DSA_MAX + 1] = { [IFLA_DSA_CONDUIT] = { .type = NLA_U32 }, }; 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; if (data[IFLA_DSA_CONDUIT]) { u32 ifindex = nla_get_u32(data[IFLA_DSA_CONDUIT]); struct net_device *conduit; conduit = __dev_get_by_index(dev_net(dev), ifindex); if (!conduit) return -EINVAL; err = dsa_user_change_conduit(dev, conduit, extack); if (err) return err; } return 0; } static size_t dsa_get_size(const struct net_device *dev) { return nla_total_size(sizeof(u32)) + /* IFLA_DSA_CONDUIT */ 0; } static int dsa_fill_info(struct sk_buff *skb, const struct net_device *dev) { struct net_device *conduit = dsa_user_to_conduit(dev); if (nla_put_u32(skb, IFLA_DSA_CONDUIT, conduit->ifindex)) 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, .netns_refund = true, };