1623cd13bSJakub Kicinski // SPDX-License-Identifier: GPL-2.0-or-later 2623cd13bSJakub Kicinski /* 3623cd13bSJakub Kicinski * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4623cd13bSJakub Kicinski * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5623cd13bSJakub Kicinski */ 6623cd13bSJakub Kicinski 7623cd13bSJakub Kicinski #include <net/genetlink.h> 807f3af66SJakub Kicinski #include <net/sock.h> 9623cd13bSJakub Kicinski 10623cd13bSJakub Kicinski #include "devl_internal.h" 11623cd13bSJakub Kicinski 12623cd13bSJakub Kicinski static const struct genl_multicast_group devlink_nl_mcgrps[] = { 13623cd13bSJakub Kicinski [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME }, 14623cd13bSJakub Kicinski }; 15623cd13bSJakub Kicinski 16623cd13bSJakub Kicinski static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 17623cd13bSJakub Kicinski [DEVLINK_ATTR_UNSPEC] = { .strict_start_type = 18623cd13bSJakub Kicinski DEVLINK_ATTR_TRAP_POLICER_ID }, 19623cd13bSJakub Kicinski [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 20623cd13bSJakub Kicinski [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 21623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, 22623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO, 23623cd13bSJakub Kicinski DEVLINK_PORT_TYPE_IB), 24623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, 25623cd13bSJakub Kicinski [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, 26623cd13bSJakub Kicinski [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, 27623cd13bSJakub Kicinski [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, 28623cd13bSJakub Kicinski [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, 29623cd13bSJakub Kicinski [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, 30623cd13bSJakub Kicinski [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, 31623cd13bSJakub Kicinski [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, 32623cd13bSJakub Kicinski [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY, 33623cd13bSJakub Kicinski DEVLINK_ESWITCH_MODE_SWITCHDEV), 34623cd13bSJakub Kicinski [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, 35623cd13bSJakub Kicinski [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, 36623cd13bSJakub Kicinski [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, 37623cd13bSJakub Kicinski [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, 38623cd13bSJakub Kicinski [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, 39623cd13bSJakub Kicinski [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, 40623cd13bSJakub Kicinski [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING }, 41623cd13bSJakub Kicinski [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 }, 42623cd13bSJakub Kicinski [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, 43623cd13bSJakub Kicinski [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING }, 44623cd13bSJakub Kicinski [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 }, 45623cd13bSJakub Kicinski [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 }, 46623cd13bSJakub Kicinski [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 }, 47623cd13bSJakub Kicinski [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING }, 48623cd13bSJakub Kicinski [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 }, 49623cd13bSJakub Kicinski [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 }, 50623cd13bSJakub Kicinski [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING }, 51623cd13bSJakub Kicinski [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING }, 52623cd13bSJakub Kicinski [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = 53623cd13bSJakub Kicinski NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS), 54623cd13bSJakub Kicinski [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING }, 55623cd13bSJakub Kicinski [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 }, 56623cd13bSJakub Kicinski [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING }, 57623cd13bSJakub Kicinski [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 }, 58623cd13bSJakub Kicinski [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 }, 59623cd13bSJakub Kicinski [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 }, 60623cd13bSJakub Kicinski [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 }, 61623cd13bSJakub Kicinski [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 }, 62623cd13bSJakub Kicinski [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 }, 63623cd13bSJakub Kicinski [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 }, 64623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED }, 65623cd13bSJakub Kicinski [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 66623cd13bSJakub Kicinski DEVLINK_RELOAD_ACTION_MAX), 67623cd13bSJakub Kicinski [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK), 68623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 }, 69623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 }, 70623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 }, 71623cd13bSJakub Kicinski [DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 }, 72623cd13bSJakub Kicinski [DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 }, 73623cd13bSJakub Kicinski [DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 }, 74623cd13bSJakub Kicinski [DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 }, 75623cd13bSJakub Kicinski [DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING }, 76623cd13bSJakub Kicinski [DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING }, 77623cd13bSJakub Kicinski [DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 }, 78623cd13bSJakub Kicinski [DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING }, 79623cd13bSJakub Kicinski [DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED }, 80623cd13bSJakub Kicinski [DEVLINK_ATTR_RATE_TX_PRIORITY] = { .type = NLA_U32 }, 81623cd13bSJakub Kicinski [DEVLINK_ATTR_RATE_TX_WEIGHT] = { .type = NLA_U32 }, 82623cd13bSJakub Kicinski [DEVLINK_ATTR_REGION_DIRECT] = { .type = NLA_FLAG }, 83623cd13bSJakub Kicinski }; 84623cd13bSJakub Kicinski 852475ed15SJiri Pirko int devlink_nl_msg_reply_and_new(struct sk_buff **msg, struct genl_info *info) 862475ed15SJiri Pirko { 872475ed15SJiri Pirko int err; 882475ed15SJiri Pirko 892475ed15SJiri Pirko if (*msg) { 902475ed15SJiri Pirko err = genlmsg_reply(*msg, info); 912475ed15SJiri Pirko if (err) 922475ed15SJiri Pirko return err; 932475ed15SJiri Pirko } 942475ed15SJiri Pirko *msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 952475ed15SJiri Pirko if (!*msg) 962475ed15SJiri Pirko return -ENOMEM; 972475ed15SJiri Pirko return 0; 982475ed15SJiri Pirko } 992475ed15SJiri Pirko 100870c7ad4SJakub Kicinski struct devlink * 101870c7ad4SJakub Kicinski devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs) 102623cd13bSJakub Kicinski { 103623cd13bSJakub Kicinski struct devlink *devlink; 104623cd13bSJakub Kicinski unsigned long index; 105623cd13bSJakub Kicinski char *busname; 106623cd13bSJakub Kicinski char *devname; 107623cd13bSJakub Kicinski 108623cd13bSJakub Kicinski if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME]) 109623cd13bSJakub Kicinski return ERR_PTR(-EINVAL); 110623cd13bSJakub Kicinski 111623cd13bSJakub Kicinski busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]); 112623cd13bSJakub Kicinski devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); 113623cd13bSJakub Kicinski 114623cd13bSJakub Kicinski devlinks_xa_for_each_registered_get(net, index, devlink) { 115870c7ad4SJakub Kicinski devl_lock(devlink); 116ed539ba6SJakub Kicinski if (devl_is_registered(devlink) && 117ed539ba6SJakub Kicinski strcmp(devlink->dev->bus->name, busname) == 0 && 118623cd13bSJakub Kicinski strcmp(dev_name(devlink->dev), devname) == 0) 119623cd13bSJakub Kicinski return devlink; 120870c7ad4SJakub Kicinski devl_unlock(devlink); 121623cd13bSJakub Kicinski devlink_put(devlink); 122623cd13bSJakub Kicinski } 123623cd13bSJakub Kicinski 124623cd13bSJakub Kicinski return ERR_PTR(-ENODEV); 125623cd13bSJakub Kicinski } 126623cd13bSJakub Kicinski 127ee6d78acSJiri Pirko static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info, 128ee6d78acSJiri Pirko u8 flags) 129623cd13bSJakub Kicinski { 130623cd13bSJakub Kicinski struct devlink_port *devlink_port; 131623cd13bSJakub Kicinski struct devlink *devlink; 132623cd13bSJakub Kicinski int err; 133623cd13bSJakub Kicinski 134870c7ad4SJakub Kicinski devlink = devlink_get_from_attrs_lock(genl_info_net(info), info->attrs); 135623cd13bSJakub Kicinski if (IS_ERR(devlink)) 136623cd13bSJakub Kicinski return PTR_ERR(devlink); 137870c7ad4SJakub Kicinski 138623cd13bSJakub Kicinski info->user_ptr[0] = devlink; 139ee6d78acSJiri Pirko if (flags & DEVLINK_NL_FLAG_NEED_PORT) { 140623cd13bSJakub Kicinski devlink_port = devlink_port_get_from_info(devlink, info); 141623cd13bSJakub Kicinski if (IS_ERR(devlink_port)) { 142623cd13bSJakub Kicinski err = PTR_ERR(devlink_port); 143623cd13bSJakub Kicinski goto unlock; 144623cd13bSJakub Kicinski } 145623cd13bSJakub Kicinski info->user_ptr[1] = devlink_port; 146ee6d78acSJiri Pirko } else if (flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) { 147623cd13bSJakub Kicinski devlink_port = devlink_port_get_from_info(devlink, info); 148623cd13bSJakub Kicinski if (!IS_ERR(devlink_port)) 149623cd13bSJakub Kicinski info->user_ptr[1] = devlink_port; 150623cd13bSJakub Kicinski } 151623cd13bSJakub Kicinski return 0; 152623cd13bSJakub Kicinski 153623cd13bSJakub Kicinski unlock: 154623cd13bSJakub Kicinski devl_unlock(devlink); 155623cd13bSJakub Kicinski devlink_put(devlink); 156623cd13bSJakub Kicinski return err; 157623cd13bSJakub Kicinski } 158623cd13bSJakub Kicinski 159ee6d78acSJiri Pirko int devlink_nl_pre_doit(const struct genl_split_ops *ops, 160ee6d78acSJiri Pirko struct sk_buff *skb, struct genl_info *info) 161ee6d78acSJiri Pirko { 162ee6d78acSJiri Pirko return __devlink_nl_pre_doit(skb, info, ops->internal_flags); 163ee6d78acSJiri Pirko } 164ee6d78acSJiri Pirko 165ee6d78acSJiri Pirko int devlink_nl_pre_doit_port(const struct genl_split_ops *ops, 166ee6d78acSJiri Pirko struct sk_buff *skb, struct genl_info *info) 167ee6d78acSJiri Pirko { 168ee6d78acSJiri Pirko return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_PORT); 169ee6d78acSJiri Pirko } 170ee6d78acSJiri Pirko 171ee6d78acSJiri Pirko int devlink_nl_pre_doit_port_optional(const struct genl_split_ops *ops, 172ee6d78acSJiri Pirko struct sk_buff *skb, 173ee6d78acSJiri Pirko struct genl_info *info) 174ee6d78acSJiri Pirko { 175ee6d78acSJiri Pirko return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT); 176ee6d78acSJiri Pirko } 177ee6d78acSJiri Pirko 1788300dce5SJiri Pirko void devlink_nl_post_doit(const struct genl_split_ops *ops, 179623cd13bSJakub Kicinski struct sk_buff *skb, struct genl_info *info) 180623cd13bSJakub Kicinski { 181623cd13bSJakub Kicinski struct devlink *devlink; 182623cd13bSJakub Kicinski 183623cd13bSJakub Kicinski devlink = info->user_ptr[0]; 184623cd13bSJakub Kicinski devl_unlock(devlink); 185623cd13bSJakub Kicinski devlink_put(devlink); 186623cd13bSJakub Kicinski } 187623cd13bSJakub Kicinski 1884a1b5aa8SJiri Pirko static int devlink_nl_inst_single_dumpit(struct sk_buff *msg, 1894a1b5aa8SJiri Pirko struct netlink_callback *cb, int flags, 1904a1b5aa8SJiri Pirko devlink_nl_dump_one_func_t *dump_one, 1914a1b5aa8SJiri Pirko struct nlattr **attrs) 1924a1b5aa8SJiri Pirko { 1934a1b5aa8SJiri Pirko struct devlink *devlink; 1944a1b5aa8SJiri Pirko int err; 1954a1b5aa8SJiri Pirko 1964a1b5aa8SJiri Pirko devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), attrs); 1974a1b5aa8SJiri Pirko if (IS_ERR(devlink)) 1984a1b5aa8SJiri Pirko return PTR_ERR(devlink); 1994a1b5aa8SJiri Pirko err = dump_one(msg, devlink, cb, flags | NLM_F_DUMP_FILTERED); 2004a1b5aa8SJiri Pirko 2014a1b5aa8SJiri Pirko devl_unlock(devlink); 2024a1b5aa8SJiri Pirko devlink_put(devlink); 2034a1b5aa8SJiri Pirko 2044a1b5aa8SJiri Pirko if (err != -EMSGSIZE) 2054a1b5aa8SJiri Pirko return err; 2064a1b5aa8SJiri Pirko return msg->len; 2074a1b5aa8SJiri Pirko } 2084a1b5aa8SJiri Pirko 2094a1b5aa8SJiri Pirko static int devlink_nl_inst_iter_dumpit(struct sk_buff *msg, 2104a1b5aa8SJiri Pirko struct netlink_callback *cb, int flags, 211491a2487SJiri Pirko devlink_nl_dump_one_func_t *dump_one) 21207f3af66SJakub Kicinski { 21307f3af66SJakub Kicinski struct devlink_nl_dump_state *state = devlink_dump_state(cb); 21407f3af66SJakub Kicinski struct devlink *devlink; 21507f3af66SJakub Kicinski int err = 0; 21607f3af66SJakub Kicinski 217543753d9SJiri Pirko while ((devlink = devlinks_xa_find_get(sock_net(msg->sk), 218543753d9SJiri Pirko &state->instance))) { 21907f3af66SJakub Kicinski devl_lock(devlink); 220ed539ba6SJakub Kicinski 221ed539ba6SJakub Kicinski if (devl_is_registered(devlink)) 2224a1b5aa8SJiri Pirko err = dump_one(msg, devlink, cb, flags); 223ed539ba6SJakub Kicinski else 224ed539ba6SJakub Kicinski err = 0; 225ed539ba6SJakub Kicinski 22607f3af66SJakub Kicinski devl_unlock(devlink); 22707f3af66SJakub Kicinski devlink_put(devlink); 22807f3af66SJakub Kicinski 22907f3af66SJakub Kicinski if (err) 23007f3af66SJakub Kicinski break; 23107f3af66SJakub Kicinski 232543753d9SJiri Pirko state->instance++; 233543753d9SJiri Pirko 23407f3af66SJakub Kicinski /* restart sub-object walk for the next instance */ 23507f3af66SJakub Kicinski state->idx = 0; 23607f3af66SJakub Kicinski } 23707f3af66SJakub Kicinski 23807f3af66SJakub Kicinski if (err != -EMSGSIZE) 23907f3af66SJakub Kicinski return err; 24007f3af66SJakub Kicinski return msg->len; 24107f3af66SJakub Kicinski } 24207f3af66SJakub Kicinski 2434a1b5aa8SJiri Pirko int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb, 2444a1b5aa8SJiri Pirko devlink_nl_dump_one_func_t *dump_one) 2454a1b5aa8SJiri Pirko { 2467288dd2fSJakub Kicinski const struct genl_info *info = genl_info_dump(cb); 2474a1b5aa8SJiri Pirko struct nlattr **attrs = info->attrs; 2484a1b5aa8SJiri Pirko int flags = NLM_F_MULTI; 2494a1b5aa8SJiri Pirko 2504a1b5aa8SJiri Pirko if (attrs && 2514a1b5aa8SJiri Pirko (attrs[DEVLINK_ATTR_BUS_NAME] || attrs[DEVLINK_ATTR_DEV_NAME])) 2524a1b5aa8SJiri Pirko return devlink_nl_inst_single_dumpit(msg, cb, flags, dump_one, 2534a1b5aa8SJiri Pirko attrs); 2544a1b5aa8SJiri Pirko else 2554a1b5aa8SJiri Pirko return devlink_nl_inst_iter_dumpit(msg, cb, flags, dump_one); 2564a1b5aa8SJiri Pirko } 2574a1b5aa8SJiri Pirko 258*29a390d1SJiri Pirko static const struct genl_small_ops devlink_nl_small_ops[40] = { 259*29a390d1SJiri Pirko { 260*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PORT_SET, 261*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 262*29a390d1SJiri Pirko .doit = devlink_nl_cmd_port_set_doit, 263*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 264*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 265*29a390d1SJiri Pirko }, 266*29a390d1SJiri Pirko { 267*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_RATE_SET, 268*29a390d1SJiri Pirko .doit = devlink_nl_cmd_rate_set_doit, 269*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 270*29a390d1SJiri Pirko }, 271*29a390d1SJiri Pirko { 272*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_RATE_NEW, 273*29a390d1SJiri Pirko .doit = devlink_nl_cmd_rate_new_doit, 274*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 275*29a390d1SJiri Pirko }, 276*29a390d1SJiri Pirko { 277*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_RATE_DEL, 278*29a390d1SJiri Pirko .doit = devlink_nl_cmd_rate_del_doit, 279*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 280*29a390d1SJiri Pirko }, 281*29a390d1SJiri Pirko { 282*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PORT_SPLIT, 283*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 284*29a390d1SJiri Pirko .doit = devlink_nl_cmd_port_split_doit, 285*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 286*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 287*29a390d1SJiri Pirko }, 288*29a390d1SJiri Pirko { 289*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PORT_UNSPLIT, 290*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 291*29a390d1SJiri Pirko .doit = devlink_nl_cmd_port_unsplit_doit, 292*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 293*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 294*29a390d1SJiri Pirko }, 295*29a390d1SJiri Pirko { 296*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PORT_NEW, 297*29a390d1SJiri Pirko .doit = devlink_nl_cmd_port_new_doit, 298*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 299*29a390d1SJiri Pirko }, 300*29a390d1SJiri Pirko { 301*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PORT_DEL, 302*29a390d1SJiri Pirko .doit = devlink_nl_cmd_port_del_doit, 303*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 304*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 305*29a390d1SJiri Pirko }, 306*29a390d1SJiri Pirko 307*29a390d1SJiri Pirko { 308*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_LINECARD_SET, 309*29a390d1SJiri Pirko .doit = devlink_nl_cmd_linecard_set_doit, 310*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 311*29a390d1SJiri Pirko }, 312*29a390d1SJiri Pirko { 313*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_SB_POOL_SET, 314*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 315*29a390d1SJiri Pirko .doit = devlink_nl_cmd_sb_pool_set_doit, 316*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 317*29a390d1SJiri Pirko }, 318*29a390d1SJiri Pirko { 319*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, 320*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 321*29a390d1SJiri Pirko .doit = devlink_nl_cmd_sb_port_pool_set_doit, 322*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 323*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 324*29a390d1SJiri Pirko }, 325*29a390d1SJiri Pirko { 326*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, 327*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 328*29a390d1SJiri Pirko .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, 329*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 330*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 331*29a390d1SJiri Pirko }, 332*29a390d1SJiri Pirko { 333*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, 334*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 335*29a390d1SJiri Pirko .doit = devlink_nl_cmd_sb_occ_snapshot_doit, 336*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 337*29a390d1SJiri Pirko }, 338*29a390d1SJiri Pirko { 339*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, 340*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 341*29a390d1SJiri Pirko .doit = devlink_nl_cmd_sb_occ_max_clear_doit, 342*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 343*29a390d1SJiri Pirko }, 344*29a390d1SJiri Pirko { 345*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_ESWITCH_GET, 346*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 347*29a390d1SJiri Pirko .doit = devlink_nl_cmd_eswitch_get_doit, 348*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 349*29a390d1SJiri Pirko }, 350*29a390d1SJiri Pirko { 351*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_ESWITCH_SET, 352*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 353*29a390d1SJiri Pirko .doit = devlink_nl_cmd_eswitch_set_doit, 354*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 355*29a390d1SJiri Pirko }, 356*29a390d1SJiri Pirko { 357*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, 358*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 359*29a390d1SJiri Pirko .doit = devlink_nl_cmd_dpipe_table_get, 360*29a390d1SJiri Pirko /* can be retrieved by unprivileged users */ 361*29a390d1SJiri Pirko }, 362*29a390d1SJiri Pirko { 363*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, 364*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 365*29a390d1SJiri Pirko .doit = devlink_nl_cmd_dpipe_entries_get, 366*29a390d1SJiri Pirko /* can be retrieved by unprivileged users */ 367*29a390d1SJiri Pirko }, 368*29a390d1SJiri Pirko { 369*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, 370*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 371*29a390d1SJiri Pirko .doit = devlink_nl_cmd_dpipe_headers_get, 372*29a390d1SJiri Pirko /* can be retrieved by unprivileged users */ 373*29a390d1SJiri Pirko }, 374*29a390d1SJiri Pirko { 375*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 376*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 377*29a390d1SJiri Pirko .doit = devlink_nl_cmd_dpipe_table_counters_set, 378*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 379*29a390d1SJiri Pirko }, 380*29a390d1SJiri Pirko { 381*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_RESOURCE_SET, 382*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 383*29a390d1SJiri Pirko .doit = devlink_nl_cmd_resource_set, 384*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 385*29a390d1SJiri Pirko }, 386*29a390d1SJiri Pirko { 387*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_RESOURCE_DUMP, 388*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 389*29a390d1SJiri Pirko .doit = devlink_nl_cmd_resource_dump, 390*29a390d1SJiri Pirko /* can be retrieved by unprivileged users */ 391*29a390d1SJiri Pirko }, 392*29a390d1SJiri Pirko { 393*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_RELOAD, 394*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 395*29a390d1SJiri Pirko .doit = devlink_nl_cmd_reload, 396*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 397*29a390d1SJiri Pirko }, 398*29a390d1SJiri Pirko { 399*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PARAM_SET, 400*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 401*29a390d1SJiri Pirko .doit = devlink_nl_cmd_param_set_doit, 402*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 403*29a390d1SJiri Pirko }, 404*29a390d1SJiri Pirko { 405*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PORT_PARAM_GET, 406*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 407*29a390d1SJiri Pirko .doit = devlink_nl_cmd_port_param_get_doit, 408*29a390d1SJiri Pirko .dumpit = devlink_nl_cmd_port_param_get_dumpit, 409*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 410*29a390d1SJiri Pirko /* can be retrieved by unprivileged users */ 411*29a390d1SJiri Pirko }, 412*29a390d1SJiri Pirko { 413*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_PORT_PARAM_SET, 414*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 415*29a390d1SJiri Pirko .doit = devlink_nl_cmd_port_param_set_doit, 416*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 417*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, 418*29a390d1SJiri Pirko }, 419*29a390d1SJiri Pirko { 420*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_REGION_NEW, 421*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 422*29a390d1SJiri Pirko .doit = devlink_nl_cmd_region_new, 423*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 424*29a390d1SJiri Pirko }, 425*29a390d1SJiri Pirko { 426*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_REGION_DEL, 427*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 428*29a390d1SJiri Pirko .doit = devlink_nl_cmd_region_del, 429*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 430*29a390d1SJiri Pirko }, 431*29a390d1SJiri Pirko { 432*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_REGION_READ, 433*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | 434*29a390d1SJiri Pirko GENL_DONT_VALIDATE_DUMP_STRICT, 435*29a390d1SJiri Pirko .dumpit = devlink_nl_cmd_region_read_dumpit, 436*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 437*29a390d1SJiri Pirko }, 438*29a390d1SJiri Pirko { 439*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, 440*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 441*29a390d1SJiri Pirko .doit = devlink_nl_cmd_health_reporter_set_doit, 442*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 443*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 444*29a390d1SJiri Pirko }, 445*29a390d1SJiri Pirko { 446*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, 447*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 448*29a390d1SJiri Pirko .doit = devlink_nl_cmd_health_reporter_recover_doit, 449*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 450*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 451*29a390d1SJiri Pirko }, 452*29a390d1SJiri Pirko { 453*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 454*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 455*29a390d1SJiri Pirko .doit = devlink_nl_cmd_health_reporter_diagnose_doit, 456*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 457*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 458*29a390d1SJiri Pirko }, 459*29a390d1SJiri Pirko { 460*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 461*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | 462*29a390d1SJiri Pirko GENL_DONT_VALIDATE_DUMP_STRICT, 463*29a390d1SJiri Pirko .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, 464*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 465*29a390d1SJiri Pirko }, 466*29a390d1SJiri Pirko { 467*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, 468*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 469*29a390d1SJiri Pirko .doit = devlink_nl_cmd_health_reporter_dump_clear_doit, 470*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 471*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 472*29a390d1SJiri Pirko }, 473*29a390d1SJiri Pirko { 474*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST, 475*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 476*29a390d1SJiri Pirko .doit = devlink_nl_cmd_health_reporter_test_doit, 477*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 478*29a390d1SJiri Pirko .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, 479*29a390d1SJiri Pirko }, 480*29a390d1SJiri Pirko { 481*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_FLASH_UPDATE, 482*29a390d1SJiri Pirko .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 483*29a390d1SJiri Pirko .doit = devlink_nl_cmd_flash_update, 484*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 485*29a390d1SJiri Pirko }, 486*29a390d1SJiri Pirko { 487*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_TRAP_SET, 488*29a390d1SJiri Pirko .doit = devlink_nl_cmd_trap_set_doit, 489*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 490*29a390d1SJiri Pirko }, 491*29a390d1SJiri Pirko { 492*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_TRAP_GROUP_SET, 493*29a390d1SJiri Pirko .doit = devlink_nl_cmd_trap_group_set_doit, 494*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 495*29a390d1SJiri Pirko }, 496*29a390d1SJiri Pirko { 497*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_TRAP_POLICER_SET, 498*29a390d1SJiri Pirko .doit = devlink_nl_cmd_trap_policer_set_doit, 499*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 500*29a390d1SJiri Pirko }, 501*29a390d1SJiri Pirko { 502*29a390d1SJiri Pirko .cmd = DEVLINK_CMD_SELFTESTS_RUN, 503*29a390d1SJiri Pirko .doit = devlink_nl_cmd_selftests_run, 504*29a390d1SJiri Pirko .flags = GENL_ADMIN_PERM, 505*29a390d1SJiri Pirko }, 506*29a390d1SJiri Pirko /* -- No new ops here! Use split ops going forward! -- */ 507*29a390d1SJiri Pirko }; 508*29a390d1SJiri Pirko 509623cd13bSJakub Kicinski struct genl_family devlink_nl_family __ro_after_init = { 510623cd13bSJakub Kicinski .name = DEVLINK_GENL_NAME, 511623cd13bSJakub Kicinski .version = DEVLINK_GENL_VERSION, 512623cd13bSJakub Kicinski .maxattr = DEVLINK_ATTR_MAX, 513623cd13bSJakub Kicinski .policy = devlink_nl_policy, 514623cd13bSJakub Kicinski .netnsok = true, 515623cd13bSJakub Kicinski .parallel_ops = true, 516623cd13bSJakub Kicinski .pre_doit = devlink_nl_pre_doit, 517623cd13bSJakub Kicinski .post_doit = devlink_nl_post_doit, 518623cd13bSJakub Kicinski .module = THIS_MODULE, 519ba0f66c9SJiri Pirko .small_ops = devlink_nl_small_ops, 520ba0f66c9SJiri Pirko .n_small_ops = ARRAY_SIZE(devlink_nl_small_ops), 5216e067d0cSJiri Pirko .split_ops = devlink_nl_ops, 5226e067d0cSJiri Pirko .n_split_ops = ARRAY_SIZE(devlink_nl_ops), 523623cd13bSJakub Kicinski .resv_start_op = DEVLINK_CMD_SELFTESTS_RUN + 1, 524623cd13bSJakub Kicinski .mcgrps = devlink_nl_mcgrps, 525623cd13bSJakub Kicinski .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 526623cd13bSJakub Kicinski }; 527