root/net/core/devlink.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. devlink_net
  2. devlink_net_set
  3. devlink_get_from_attrs
  4. devlink_get_from_info
  5. devlink_port_get_by_index
  6. devlink_port_index_exists
  7. devlink_port_get_from_attrs
  8. devlink_port_get_from_info
  9. devlink_sb_pool_count
  10. devlink_sb_get_by_index
  11. devlink_sb_index_exists
  12. devlink_sb_get_from_attrs
  13. devlink_sb_get_from_info
  14. devlink_sb_pool_index_get_from_attrs
  15. devlink_sb_pool_index_get_from_info
  16. devlink_sb_pool_type_get_from_attrs
  17. devlink_sb_pool_type_get_from_info
  18. devlink_sb_th_type_get_from_attrs
  19. devlink_sb_th_type_get_from_info
  20. devlink_sb_tc_index_get_from_attrs
  21. devlink_sb_tc_index_get_from_info
  22. devlink_region_get_by_name
  23. devlink_region_snapshot_get_by_id
  24. devlink_nl_pre_doit
  25. devlink_nl_post_doit
  26. devlink_nl_put_handle
  27. devlink_nl_fill
  28. devlink_notify
  29. devlink_nl_port_attrs_put
  30. devlink_nl_port_fill
  31. devlink_port_notify
  32. devlink_nl_cmd_get_doit
  33. devlink_nl_cmd_get_dumpit
  34. devlink_nl_cmd_port_get_doit
  35. devlink_nl_cmd_port_get_dumpit
  36. devlink_port_type_set
  37. devlink_nl_cmd_port_set_doit
  38. devlink_port_split
  39. devlink_nl_cmd_port_split_doit
  40. devlink_port_unsplit
  41. devlink_nl_cmd_port_unsplit_doit
  42. devlink_nl_sb_fill
  43. devlink_nl_cmd_sb_get_doit
  44. devlink_nl_cmd_sb_get_dumpit
  45. devlink_nl_sb_pool_fill
  46. devlink_nl_cmd_sb_pool_get_doit
  47. __sb_pool_get_dumpit
  48. devlink_nl_cmd_sb_pool_get_dumpit
  49. devlink_sb_pool_set
  50. devlink_nl_cmd_sb_pool_set_doit
  51. devlink_nl_sb_port_pool_fill
  52. devlink_nl_cmd_sb_port_pool_get_doit
  53. __sb_port_pool_get_dumpit
  54. devlink_nl_cmd_sb_port_pool_get_dumpit
  55. devlink_sb_port_pool_set
  56. devlink_nl_cmd_sb_port_pool_set_doit
  57. devlink_nl_sb_tc_pool_bind_fill
  58. devlink_nl_cmd_sb_tc_pool_bind_get_doit
  59. __sb_tc_pool_bind_get_dumpit
  60. devlink_nl_cmd_sb_tc_pool_bind_get_dumpit
  61. devlink_sb_tc_pool_bind_set
  62. devlink_nl_cmd_sb_tc_pool_bind_set_doit
  63. devlink_nl_cmd_sb_occ_snapshot_doit
  64. devlink_nl_cmd_sb_occ_max_clear_doit
  65. devlink_nl_eswitch_fill
  66. devlink_nl_cmd_eswitch_get_doit
  67. devlink_nl_cmd_eswitch_set_doit
  68. devlink_dpipe_match_put
  69. devlink_dpipe_matches_put
  70. devlink_dpipe_action_put
  71. devlink_dpipe_actions_put
  72. devlink_dpipe_table_put
  73. devlink_dpipe_send_and_alloc_skb
  74. devlink_dpipe_tables_fill
  75. devlink_nl_cmd_dpipe_table_get
  76. devlink_dpipe_value_put
  77. devlink_dpipe_action_value_put
  78. devlink_dpipe_action_values_put
  79. devlink_dpipe_match_value_put
  80. devlink_dpipe_match_values_put
  81. devlink_dpipe_entry_put
  82. devlink_dpipe_table_find
  83. devlink_dpipe_entry_ctx_prepare
  84. devlink_dpipe_entry_ctx_append
  85. devlink_dpipe_entry_ctx_close
  86. devlink_dpipe_entry_clear
  87. devlink_dpipe_entries_fill
  88. devlink_nl_cmd_dpipe_entries_get
  89. devlink_dpipe_fields_put
  90. devlink_dpipe_header_put
  91. devlink_dpipe_headers_fill
  92. devlink_nl_cmd_dpipe_headers_get
  93. devlink_dpipe_table_counters_set
  94. devlink_nl_cmd_dpipe_table_counters_set
  95. devlink_resource_find
  96. devlink_resource_validate_children
  97. devlink_resource_validate_size
  98. devlink_nl_cmd_resource_set
  99. devlink_resource_size_params_put
  100. devlink_resource_occ_put
  101. devlink_resource_put
  102. devlink_resource_fill
  103. devlink_nl_cmd_resource_dump
  104. devlink_resources_validate
  105. devlink_reload_supported
  106. devlink_reload_failed_set
  107. devlink_is_reload_failed
  108. devlink_nl_cmd_reload
  109. devlink_nl_flash_update_fill
  110. __devlink_flash_update_notify
  111. devlink_flash_update_begin_notify
  112. devlink_flash_update_end_notify
  113. devlink_flash_update_status_notify
  114. devlink_nl_cmd_flash_update
  115. devlink_param_generic_verify
  116. devlink_param_driver_verify
  117. devlink_param_find_by_name
  118. devlink_param_find_by_id
  119. devlink_param_cmode_is_supported
  120. devlink_param_get
  121. devlink_param_set
  122. devlink_param_type_to_nla_type
  123. devlink_nl_param_value_fill_one
  124. devlink_nl_param_fill
  125. devlink_param_notify
  126. devlink_nl_cmd_param_get_dumpit
  127. devlink_param_type_get_from_info
  128. devlink_param_value_get_from_info
  129. devlink_param_get_from_info
  130. devlink_nl_cmd_param_get_doit
  131. __devlink_nl_cmd_param_set_doit
  132. devlink_nl_cmd_param_set_doit
  133. devlink_param_register_one
  134. devlink_param_unregister_one
  135. devlink_nl_cmd_port_param_get_dumpit
  136. devlink_nl_cmd_port_param_get_doit
  137. devlink_nl_cmd_port_param_set_doit
  138. devlink_nl_region_snapshot_id_put
  139. devlink_nl_region_snapshots_id_put
  140. devlink_nl_region_fill
  141. devlink_nl_region_notify
  142. devlink_region_snapshot_del
  143. devlink_nl_cmd_region_get_doit
  144. devlink_nl_cmd_region_get_dumpit
  145. devlink_nl_cmd_region_del
  146. devlink_nl_cmd_region_read_chunk_fill
  147. devlink_nl_region_read_snapshot_fill
  148. devlink_nl_cmd_region_read_dumpit
  149. devlink_info_driver_name_put
  150. devlink_info_serial_number_put
  151. devlink_info_version_put
  152. devlink_info_version_fixed_put
  153. devlink_info_version_stored_put
  154. devlink_info_version_running_put
  155. devlink_nl_info_fill
  156. devlink_nl_cmd_info_get_doit
  157. devlink_nl_cmd_info_get_dumpit
  158. devlink_fmsg_alloc
  159. devlink_fmsg_free
  160. devlink_fmsg_nest_common
  161. devlink_fmsg_obj_nest_start
  162. devlink_fmsg_nest_end
  163. devlink_fmsg_obj_nest_end
  164. devlink_fmsg_put_name
  165. devlink_fmsg_pair_nest_start
  166. devlink_fmsg_pair_nest_end
  167. devlink_fmsg_arr_pair_nest_start
  168. devlink_fmsg_arr_pair_nest_end
  169. devlink_fmsg_put_value
  170. devlink_fmsg_bool_put
  171. devlink_fmsg_u8_put
  172. devlink_fmsg_u32_put
  173. devlink_fmsg_u64_put
  174. devlink_fmsg_string_put
  175. devlink_fmsg_binary_put
  176. devlink_fmsg_bool_pair_put
  177. devlink_fmsg_u8_pair_put
  178. devlink_fmsg_u32_pair_put
  179. devlink_fmsg_u64_pair_put
  180. devlink_fmsg_string_pair_put
  181. devlink_fmsg_binary_pair_put
  182. devlink_fmsg_item_fill_type
  183. devlink_fmsg_item_fill_data
  184. devlink_fmsg_prepare_skb
  185. devlink_fmsg_snd
  186. devlink_fmsg_dumpit
  187. devlink_health_reporter_priv
  188. devlink_health_reporter_find_by_name
  189. devlink_health_reporter_create
  190. devlink_health_reporter_destroy
  191. devlink_health_reporter_state_update
  192. devlink_health_reporter_recover
  193. devlink_health_dump_clear
  194. devlink_health_do_dump
  195. devlink_health_report
  196. devlink_health_reporter_get_from_attrs
  197. devlink_health_reporter_get_from_info
  198. devlink_health_reporter_get_from_cb
  199. devlink_health_reporter_put
  200. devlink_nl_health_reporter_fill
  201. devlink_nl_cmd_health_reporter_get_doit
  202. devlink_nl_cmd_health_reporter_get_dumpit
  203. devlink_nl_cmd_health_reporter_set_doit
  204. devlink_nl_cmd_health_reporter_recover_doit
  205. devlink_nl_cmd_health_reporter_diagnose_doit
  206. devlink_nl_cmd_health_reporter_dump_get_dumpit
  207. devlink_nl_cmd_health_reporter_dump_clear_doit
  208. devlink_trap_item_lookup
  209. devlink_trap_item_get_from_info
  210. devlink_trap_action_get_from_info
  211. devlink_trap_metadata_put
  212. devlink_trap_stats_read
  213. devlink_trap_stats_put
  214. devlink_nl_trap_fill
  215. devlink_nl_cmd_trap_get_doit
  216. devlink_nl_cmd_trap_get_dumpit
  217. __devlink_trap_action_set
  218. devlink_trap_action_set
  219. devlink_nl_cmd_trap_set_doit
  220. devlink_trap_group_item_lookup
  221. devlink_trap_group_item_get_from_info
  222. devlink_nl_trap_group_fill
  223. devlink_nl_cmd_trap_group_get_doit
  224. devlink_nl_cmd_trap_group_get_dumpit
  225. __devlink_trap_group_action_set
  226. devlink_trap_group_action_set
  227. devlink_nl_cmd_trap_group_set_doit
  228. devlink_alloc
  229. devlink_register
  230. devlink_unregister
  231. devlink_reload_enable
  232. devlink_reload_disable
  233. devlink_free
  234. devlink_port_type_warn
  235. devlink_port_type_should_warn
  236. devlink_port_type_warn_schedule
  237. devlink_port_type_warn_cancel
  238. devlink_port_register
  239. devlink_port_unregister
  240. __devlink_port_type_set
  241. devlink_port_type_eth_set
  242. devlink_port_type_ib_set
  243. devlink_port_type_clear
  244. __devlink_port_attrs_set
  245. devlink_port_attrs_set
  246. devlink_port_attrs_pci_pf_set
  247. devlink_port_attrs_pci_vf_set
  248. __devlink_port_phys_port_name_get
  249. devlink_sb_register
  250. devlink_sb_unregister
  251. devlink_dpipe_headers_register
  252. devlink_dpipe_headers_unregister
  253. devlink_dpipe_table_counter_enabled
  254. devlink_dpipe_table_register
  255. devlink_dpipe_table_unregister
  256. devlink_resource_register
  257. devlink_resources_unregister
  258. devlink_resource_size_get
  259. devlink_dpipe_table_resource_set
  260. devlink_resource_occ_get_register
  261. devlink_resource_occ_get_unregister
  262. devlink_param_verify
  263. __devlink_params_register
  264. __devlink_params_unregister
  265. devlink_params_register
  266. devlink_params_unregister
  267. devlink_params_publish
  268. devlink_params_unpublish
  269. devlink_port_params_register
  270. devlink_port_params_unregister
  271. __devlink_param_driverinit_value_get
  272. __devlink_param_driverinit_value_set
  273. devlink_param_driverinit_value_get
  274. devlink_param_driverinit_value_set
  275. devlink_port_param_driverinit_value_get
  276. devlink_port_param_driverinit_value_set
  277. devlink_param_value_changed
  278. devlink_port_param_value_changed
  279. devlink_param_value_str_fill
  280. devlink_region_create
  281. devlink_region_destroy
  282. devlink_region_shapshot_id_get
  283. devlink_region_snapshot_create
  284. devlink_trap_generic_verify
  285. devlink_trap_driver_verify
  286. devlink_trap_verify
  287. devlink_trap_group_generic_verify
  288. devlink_trap_group_driver_verify
  289. devlink_trap_group_verify
  290. devlink_trap_group_notify
  291. devlink_trap_group_item_create
  292. devlink_trap_group_item_destroy
  293. devlink_trap_group_item_get
  294. devlink_trap_group_item_put
  295. devlink_trap_item_group_link
  296. devlink_trap_item_group_unlink
  297. devlink_trap_notify
  298. devlink_trap_register
  299. devlink_trap_unregister
  300. devlink_trap_disable
  301. devlink_traps_register
  302. devlink_traps_unregister
  303. devlink_trap_stats_update
  304. devlink_trap_report_metadata_fill
  305. devlink_trap_report
  306. devlink_trap_ctx_priv
  307. __devlink_compat_running_version
  308. devlink_compat_running_version
  309. devlink_compat_flash_update
  310. devlink_compat_phys_port_name_get
  311. devlink_compat_switch_id_get
  312. devlink_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * net/core/devlink.c - Network physical/parent device Netlink interface
   4  *
   5  * Heavily inspired by net/wireless/
   6  * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
   7  * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/types.h>
  13 #include <linux/slab.h>
  14 #include <linux/gfp.h>
  15 #include <linux/device.h>
  16 #include <linux/list.h>
  17 #include <linux/netdevice.h>
  18 #include <linux/spinlock.h>
  19 #include <linux/refcount.h>
  20 #include <linux/workqueue.h>
  21 #include <linux/u64_stats_sync.h>
  22 #include <linux/timekeeping.h>
  23 #include <rdma/ib_verbs.h>
  24 #include <net/netlink.h>
  25 #include <net/genetlink.h>
  26 #include <net/rtnetlink.h>
  27 #include <net/net_namespace.h>
  28 #include <net/sock.h>
  29 #include <net/devlink.h>
  30 #include <net/drop_monitor.h>
  31 #define CREATE_TRACE_POINTS
  32 #include <trace/events/devlink.h>
  33 
  34 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
  35         {
  36                 .name = "destination mac",
  37                 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
  38                 .bitwidth = 48,
  39         },
  40 };
  41 
  42 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
  43         .name = "ethernet",
  44         .id = DEVLINK_DPIPE_HEADER_ETHERNET,
  45         .fields = devlink_dpipe_fields_ethernet,
  46         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
  47         .global = true,
  48 };
  49 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
  50 
  51 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
  52         {
  53                 .name = "destination ip",
  54                 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
  55                 .bitwidth = 32,
  56         },
  57 };
  58 
  59 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
  60         .name = "ipv4",
  61         .id = DEVLINK_DPIPE_HEADER_IPV4,
  62         .fields = devlink_dpipe_fields_ipv4,
  63         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
  64         .global = true,
  65 };
  66 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
  67 
  68 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
  69         {
  70                 .name = "destination ip",
  71                 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
  72                 .bitwidth = 128,
  73         },
  74 };
  75 
  76 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
  77         .name = "ipv6",
  78         .id = DEVLINK_DPIPE_HEADER_IPV6,
  79         .fields = devlink_dpipe_fields_ipv6,
  80         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
  81         .global = true,
  82 };
  83 EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
  84 
  85 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
  86 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
  87 
  88 static LIST_HEAD(devlink_list);
  89 
  90 /* devlink_mutex
  91  *
  92  * An overall lock guarding every operation coming from userspace.
  93  * It also guards devlink devices list and it is taken when
  94  * driver registers/unregisters it.
  95  */
  96 static DEFINE_MUTEX(devlink_mutex);
  97 
  98 static struct net *devlink_net(const struct devlink *devlink)
  99 {
 100         return read_pnet(&devlink->_net);
 101 }
 102 
 103 static void devlink_net_set(struct devlink *devlink, struct net *net)
 104 {
 105         write_pnet(&devlink->_net, net);
 106 }
 107 
 108 static struct devlink *devlink_get_from_attrs(struct net *net,
 109                                               struct nlattr **attrs)
 110 {
 111         struct devlink *devlink;
 112         char *busname;
 113         char *devname;
 114 
 115         if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
 116                 return ERR_PTR(-EINVAL);
 117 
 118         busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
 119         devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
 120 
 121         lockdep_assert_held(&devlink_mutex);
 122 
 123         list_for_each_entry(devlink, &devlink_list, list) {
 124                 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
 125                     strcmp(dev_name(devlink->dev), devname) == 0 &&
 126                     net_eq(devlink_net(devlink), net))
 127                         return devlink;
 128         }
 129 
 130         return ERR_PTR(-ENODEV);
 131 }
 132 
 133 static struct devlink *devlink_get_from_info(struct genl_info *info)
 134 {
 135         return devlink_get_from_attrs(genl_info_net(info), info->attrs);
 136 }
 137 
 138 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
 139                                                       unsigned int port_index)
 140 {
 141         struct devlink_port *devlink_port;
 142 
 143         list_for_each_entry(devlink_port, &devlink->port_list, list) {
 144                 if (devlink_port->index == port_index)
 145                         return devlink_port;
 146         }
 147         return NULL;
 148 }
 149 
 150 static bool devlink_port_index_exists(struct devlink *devlink,
 151                                       unsigned int port_index)
 152 {
 153         return devlink_port_get_by_index(devlink, port_index);
 154 }
 155 
 156 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
 157                                                         struct nlattr **attrs)
 158 {
 159         if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
 160                 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
 161                 struct devlink_port *devlink_port;
 162 
 163                 devlink_port = devlink_port_get_by_index(devlink, port_index);
 164                 if (!devlink_port)
 165                         return ERR_PTR(-ENODEV);
 166                 return devlink_port;
 167         }
 168         return ERR_PTR(-EINVAL);
 169 }
 170 
 171 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
 172                                                        struct genl_info *info)
 173 {
 174         return devlink_port_get_from_attrs(devlink, info->attrs);
 175 }
 176 
 177 struct devlink_sb {
 178         struct list_head list;
 179         unsigned int index;
 180         u32 size;
 181         u16 ingress_pools_count;
 182         u16 egress_pools_count;
 183         u16 ingress_tc_count;
 184         u16 egress_tc_count;
 185 };
 186 
 187 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
 188 {
 189         return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
 190 }
 191 
 192 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
 193                                                   unsigned int sb_index)
 194 {
 195         struct devlink_sb *devlink_sb;
 196 
 197         list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 198                 if (devlink_sb->index == sb_index)
 199                         return devlink_sb;
 200         }
 201         return NULL;
 202 }
 203 
 204 static bool devlink_sb_index_exists(struct devlink *devlink,
 205                                     unsigned int sb_index)
 206 {
 207         return devlink_sb_get_by_index(devlink, sb_index);
 208 }
 209 
 210 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
 211                                                     struct nlattr **attrs)
 212 {
 213         if (attrs[DEVLINK_ATTR_SB_INDEX]) {
 214                 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
 215                 struct devlink_sb *devlink_sb;
 216 
 217                 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
 218                 if (!devlink_sb)
 219                         return ERR_PTR(-ENODEV);
 220                 return devlink_sb;
 221         }
 222         return ERR_PTR(-EINVAL);
 223 }
 224 
 225 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
 226                                                    struct genl_info *info)
 227 {
 228         return devlink_sb_get_from_attrs(devlink, info->attrs);
 229 }
 230 
 231 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
 232                                                 struct nlattr **attrs,
 233                                                 u16 *p_pool_index)
 234 {
 235         u16 val;
 236 
 237         if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
 238                 return -EINVAL;
 239 
 240         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
 241         if (val >= devlink_sb_pool_count(devlink_sb))
 242                 return -EINVAL;
 243         *p_pool_index = val;
 244         return 0;
 245 }
 246 
 247 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
 248                                                struct genl_info *info,
 249                                                u16 *p_pool_index)
 250 {
 251         return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
 252                                                     p_pool_index);
 253 }
 254 
 255 static int
 256 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
 257                                     enum devlink_sb_pool_type *p_pool_type)
 258 {
 259         u8 val;
 260 
 261         if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
 262                 return -EINVAL;
 263 
 264         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
 265         if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
 266             val != DEVLINK_SB_POOL_TYPE_EGRESS)
 267                 return -EINVAL;
 268         *p_pool_type = val;
 269         return 0;
 270 }
 271 
 272 static int
 273 devlink_sb_pool_type_get_from_info(struct genl_info *info,
 274                                    enum devlink_sb_pool_type *p_pool_type)
 275 {
 276         return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
 277 }
 278 
 279 static int
 280 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
 281                                   enum devlink_sb_threshold_type *p_th_type)
 282 {
 283         u8 val;
 284 
 285         if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
 286                 return -EINVAL;
 287 
 288         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
 289         if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
 290             val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
 291                 return -EINVAL;
 292         *p_th_type = val;
 293         return 0;
 294 }
 295 
 296 static int
 297 devlink_sb_th_type_get_from_info(struct genl_info *info,
 298                                  enum devlink_sb_threshold_type *p_th_type)
 299 {
 300         return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
 301 }
 302 
 303 static int
 304 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
 305                                    struct nlattr **attrs,
 306                                    enum devlink_sb_pool_type pool_type,
 307                                    u16 *p_tc_index)
 308 {
 309         u16 val;
 310 
 311         if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
 312                 return -EINVAL;
 313 
 314         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
 315         if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
 316             val >= devlink_sb->ingress_tc_count)
 317                 return -EINVAL;
 318         if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
 319             val >= devlink_sb->egress_tc_count)
 320                 return -EINVAL;
 321         *p_tc_index = val;
 322         return 0;
 323 }
 324 
 325 static int
 326 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
 327                                   struct genl_info *info,
 328                                   enum devlink_sb_pool_type pool_type,
 329                                   u16 *p_tc_index)
 330 {
 331         return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
 332                                                   pool_type, p_tc_index);
 333 }
 334 
 335 struct devlink_region {
 336         struct devlink *devlink;
 337         struct list_head list;
 338         const char *name;
 339         struct list_head snapshot_list;
 340         u32 max_snapshots;
 341         u32 cur_snapshots;
 342         u64 size;
 343 };
 344 
 345 struct devlink_snapshot {
 346         struct list_head list;
 347         struct devlink_region *region;
 348         devlink_snapshot_data_dest_t *data_destructor;
 349         u8 *data;
 350         u32 id;
 351 };
 352 
 353 static struct devlink_region *
 354 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
 355 {
 356         struct devlink_region *region;
 357 
 358         list_for_each_entry(region, &devlink->region_list, list)
 359                 if (!strcmp(region->name, region_name))
 360                         return region;
 361 
 362         return NULL;
 363 }
 364 
 365 static struct devlink_snapshot *
 366 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
 367 {
 368         struct devlink_snapshot *snapshot;
 369 
 370         list_for_each_entry(snapshot, &region->snapshot_list, list)
 371                 if (snapshot->id == id)
 372                         return snapshot;
 373 
 374         return NULL;
 375 }
 376 
 377 #define DEVLINK_NL_FLAG_NEED_DEVLINK    BIT(0)
 378 #define DEVLINK_NL_FLAG_NEED_PORT       BIT(1)
 379 #define DEVLINK_NL_FLAG_NEED_SB         BIT(2)
 380 
 381 /* The per devlink instance lock is taken by default in the pre-doit
 382  * operation, yet several commands do not require this. The global
 383  * devlink lock is taken and protects from disruption by user-calls.
 384  */
 385 #define DEVLINK_NL_FLAG_NO_LOCK         BIT(3)
 386 
 387 static int devlink_nl_pre_doit(const struct genl_ops *ops,
 388                                struct sk_buff *skb, struct genl_info *info)
 389 {
 390         struct devlink *devlink;
 391         int err;
 392 
 393         mutex_lock(&devlink_mutex);
 394         devlink = devlink_get_from_info(info);
 395         if (IS_ERR(devlink)) {
 396                 mutex_unlock(&devlink_mutex);
 397                 return PTR_ERR(devlink);
 398         }
 399         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
 400                 mutex_lock(&devlink->lock);
 401         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
 402                 info->user_ptr[0] = devlink;
 403         } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
 404                 struct devlink_port *devlink_port;
 405 
 406                 devlink_port = devlink_port_get_from_info(devlink, info);
 407                 if (IS_ERR(devlink_port)) {
 408                         err = PTR_ERR(devlink_port);
 409                         goto unlock;
 410                 }
 411                 info->user_ptr[0] = devlink_port;
 412         }
 413         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
 414                 struct devlink_sb *devlink_sb;
 415 
 416                 devlink_sb = devlink_sb_get_from_info(devlink, info);
 417                 if (IS_ERR(devlink_sb)) {
 418                         err = PTR_ERR(devlink_sb);
 419                         goto unlock;
 420                 }
 421                 info->user_ptr[1] = devlink_sb;
 422         }
 423         return 0;
 424 
 425 unlock:
 426         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
 427                 mutex_unlock(&devlink->lock);
 428         mutex_unlock(&devlink_mutex);
 429         return err;
 430 }
 431 
 432 static void devlink_nl_post_doit(const struct genl_ops *ops,
 433                                  struct sk_buff *skb, struct genl_info *info)
 434 {
 435         struct devlink *devlink;
 436 
 437         devlink = devlink_get_from_info(info);
 438         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
 439                 mutex_unlock(&devlink->lock);
 440         mutex_unlock(&devlink_mutex);
 441 }
 442 
 443 static struct genl_family devlink_nl_family;
 444 
 445 enum devlink_multicast_groups {
 446         DEVLINK_MCGRP_CONFIG,
 447 };
 448 
 449 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
 450         [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
 451 };
 452 
 453 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
 454 {
 455         if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
 456                 return -EMSGSIZE;
 457         if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
 458                 return -EMSGSIZE;
 459         return 0;
 460 }
 461 
 462 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
 463                            enum devlink_command cmd, u32 portid,
 464                            u32 seq, int flags)
 465 {
 466         void *hdr;
 467 
 468         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 469         if (!hdr)
 470                 return -EMSGSIZE;
 471 
 472         if (devlink_nl_put_handle(msg, devlink))
 473                 goto nla_put_failure;
 474         if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
 475                 goto nla_put_failure;
 476 
 477         genlmsg_end(msg, hdr);
 478         return 0;
 479 
 480 nla_put_failure:
 481         genlmsg_cancel(msg, hdr);
 482         return -EMSGSIZE;
 483 }
 484 
 485 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
 486 {
 487         struct sk_buff *msg;
 488         int err;
 489 
 490         WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
 491 
 492         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 493         if (!msg)
 494                 return;
 495 
 496         err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
 497         if (err) {
 498                 nlmsg_free(msg);
 499                 return;
 500         }
 501 
 502         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 503                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 504 }
 505 
 506 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
 507                                      struct devlink_port *devlink_port)
 508 {
 509         struct devlink_port_attrs *attrs = &devlink_port->attrs;
 510 
 511         if (!attrs->set)
 512                 return 0;
 513         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
 514                 return -EMSGSIZE;
 515         switch (devlink_port->attrs.flavour) {
 516         case DEVLINK_PORT_FLAVOUR_PCI_PF:
 517                 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
 518                                 attrs->pci_pf.pf))
 519                         return -EMSGSIZE;
 520                 break;
 521         case DEVLINK_PORT_FLAVOUR_PCI_VF:
 522                 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
 523                                 attrs->pci_vf.pf) ||
 524                     nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER,
 525                                 attrs->pci_vf.vf))
 526                         return -EMSGSIZE;
 527                 break;
 528         case DEVLINK_PORT_FLAVOUR_PHYSICAL:
 529         case DEVLINK_PORT_FLAVOUR_CPU:
 530         case DEVLINK_PORT_FLAVOUR_DSA:
 531                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
 532                                 attrs->phys.port_number))
 533                         return -EMSGSIZE;
 534                 if (!attrs->split)
 535                         return 0;
 536                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
 537                                 attrs->phys.port_number))
 538                         return -EMSGSIZE;
 539                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
 540                                 attrs->phys.split_subport_number))
 541                         return -EMSGSIZE;
 542                 break;
 543         default:
 544                 break;
 545         }
 546         return 0;
 547 }
 548 
 549 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
 550                                 struct devlink_port *devlink_port,
 551                                 enum devlink_command cmd, u32 portid,
 552                                 u32 seq, int flags)
 553 {
 554         void *hdr;
 555 
 556         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 557         if (!hdr)
 558                 return -EMSGSIZE;
 559 
 560         if (devlink_nl_put_handle(msg, devlink))
 561                 goto nla_put_failure;
 562         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
 563                 goto nla_put_failure;
 564 
 565         spin_lock_bh(&devlink_port->type_lock);
 566         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
 567                 goto nla_put_failure_type_locked;
 568         if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
 569             nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
 570                         devlink_port->desired_type))
 571                 goto nla_put_failure_type_locked;
 572         if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
 573                 struct net_device *netdev = devlink_port->type_dev;
 574 
 575                 if (netdev &&
 576                     (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
 577                                  netdev->ifindex) ||
 578                      nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
 579                                     netdev->name)))
 580                         goto nla_put_failure_type_locked;
 581         }
 582         if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
 583                 struct ib_device *ibdev = devlink_port->type_dev;
 584 
 585                 if (ibdev &&
 586                     nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
 587                                    ibdev->name))
 588                         goto nla_put_failure_type_locked;
 589         }
 590         spin_unlock_bh(&devlink_port->type_lock);
 591         if (devlink_nl_port_attrs_put(msg, devlink_port))
 592                 goto nla_put_failure;
 593 
 594         genlmsg_end(msg, hdr);
 595         return 0;
 596 
 597 nla_put_failure_type_locked:
 598         spin_unlock_bh(&devlink_port->type_lock);
 599 nla_put_failure:
 600         genlmsg_cancel(msg, hdr);
 601         return -EMSGSIZE;
 602 }
 603 
 604 static void devlink_port_notify(struct devlink_port *devlink_port,
 605                                 enum devlink_command cmd)
 606 {
 607         struct devlink *devlink = devlink_port->devlink;
 608         struct sk_buff *msg;
 609         int err;
 610 
 611         if (!devlink_port->registered)
 612                 return;
 613 
 614         WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
 615 
 616         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 617         if (!msg)
 618                 return;
 619 
 620         err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
 621         if (err) {
 622                 nlmsg_free(msg);
 623                 return;
 624         }
 625 
 626         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
 627                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
 628 }
 629 
 630 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
 631 {
 632         struct devlink *devlink = info->user_ptr[0];
 633         struct sk_buff *msg;
 634         int err;
 635 
 636         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 637         if (!msg)
 638                 return -ENOMEM;
 639 
 640         err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 641                               info->snd_portid, info->snd_seq, 0);
 642         if (err) {
 643                 nlmsg_free(msg);
 644                 return err;
 645         }
 646 
 647         return genlmsg_reply(msg, info);
 648 }
 649 
 650 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
 651                                      struct netlink_callback *cb)
 652 {
 653         struct devlink *devlink;
 654         int start = cb->args[0];
 655         int idx = 0;
 656         int err;
 657 
 658         mutex_lock(&devlink_mutex);
 659         list_for_each_entry(devlink, &devlink_list, list) {
 660                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 661                         continue;
 662                 if (idx < start) {
 663                         idx++;
 664                         continue;
 665                 }
 666                 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
 667                                       NETLINK_CB(cb->skb).portid,
 668                                       cb->nlh->nlmsg_seq, NLM_F_MULTI);
 669                 if (err)
 670                         goto out;
 671                 idx++;
 672         }
 673 out:
 674         mutex_unlock(&devlink_mutex);
 675 
 676         cb->args[0] = idx;
 677         return msg->len;
 678 }
 679 
 680 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
 681                                         struct genl_info *info)
 682 {
 683         struct devlink_port *devlink_port = info->user_ptr[0];
 684         struct devlink *devlink = devlink_port->devlink;
 685         struct sk_buff *msg;
 686         int err;
 687 
 688         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 689         if (!msg)
 690                 return -ENOMEM;
 691 
 692         err = devlink_nl_port_fill(msg, devlink, devlink_port,
 693                                    DEVLINK_CMD_PORT_NEW,
 694                                    info->snd_portid, info->snd_seq, 0);
 695         if (err) {
 696                 nlmsg_free(msg);
 697                 return err;
 698         }
 699 
 700         return genlmsg_reply(msg, info);
 701 }
 702 
 703 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
 704                                           struct netlink_callback *cb)
 705 {
 706         struct devlink *devlink;
 707         struct devlink_port *devlink_port;
 708         int start = cb->args[0];
 709         int idx = 0;
 710         int err;
 711 
 712         mutex_lock(&devlink_mutex);
 713         list_for_each_entry(devlink, &devlink_list, list) {
 714                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 715                         continue;
 716                 mutex_lock(&devlink->lock);
 717                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
 718                         if (idx < start) {
 719                                 idx++;
 720                                 continue;
 721                         }
 722                         err = devlink_nl_port_fill(msg, devlink, devlink_port,
 723                                                    DEVLINK_CMD_NEW,
 724                                                    NETLINK_CB(cb->skb).portid,
 725                                                    cb->nlh->nlmsg_seq,
 726                                                    NLM_F_MULTI);
 727                         if (err) {
 728                                 mutex_unlock(&devlink->lock);
 729                                 goto out;
 730                         }
 731                         idx++;
 732                 }
 733                 mutex_unlock(&devlink->lock);
 734         }
 735 out:
 736         mutex_unlock(&devlink_mutex);
 737 
 738         cb->args[0] = idx;
 739         return msg->len;
 740 }
 741 
 742 static int devlink_port_type_set(struct devlink *devlink,
 743                                  struct devlink_port *devlink_port,
 744                                  enum devlink_port_type port_type)
 745 
 746 {
 747         int err;
 748 
 749         if (devlink->ops->port_type_set) {
 750                 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
 751                         return -EINVAL;
 752                 if (port_type == devlink_port->type)
 753                         return 0;
 754                 err = devlink->ops->port_type_set(devlink_port, port_type);
 755                 if (err)
 756                         return err;
 757                 devlink_port->desired_type = port_type;
 758                 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
 759                 return 0;
 760         }
 761         return -EOPNOTSUPP;
 762 }
 763 
 764 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
 765                                         struct genl_info *info)
 766 {
 767         struct devlink_port *devlink_port = info->user_ptr[0];
 768         struct devlink *devlink = devlink_port->devlink;
 769         int err;
 770 
 771         if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
 772                 enum devlink_port_type port_type;
 773 
 774                 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
 775                 err = devlink_port_type_set(devlink, devlink_port, port_type);
 776                 if (err)
 777                         return err;
 778         }
 779         return 0;
 780 }
 781 
 782 static int devlink_port_split(struct devlink *devlink, u32 port_index,
 783                               u32 count, struct netlink_ext_ack *extack)
 784 
 785 {
 786         if (devlink->ops->port_split)
 787                 return devlink->ops->port_split(devlink, port_index, count,
 788                                                 extack);
 789         return -EOPNOTSUPP;
 790 }
 791 
 792 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
 793                                           struct genl_info *info)
 794 {
 795         struct devlink *devlink = info->user_ptr[0];
 796         u32 port_index;
 797         u32 count;
 798 
 799         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
 800             !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
 801                 return -EINVAL;
 802 
 803         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 804         count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
 805         return devlink_port_split(devlink, port_index, count, info->extack);
 806 }
 807 
 808 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
 809                                 struct netlink_ext_ack *extack)
 810 
 811 {
 812         if (devlink->ops->port_unsplit)
 813                 return devlink->ops->port_unsplit(devlink, port_index, extack);
 814         return -EOPNOTSUPP;
 815 }
 816 
 817 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
 818                                             struct genl_info *info)
 819 {
 820         struct devlink *devlink = info->user_ptr[0];
 821         u32 port_index;
 822 
 823         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
 824                 return -EINVAL;
 825 
 826         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
 827         return devlink_port_unsplit(devlink, port_index, info->extack);
 828 }
 829 
 830 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
 831                               struct devlink_sb *devlink_sb,
 832                               enum devlink_command cmd, u32 portid,
 833                               u32 seq, int flags)
 834 {
 835         void *hdr;
 836 
 837         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 838         if (!hdr)
 839                 return -EMSGSIZE;
 840 
 841         if (devlink_nl_put_handle(msg, devlink))
 842                 goto nla_put_failure;
 843         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 844                 goto nla_put_failure;
 845         if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
 846                 goto nla_put_failure;
 847         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
 848                         devlink_sb->ingress_pools_count))
 849                 goto nla_put_failure;
 850         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
 851                         devlink_sb->egress_pools_count))
 852                 goto nla_put_failure;
 853         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
 854                         devlink_sb->ingress_tc_count))
 855                 goto nla_put_failure;
 856         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
 857                         devlink_sb->egress_tc_count))
 858                 goto nla_put_failure;
 859 
 860         genlmsg_end(msg, hdr);
 861         return 0;
 862 
 863 nla_put_failure:
 864         genlmsg_cancel(msg, hdr);
 865         return -EMSGSIZE;
 866 }
 867 
 868 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
 869                                       struct genl_info *info)
 870 {
 871         struct devlink *devlink = info->user_ptr[0];
 872         struct devlink_sb *devlink_sb = info->user_ptr[1];
 873         struct sk_buff *msg;
 874         int err;
 875 
 876         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 877         if (!msg)
 878                 return -ENOMEM;
 879 
 880         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 881                                  DEVLINK_CMD_SB_NEW,
 882                                  info->snd_portid, info->snd_seq, 0);
 883         if (err) {
 884                 nlmsg_free(msg);
 885                 return err;
 886         }
 887 
 888         return genlmsg_reply(msg, info);
 889 }
 890 
 891 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
 892                                         struct netlink_callback *cb)
 893 {
 894         struct devlink *devlink;
 895         struct devlink_sb *devlink_sb;
 896         int start = cb->args[0];
 897         int idx = 0;
 898         int err;
 899 
 900         mutex_lock(&devlink_mutex);
 901         list_for_each_entry(devlink, &devlink_list, list) {
 902                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
 903                         continue;
 904                 mutex_lock(&devlink->lock);
 905                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
 906                         if (idx < start) {
 907                                 idx++;
 908                                 continue;
 909                         }
 910                         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
 911                                                  DEVLINK_CMD_SB_NEW,
 912                                                  NETLINK_CB(cb->skb).portid,
 913                                                  cb->nlh->nlmsg_seq,
 914                                                  NLM_F_MULTI);
 915                         if (err) {
 916                                 mutex_unlock(&devlink->lock);
 917                                 goto out;
 918                         }
 919                         idx++;
 920                 }
 921                 mutex_unlock(&devlink->lock);
 922         }
 923 out:
 924         mutex_unlock(&devlink_mutex);
 925 
 926         cb->args[0] = idx;
 927         return msg->len;
 928 }
 929 
 930 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
 931                                    struct devlink_sb *devlink_sb,
 932                                    u16 pool_index, enum devlink_command cmd,
 933                                    u32 portid, u32 seq, int flags)
 934 {
 935         struct devlink_sb_pool_info pool_info;
 936         void *hdr;
 937         int err;
 938 
 939         err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
 940                                         pool_index, &pool_info);
 941         if (err)
 942                 return err;
 943 
 944         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
 945         if (!hdr)
 946                 return -EMSGSIZE;
 947 
 948         if (devlink_nl_put_handle(msg, devlink))
 949                 goto nla_put_failure;
 950         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
 951                 goto nla_put_failure;
 952         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
 953                 goto nla_put_failure;
 954         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
 955                 goto nla_put_failure;
 956         if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
 957                 goto nla_put_failure;
 958         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
 959                        pool_info.threshold_type))
 960                 goto nla_put_failure;
 961         if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
 962                         pool_info.cell_size))
 963                 goto nla_put_failure;
 964 
 965         genlmsg_end(msg, hdr);
 966         return 0;
 967 
 968 nla_put_failure:
 969         genlmsg_cancel(msg, hdr);
 970         return -EMSGSIZE;
 971 }
 972 
 973 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
 974                                            struct genl_info *info)
 975 {
 976         struct devlink *devlink = info->user_ptr[0];
 977         struct devlink_sb *devlink_sb = info->user_ptr[1];
 978         struct sk_buff *msg;
 979         u16 pool_index;
 980         int err;
 981 
 982         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
 983                                                   &pool_index);
 984         if (err)
 985                 return err;
 986 
 987         if (!devlink->ops->sb_pool_get)
 988                 return -EOPNOTSUPP;
 989 
 990         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 991         if (!msg)
 992                 return -ENOMEM;
 993 
 994         err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
 995                                       DEVLINK_CMD_SB_POOL_NEW,
 996                                       info->snd_portid, info->snd_seq, 0);
 997         if (err) {
 998                 nlmsg_free(msg);
 999                 return err;
1000         }
1001 
1002         return genlmsg_reply(msg, info);
1003 }
1004 
1005 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1006                                 struct devlink *devlink,
1007                                 struct devlink_sb *devlink_sb,
1008                                 u32 portid, u32 seq)
1009 {
1010         u16 pool_count = devlink_sb_pool_count(devlink_sb);
1011         u16 pool_index;
1012         int err;
1013 
1014         for (pool_index = 0; pool_index < pool_count; pool_index++) {
1015                 if (*p_idx < start) {
1016                         (*p_idx)++;
1017                         continue;
1018                 }
1019                 err = devlink_nl_sb_pool_fill(msg, devlink,
1020                                               devlink_sb,
1021                                               pool_index,
1022                                               DEVLINK_CMD_SB_POOL_NEW,
1023                                               portid, seq, NLM_F_MULTI);
1024                 if (err)
1025                         return err;
1026                 (*p_idx)++;
1027         }
1028         return 0;
1029 }
1030 
1031 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
1032                                              struct netlink_callback *cb)
1033 {
1034         struct devlink *devlink;
1035         struct devlink_sb *devlink_sb;
1036         int start = cb->args[0];
1037         int idx = 0;
1038         int err;
1039 
1040         mutex_lock(&devlink_mutex);
1041         list_for_each_entry(devlink, &devlink_list, list) {
1042                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1043                     !devlink->ops->sb_pool_get)
1044                         continue;
1045                 mutex_lock(&devlink->lock);
1046                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1047                         err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
1048                                                    devlink_sb,
1049                                                    NETLINK_CB(cb->skb).portid,
1050                                                    cb->nlh->nlmsg_seq);
1051                         if (err && err != -EOPNOTSUPP) {
1052                                 mutex_unlock(&devlink->lock);
1053                                 goto out;
1054                         }
1055                 }
1056                 mutex_unlock(&devlink->lock);
1057         }
1058 out:
1059         mutex_unlock(&devlink_mutex);
1060 
1061         cb->args[0] = idx;
1062         return msg->len;
1063 }
1064 
1065 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
1066                                u16 pool_index, u32 size,
1067                                enum devlink_sb_threshold_type threshold_type,
1068                                struct netlink_ext_ack *extack)
1069 
1070 {
1071         const struct devlink_ops *ops = devlink->ops;
1072 
1073         if (ops->sb_pool_set)
1074                 return ops->sb_pool_set(devlink, sb_index, pool_index,
1075                                         size, threshold_type, extack);
1076         return -EOPNOTSUPP;
1077 }
1078 
1079 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
1080                                            struct genl_info *info)
1081 {
1082         struct devlink *devlink = info->user_ptr[0];
1083         struct devlink_sb *devlink_sb = info->user_ptr[1];
1084         enum devlink_sb_threshold_type threshold_type;
1085         u16 pool_index;
1086         u32 size;
1087         int err;
1088 
1089         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1090                                                   &pool_index);
1091         if (err)
1092                 return err;
1093 
1094         err = devlink_sb_th_type_get_from_info(info, &threshold_type);
1095         if (err)
1096                 return err;
1097 
1098         if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
1099                 return -EINVAL;
1100 
1101         size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1102         return devlink_sb_pool_set(devlink, devlink_sb->index,
1103                                    pool_index, size, threshold_type,
1104                                    info->extack);
1105 }
1106 
1107 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1108                                         struct devlink *devlink,
1109                                         struct devlink_port *devlink_port,
1110                                         struct devlink_sb *devlink_sb,
1111                                         u16 pool_index,
1112                                         enum devlink_command cmd,
1113                                         u32 portid, u32 seq, int flags)
1114 {
1115         const struct devlink_ops *ops = devlink->ops;
1116         u32 threshold;
1117         void *hdr;
1118         int err;
1119 
1120         err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1121                                     pool_index, &threshold);
1122         if (err)
1123                 return err;
1124 
1125         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1126         if (!hdr)
1127                 return -EMSGSIZE;
1128 
1129         if (devlink_nl_put_handle(msg, devlink))
1130                 goto nla_put_failure;
1131         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1132                 goto nla_put_failure;
1133         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1134                 goto nla_put_failure;
1135         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1136                 goto nla_put_failure;
1137         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1138                 goto nla_put_failure;
1139 
1140         if (ops->sb_occ_port_pool_get) {
1141                 u32 cur;
1142                 u32 max;
1143 
1144                 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1145                                                 pool_index, &cur, &max);
1146                 if (err && err != -EOPNOTSUPP)
1147                         return err;
1148                 if (!err) {
1149                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1150                                 goto nla_put_failure;
1151                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1152                                 goto nla_put_failure;
1153                 }
1154         }
1155 
1156         genlmsg_end(msg, hdr);
1157         return 0;
1158 
1159 nla_put_failure:
1160         genlmsg_cancel(msg, hdr);
1161         return -EMSGSIZE;
1162 }
1163 
1164 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1165                                                 struct genl_info *info)
1166 {
1167         struct devlink_port *devlink_port = info->user_ptr[0];
1168         struct devlink *devlink = devlink_port->devlink;
1169         struct devlink_sb *devlink_sb = info->user_ptr[1];
1170         struct sk_buff *msg;
1171         u16 pool_index;
1172         int err;
1173 
1174         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1175                                                   &pool_index);
1176         if (err)
1177                 return err;
1178 
1179         if (!devlink->ops->sb_port_pool_get)
1180                 return -EOPNOTSUPP;
1181 
1182         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1183         if (!msg)
1184                 return -ENOMEM;
1185 
1186         err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1187                                            devlink_sb, pool_index,
1188                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1189                                            info->snd_portid, info->snd_seq, 0);
1190         if (err) {
1191                 nlmsg_free(msg);
1192                 return err;
1193         }
1194 
1195         return genlmsg_reply(msg, info);
1196 }
1197 
1198 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1199                                      struct devlink *devlink,
1200                                      struct devlink_sb *devlink_sb,
1201                                      u32 portid, u32 seq)
1202 {
1203         struct devlink_port *devlink_port;
1204         u16 pool_count = devlink_sb_pool_count(devlink_sb);
1205         u16 pool_index;
1206         int err;
1207 
1208         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1209                 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1210                         if (*p_idx < start) {
1211                                 (*p_idx)++;
1212                                 continue;
1213                         }
1214                         err = devlink_nl_sb_port_pool_fill(msg, devlink,
1215                                                            devlink_port,
1216                                                            devlink_sb,
1217                                                            pool_index,
1218                                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1219                                                            portid, seq,
1220                                                            NLM_F_MULTI);
1221                         if (err)
1222                                 return err;
1223                         (*p_idx)++;
1224                 }
1225         }
1226         return 0;
1227 }
1228 
1229 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1230                                                   struct netlink_callback *cb)
1231 {
1232         struct devlink *devlink;
1233         struct devlink_sb *devlink_sb;
1234         int start = cb->args[0];
1235         int idx = 0;
1236         int err;
1237 
1238         mutex_lock(&devlink_mutex);
1239         list_for_each_entry(devlink, &devlink_list, list) {
1240                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1241                     !devlink->ops->sb_port_pool_get)
1242                         continue;
1243                 mutex_lock(&devlink->lock);
1244                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1245                         err = __sb_port_pool_get_dumpit(msg, start, &idx,
1246                                                         devlink, devlink_sb,
1247                                                         NETLINK_CB(cb->skb).portid,
1248                                                         cb->nlh->nlmsg_seq);
1249                         if (err && err != -EOPNOTSUPP) {
1250                                 mutex_unlock(&devlink->lock);
1251                                 goto out;
1252                         }
1253                 }
1254                 mutex_unlock(&devlink->lock);
1255         }
1256 out:
1257         mutex_unlock(&devlink_mutex);
1258 
1259         cb->args[0] = idx;
1260         return msg->len;
1261 }
1262 
1263 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1264                                     unsigned int sb_index, u16 pool_index,
1265                                     u32 threshold,
1266                                     struct netlink_ext_ack *extack)
1267 
1268 {
1269         const struct devlink_ops *ops = devlink_port->devlink->ops;
1270 
1271         if (ops->sb_port_pool_set)
1272                 return ops->sb_port_pool_set(devlink_port, sb_index,
1273                                              pool_index, threshold, extack);
1274         return -EOPNOTSUPP;
1275 }
1276 
1277 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1278                                                 struct genl_info *info)
1279 {
1280         struct devlink_port *devlink_port = info->user_ptr[0];
1281         struct devlink_sb *devlink_sb = info->user_ptr[1];
1282         u16 pool_index;
1283         u32 threshold;
1284         int err;
1285 
1286         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1287                                                   &pool_index);
1288         if (err)
1289                 return err;
1290 
1291         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1292                 return -EINVAL;
1293 
1294         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1295         return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1296                                         pool_index, threshold, info->extack);
1297 }
1298 
1299 static int
1300 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1301                                 struct devlink_port *devlink_port,
1302                                 struct devlink_sb *devlink_sb, u16 tc_index,
1303                                 enum devlink_sb_pool_type pool_type,
1304                                 enum devlink_command cmd,
1305                                 u32 portid, u32 seq, int flags)
1306 {
1307         const struct devlink_ops *ops = devlink->ops;
1308         u16 pool_index;
1309         u32 threshold;
1310         void *hdr;
1311         int err;
1312 
1313         err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1314                                        tc_index, pool_type,
1315                                        &pool_index, &threshold);
1316         if (err)
1317                 return err;
1318 
1319         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1320         if (!hdr)
1321                 return -EMSGSIZE;
1322 
1323         if (devlink_nl_put_handle(msg, devlink))
1324                 goto nla_put_failure;
1325         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1326                 goto nla_put_failure;
1327         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1328                 goto nla_put_failure;
1329         if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1330                 goto nla_put_failure;
1331         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1332                 goto nla_put_failure;
1333         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1334                 goto nla_put_failure;
1335         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1336                 goto nla_put_failure;
1337 
1338         if (ops->sb_occ_tc_port_bind_get) {
1339                 u32 cur;
1340                 u32 max;
1341 
1342                 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1343                                                    devlink_sb->index,
1344                                                    tc_index, pool_type,
1345                                                    &cur, &max);
1346                 if (err && err != -EOPNOTSUPP)
1347                         return err;
1348                 if (!err) {
1349                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1350                                 goto nla_put_failure;
1351                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1352                                 goto nla_put_failure;
1353                 }
1354         }
1355 
1356         genlmsg_end(msg, hdr);
1357         return 0;
1358 
1359 nla_put_failure:
1360         genlmsg_cancel(msg, hdr);
1361         return -EMSGSIZE;
1362 }
1363 
1364 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1365                                                    struct genl_info *info)
1366 {
1367         struct devlink_port *devlink_port = info->user_ptr[0];
1368         struct devlink *devlink = devlink_port->devlink;
1369         struct devlink_sb *devlink_sb = info->user_ptr[1];
1370         struct sk_buff *msg;
1371         enum devlink_sb_pool_type pool_type;
1372         u16 tc_index;
1373         int err;
1374 
1375         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1376         if (err)
1377                 return err;
1378 
1379         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1380                                                 pool_type, &tc_index);
1381         if (err)
1382                 return err;
1383 
1384         if (!devlink->ops->sb_tc_pool_bind_get)
1385                 return -EOPNOTSUPP;
1386 
1387         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1388         if (!msg)
1389                 return -ENOMEM;
1390 
1391         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1392                                               devlink_sb, tc_index, pool_type,
1393                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1394                                               info->snd_portid,
1395                                               info->snd_seq, 0);
1396         if (err) {
1397                 nlmsg_free(msg);
1398                 return err;
1399         }
1400 
1401         return genlmsg_reply(msg, info);
1402 }
1403 
1404 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1405                                         int start, int *p_idx,
1406                                         struct devlink *devlink,
1407                                         struct devlink_sb *devlink_sb,
1408                                         u32 portid, u32 seq)
1409 {
1410         struct devlink_port *devlink_port;
1411         u16 tc_index;
1412         int err;
1413 
1414         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1415                 for (tc_index = 0;
1416                      tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1417                         if (*p_idx < start) {
1418                                 (*p_idx)++;
1419                                 continue;
1420                         }
1421                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1422                                                               devlink_port,
1423                                                               devlink_sb,
1424                                                               tc_index,
1425                                                               DEVLINK_SB_POOL_TYPE_INGRESS,
1426                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1427                                                               portid, seq,
1428                                                               NLM_F_MULTI);
1429                         if (err)
1430                                 return err;
1431                         (*p_idx)++;
1432                 }
1433                 for (tc_index = 0;
1434                      tc_index < devlink_sb->egress_tc_count; tc_index++) {
1435                         if (*p_idx < start) {
1436                                 (*p_idx)++;
1437                                 continue;
1438                         }
1439                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1440                                                               devlink_port,
1441                                                               devlink_sb,
1442                                                               tc_index,
1443                                                               DEVLINK_SB_POOL_TYPE_EGRESS,
1444                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1445                                                               portid, seq,
1446                                                               NLM_F_MULTI);
1447                         if (err)
1448                                 return err;
1449                         (*p_idx)++;
1450                 }
1451         }
1452         return 0;
1453 }
1454 
1455 static int
1456 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1457                                           struct netlink_callback *cb)
1458 {
1459         struct devlink *devlink;
1460         struct devlink_sb *devlink_sb;
1461         int start = cb->args[0];
1462         int idx = 0;
1463         int err;
1464 
1465         mutex_lock(&devlink_mutex);
1466         list_for_each_entry(devlink, &devlink_list, list) {
1467                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1468                     !devlink->ops->sb_tc_pool_bind_get)
1469                         continue;
1470 
1471                 mutex_lock(&devlink->lock);
1472                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1473                         err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1474                                                            devlink,
1475                                                            devlink_sb,
1476                                                            NETLINK_CB(cb->skb).portid,
1477                                                            cb->nlh->nlmsg_seq);
1478                         if (err && err != -EOPNOTSUPP) {
1479                                 mutex_unlock(&devlink->lock);
1480                                 goto out;
1481                         }
1482                 }
1483                 mutex_unlock(&devlink->lock);
1484         }
1485 out:
1486         mutex_unlock(&devlink_mutex);
1487 
1488         cb->args[0] = idx;
1489         return msg->len;
1490 }
1491 
1492 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1493                                        unsigned int sb_index, u16 tc_index,
1494                                        enum devlink_sb_pool_type pool_type,
1495                                        u16 pool_index, u32 threshold,
1496                                        struct netlink_ext_ack *extack)
1497 
1498 {
1499         const struct devlink_ops *ops = devlink_port->devlink->ops;
1500 
1501         if (ops->sb_tc_pool_bind_set)
1502                 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1503                                                 tc_index, pool_type,
1504                                                 pool_index, threshold, extack);
1505         return -EOPNOTSUPP;
1506 }
1507 
1508 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1509                                                    struct genl_info *info)
1510 {
1511         struct devlink_port *devlink_port = info->user_ptr[0];
1512         struct devlink_sb *devlink_sb = info->user_ptr[1];
1513         enum devlink_sb_pool_type pool_type;
1514         u16 tc_index;
1515         u16 pool_index;
1516         u32 threshold;
1517         int err;
1518 
1519         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1520         if (err)
1521                 return err;
1522 
1523         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1524                                                 pool_type, &tc_index);
1525         if (err)
1526                 return err;
1527 
1528         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1529                                                   &pool_index);
1530         if (err)
1531                 return err;
1532 
1533         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1534                 return -EINVAL;
1535 
1536         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1537         return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1538                                            tc_index, pool_type,
1539                                            pool_index, threshold, info->extack);
1540 }
1541 
1542 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1543                                                struct genl_info *info)
1544 {
1545         struct devlink *devlink = info->user_ptr[0];
1546         struct devlink_sb *devlink_sb = info->user_ptr[1];
1547         const struct devlink_ops *ops = devlink->ops;
1548 
1549         if (ops->sb_occ_snapshot)
1550                 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1551         return -EOPNOTSUPP;
1552 }
1553 
1554 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1555                                                 struct genl_info *info)
1556 {
1557         struct devlink *devlink = info->user_ptr[0];
1558         struct devlink_sb *devlink_sb = info->user_ptr[1];
1559         const struct devlink_ops *ops = devlink->ops;
1560 
1561         if (ops->sb_occ_max_clear)
1562                 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1563         return -EOPNOTSUPP;
1564 }
1565 
1566 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1567                                    enum devlink_command cmd, u32 portid,
1568                                    u32 seq, int flags)
1569 {
1570         const struct devlink_ops *ops = devlink->ops;
1571         enum devlink_eswitch_encap_mode encap_mode;
1572         u8 inline_mode;
1573         void *hdr;
1574         int err = 0;
1575         u16 mode;
1576 
1577         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1578         if (!hdr)
1579                 return -EMSGSIZE;
1580 
1581         err = devlink_nl_put_handle(msg, devlink);
1582         if (err)
1583                 goto nla_put_failure;
1584 
1585         if (ops->eswitch_mode_get) {
1586                 err = ops->eswitch_mode_get(devlink, &mode);
1587                 if (err)
1588                         goto nla_put_failure;
1589                 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1590                 if (err)
1591                         goto nla_put_failure;
1592         }
1593 
1594         if (ops->eswitch_inline_mode_get) {
1595                 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1596                 if (err)
1597                         goto nla_put_failure;
1598                 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1599                                  inline_mode);
1600                 if (err)
1601                         goto nla_put_failure;
1602         }
1603 
1604         if (ops->eswitch_encap_mode_get) {
1605                 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1606                 if (err)
1607                         goto nla_put_failure;
1608                 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1609                 if (err)
1610                         goto nla_put_failure;
1611         }
1612 
1613         genlmsg_end(msg, hdr);
1614         return 0;
1615 
1616 nla_put_failure:
1617         genlmsg_cancel(msg, hdr);
1618         return err;
1619 }
1620 
1621 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1622                                            struct genl_info *info)
1623 {
1624         struct devlink *devlink = info->user_ptr[0];
1625         struct sk_buff *msg;
1626         int err;
1627 
1628         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1629         if (!msg)
1630                 return -ENOMEM;
1631 
1632         err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1633                                       info->snd_portid, info->snd_seq, 0);
1634 
1635         if (err) {
1636                 nlmsg_free(msg);
1637                 return err;
1638         }
1639 
1640         return genlmsg_reply(msg, info);
1641 }
1642 
1643 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1644                                            struct genl_info *info)
1645 {
1646         struct devlink *devlink = info->user_ptr[0];
1647         const struct devlink_ops *ops = devlink->ops;
1648         enum devlink_eswitch_encap_mode encap_mode;
1649         u8 inline_mode;
1650         int err = 0;
1651         u16 mode;
1652 
1653         if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1654                 if (!ops->eswitch_mode_set)
1655                         return -EOPNOTSUPP;
1656                 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1657                 err = ops->eswitch_mode_set(devlink, mode, info->extack);
1658                 if (err)
1659                         return err;
1660         }
1661 
1662         if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1663                 if (!ops->eswitch_inline_mode_set)
1664                         return -EOPNOTSUPP;
1665                 inline_mode = nla_get_u8(
1666                                 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1667                 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
1668                                                    info->extack);
1669                 if (err)
1670                         return err;
1671         }
1672 
1673         if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1674                 if (!ops->eswitch_encap_mode_set)
1675                         return -EOPNOTSUPP;
1676                 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1677                 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
1678                                                   info->extack);
1679                 if (err)
1680                         return err;
1681         }
1682 
1683         return 0;
1684 }
1685 
1686 int devlink_dpipe_match_put(struct sk_buff *skb,
1687                             struct devlink_dpipe_match *match)
1688 {
1689         struct devlink_dpipe_header *header = match->header;
1690         struct devlink_dpipe_field *field = &header->fields[match->field_id];
1691         struct nlattr *match_attr;
1692 
1693         match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
1694         if (!match_attr)
1695                 return -EMSGSIZE;
1696 
1697         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1698             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1699             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1700             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1701             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1702                 goto nla_put_failure;
1703 
1704         nla_nest_end(skb, match_attr);
1705         return 0;
1706 
1707 nla_put_failure:
1708         nla_nest_cancel(skb, match_attr);
1709         return -EMSGSIZE;
1710 }
1711 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1712 
1713 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1714                                      struct sk_buff *skb)
1715 {
1716         struct nlattr *matches_attr;
1717 
1718         matches_attr = nla_nest_start_noflag(skb,
1719                                              DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1720         if (!matches_attr)
1721                 return -EMSGSIZE;
1722 
1723         if (table->table_ops->matches_dump(table->priv, skb))
1724                 goto nla_put_failure;
1725 
1726         nla_nest_end(skb, matches_attr);
1727         return 0;
1728 
1729 nla_put_failure:
1730         nla_nest_cancel(skb, matches_attr);
1731         return -EMSGSIZE;
1732 }
1733 
1734 int devlink_dpipe_action_put(struct sk_buff *skb,
1735                              struct devlink_dpipe_action *action)
1736 {
1737         struct devlink_dpipe_header *header = action->header;
1738         struct devlink_dpipe_field *field = &header->fields[action->field_id];
1739         struct nlattr *action_attr;
1740 
1741         action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
1742         if (!action_attr)
1743                 return -EMSGSIZE;
1744 
1745         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1746             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1747             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1748             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1749             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1750                 goto nla_put_failure;
1751 
1752         nla_nest_end(skb, action_attr);
1753         return 0;
1754 
1755 nla_put_failure:
1756         nla_nest_cancel(skb, action_attr);
1757         return -EMSGSIZE;
1758 }
1759 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1760 
1761 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1762                                      struct sk_buff *skb)
1763 {
1764         struct nlattr *actions_attr;
1765 
1766         actions_attr = nla_nest_start_noflag(skb,
1767                                              DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1768         if (!actions_attr)
1769                 return -EMSGSIZE;
1770 
1771         if (table->table_ops->actions_dump(table->priv, skb))
1772                 goto nla_put_failure;
1773 
1774         nla_nest_end(skb, actions_attr);
1775         return 0;
1776 
1777 nla_put_failure:
1778         nla_nest_cancel(skb, actions_attr);
1779         return -EMSGSIZE;
1780 }
1781 
1782 static int devlink_dpipe_table_put(struct sk_buff *skb,
1783                                    struct devlink_dpipe_table *table)
1784 {
1785         struct nlattr *table_attr;
1786         u64 table_size;
1787 
1788         table_size = table->table_ops->size_get(table->priv);
1789         table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
1790         if (!table_attr)
1791                 return -EMSGSIZE;
1792 
1793         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1794             nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1795                               DEVLINK_ATTR_PAD))
1796                 goto nla_put_failure;
1797         if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1798                        table->counters_enabled))
1799                 goto nla_put_failure;
1800 
1801         if (table->resource_valid) {
1802                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1803                                       table->resource_id, DEVLINK_ATTR_PAD) ||
1804                     nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1805                                       table->resource_units, DEVLINK_ATTR_PAD))
1806                         goto nla_put_failure;
1807         }
1808         if (devlink_dpipe_matches_put(table, skb))
1809                 goto nla_put_failure;
1810 
1811         if (devlink_dpipe_actions_put(table, skb))
1812                 goto nla_put_failure;
1813 
1814         nla_nest_end(skb, table_attr);
1815         return 0;
1816 
1817 nla_put_failure:
1818         nla_nest_cancel(skb, table_attr);
1819         return -EMSGSIZE;
1820 }
1821 
1822 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1823                                             struct genl_info *info)
1824 {
1825         int err;
1826 
1827         if (*pskb) {
1828                 err = genlmsg_reply(*pskb, info);
1829                 if (err)
1830                         return err;
1831         }
1832         *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1833         if (!*pskb)
1834                 return -ENOMEM;
1835         return 0;
1836 }
1837 
1838 static int devlink_dpipe_tables_fill(struct genl_info *info,
1839                                      enum devlink_command cmd, int flags,
1840                                      struct list_head *dpipe_tables,
1841                                      const char *table_name)
1842 {
1843         struct devlink *devlink = info->user_ptr[0];
1844         struct devlink_dpipe_table *table;
1845         struct nlattr *tables_attr;
1846         struct sk_buff *skb = NULL;
1847         struct nlmsghdr *nlh;
1848         bool incomplete;
1849         void *hdr;
1850         int i;
1851         int err;
1852 
1853         table = list_first_entry(dpipe_tables,
1854                                  struct devlink_dpipe_table, list);
1855 start_again:
1856         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1857         if (err)
1858                 return err;
1859 
1860         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1861                           &devlink_nl_family, NLM_F_MULTI, cmd);
1862         if (!hdr) {
1863                 nlmsg_free(skb);
1864                 return -EMSGSIZE;
1865         }
1866 
1867         if (devlink_nl_put_handle(skb, devlink))
1868                 goto nla_put_failure;
1869         tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
1870         if (!tables_attr)
1871                 goto nla_put_failure;
1872 
1873         i = 0;
1874         incomplete = false;
1875         list_for_each_entry_from(table, dpipe_tables, list) {
1876                 if (!table_name) {
1877                         err = devlink_dpipe_table_put(skb, table);
1878                         if (err) {
1879                                 if (!i)
1880                                         goto err_table_put;
1881                                 incomplete = true;
1882                                 break;
1883                         }
1884                 } else {
1885                         if (!strcmp(table->name, table_name)) {
1886                                 err = devlink_dpipe_table_put(skb, table);
1887                                 if (err)
1888                                         break;
1889                         }
1890                 }
1891                 i++;
1892         }
1893 
1894         nla_nest_end(skb, tables_attr);
1895         genlmsg_end(skb, hdr);
1896         if (incomplete)
1897                 goto start_again;
1898 
1899 send_done:
1900         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1901                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
1902         if (!nlh) {
1903                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1904                 if (err)
1905                         return err;
1906                 goto send_done;
1907         }
1908 
1909         return genlmsg_reply(skb, info);
1910 
1911 nla_put_failure:
1912         err = -EMSGSIZE;
1913 err_table_put:
1914         nlmsg_free(skb);
1915         return err;
1916 }
1917 
1918 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1919                                           struct genl_info *info)
1920 {
1921         struct devlink *devlink = info->user_ptr[0];
1922         const char *table_name =  NULL;
1923 
1924         if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1925                 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1926 
1927         return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1928                                          &devlink->dpipe_table_list,
1929                                          table_name);
1930 }
1931 
1932 static int devlink_dpipe_value_put(struct sk_buff *skb,
1933                                    struct devlink_dpipe_value *value)
1934 {
1935         if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1936                     value->value_size, value->value))
1937                 return -EMSGSIZE;
1938         if (value->mask)
1939                 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1940                             value->value_size, value->mask))
1941                         return -EMSGSIZE;
1942         if (value->mapping_valid)
1943                 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1944                                 value->mapping_value))
1945                         return -EMSGSIZE;
1946         return 0;
1947 }
1948 
1949 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1950                                           struct devlink_dpipe_value *value)
1951 {
1952         if (!value->action)
1953                 return -EINVAL;
1954         if (devlink_dpipe_action_put(skb, value->action))
1955                 return -EMSGSIZE;
1956         if (devlink_dpipe_value_put(skb, value))
1957                 return -EMSGSIZE;
1958         return 0;
1959 }
1960 
1961 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1962                                            struct devlink_dpipe_value *values,
1963                                            unsigned int values_count)
1964 {
1965         struct nlattr *action_attr;
1966         int i;
1967         int err;
1968 
1969         for (i = 0; i < values_count; i++) {
1970                 action_attr = nla_nest_start_noflag(skb,
1971                                                     DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1972                 if (!action_attr)
1973                         return -EMSGSIZE;
1974                 err = devlink_dpipe_action_value_put(skb, &values[i]);
1975                 if (err)
1976                         goto err_action_value_put;
1977                 nla_nest_end(skb, action_attr);
1978         }
1979         return 0;
1980 
1981 err_action_value_put:
1982         nla_nest_cancel(skb, action_attr);
1983         return err;
1984 }
1985 
1986 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1987                                          struct devlink_dpipe_value *value)
1988 {
1989         if (!value->match)
1990                 return -EINVAL;
1991         if (devlink_dpipe_match_put(skb, value->match))
1992                 return -EMSGSIZE;
1993         if (devlink_dpipe_value_put(skb, value))
1994                 return -EMSGSIZE;
1995         return 0;
1996 }
1997 
1998 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1999                                           struct devlink_dpipe_value *values,
2000                                           unsigned int values_count)
2001 {
2002         struct nlattr *match_attr;
2003         int i;
2004         int err;
2005 
2006         for (i = 0; i < values_count; i++) {
2007                 match_attr = nla_nest_start_noflag(skb,
2008                                                    DEVLINK_ATTR_DPIPE_MATCH_VALUE);
2009                 if (!match_attr)
2010                         return -EMSGSIZE;
2011                 err = devlink_dpipe_match_value_put(skb, &values[i]);
2012                 if (err)
2013                         goto err_match_value_put;
2014                 nla_nest_end(skb, match_attr);
2015         }
2016         return 0;
2017 
2018 err_match_value_put:
2019         nla_nest_cancel(skb, match_attr);
2020         return err;
2021 }
2022 
2023 static int devlink_dpipe_entry_put(struct sk_buff *skb,
2024                                    struct devlink_dpipe_entry *entry)
2025 {
2026         struct nlattr *entry_attr, *matches_attr, *actions_attr;
2027         int err;
2028 
2029         entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
2030         if (!entry_attr)
2031                 return  -EMSGSIZE;
2032 
2033         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
2034                               DEVLINK_ATTR_PAD))
2035                 goto nla_put_failure;
2036         if (entry->counter_valid)
2037                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
2038                                       entry->counter, DEVLINK_ATTR_PAD))
2039                         goto nla_put_failure;
2040 
2041         matches_attr = nla_nest_start_noflag(skb,
2042                                              DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
2043         if (!matches_attr)
2044                 goto nla_put_failure;
2045 
2046         err = devlink_dpipe_match_values_put(skb, entry->match_values,
2047                                              entry->match_values_count);
2048         if (err) {
2049                 nla_nest_cancel(skb, matches_attr);
2050                 goto err_match_values_put;
2051         }
2052         nla_nest_end(skb, matches_attr);
2053 
2054         actions_attr = nla_nest_start_noflag(skb,
2055                                              DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
2056         if (!actions_attr)
2057                 goto nla_put_failure;
2058 
2059         err = devlink_dpipe_action_values_put(skb, entry->action_values,
2060                                               entry->action_values_count);
2061         if (err) {
2062                 nla_nest_cancel(skb, actions_attr);
2063                 goto err_action_values_put;
2064         }
2065         nla_nest_end(skb, actions_attr);
2066 
2067         nla_nest_end(skb, entry_attr);
2068         return 0;
2069 
2070 nla_put_failure:
2071         err = -EMSGSIZE;
2072 err_match_values_put:
2073 err_action_values_put:
2074         nla_nest_cancel(skb, entry_attr);
2075         return err;
2076 }
2077 
2078 static struct devlink_dpipe_table *
2079 devlink_dpipe_table_find(struct list_head *dpipe_tables,
2080                          const char *table_name)
2081 {
2082         struct devlink_dpipe_table *table;
2083 
2084         list_for_each_entry_rcu(table, dpipe_tables, list) {
2085                 if (!strcmp(table->name, table_name))
2086                         return table;
2087         }
2088         return NULL;
2089 }
2090 
2091 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2092 {
2093         struct devlink *devlink;
2094         int err;
2095 
2096         err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2097                                                dump_ctx->info);
2098         if (err)
2099                 return err;
2100 
2101         dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2102                                     dump_ctx->info->snd_portid,
2103                                     dump_ctx->info->snd_seq,
2104                                     &devlink_nl_family, NLM_F_MULTI,
2105                                     dump_ctx->cmd);
2106         if (!dump_ctx->hdr)
2107                 goto nla_put_failure;
2108 
2109         devlink = dump_ctx->info->user_ptr[0];
2110         if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2111                 goto nla_put_failure;
2112         dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
2113                                                DEVLINK_ATTR_DPIPE_ENTRIES);
2114         if (!dump_ctx->nest)
2115                 goto nla_put_failure;
2116         return 0;
2117 
2118 nla_put_failure:
2119         nlmsg_free(dump_ctx->skb);
2120         return -EMSGSIZE;
2121 }
2122 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2123 
2124 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2125                                    struct devlink_dpipe_entry *entry)
2126 {
2127         return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2128 }
2129 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2130 
2131 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2132 {
2133         nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2134         genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2135         return 0;
2136 }
2137 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2138 
2139 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2140 
2141 {
2142         unsigned int value_count, value_index;
2143         struct devlink_dpipe_value *value;
2144 
2145         value = entry->action_values;
2146         value_count = entry->action_values_count;
2147         for (value_index = 0; value_index < value_count; value_index++) {
2148                 kfree(value[value_index].value);
2149                 kfree(value[value_index].mask);
2150         }
2151 
2152         value = entry->match_values;
2153         value_count = entry->match_values_count;
2154         for (value_index = 0; value_index < value_count; value_index++) {
2155                 kfree(value[value_index].value);
2156                 kfree(value[value_index].mask);
2157         }
2158 }
2159 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2160 
2161 static int devlink_dpipe_entries_fill(struct genl_info *info,
2162                                       enum devlink_command cmd, int flags,
2163                                       struct devlink_dpipe_table *table)
2164 {
2165         struct devlink_dpipe_dump_ctx dump_ctx;
2166         struct nlmsghdr *nlh;
2167         int err;
2168 
2169         dump_ctx.skb = NULL;
2170         dump_ctx.cmd = cmd;
2171         dump_ctx.info = info;
2172 
2173         err = table->table_ops->entries_dump(table->priv,
2174                                              table->counters_enabled,
2175                                              &dump_ctx);
2176         if (err)
2177                 return err;
2178 
2179 send_done:
2180         nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2181                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2182         if (!nlh) {
2183                 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2184                 if (err)
2185                         return err;
2186                 goto send_done;
2187         }
2188         return genlmsg_reply(dump_ctx.skb, info);
2189 }
2190 
2191 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2192                                             struct genl_info *info)
2193 {
2194         struct devlink *devlink = info->user_ptr[0];
2195         struct devlink_dpipe_table *table;
2196         const char *table_name;
2197 
2198         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2199                 return -EINVAL;
2200 
2201         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2202         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2203                                          table_name);
2204         if (!table)
2205                 return -EINVAL;
2206 
2207         if (!table->table_ops->entries_dump)
2208                 return -EINVAL;
2209 
2210         return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2211                                           0, table);
2212 }
2213 
2214 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2215                                     const struct devlink_dpipe_header *header)
2216 {
2217         struct devlink_dpipe_field *field;
2218         struct nlattr *field_attr;
2219         int i;
2220 
2221         for (i = 0; i < header->fields_count; i++) {
2222                 field = &header->fields[i];
2223                 field_attr = nla_nest_start_noflag(skb,
2224                                                    DEVLINK_ATTR_DPIPE_FIELD);
2225                 if (!field_attr)
2226                         return -EMSGSIZE;
2227                 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2228                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2229                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2230                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2231                         goto nla_put_failure;
2232                 nla_nest_end(skb, field_attr);
2233         }
2234         return 0;
2235 
2236 nla_put_failure:
2237         nla_nest_cancel(skb, field_attr);
2238         return -EMSGSIZE;
2239 }
2240 
2241 static int devlink_dpipe_header_put(struct sk_buff *skb,
2242                                     struct devlink_dpipe_header *header)
2243 {
2244         struct nlattr *fields_attr, *header_attr;
2245         int err;
2246 
2247         header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
2248         if (!header_attr)
2249                 return -EMSGSIZE;
2250 
2251         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2252             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2253             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2254                 goto nla_put_failure;
2255 
2256         fields_attr = nla_nest_start_noflag(skb,
2257                                             DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2258         if (!fields_attr)
2259                 goto nla_put_failure;
2260 
2261         err = devlink_dpipe_fields_put(skb, header);
2262         if (err) {
2263                 nla_nest_cancel(skb, fields_attr);
2264                 goto nla_put_failure;
2265         }
2266         nla_nest_end(skb, fields_attr);
2267         nla_nest_end(skb, header_attr);
2268         return 0;
2269 
2270 nla_put_failure:
2271         err = -EMSGSIZE;
2272         nla_nest_cancel(skb, header_attr);
2273         return err;
2274 }
2275 
2276 static int devlink_dpipe_headers_fill(struct genl_info *info,
2277                                       enum devlink_command cmd, int flags,
2278                                       struct devlink_dpipe_headers *
2279                                       dpipe_headers)
2280 {
2281         struct devlink *devlink = info->user_ptr[0];
2282         struct nlattr *headers_attr;
2283         struct sk_buff *skb = NULL;
2284         struct nlmsghdr *nlh;
2285         void *hdr;
2286         int i, j;
2287         int err;
2288 
2289         i = 0;
2290 start_again:
2291         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2292         if (err)
2293                 return err;
2294 
2295         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2296                           &devlink_nl_family, NLM_F_MULTI, cmd);
2297         if (!hdr) {
2298                 nlmsg_free(skb);
2299                 return -EMSGSIZE;
2300         }
2301 
2302         if (devlink_nl_put_handle(skb, devlink))
2303                 goto nla_put_failure;
2304         headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2305         if (!headers_attr)
2306                 goto nla_put_failure;
2307 
2308         j = 0;
2309         for (; i < dpipe_headers->headers_count; i++) {
2310                 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2311                 if (err) {
2312                         if (!j)
2313                                 goto err_table_put;
2314                         break;
2315                 }
2316                 j++;
2317         }
2318         nla_nest_end(skb, headers_attr);
2319         genlmsg_end(skb, hdr);
2320         if (i != dpipe_headers->headers_count)
2321                 goto start_again;
2322 
2323 send_done:
2324         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2325                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2326         if (!nlh) {
2327                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2328                 if (err)
2329                         return err;
2330                 goto send_done;
2331         }
2332         return genlmsg_reply(skb, info);
2333 
2334 nla_put_failure:
2335         err = -EMSGSIZE;
2336 err_table_put:
2337         nlmsg_free(skb);
2338         return err;
2339 }
2340 
2341 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2342                                             struct genl_info *info)
2343 {
2344         struct devlink *devlink = info->user_ptr[0];
2345 
2346         if (!devlink->dpipe_headers)
2347                 return -EOPNOTSUPP;
2348         return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2349                                           0, devlink->dpipe_headers);
2350 }
2351 
2352 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2353                                             const char *table_name,
2354                                             bool enable)
2355 {
2356         struct devlink_dpipe_table *table;
2357 
2358         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2359                                          table_name);
2360         if (!table)
2361                 return -EINVAL;
2362 
2363         if (table->counter_control_extern)
2364                 return -EOPNOTSUPP;
2365 
2366         if (!(table->counters_enabled ^ enable))
2367                 return 0;
2368 
2369         table->counters_enabled = enable;
2370         if (table->table_ops->counters_set_update)
2371                 table->table_ops->counters_set_update(table->priv, enable);
2372         return 0;
2373 }
2374 
2375 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2376                                                    struct genl_info *info)
2377 {
2378         struct devlink *devlink = info->user_ptr[0];
2379         const char *table_name;
2380         bool counters_enable;
2381 
2382         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2383             !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2384                 return -EINVAL;
2385 
2386         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2387         counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2388 
2389         return devlink_dpipe_table_counters_set(devlink, table_name,
2390                                                 counters_enable);
2391 }
2392 
2393 static struct devlink_resource *
2394 devlink_resource_find(struct devlink *devlink,
2395                       struct devlink_resource *resource, u64 resource_id)
2396 {
2397         struct list_head *resource_list;
2398 
2399         if (resource)
2400                 resource_list = &resource->resource_list;
2401         else
2402                 resource_list = &devlink->resource_list;
2403 
2404         list_for_each_entry(resource, resource_list, list) {
2405                 struct devlink_resource *child_resource;
2406 
2407                 if (resource->id == resource_id)
2408                         return resource;
2409 
2410                 child_resource = devlink_resource_find(devlink, resource,
2411                                                        resource_id);
2412                 if (child_resource)
2413                         return child_resource;
2414         }
2415         return NULL;
2416 }
2417 
2418 static void
2419 devlink_resource_validate_children(struct devlink_resource *resource)
2420 {
2421         struct devlink_resource *child_resource;
2422         bool size_valid = true;
2423         u64 parts_size = 0;
2424 
2425         if (list_empty(&resource->resource_list))
2426                 goto out;
2427 
2428         list_for_each_entry(child_resource, &resource->resource_list, list)
2429                 parts_size += child_resource->size_new;
2430 
2431         if (parts_size > resource->size_new)
2432                 size_valid = false;
2433 out:
2434         resource->size_valid = size_valid;
2435 }
2436 
2437 static int
2438 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2439                                struct netlink_ext_ack *extack)
2440 {
2441         u64 reminder;
2442         int err = 0;
2443 
2444         if (size > resource->size_params.size_max) {
2445                 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2446                 err = -EINVAL;
2447         }
2448 
2449         if (size < resource->size_params.size_min) {
2450                 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2451                 err = -EINVAL;
2452         }
2453 
2454         div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2455         if (reminder) {
2456                 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2457                 err = -EINVAL;
2458         }
2459 
2460         return err;
2461 }
2462 
2463 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2464                                        struct genl_info *info)
2465 {
2466         struct devlink *devlink = info->user_ptr[0];
2467         struct devlink_resource *resource;
2468         u64 resource_id;
2469         u64 size;
2470         int err;
2471 
2472         if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2473             !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2474                 return -EINVAL;
2475         resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2476 
2477         resource = devlink_resource_find(devlink, NULL, resource_id);
2478         if (!resource)
2479                 return -EINVAL;
2480 
2481         size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2482         err = devlink_resource_validate_size(resource, size, info->extack);
2483         if (err)
2484                 return err;
2485 
2486         resource->size_new = size;
2487         devlink_resource_validate_children(resource);
2488         if (resource->parent)
2489                 devlink_resource_validate_children(resource->parent);
2490         return 0;
2491 }
2492 
2493 static int
2494 devlink_resource_size_params_put(struct devlink_resource *resource,
2495                                  struct sk_buff *skb)
2496 {
2497         struct devlink_resource_size_params *size_params;
2498 
2499         size_params = &resource->size_params;
2500         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2501                               size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2502             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2503                               size_params->size_max, DEVLINK_ATTR_PAD) ||
2504             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2505                               size_params->size_min, DEVLINK_ATTR_PAD) ||
2506             nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2507                 return -EMSGSIZE;
2508         return 0;
2509 }
2510 
2511 static int devlink_resource_occ_put(struct devlink_resource *resource,
2512                                     struct sk_buff *skb)
2513 {
2514         if (!resource->occ_get)
2515                 return 0;
2516         return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2517                                  resource->occ_get(resource->occ_get_priv),
2518                                  DEVLINK_ATTR_PAD);
2519 }
2520 
2521 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2522                                 struct devlink_resource *resource)
2523 {
2524         struct devlink_resource *child_resource;
2525         struct nlattr *child_resource_attr;
2526         struct nlattr *resource_attr;
2527 
2528         resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
2529         if (!resource_attr)
2530                 return -EMSGSIZE;
2531 
2532         if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2533             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2534                               DEVLINK_ATTR_PAD) ||
2535             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2536                               DEVLINK_ATTR_PAD))
2537                 goto nla_put_failure;
2538         if (resource->size != resource->size_new)
2539                 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2540                                   resource->size_new, DEVLINK_ATTR_PAD);
2541         if (devlink_resource_occ_put(resource, skb))
2542                 goto nla_put_failure;
2543         if (devlink_resource_size_params_put(resource, skb))
2544                 goto nla_put_failure;
2545         if (list_empty(&resource->resource_list))
2546                 goto out;
2547 
2548         if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2549                        resource->size_valid))
2550                 goto nla_put_failure;
2551 
2552         child_resource_attr = nla_nest_start_noflag(skb,
2553                                                     DEVLINK_ATTR_RESOURCE_LIST);
2554         if (!child_resource_attr)
2555                 goto nla_put_failure;
2556 
2557         list_for_each_entry(child_resource, &resource->resource_list, list) {
2558                 if (devlink_resource_put(devlink, skb, child_resource))
2559                         goto resource_put_failure;
2560         }
2561 
2562         nla_nest_end(skb, child_resource_attr);
2563 out:
2564         nla_nest_end(skb, resource_attr);
2565         return 0;
2566 
2567 resource_put_failure:
2568         nla_nest_cancel(skb, child_resource_attr);
2569 nla_put_failure:
2570         nla_nest_cancel(skb, resource_attr);
2571         return -EMSGSIZE;
2572 }
2573 
2574 static int devlink_resource_fill(struct genl_info *info,
2575                                  enum devlink_command cmd, int flags)
2576 {
2577         struct devlink *devlink = info->user_ptr[0];
2578         struct devlink_resource *resource;
2579         struct nlattr *resources_attr;
2580         struct sk_buff *skb = NULL;
2581         struct nlmsghdr *nlh;
2582         bool incomplete;
2583         void *hdr;
2584         int i;
2585         int err;
2586 
2587         resource = list_first_entry(&devlink->resource_list,
2588                                     struct devlink_resource, list);
2589 start_again:
2590         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2591         if (err)
2592                 return err;
2593 
2594         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2595                           &devlink_nl_family, NLM_F_MULTI, cmd);
2596         if (!hdr) {
2597                 nlmsg_free(skb);
2598                 return -EMSGSIZE;
2599         }
2600 
2601         if (devlink_nl_put_handle(skb, devlink))
2602                 goto nla_put_failure;
2603 
2604         resources_attr = nla_nest_start_noflag(skb,
2605                                                DEVLINK_ATTR_RESOURCE_LIST);
2606         if (!resources_attr)
2607                 goto nla_put_failure;
2608 
2609         incomplete = false;
2610         i = 0;
2611         list_for_each_entry_from(resource, &devlink->resource_list, list) {
2612                 err = devlink_resource_put(devlink, skb, resource);
2613                 if (err) {
2614                         if (!i)
2615                                 goto err_resource_put;
2616                         incomplete = true;
2617                         break;
2618                 }
2619                 i++;
2620         }
2621         nla_nest_end(skb, resources_attr);
2622         genlmsg_end(skb, hdr);
2623         if (incomplete)
2624                 goto start_again;
2625 send_done:
2626         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2627                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2628         if (!nlh) {
2629                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2630                 if (err)
2631                         return err;
2632                 goto send_done;
2633         }
2634         return genlmsg_reply(skb, info);
2635 
2636 nla_put_failure:
2637         err = -EMSGSIZE;
2638 err_resource_put:
2639         nlmsg_free(skb);
2640         return err;
2641 }
2642 
2643 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2644                                         struct genl_info *info)
2645 {
2646         struct devlink *devlink = info->user_ptr[0];
2647 
2648         if (list_empty(&devlink->resource_list))
2649                 return -EOPNOTSUPP;
2650 
2651         return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2652 }
2653 
2654 static int
2655 devlink_resources_validate(struct devlink *devlink,
2656                            struct devlink_resource *resource,
2657                            struct genl_info *info)
2658 {
2659         struct list_head *resource_list;
2660         int err = 0;
2661 
2662         if (resource)
2663                 resource_list = &resource->resource_list;
2664         else
2665                 resource_list = &devlink->resource_list;
2666 
2667         list_for_each_entry(resource, resource_list, list) {
2668                 if (!resource->size_valid)
2669                         return -EINVAL;
2670                 err = devlink_resources_validate(devlink, resource, info);
2671                 if (err)
2672                         return err;
2673         }
2674         return err;
2675 }
2676 
2677 static bool devlink_reload_supported(struct devlink *devlink)
2678 {
2679         return devlink->ops->reload_down && devlink->ops->reload_up;
2680 }
2681 
2682 static void devlink_reload_failed_set(struct devlink *devlink,
2683                                       bool reload_failed)
2684 {
2685         if (devlink->reload_failed == reload_failed)
2686                 return;
2687         devlink->reload_failed = reload_failed;
2688         devlink_notify(devlink, DEVLINK_CMD_NEW);
2689 }
2690 
2691 bool devlink_is_reload_failed(const struct devlink *devlink)
2692 {
2693         return devlink->reload_failed;
2694 }
2695 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
2696 
2697 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2698 {
2699         struct devlink *devlink = info->user_ptr[0];
2700         int err;
2701 
2702         if (!devlink_reload_supported(devlink) || !devlink->reload_enabled)
2703                 return -EOPNOTSUPP;
2704 
2705         err = devlink_resources_validate(devlink, NULL, info);
2706         if (err) {
2707                 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2708                 return err;
2709         }
2710         err = devlink->ops->reload_down(devlink, info->extack);
2711         if (err)
2712                 return err;
2713         err = devlink->ops->reload_up(devlink, info->extack);
2714         devlink_reload_failed_set(devlink, !!err);
2715         return err;
2716 }
2717 
2718 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
2719                                         struct devlink *devlink,
2720                                         enum devlink_command cmd,
2721                                         const char *status_msg,
2722                                         const char *component,
2723                                         unsigned long done, unsigned long total)
2724 {
2725         void *hdr;
2726 
2727         hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
2728         if (!hdr)
2729                 return -EMSGSIZE;
2730 
2731         if (devlink_nl_put_handle(msg, devlink))
2732                 goto nla_put_failure;
2733 
2734         if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
2735                 goto out;
2736 
2737         if (status_msg &&
2738             nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
2739                            status_msg))
2740                 goto nla_put_failure;
2741         if (component &&
2742             nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
2743                            component))
2744                 goto nla_put_failure;
2745         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
2746                               done, DEVLINK_ATTR_PAD))
2747                 goto nla_put_failure;
2748         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
2749                               total, DEVLINK_ATTR_PAD))
2750                 goto nla_put_failure;
2751 
2752 out:
2753         genlmsg_end(msg, hdr);
2754         return 0;
2755 
2756 nla_put_failure:
2757         genlmsg_cancel(msg, hdr);
2758         return -EMSGSIZE;
2759 }
2760 
2761 static void __devlink_flash_update_notify(struct devlink *devlink,
2762                                           enum devlink_command cmd,
2763                                           const char *status_msg,
2764                                           const char *component,
2765                                           unsigned long done,
2766                                           unsigned long total)
2767 {
2768         struct sk_buff *msg;
2769         int err;
2770 
2771         WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
2772                 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
2773                 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
2774 
2775         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2776         if (!msg)
2777                 return;
2778 
2779         err = devlink_nl_flash_update_fill(msg, devlink, cmd, status_msg,
2780                                            component, done, total);
2781         if (err)
2782                 goto out_free_msg;
2783 
2784         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2785                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2786         return;
2787 
2788 out_free_msg:
2789         nlmsg_free(msg);
2790 }
2791 
2792 void devlink_flash_update_begin_notify(struct devlink *devlink)
2793 {
2794         __devlink_flash_update_notify(devlink,
2795                                       DEVLINK_CMD_FLASH_UPDATE,
2796                                       NULL, NULL, 0, 0);
2797 }
2798 EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify);
2799 
2800 void devlink_flash_update_end_notify(struct devlink *devlink)
2801 {
2802         __devlink_flash_update_notify(devlink,
2803                                       DEVLINK_CMD_FLASH_UPDATE_END,
2804                                       NULL, NULL, 0, 0);
2805 }
2806 EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify);
2807 
2808 void devlink_flash_update_status_notify(struct devlink *devlink,
2809                                         const char *status_msg,
2810                                         const char *component,
2811                                         unsigned long done,
2812                                         unsigned long total)
2813 {
2814         __devlink_flash_update_notify(devlink,
2815                                       DEVLINK_CMD_FLASH_UPDATE_STATUS,
2816                                       status_msg, component, done, total);
2817 }
2818 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
2819 
2820 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
2821                                        struct genl_info *info)
2822 {
2823         struct devlink *devlink = info->user_ptr[0];
2824         const char *file_name, *component;
2825         struct nlattr *nla_component;
2826 
2827         if (!devlink->ops->flash_update)
2828                 return -EOPNOTSUPP;
2829 
2830         if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
2831                 return -EINVAL;
2832         file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
2833 
2834         nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
2835         component = nla_component ? nla_data(nla_component) : NULL;
2836 
2837         return devlink->ops->flash_update(devlink, file_name, component,
2838                                           info->extack);
2839 }
2840 
2841 static const struct devlink_param devlink_param_generic[] = {
2842         {
2843                 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
2844                 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
2845                 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
2846         },
2847         {
2848                 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
2849                 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
2850                 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
2851         },
2852         {
2853                 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
2854                 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
2855                 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
2856         },
2857         {
2858                 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
2859                 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
2860                 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
2861         },
2862         {
2863                 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
2864                 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
2865                 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
2866         },
2867         {
2868                 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
2869                 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
2870                 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
2871         },
2872         {
2873                 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
2874                 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
2875                 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
2876         },
2877         {
2878                 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
2879                 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
2880                 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
2881         },
2882         {
2883                 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
2884                 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
2885                 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
2886         },
2887 };
2888 
2889 static int devlink_param_generic_verify(const struct devlink_param *param)
2890 {
2891         /* verify it match generic parameter by id and name */
2892         if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
2893                 return -EINVAL;
2894         if (strcmp(param->name, devlink_param_generic[param->id].name))
2895                 return -ENOENT;
2896 
2897         WARN_ON(param->type != devlink_param_generic[param->id].type);
2898 
2899         return 0;
2900 }
2901 
2902 static int devlink_param_driver_verify(const struct devlink_param *param)
2903 {
2904         int i;
2905 
2906         if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
2907                 return -EINVAL;
2908         /* verify no such name in generic params */
2909         for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
2910                 if (!strcmp(param->name, devlink_param_generic[i].name))
2911                         return -EEXIST;
2912 
2913         return 0;
2914 }
2915 
2916 static struct devlink_param_item *
2917 devlink_param_find_by_name(struct list_head *param_list,
2918                            const char *param_name)
2919 {
2920         struct devlink_param_item *param_item;
2921 
2922         list_for_each_entry(param_item, param_list, list)
2923                 if (!strcmp(param_item->param->name, param_name))
2924                         return param_item;
2925         return NULL;
2926 }
2927 
2928 static struct devlink_param_item *
2929 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
2930 {
2931         struct devlink_param_item *param_item;
2932 
2933         list_for_each_entry(param_item, param_list, list)
2934                 if (param_item->param->id == param_id)
2935                         return param_item;
2936         return NULL;
2937 }
2938 
2939 static bool
2940 devlink_param_cmode_is_supported(const struct devlink_param *param,
2941                                  enum devlink_param_cmode cmode)
2942 {
2943         return test_bit(cmode, &param->supported_cmodes);
2944 }
2945 
2946 static int devlink_param_get(struct devlink *devlink,
2947                              const struct devlink_param *param,
2948                              struct devlink_param_gset_ctx *ctx)
2949 {
2950         if (!param->get)
2951                 return -EOPNOTSUPP;
2952         return param->get(devlink, param->id, ctx);
2953 }
2954 
2955 static int devlink_param_set(struct devlink *devlink,
2956                              const struct devlink_param *param,
2957                              struct devlink_param_gset_ctx *ctx)
2958 {
2959         if (!param->set)
2960                 return -EOPNOTSUPP;
2961         return param->set(devlink, param->id, ctx);
2962 }
2963 
2964 static int
2965 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
2966 {
2967         switch (param_type) {
2968         case DEVLINK_PARAM_TYPE_U8:
2969                 return NLA_U8;
2970         case DEVLINK_PARAM_TYPE_U16:
2971                 return NLA_U16;
2972         case DEVLINK_PARAM_TYPE_U32:
2973                 return NLA_U32;
2974         case DEVLINK_PARAM_TYPE_STRING:
2975                 return NLA_STRING;
2976         case DEVLINK_PARAM_TYPE_BOOL:
2977                 return NLA_FLAG;
2978         default:
2979                 return -EINVAL;
2980         }
2981 }
2982 
2983 static int
2984 devlink_nl_param_value_fill_one(struct sk_buff *msg,
2985                                 enum devlink_param_type type,
2986                                 enum devlink_param_cmode cmode,
2987                                 union devlink_param_value val)
2988 {
2989         struct nlattr *param_value_attr;
2990 
2991         param_value_attr = nla_nest_start_noflag(msg,
2992                                                  DEVLINK_ATTR_PARAM_VALUE);
2993         if (!param_value_attr)
2994                 goto nla_put_failure;
2995 
2996         if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
2997                 goto value_nest_cancel;
2998 
2999         switch (type) {
3000         case DEVLINK_PARAM_TYPE_U8:
3001                 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
3002                         goto value_nest_cancel;
3003                 break;
3004         case DEVLINK_PARAM_TYPE_U16:
3005                 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
3006                         goto value_nest_cancel;
3007                 break;
3008         case DEVLINK_PARAM_TYPE_U32:
3009                 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
3010                         goto value_nest_cancel;
3011                 break;
3012         case DEVLINK_PARAM_TYPE_STRING:
3013                 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
3014                                    val.vstr))
3015                         goto value_nest_cancel;
3016                 break;
3017         case DEVLINK_PARAM_TYPE_BOOL:
3018                 if (val.vbool &&
3019                     nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
3020                         goto value_nest_cancel;
3021                 break;
3022         }
3023 
3024         nla_nest_end(msg, param_value_attr);
3025         return 0;
3026 
3027 value_nest_cancel:
3028         nla_nest_cancel(msg, param_value_attr);
3029 nla_put_failure:
3030         return -EMSGSIZE;
3031 }
3032 
3033 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
3034                                  unsigned int port_index,
3035                                  struct devlink_param_item *param_item,
3036                                  enum devlink_command cmd,
3037                                  u32 portid, u32 seq, int flags)
3038 {
3039         union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
3040         bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
3041         const struct devlink_param *param = param_item->param;
3042         struct devlink_param_gset_ctx ctx;
3043         struct nlattr *param_values_list;
3044         struct nlattr *param_attr;
3045         int nla_type;
3046         void *hdr;
3047         int err;
3048         int i;
3049 
3050         /* Get value from driver part to driverinit configuration mode */
3051         for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3052                 if (!devlink_param_cmode_is_supported(param, i))
3053                         continue;
3054                 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3055                         if (!param_item->driverinit_value_valid)
3056                                 return -EOPNOTSUPP;
3057                         param_value[i] = param_item->driverinit_value;
3058                 } else {
3059                         if (!param_item->published)
3060                                 continue;
3061                         ctx.cmode = i;
3062                         err = devlink_param_get(devlink, param, &ctx);
3063                         if (err)
3064                                 return err;
3065                         param_value[i] = ctx.val;
3066                 }
3067                 param_value_set[i] = true;
3068         }
3069 
3070         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3071         if (!hdr)
3072                 return -EMSGSIZE;
3073 
3074         if (devlink_nl_put_handle(msg, devlink))
3075                 goto genlmsg_cancel;
3076 
3077         if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
3078             cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
3079             cmd == DEVLINK_CMD_PORT_PARAM_DEL)
3080                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
3081                         goto genlmsg_cancel;
3082 
3083         param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
3084         if (!param_attr)
3085                 goto genlmsg_cancel;
3086         if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
3087                 goto param_nest_cancel;
3088         if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
3089                 goto param_nest_cancel;
3090 
3091         nla_type = devlink_param_type_to_nla_type(param->type);
3092         if (nla_type < 0)
3093                 goto param_nest_cancel;
3094         if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
3095                 goto param_nest_cancel;
3096 
3097         param_values_list = nla_nest_start_noflag(msg,
3098                                                   DEVLINK_ATTR_PARAM_VALUES_LIST);
3099         if (!param_values_list)
3100                 goto param_nest_cancel;
3101 
3102         for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
3103                 if (!param_value_set[i])
3104                         continue;
3105                 err = devlink_nl_param_value_fill_one(msg, param->type,
3106                                                       i, param_value[i]);
3107                 if (err)
3108                         goto values_list_nest_cancel;
3109         }
3110 
3111         nla_nest_end(msg, param_values_list);
3112         nla_nest_end(msg, param_attr);
3113         genlmsg_end(msg, hdr);
3114         return 0;
3115 
3116 values_list_nest_cancel:
3117         nla_nest_end(msg, param_values_list);
3118 param_nest_cancel:
3119         nla_nest_cancel(msg, param_attr);
3120 genlmsg_cancel:
3121         genlmsg_cancel(msg, hdr);
3122         return -EMSGSIZE;
3123 }
3124 
3125 static void devlink_param_notify(struct devlink *devlink,
3126                                  unsigned int port_index,
3127                                  struct devlink_param_item *param_item,
3128                                  enum devlink_command cmd)
3129 {
3130         struct sk_buff *msg;
3131         int err;
3132 
3133         WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
3134                 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
3135                 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
3136 
3137         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3138         if (!msg)
3139                 return;
3140         err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
3141                                     0, 0, 0);
3142         if (err) {
3143                 nlmsg_free(msg);
3144                 return;
3145         }
3146 
3147         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3148                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3149 }
3150 
3151 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
3152                                            struct netlink_callback *cb)
3153 {
3154         struct devlink_param_item *param_item;
3155         struct devlink *devlink;
3156         int start = cb->args[0];
3157         int idx = 0;
3158         int err;
3159 
3160         mutex_lock(&devlink_mutex);
3161         list_for_each_entry(devlink, &devlink_list, list) {
3162                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3163                         continue;
3164                 mutex_lock(&devlink->lock);
3165                 list_for_each_entry(param_item, &devlink->param_list, list) {
3166                         if (idx < start) {
3167                                 idx++;
3168                                 continue;
3169                         }
3170                         err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3171                                                     DEVLINK_CMD_PARAM_GET,
3172                                                     NETLINK_CB(cb->skb).portid,
3173                                                     cb->nlh->nlmsg_seq,
3174                                                     NLM_F_MULTI);
3175                         if (err && err != -EOPNOTSUPP) {
3176                                 mutex_unlock(&devlink->lock);
3177                                 goto out;
3178                         }
3179                         idx++;
3180                 }
3181                 mutex_unlock(&devlink->lock);
3182         }
3183 out:
3184         mutex_unlock(&devlink_mutex);
3185 
3186         cb->args[0] = idx;
3187         return msg->len;
3188 }
3189 
3190 static int
3191 devlink_param_type_get_from_info(struct genl_info *info,
3192                                  enum devlink_param_type *param_type)
3193 {
3194         if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
3195                 return -EINVAL;
3196 
3197         switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
3198         case NLA_U8:
3199                 *param_type = DEVLINK_PARAM_TYPE_U8;
3200                 break;
3201         case NLA_U16:
3202                 *param_type = DEVLINK_PARAM_TYPE_U16;
3203                 break;
3204         case NLA_U32:
3205                 *param_type = DEVLINK_PARAM_TYPE_U32;
3206                 break;
3207         case NLA_STRING:
3208                 *param_type = DEVLINK_PARAM_TYPE_STRING;
3209                 break;
3210         case NLA_FLAG:
3211                 *param_type = DEVLINK_PARAM_TYPE_BOOL;
3212                 break;
3213         default:
3214                 return -EINVAL;
3215         }
3216 
3217         return 0;
3218 }
3219 
3220 static int
3221 devlink_param_value_get_from_info(const struct devlink_param *param,
3222                                   struct genl_info *info,
3223                                   union devlink_param_value *value)
3224 {
3225         struct nlattr *param_data;
3226         int len;
3227 
3228         param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
3229 
3230         if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
3231                 return -EINVAL;
3232 
3233         switch (param->type) {
3234         case DEVLINK_PARAM_TYPE_U8:
3235                 if (nla_len(param_data) != sizeof(u8))
3236                         return -EINVAL;
3237                 value->vu8 = nla_get_u8(param_data);
3238                 break;
3239         case DEVLINK_PARAM_TYPE_U16:
3240                 if (nla_len(param_data) != sizeof(u16))
3241                         return -EINVAL;
3242                 value->vu16 = nla_get_u16(param_data);
3243                 break;
3244         case DEVLINK_PARAM_TYPE_U32:
3245                 if (nla_len(param_data) != sizeof(u32))
3246                         return -EINVAL;
3247                 value->vu32 = nla_get_u32(param_data);
3248                 break;
3249         case DEVLINK_PARAM_TYPE_STRING:
3250                 len = strnlen(nla_data(param_data), nla_len(param_data));
3251                 if (len == nla_len(param_data) ||
3252                     len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3253                         return -EINVAL;
3254                 strcpy(value->vstr, nla_data(param_data));
3255                 break;
3256         case DEVLINK_PARAM_TYPE_BOOL:
3257                 if (param_data && nla_len(param_data))
3258                         return -EINVAL;
3259                 value->vbool = nla_get_flag(param_data);
3260                 break;
3261         }
3262         return 0;
3263 }
3264 
3265 static struct devlink_param_item *
3266 devlink_param_get_from_info(struct list_head *param_list,
3267                             struct genl_info *info)
3268 {
3269         char *param_name;
3270 
3271         if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
3272                 return NULL;
3273 
3274         param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
3275         return devlink_param_find_by_name(param_list, param_name);
3276 }
3277 
3278 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
3279                                          struct genl_info *info)
3280 {
3281         struct devlink *devlink = info->user_ptr[0];
3282         struct devlink_param_item *param_item;
3283         struct sk_buff *msg;
3284         int err;
3285 
3286         param_item = devlink_param_get_from_info(&devlink->param_list, info);
3287         if (!param_item)
3288                 return -EINVAL;
3289 
3290         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3291         if (!msg)
3292                 return -ENOMEM;
3293 
3294         err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3295                                     DEVLINK_CMD_PARAM_GET,
3296                                     info->snd_portid, info->snd_seq, 0);
3297         if (err) {
3298                 nlmsg_free(msg);
3299                 return err;
3300         }
3301 
3302         return genlmsg_reply(msg, info);
3303 }
3304 
3305 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
3306                                            unsigned int port_index,
3307                                            struct list_head *param_list,
3308                                            struct genl_info *info,
3309                                            enum devlink_command cmd)
3310 {
3311         enum devlink_param_type param_type;
3312         struct devlink_param_gset_ctx ctx;
3313         enum devlink_param_cmode cmode;
3314         struct devlink_param_item *param_item;
3315         const struct devlink_param *param;
3316         union devlink_param_value value;
3317         int err = 0;
3318 
3319         param_item = devlink_param_get_from_info(param_list, info);
3320         if (!param_item)
3321                 return -EINVAL;
3322         param = param_item->param;
3323         err = devlink_param_type_get_from_info(info, &param_type);
3324         if (err)
3325                 return err;
3326         if (param_type != param->type)
3327                 return -EINVAL;
3328         err = devlink_param_value_get_from_info(param, info, &value);
3329         if (err)
3330                 return err;
3331         if (param->validate) {
3332                 err = param->validate(devlink, param->id, value, info->extack);
3333                 if (err)
3334                         return err;
3335         }
3336 
3337         if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
3338                 return -EINVAL;
3339         cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
3340         if (!devlink_param_cmode_is_supported(param, cmode))
3341                 return -EOPNOTSUPP;
3342 
3343         if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3344                 if (param->type == DEVLINK_PARAM_TYPE_STRING)
3345                         strcpy(param_item->driverinit_value.vstr, value.vstr);
3346                 else
3347                         param_item->driverinit_value = value;
3348                 param_item->driverinit_value_valid = true;
3349         } else {
3350                 if (!param->set)
3351                         return -EOPNOTSUPP;
3352                 ctx.val = value;
3353                 ctx.cmode = cmode;
3354                 err = devlink_param_set(devlink, param, &ctx);
3355                 if (err)
3356                         return err;
3357         }
3358 
3359         devlink_param_notify(devlink, port_index, param_item, cmd);
3360         return 0;
3361 }
3362 
3363 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
3364                                          struct genl_info *info)
3365 {
3366         struct devlink *devlink = info->user_ptr[0];
3367 
3368         return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
3369                                                info, DEVLINK_CMD_PARAM_NEW);
3370 }
3371 
3372 static int devlink_param_register_one(struct devlink *devlink,
3373                                       unsigned int port_index,
3374                                       struct list_head *param_list,
3375                                       const struct devlink_param *param,
3376                                       enum devlink_command cmd)
3377 {
3378         struct devlink_param_item *param_item;
3379 
3380         if (devlink_param_find_by_name(param_list, param->name))
3381                 return -EEXIST;
3382 
3383         if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
3384                 WARN_ON(param->get || param->set);
3385         else
3386                 WARN_ON(!param->get || !param->set);
3387 
3388         param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
3389         if (!param_item)
3390                 return -ENOMEM;
3391         param_item->param = param;
3392 
3393         list_add_tail(&param_item->list, param_list);
3394         devlink_param_notify(devlink, port_index, param_item, cmd);
3395         return 0;
3396 }
3397 
3398 static void devlink_param_unregister_one(struct devlink *devlink,
3399                                          unsigned int port_index,
3400                                          struct list_head *param_list,
3401                                          const struct devlink_param *param,
3402                                          enum devlink_command cmd)
3403 {
3404         struct devlink_param_item *param_item;
3405 
3406         param_item = devlink_param_find_by_name(param_list, param->name);
3407         WARN_ON(!param_item);
3408         devlink_param_notify(devlink, port_index, param_item, cmd);
3409         list_del(&param_item->list);
3410         kfree(param_item);
3411 }
3412 
3413 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
3414                                                 struct netlink_callback *cb)
3415 {
3416         struct devlink_param_item *param_item;
3417         struct devlink_port *devlink_port;
3418         struct devlink *devlink;
3419         int start = cb->args[0];
3420         int idx = 0;
3421         int err;
3422 
3423         mutex_lock(&devlink_mutex);
3424         list_for_each_entry(devlink, &devlink_list, list) {
3425                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3426                         continue;
3427                 mutex_lock(&devlink->lock);
3428                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3429                         list_for_each_entry(param_item,
3430                                             &devlink_port->param_list, list) {
3431                                 if (idx < start) {
3432                                         idx++;
3433                                         continue;
3434                                 }
3435                                 err = devlink_nl_param_fill(msg,
3436                                                 devlink_port->devlink,
3437                                                 devlink_port->index, param_item,
3438                                                 DEVLINK_CMD_PORT_PARAM_GET,
3439                                                 NETLINK_CB(cb->skb).portid,
3440                                                 cb->nlh->nlmsg_seq,
3441                                                 NLM_F_MULTI);
3442                                 if (err && err != -EOPNOTSUPP) {
3443                                         mutex_unlock(&devlink->lock);
3444                                         goto out;
3445                                 }
3446                                 idx++;
3447                         }
3448                 }
3449                 mutex_unlock(&devlink->lock);
3450         }
3451 out:
3452         mutex_unlock(&devlink_mutex);
3453 
3454         cb->args[0] = idx;
3455         return msg->len;
3456 }
3457 
3458 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
3459                                               struct genl_info *info)
3460 {
3461         struct devlink_port *devlink_port = info->user_ptr[0];
3462         struct devlink_param_item *param_item;
3463         struct sk_buff *msg;
3464         int err;
3465 
3466         param_item = devlink_param_get_from_info(&devlink_port->param_list,
3467                                                  info);
3468         if (!param_item)
3469                 return -EINVAL;
3470 
3471         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3472         if (!msg)
3473                 return -ENOMEM;
3474 
3475         err = devlink_nl_param_fill(msg, devlink_port->devlink,
3476                                     devlink_port->index, param_item,
3477                                     DEVLINK_CMD_PORT_PARAM_GET,
3478                                     info->snd_portid, info->snd_seq, 0);
3479         if (err) {
3480                 nlmsg_free(msg);
3481                 return err;
3482         }
3483 
3484         return genlmsg_reply(msg, info);
3485 }
3486 
3487 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
3488                                               struct genl_info *info)
3489 {
3490         struct devlink_port *devlink_port = info->user_ptr[0];
3491 
3492         return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
3493                                                devlink_port->index,
3494                                                &devlink_port->param_list, info,
3495                                                DEVLINK_CMD_PORT_PARAM_NEW);
3496 }
3497 
3498 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
3499                                              struct devlink *devlink,
3500                                              struct devlink_snapshot *snapshot)
3501 {
3502         struct nlattr *snap_attr;
3503         int err;
3504 
3505         snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
3506         if (!snap_attr)
3507                 return -EINVAL;
3508 
3509         err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
3510         if (err)
3511                 goto nla_put_failure;
3512 
3513         nla_nest_end(msg, snap_attr);
3514         return 0;
3515 
3516 nla_put_failure:
3517         nla_nest_cancel(msg, snap_attr);
3518         return err;
3519 }
3520 
3521 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
3522                                               struct devlink *devlink,
3523                                               struct devlink_region *region)
3524 {
3525         struct devlink_snapshot *snapshot;
3526         struct nlattr *snapshots_attr;
3527         int err;
3528 
3529         snapshots_attr = nla_nest_start_noflag(msg,
3530                                                DEVLINK_ATTR_REGION_SNAPSHOTS);
3531         if (!snapshots_attr)
3532                 return -EINVAL;
3533 
3534         list_for_each_entry(snapshot, &region->snapshot_list, list) {
3535                 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
3536                 if (err)
3537                         goto nla_put_failure;
3538         }
3539 
3540         nla_nest_end(msg, snapshots_attr);
3541         return 0;
3542 
3543 nla_put_failure:
3544         nla_nest_cancel(msg, snapshots_attr);
3545         return err;
3546 }
3547 
3548 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3549                                   enum devlink_command cmd, u32 portid,
3550                                   u32 seq, int flags,
3551                                   struct devlink_region *region)
3552 {
3553         void *hdr;
3554         int err;
3555 
3556         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3557         if (!hdr)
3558                 return -EMSGSIZE;
3559 
3560         err = devlink_nl_put_handle(msg, devlink);
3561         if (err)
3562                 goto nla_put_failure;
3563 
3564         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->name);
3565         if (err)
3566                 goto nla_put_failure;
3567 
3568         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3569                                 region->size,
3570                                 DEVLINK_ATTR_PAD);
3571         if (err)
3572                 goto nla_put_failure;
3573 
3574         err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
3575         if (err)
3576                 goto nla_put_failure;
3577 
3578         genlmsg_end(msg, hdr);
3579         return 0;
3580 
3581 nla_put_failure:
3582         genlmsg_cancel(msg, hdr);
3583         return err;
3584 }
3585 
3586 static void devlink_nl_region_notify(struct devlink_region *region,
3587                                      struct devlink_snapshot *snapshot,
3588                                      enum devlink_command cmd)
3589 {
3590         struct devlink *devlink = region->devlink;
3591         struct sk_buff *msg;
3592         void *hdr;
3593         int err;
3594 
3595         WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3596 
3597         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3598         if (!msg)
3599                 return;
3600 
3601         hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3602         if (!hdr)
3603                 goto out_free_msg;
3604 
3605         err = devlink_nl_put_handle(msg, devlink);
3606         if (err)
3607                 goto out_cancel_msg;
3608 
3609         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
3610                              region->name);
3611         if (err)
3612                 goto out_cancel_msg;
3613 
3614         if (snapshot) {
3615                 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
3616                                   snapshot->id);
3617                 if (err)
3618                         goto out_cancel_msg;
3619         } else {
3620                 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3621                                         region->size, DEVLINK_ATTR_PAD);
3622                 if (err)
3623                         goto out_cancel_msg;
3624         }
3625         genlmsg_end(msg, hdr);
3626 
3627         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3628                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3629 
3630         return;
3631 
3632 out_cancel_msg:
3633         genlmsg_cancel(msg, hdr);
3634 out_free_msg:
3635         nlmsg_free(msg);
3636 }
3637 
3638 static void devlink_region_snapshot_del(struct devlink_region *region,
3639                                         struct devlink_snapshot *snapshot)
3640 {
3641         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
3642         region->cur_snapshots--;
3643         list_del(&snapshot->list);
3644         (*snapshot->data_destructor)(snapshot->data);
3645         kfree(snapshot);
3646 }
3647 
3648 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
3649                                           struct genl_info *info)
3650 {
3651         struct devlink *devlink = info->user_ptr[0];
3652         struct devlink_region *region;
3653         const char *region_name;
3654         struct sk_buff *msg;
3655         int err;
3656 
3657         if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
3658                 return -EINVAL;
3659 
3660         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3661         region = devlink_region_get_by_name(devlink, region_name);
3662         if (!region)
3663                 return -EINVAL;
3664 
3665         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3666         if (!msg)
3667                 return -ENOMEM;
3668 
3669         err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
3670                                      info->snd_portid, info->snd_seq, 0,
3671                                      region);
3672         if (err) {
3673                 nlmsg_free(msg);
3674                 return err;
3675         }
3676 
3677         return genlmsg_reply(msg, info);
3678 }
3679 
3680 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
3681                                             struct netlink_callback *cb)
3682 {
3683         struct devlink_region *region;
3684         struct devlink *devlink;
3685         int start = cb->args[0];
3686         int idx = 0;
3687         int err;
3688 
3689         mutex_lock(&devlink_mutex);
3690         list_for_each_entry(devlink, &devlink_list, list) {
3691                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3692                         continue;
3693 
3694                 mutex_lock(&devlink->lock);
3695                 list_for_each_entry(region, &devlink->region_list, list) {
3696                         if (idx < start) {
3697                                 idx++;
3698                                 continue;
3699                         }
3700                         err = devlink_nl_region_fill(msg, devlink,
3701                                                      DEVLINK_CMD_REGION_GET,
3702                                                      NETLINK_CB(cb->skb).portid,
3703                                                      cb->nlh->nlmsg_seq,
3704                                                      NLM_F_MULTI, region);
3705                         if (err) {
3706                                 mutex_unlock(&devlink->lock);
3707                                 goto out;
3708                         }
3709                         idx++;
3710                 }
3711                 mutex_unlock(&devlink->lock);
3712         }
3713 out:
3714         mutex_unlock(&devlink_mutex);
3715         cb->args[0] = idx;
3716         return msg->len;
3717 }
3718 
3719 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
3720                                      struct genl_info *info)
3721 {
3722         struct devlink *devlink = info->user_ptr[0];
3723         struct devlink_snapshot *snapshot;
3724         struct devlink_region *region;
3725         const char *region_name;
3726         u32 snapshot_id;
3727 
3728         if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
3729             !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
3730                 return -EINVAL;
3731 
3732         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3733         snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3734 
3735         region = devlink_region_get_by_name(devlink, region_name);
3736         if (!region)
3737                 return -EINVAL;
3738 
3739         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3740         if (!snapshot)
3741                 return -EINVAL;
3742 
3743         devlink_region_snapshot_del(region, snapshot);
3744         return 0;
3745 }
3746 
3747 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
3748                                                  struct devlink *devlink,
3749                                                  u8 *chunk, u32 chunk_size,
3750                                                  u64 addr)
3751 {
3752         struct nlattr *chunk_attr;
3753         int err;
3754 
3755         chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
3756         if (!chunk_attr)
3757                 return -EINVAL;
3758 
3759         err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
3760         if (err)
3761                 goto nla_put_failure;
3762 
3763         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
3764                                 DEVLINK_ATTR_PAD);
3765         if (err)
3766                 goto nla_put_failure;
3767 
3768         nla_nest_end(msg, chunk_attr);
3769         return 0;
3770 
3771 nla_put_failure:
3772         nla_nest_cancel(msg, chunk_attr);
3773         return err;
3774 }
3775 
3776 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
3777 
3778 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
3779                                                 struct devlink *devlink,
3780                                                 struct devlink_region *region,
3781                                                 struct nlattr **attrs,
3782                                                 u64 start_offset,
3783                                                 u64 end_offset,
3784                                                 bool dump,
3785                                                 u64 *new_offset)
3786 {
3787         struct devlink_snapshot *snapshot;
3788         u64 curr_offset = start_offset;
3789         u32 snapshot_id;
3790         int err = 0;
3791 
3792         *new_offset = start_offset;
3793 
3794         snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3795         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3796         if (!snapshot)
3797                 return -EINVAL;
3798 
3799         if (end_offset > region->size || dump)
3800                 end_offset = region->size;
3801 
3802         while (curr_offset < end_offset) {
3803                 u32 data_size;
3804                 u8 *data;
3805 
3806                 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
3807                         data_size = end_offset - curr_offset;
3808                 else
3809                         data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
3810 
3811                 data = &snapshot->data[curr_offset];
3812                 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
3813                                                             data, data_size,
3814                                                             curr_offset);
3815                 if (err)
3816                         break;
3817 
3818                 curr_offset += data_size;
3819         }
3820         *new_offset = curr_offset;
3821 
3822         return err;
3823 }
3824 
3825 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3826                                              struct netlink_callback *cb)
3827 {
3828         u64 ret_offset, start_offset, end_offset = 0;
3829         struct devlink_region *region;
3830         struct nlattr *chunks_attr;
3831         const char *region_name;
3832         struct devlink *devlink;
3833         struct nlattr **attrs;
3834         bool dump = true;
3835         void *hdr;
3836         int err;
3837 
3838         start_offset = *((u64 *)&cb->args[0]);
3839 
3840         attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
3841         if (!attrs)
3842                 return -ENOMEM;
3843 
3844         err = nlmsg_parse_deprecated(cb->nlh,
3845                                      GENL_HDRLEN + devlink_nl_family.hdrsize,
3846                                      attrs, DEVLINK_ATTR_MAX,
3847                                      devlink_nl_family.policy, cb->extack);
3848         if (err)
3849                 goto out_free;
3850 
3851         mutex_lock(&devlink_mutex);
3852         devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
3853         if (IS_ERR(devlink)) {
3854                 err = PTR_ERR(devlink);
3855                 goto out_dev;
3856         }
3857 
3858         mutex_lock(&devlink->lock);
3859 
3860         if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
3861             !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
3862                 err = -EINVAL;
3863                 goto out_unlock;
3864         }
3865 
3866         region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
3867         region = devlink_region_get_by_name(devlink, region_name);
3868         if (!region) {
3869                 err = -EINVAL;
3870                 goto out_unlock;
3871         }
3872 
3873         /* return 0 if there is no further data to read */
3874         if (start_offset >= region->size) {
3875                 err = 0;
3876                 goto out_unlock;
3877         }
3878 
3879         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
3880                           &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
3881                           DEVLINK_CMD_REGION_READ);
3882         if (!hdr) {
3883                 err = -EMSGSIZE;
3884                 goto out_unlock;
3885         }
3886 
3887         err = devlink_nl_put_handle(skb, devlink);
3888         if (err)
3889                 goto nla_put_failure;
3890 
3891         err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
3892         if (err)
3893                 goto nla_put_failure;
3894 
3895         chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
3896         if (!chunks_attr) {
3897                 err = -EMSGSIZE;
3898                 goto nla_put_failure;
3899         }
3900 
3901         if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
3902             attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
3903                 if (!start_offset)
3904                         start_offset =
3905                                 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3906 
3907                 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3908                 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
3909                 dump = false;
3910 
3911                 if (start_offset == end_offset) {
3912                         err = 0;
3913                         goto nla_put_failure;
3914                 }
3915         }
3916 
3917         err = devlink_nl_region_read_snapshot_fill(skb, devlink,
3918                                                    region, attrs,
3919                                                    start_offset,
3920                                                    end_offset, dump,
3921                                                    &ret_offset);
3922 
3923         if (err && err != -EMSGSIZE)
3924                 goto nla_put_failure;
3925 
3926         /* Check if there was any progress done to prevent infinite loop */
3927         if (ret_offset == start_offset) {
3928                 err = -EINVAL;
3929                 goto nla_put_failure;
3930         }
3931 
3932         *((u64 *)&cb->args[0]) = ret_offset;
3933 
3934         nla_nest_end(skb, chunks_attr);
3935         genlmsg_end(skb, hdr);
3936         mutex_unlock(&devlink->lock);
3937         mutex_unlock(&devlink_mutex);
3938         kfree(attrs);
3939 
3940         return skb->len;
3941 
3942 nla_put_failure:
3943         genlmsg_cancel(skb, hdr);
3944 out_unlock:
3945         mutex_unlock(&devlink->lock);
3946 out_dev:
3947         mutex_unlock(&devlink_mutex);
3948 out_free:
3949         kfree(attrs);
3950         return err;
3951 }
3952 
3953 struct devlink_info_req {
3954         struct sk_buff *msg;
3955 };
3956 
3957 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
3958 {
3959         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
3960 }
3961 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
3962 
3963 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
3964 {
3965         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
3966 }
3967 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
3968 
3969 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
3970                                     const char *version_name,
3971                                     const char *version_value)
3972 {
3973         struct nlattr *nest;
3974         int err;
3975 
3976         nest = nla_nest_start_noflag(req->msg, attr);
3977         if (!nest)
3978                 return -EMSGSIZE;
3979 
3980         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
3981                              version_name);
3982         if (err)
3983                 goto nla_put_failure;
3984 
3985         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
3986                              version_value);
3987         if (err)
3988                 goto nla_put_failure;
3989 
3990         nla_nest_end(req->msg, nest);
3991 
3992         return 0;
3993 
3994 nla_put_failure:
3995         nla_nest_cancel(req->msg, nest);
3996         return err;
3997 }
3998 
3999 int devlink_info_version_fixed_put(struct devlink_info_req *req,
4000                                    const char *version_name,
4001                                    const char *version_value)
4002 {
4003         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
4004                                         version_name, version_value);
4005 }
4006 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
4007 
4008 int devlink_info_version_stored_put(struct devlink_info_req *req,
4009                                     const char *version_name,
4010                                     const char *version_value)
4011 {
4012         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
4013                                         version_name, version_value);
4014 }
4015 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
4016 
4017 int devlink_info_version_running_put(struct devlink_info_req *req,
4018                                      const char *version_name,
4019                                      const char *version_value)
4020 {
4021         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
4022                                         version_name, version_value);
4023 }
4024 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
4025 
4026 static int
4027 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
4028                      enum devlink_command cmd, u32 portid,
4029                      u32 seq, int flags, struct netlink_ext_ack *extack)
4030 {
4031         struct devlink_info_req req;
4032         void *hdr;
4033         int err;
4034 
4035         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4036         if (!hdr)
4037                 return -EMSGSIZE;
4038 
4039         err = -EMSGSIZE;
4040         if (devlink_nl_put_handle(msg, devlink))
4041                 goto err_cancel_msg;
4042 
4043         req.msg = msg;
4044         err = devlink->ops->info_get(devlink, &req, extack);
4045         if (err)
4046                 goto err_cancel_msg;
4047 
4048         genlmsg_end(msg, hdr);
4049         return 0;
4050 
4051 err_cancel_msg:
4052         genlmsg_cancel(msg, hdr);
4053         return err;
4054 }
4055 
4056 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
4057                                         struct genl_info *info)
4058 {
4059         struct devlink *devlink = info->user_ptr[0];
4060         struct sk_buff *msg;
4061         int err;
4062 
4063         if (!devlink->ops->info_get)
4064                 return -EOPNOTSUPP;
4065 
4066         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4067         if (!msg)
4068                 return -ENOMEM;
4069 
4070         err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4071                                    info->snd_portid, info->snd_seq, 0,
4072                                    info->extack);
4073         if (err) {
4074                 nlmsg_free(msg);
4075                 return err;
4076         }
4077 
4078         return genlmsg_reply(msg, info);
4079 }
4080 
4081 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
4082                                           struct netlink_callback *cb)
4083 {
4084         struct devlink *devlink;
4085         int start = cb->args[0];
4086         int idx = 0;
4087         int err;
4088 
4089         mutex_lock(&devlink_mutex);
4090         list_for_each_entry(devlink, &devlink_list, list) {
4091                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4092                         continue;
4093                 if (idx < start) {
4094                         idx++;
4095                         continue;
4096                 }
4097 
4098                 if (!devlink->ops->info_get) {
4099                         idx++;
4100                         continue;
4101                 }
4102 
4103                 mutex_lock(&devlink->lock);
4104                 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
4105                                            NETLINK_CB(cb->skb).portid,
4106                                            cb->nlh->nlmsg_seq, NLM_F_MULTI,
4107                                            cb->extack);
4108                 mutex_unlock(&devlink->lock);
4109                 if (err && err != -EOPNOTSUPP)
4110                         break;
4111                 idx++;
4112         }
4113         mutex_unlock(&devlink_mutex);
4114 
4115         cb->args[0] = idx;
4116         return msg->len;
4117 }
4118 
4119 struct devlink_fmsg_item {
4120         struct list_head list;
4121         int attrtype;
4122         u8 nla_type;
4123         u16 len;
4124         int value[0];
4125 };
4126 
4127 struct devlink_fmsg {
4128         struct list_head item_list;
4129 };
4130 
4131 static struct devlink_fmsg *devlink_fmsg_alloc(void)
4132 {
4133         struct devlink_fmsg *fmsg;
4134 
4135         fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
4136         if (!fmsg)
4137                 return NULL;
4138 
4139         INIT_LIST_HEAD(&fmsg->item_list);
4140 
4141         return fmsg;
4142 }
4143 
4144 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
4145 {
4146         struct devlink_fmsg_item *item, *tmp;
4147 
4148         list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
4149                 list_del(&item->list);
4150                 kfree(item);
4151         }
4152         kfree(fmsg);
4153 }
4154 
4155 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
4156                                     int attrtype)
4157 {
4158         struct devlink_fmsg_item *item;
4159 
4160         item = kzalloc(sizeof(*item), GFP_KERNEL);
4161         if (!item)
4162                 return -ENOMEM;
4163 
4164         item->attrtype = attrtype;
4165         list_add_tail(&item->list, &fmsg->item_list);
4166 
4167         return 0;
4168 }
4169 
4170 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
4171 {
4172         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
4173 }
4174 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
4175 
4176 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
4177 {
4178         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
4179 }
4180 
4181 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
4182 {
4183         return devlink_fmsg_nest_end(fmsg);
4184 }
4185 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
4186 
4187 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4188 
4189 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
4190 {
4191         struct devlink_fmsg_item *item;
4192 
4193         if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
4194                 return -EMSGSIZE;
4195 
4196         item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
4197         if (!item)
4198                 return -ENOMEM;
4199 
4200         item->nla_type = NLA_NUL_STRING;
4201         item->len = strlen(name) + 1;
4202         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
4203         memcpy(&item->value, name, item->len);
4204         list_add_tail(&item->list, &fmsg->item_list);
4205 
4206         return 0;
4207 }
4208 
4209 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
4210 {
4211         int err;
4212 
4213         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
4214         if (err)
4215                 return err;
4216 
4217         err = devlink_fmsg_put_name(fmsg, name);
4218         if (err)
4219                 return err;
4220 
4221         return 0;
4222 }
4223 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
4224 
4225 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
4226 {
4227         return devlink_fmsg_nest_end(fmsg);
4228 }
4229 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
4230 
4231 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
4232                                      const char *name)
4233 {
4234         int err;
4235 
4236         err = devlink_fmsg_pair_nest_start(fmsg, name);
4237         if (err)
4238                 return err;
4239 
4240         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
4241         if (err)
4242                 return err;
4243 
4244         return 0;
4245 }
4246 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
4247 
4248 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
4249 {
4250         int err;
4251 
4252         err = devlink_fmsg_nest_end(fmsg);
4253         if (err)
4254                 return err;
4255 
4256         err = devlink_fmsg_nest_end(fmsg);
4257         if (err)
4258                 return err;
4259 
4260         return 0;
4261 }
4262 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
4263 
4264 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
4265                                   const void *value, u16 value_len,
4266                                   u8 value_nla_type)
4267 {
4268         struct devlink_fmsg_item *item;
4269 
4270         if (value_len > DEVLINK_FMSG_MAX_SIZE)
4271                 return -EMSGSIZE;
4272 
4273         item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
4274         if (!item)
4275                 return -ENOMEM;
4276 
4277         item->nla_type = value_nla_type;
4278         item->len = value_len;
4279         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4280         memcpy(&item->value, value, item->len);
4281         list_add_tail(&item->list, &fmsg->item_list);
4282 
4283         return 0;
4284 }
4285 
4286 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
4287 {
4288         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
4289 }
4290 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
4291 
4292 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
4293 {
4294         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
4295 }
4296 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
4297 
4298 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
4299 {
4300         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
4301 }
4302 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
4303 
4304 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
4305 {
4306         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
4307 }
4308 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
4309 
4310 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
4311 {
4312         return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
4313                                       NLA_NUL_STRING);
4314 }
4315 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
4316 
4317 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
4318                             u16 value_len)
4319 {
4320         return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
4321 }
4322 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
4323 
4324 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
4325                                bool value)
4326 {
4327         int err;
4328 
4329         err = devlink_fmsg_pair_nest_start(fmsg, name);
4330         if (err)
4331                 return err;
4332 
4333         err = devlink_fmsg_bool_put(fmsg, value);
4334         if (err)
4335                 return err;
4336 
4337         err = devlink_fmsg_pair_nest_end(fmsg);
4338         if (err)
4339                 return err;
4340 
4341         return 0;
4342 }
4343 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
4344 
4345 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
4346                              u8 value)
4347 {
4348         int err;
4349 
4350         err = devlink_fmsg_pair_nest_start(fmsg, name);
4351         if (err)
4352                 return err;
4353 
4354         err = devlink_fmsg_u8_put(fmsg, value);
4355         if (err)
4356                 return err;
4357 
4358         err = devlink_fmsg_pair_nest_end(fmsg);
4359         if (err)
4360                 return err;
4361 
4362         return 0;
4363 }
4364 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
4365 
4366 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
4367                               u32 value)
4368 {
4369         int err;
4370 
4371         err = devlink_fmsg_pair_nest_start(fmsg, name);
4372         if (err)
4373                 return err;
4374 
4375         err = devlink_fmsg_u32_put(fmsg, value);
4376         if (err)
4377                 return err;
4378 
4379         err = devlink_fmsg_pair_nest_end(fmsg);
4380         if (err)
4381                 return err;
4382 
4383         return 0;
4384 }
4385 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
4386 
4387 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
4388                               u64 value)
4389 {
4390         int err;
4391 
4392         err = devlink_fmsg_pair_nest_start(fmsg, name);
4393         if (err)
4394                 return err;
4395 
4396         err = devlink_fmsg_u64_put(fmsg, value);
4397         if (err)
4398                 return err;
4399 
4400         err = devlink_fmsg_pair_nest_end(fmsg);
4401         if (err)
4402                 return err;
4403 
4404         return 0;
4405 }
4406 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
4407 
4408 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
4409                                  const char *value)
4410 {
4411         int err;
4412 
4413         err = devlink_fmsg_pair_nest_start(fmsg, name);
4414         if (err)
4415                 return err;
4416 
4417         err = devlink_fmsg_string_put(fmsg, value);
4418         if (err)
4419                 return err;
4420 
4421         err = devlink_fmsg_pair_nest_end(fmsg);
4422         if (err)
4423                 return err;
4424 
4425         return 0;
4426 }
4427 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
4428 
4429 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
4430                                  const void *value, u16 value_len)
4431 {
4432         int err;
4433 
4434         err = devlink_fmsg_pair_nest_start(fmsg, name);
4435         if (err)
4436                 return err;
4437 
4438         err = devlink_fmsg_binary_put(fmsg, value, value_len);
4439         if (err)
4440                 return err;
4441 
4442         err = devlink_fmsg_pair_nest_end(fmsg);
4443         if (err)
4444                 return err;
4445 
4446         return 0;
4447 }
4448 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
4449 
4450 static int
4451 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4452 {
4453         switch (msg->nla_type) {
4454         case NLA_FLAG:
4455         case NLA_U8:
4456         case NLA_U32:
4457         case NLA_U64:
4458         case NLA_NUL_STRING:
4459         case NLA_BINARY:
4460                 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
4461                                   msg->nla_type);
4462         default:
4463                 return -EINVAL;
4464         }
4465 }
4466 
4467 static int
4468 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4469 {
4470         int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4471         u8 tmp;
4472 
4473         switch (msg->nla_type) {
4474         case NLA_FLAG:
4475                 /* Always provide flag data, regardless of its value */
4476                 tmp = *(bool *) msg->value;
4477 
4478                 return nla_put_u8(skb, attrtype, tmp);
4479         case NLA_U8:
4480                 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
4481         case NLA_U32:
4482                 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
4483         case NLA_U64:
4484                 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
4485                                          DEVLINK_ATTR_PAD);
4486         case NLA_NUL_STRING:
4487                 return nla_put_string(skb, attrtype, (char *) &msg->value);
4488         case NLA_BINARY:
4489                 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
4490         default:
4491                 return -EINVAL;
4492         }
4493 }
4494 
4495 static int
4496 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
4497                          int *start)
4498 {
4499         struct devlink_fmsg_item *item;
4500         struct nlattr *fmsg_nlattr;
4501         int i = 0;
4502         int err;
4503 
4504         fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
4505         if (!fmsg_nlattr)
4506                 return -EMSGSIZE;
4507 
4508         list_for_each_entry(item, &fmsg->item_list, list) {
4509                 if (i < *start) {
4510                         i++;
4511                         continue;
4512                 }
4513 
4514                 switch (item->attrtype) {
4515                 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
4516                 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
4517                 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
4518                 case DEVLINK_ATTR_FMSG_NEST_END:
4519                         err = nla_put_flag(skb, item->attrtype);
4520                         break;
4521                 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
4522                         err = devlink_fmsg_item_fill_type(item, skb);
4523                         if (err)
4524                                 break;
4525                         err = devlink_fmsg_item_fill_data(item, skb);
4526                         break;
4527                 case DEVLINK_ATTR_FMSG_OBJ_NAME:
4528                         err = nla_put_string(skb, item->attrtype,
4529                                              (char *) &item->value);
4530                         break;
4531                 default:
4532                         err = -EINVAL;
4533                         break;
4534                 }
4535                 if (!err)
4536                         *start = ++i;
4537                 else
4538                         break;
4539         }
4540 
4541         nla_nest_end(skb, fmsg_nlattr);
4542         return err;
4543 }
4544 
4545 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
4546                             struct genl_info *info,
4547                             enum devlink_command cmd, int flags)
4548 {
4549         struct nlmsghdr *nlh;
4550         struct sk_buff *skb;
4551         bool last = false;
4552         int index = 0;
4553         void *hdr;
4554         int err;
4555 
4556         while (!last) {
4557                 int tmp_index = index;
4558 
4559                 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4560                 if (!skb)
4561                         return -ENOMEM;
4562 
4563                 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4564                                   &devlink_nl_family, flags | NLM_F_MULTI, cmd);
4565                 if (!hdr) {
4566                         err = -EMSGSIZE;
4567                         goto nla_put_failure;
4568                 }
4569 
4570                 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
4571                 if (!err)
4572                         last = true;
4573                 else if (err != -EMSGSIZE || tmp_index == index)
4574                         goto nla_put_failure;
4575 
4576                 genlmsg_end(skb, hdr);
4577                 err = genlmsg_reply(skb, info);
4578                 if (err)
4579                         return err;
4580         }
4581 
4582         skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4583         if (!skb)
4584                 return -ENOMEM;
4585         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4586                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
4587         if (!nlh) {
4588                 err = -EMSGSIZE;
4589                 goto nla_put_failure;
4590         }
4591 
4592         return genlmsg_reply(skb, info);
4593 
4594 nla_put_failure:
4595         nlmsg_free(skb);
4596         return err;
4597 }
4598 
4599 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
4600                                struct netlink_callback *cb,
4601                                enum devlink_command cmd)
4602 {
4603         int index = cb->args[0];
4604         int tmp_index = index;
4605         void *hdr;
4606         int err;
4607 
4608         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
4609                           &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
4610         if (!hdr) {
4611                 err = -EMSGSIZE;
4612                 goto nla_put_failure;
4613         }
4614 
4615         err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
4616         if ((err && err != -EMSGSIZE) || tmp_index == index)
4617                 goto nla_put_failure;
4618 
4619         cb->args[0] = index;
4620         genlmsg_end(skb, hdr);
4621         return skb->len;
4622 
4623 nla_put_failure:
4624         genlmsg_cancel(skb, hdr);
4625         return err;
4626 }
4627 
4628 struct devlink_health_reporter {
4629         struct list_head list;
4630         void *priv;
4631         const struct devlink_health_reporter_ops *ops;
4632         struct devlink *devlink;
4633         struct devlink_fmsg *dump_fmsg;
4634         struct mutex dump_lock; /* lock parallel read/write from dump buffers */
4635         u64 graceful_period;
4636         bool auto_recover;
4637         u8 health_state;
4638         u64 dump_ts;
4639         u64 dump_real_ts;
4640         u64 error_count;
4641         u64 recovery_count;
4642         u64 last_recovery_ts;
4643         refcount_t refcount;
4644 };
4645 
4646 void *
4647 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
4648 {
4649         return reporter->priv;
4650 }
4651 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
4652 
4653 static struct devlink_health_reporter *
4654 devlink_health_reporter_find_by_name(struct devlink *devlink,
4655                                      const char *reporter_name)
4656 {
4657         struct devlink_health_reporter *reporter;
4658 
4659         lockdep_assert_held(&devlink->reporters_lock);
4660         list_for_each_entry(reporter, &devlink->reporter_list, list)
4661                 if (!strcmp(reporter->ops->name, reporter_name))
4662                         return reporter;
4663         return NULL;
4664 }
4665 
4666 /**
4667  *      devlink_health_reporter_create - create devlink health reporter
4668  *
4669  *      @devlink: devlink
4670  *      @ops: ops
4671  *      @graceful_period: to avoid recovery loops, in msecs
4672  *      @auto_recover: auto recover when error occurs
4673  *      @priv: priv
4674  */
4675 struct devlink_health_reporter *
4676 devlink_health_reporter_create(struct devlink *devlink,
4677                                const struct devlink_health_reporter_ops *ops,
4678                                u64 graceful_period, bool auto_recover,
4679                                void *priv)
4680 {
4681         struct devlink_health_reporter *reporter;
4682 
4683         mutex_lock(&devlink->reporters_lock);
4684         if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
4685                 reporter = ERR_PTR(-EEXIST);
4686                 goto unlock;
4687         }
4688 
4689         if (WARN_ON(auto_recover && !ops->recover) ||
4690             WARN_ON(graceful_period && !ops->recover)) {
4691                 reporter = ERR_PTR(-EINVAL);
4692                 goto unlock;
4693         }
4694 
4695         reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
4696         if (!reporter) {
4697                 reporter = ERR_PTR(-ENOMEM);
4698                 goto unlock;
4699         }
4700 
4701         reporter->priv = priv;
4702         reporter->ops = ops;
4703         reporter->devlink = devlink;
4704         reporter->graceful_period = graceful_period;
4705         reporter->auto_recover = auto_recover;
4706         mutex_init(&reporter->dump_lock);
4707         refcount_set(&reporter->refcount, 1);
4708         list_add_tail(&reporter->list, &devlink->reporter_list);
4709 unlock:
4710         mutex_unlock(&devlink->reporters_lock);
4711         return reporter;
4712 }
4713 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
4714 
4715 /**
4716  *      devlink_health_reporter_destroy - destroy devlink health reporter
4717  *
4718  *      @reporter: devlink health reporter to destroy
4719  */
4720 void
4721 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
4722 {
4723         mutex_lock(&reporter->devlink->reporters_lock);
4724         list_del(&reporter->list);
4725         mutex_unlock(&reporter->devlink->reporters_lock);
4726         while (refcount_read(&reporter->refcount) > 1)
4727                 msleep(100);
4728         mutex_destroy(&reporter->dump_lock);
4729         if (reporter->dump_fmsg)
4730                 devlink_fmsg_free(reporter->dump_fmsg);
4731         kfree(reporter);
4732 }
4733 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
4734 
4735 void
4736 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
4737                                      enum devlink_health_reporter_state state)
4738 {
4739         if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
4740                     state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
4741                 return;
4742 
4743         if (reporter->health_state == state)
4744                 return;
4745 
4746         reporter->health_state = state;
4747         trace_devlink_health_reporter_state_update(reporter->devlink,
4748                                                    reporter->ops->name, state);
4749 }
4750 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
4751 
4752 static int
4753 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
4754                                 void *priv_ctx)
4755 {
4756         int err;
4757 
4758         if (!reporter->ops->recover)
4759                 return -EOPNOTSUPP;
4760 
4761         err = reporter->ops->recover(reporter, priv_ctx);
4762         if (err)
4763                 return err;
4764 
4765         reporter->recovery_count++;
4766         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
4767         reporter->last_recovery_ts = jiffies;
4768 
4769         return 0;
4770 }
4771 
4772 static void
4773 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
4774 {
4775         if (!reporter->dump_fmsg)
4776                 return;
4777         devlink_fmsg_free(reporter->dump_fmsg);
4778         reporter->dump_fmsg = NULL;
4779 }
4780 
4781 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
4782                                   void *priv_ctx)
4783 {
4784         int err;
4785 
4786         if (!reporter->ops->dump)
4787                 return 0;
4788 
4789         if (reporter->dump_fmsg)
4790                 return 0;
4791 
4792         reporter->dump_fmsg = devlink_fmsg_alloc();
4793         if (!reporter->dump_fmsg) {
4794                 err = -ENOMEM;
4795                 return err;
4796         }
4797 
4798         err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
4799         if (err)
4800                 goto dump_err;
4801 
4802         err = reporter->ops->dump(reporter, reporter->dump_fmsg,
4803                                   priv_ctx);
4804         if (err)
4805                 goto dump_err;
4806 
4807         err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
4808         if (err)
4809                 goto dump_err;
4810 
4811         reporter->dump_ts = jiffies;
4812         reporter->dump_real_ts = ktime_get_real_ns();
4813 
4814         return 0;
4815 
4816 dump_err:
4817         devlink_health_dump_clear(reporter);
4818         return err;
4819 }
4820 
4821 int devlink_health_report(struct devlink_health_reporter *reporter,
4822                           const char *msg, void *priv_ctx)
4823 {
4824         enum devlink_health_reporter_state prev_health_state;
4825         struct devlink *devlink = reporter->devlink;
4826 
4827         /* write a log message of the current error */
4828         WARN_ON(!msg);
4829         trace_devlink_health_report(devlink, reporter->ops->name, msg);
4830         reporter->error_count++;
4831         prev_health_state = reporter->health_state;
4832         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4833 
4834         /* abort if the previous error wasn't recovered */
4835         if (reporter->auto_recover &&
4836             (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
4837              jiffies - reporter->last_recovery_ts <
4838              msecs_to_jiffies(reporter->graceful_period))) {
4839                 trace_devlink_health_recover_aborted(devlink,
4840                                                      reporter->ops->name,
4841                                                      reporter->health_state,
4842                                                      jiffies -
4843                                                      reporter->last_recovery_ts);
4844                 return -ECANCELED;
4845         }
4846 
4847         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4848 
4849         mutex_lock(&reporter->dump_lock);
4850         /* store current dump of current error, for later analysis */
4851         devlink_health_do_dump(reporter, priv_ctx);
4852         mutex_unlock(&reporter->dump_lock);
4853 
4854         if (reporter->auto_recover)
4855                 return devlink_health_reporter_recover(reporter, priv_ctx);
4856 
4857         return 0;
4858 }
4859 EXPORT_SYMBOL_GPL(devlink_health_report);
4860 
4861 static struct devlink_health_reporter *
4862 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
4863                                        struct nlattr **attrs)
4864 {
4865         struct devlink_health_reporter *reporter;
4866         char *reporter_name;
4867 
4868         if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
4869                 return NULL;
4870 
4871         reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
4872         mutex_lock(&devlink->reporters_lock);
4873         reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
4874         if (reporter)
4875                 refcount_inc(&reporter->refcount);
4876         mutex_unlock(&devlink->reporters_lock);
4877         return reporter;
4878 }
4879 
4880 static struct devlink_health_reporter *
4881 devlink_health_reporter_get_from_info(struct devlink *devlink,
4882                                       struct genl_info *info)
4883 {
4884         return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
4885 }
4886 
4887 static struct devlink_health_reporter *
4888 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
4889 {
4890         struct devlink_health_reporter *reporter;
4891         struct devlink *devlink;
4892         struct nlattr **attrs;
4893         int err;
4894 
4895         attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
4896         if (!attrs)
4897                 return NULL;
4898 
4899         err = nlmsg_parse_deprecated(cb->nlh,
4900                                      GENL_HDRLEN + devlink_nl_family.hdrsize,
4901                                      attrs, DEVLINK_ATTR_MAX,
4902                                      devlink_nl_family.policy, cb->extack);
4903         if (err)
4904                 goto free;
4905 
4906         mutex_lock(&devlink_mutex);
4907         devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
4908         if (IS_ERR(devlink))
4909                 goto unlock;
4910 
4911         reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
4912         mutex_unlock(&devlink_mutex);
4913         kfree(attrs);
4914         return reporter;
4915 unlock:
4916         mutex_unlock(&devlink_mutex);
4917 free:
4918         kfree(attrs);
4919         return NULL;
4920 }
4921 
4922 static void
4923 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
4924 {
4925         refcount_dec(&reporter->refcount);
4926 }
4927 
4928 static int
4929 devlink_nl_health_reporter_fill(struct sk_buff *msg,
4930                                 struct devlink *devlink,
4931                                 struct devlink_health_reporter *reporter,
4932                                 enum devlink_command cmd, u32 portid,
4933                                 u32 seq, int flags)
4934 {
4935         struct nlattr *reporter_attr;
4936         void *hdr;
4937 
4938         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4939         if (!hdr)
4940                 return -EMSGSIZE;
4941 
4942         if (devlink_nl_put_handle(msg, devlink))
4943                 goto genlmsg_cancel;
4944 
4945         reporter_attr = nla_nest_start_noflag(msg,
4946                                               DEVLINK_ATTR_HEALTH_REPORTER);
4947         if (!reporter_attr)
4948                 goto genlmsg_cancel;
4949         if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
4950                            reporter->ops->name))
4951                 goto reporter_nest_cancel;
4952         if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
4953                        reporter->health_state))
4954                 goto reporter_nest_cancel;
4955         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
4956                               reporter->error_count, DEVLINK_ATTR_PAD))
4957                 goto reporter_nest_cancel;
4958         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
4959                               reporter->recovery_count, DEVLINK_ATTR_PAD))
4960                 goto reporter_nest_cancel;
4961         if (reporter->ops->recover &&
4962             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
4963                               reporter->graceful_period,
4964                               DEVLINK_ATTR_PAD))
4965                 goto reporter_nest_cancel;
4966         if (reporter->ops->recover &&
4967             nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
4968                        reporter->auto_recover))
4969                 goto reporter_nest_cancel;
4970         if (reporter->dump_fmsg &&
4971             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
4972                               jiffies_to_msecs(reporter->dump_ts),
4973                               DEVLINK_ATTR_PAD))
4974                 goto reporter_nest_cancel;
4975         if (reporter->dump_fmsg &&
4976             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
4977                               reporter->dump_real_ts, DEVLINK_ATTR_PAD))
4978                 goto reporter_nest_cancel;
4979 
4980         nla_nest_end(msg, reporter_attr);
4981         genlmsg_end(msg, hdr);
4982         return 0;
4983 
4984 reporter_nest_cancel:
4985         nla_nest_end(msg, reporter_attr);
4986 genlmsg_cancel:
4987         genlmsg_cancel(msg, hdr);
4988         return -EMSGSIZE;
4989 }
4990 
4991 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
4992                                                    struct genl_info *info)
4993 {
4994         struct devlink *devlink = info->user_ptr[0];
4995         struct devlink_health_reporter *reporter;
4996         struct sk_buff *msg;
4997         int err;
4998 
4999         reporter = devlink_health_reporter_get_from_info(devlink, info);
5000         if (!reporter)
5001                 return -EINVAL;
5002 
5003         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5004         if (!msg) {
5005                 err = -ENOMEM;
5006                 goto out;
5007         }
5008 
5009         err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
5010                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
5011                                               info->snd_portid, info->snd_seq,
5012                                               0);
5013         if (err) {
5014                 nlmsg_free(msg);
5015                 goto out;
5016         }
5017 
5018         err = genlmsg_reply(msg, info);
5019 out:
5020         devlink_health_reporter_put(reporter);
5021         return err;
5022 }
5023 
5024 static int
5025 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
5026                                           struct netlink_callback *cb)
5027 {
5028         struct devlink_health_reporter *reporter;
5029         struct devlink *devlink;
5030         int start = cb->args[0];
5031         int idx = 0;
5032         int err;
5033 
5034         mutex_lock(&devlink_mutex);
5035         list_for_each_entry(devlink, &devlink_list, list) {
5036                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5037                         continue;
5038                 mutex_lock(&devlink->reporters_lock);
5039                 list_for_each_entry(reporter, &devlink->reporter_list,
5040                                     list) {
5041                         if (idx < start) {
5042                                 idx++;
5043                                 continue;
5044                         }
5045                         err = devlink_nl_health_reporter_fill(msg, devlink,
5046                                                               reporter,
5047                                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
5048                                                               NETLINK_CB(cb->skb).portid,
5049                                                               cb->nlh->nlmsg_seq,
5050                                                               NLM_F_MULTI);
5051                         if (err) {
5052                                 mutex_unlock(&devlink->reporters_lock);
5053                                 goto out;
5054                         }
5055                         idx++;
5056                 }
5057                 mutex_unlock(&devlink->reporters_lock);
5058         }
5059 out:
5060         mutex_unlock(&devlink_mutex);
5061 
5062         cb->args[0] = idx;
5063         return msg->len;
5064 }
5065 
5066 static int
5067 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
5068                                         struct genl_info *info)
5069 {
5070         struct devlink *devlink = info->user_ptr[0];
5071         struct devlink_health_reporter *reporter;
5072         int err;
5073 
5074         reporter = devlink_health_reporter_get_from_info(devlink, info);
5075         if (!reporter)
5076                 return -EINVAL;
5077 
5078         if (!reporter->ops->recover &&
5079             (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
5080              info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
5081                 err = -EOPNOTSUPP;
5082                 goto out;
5083         }
5084 
5085         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
5086                 reporter->graceful_period =
5087                         nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
5088 
5089         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
5090                 reporter->auto_recover =
5091                         nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
5092 
5093         devlink_health_reporter_put(reporter);
5094         return 0;
5095 out:
5096         devlink_health_reporter_put(reporter);
5097         return err;
5098 }
5099 
5100 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
5101                                                        struct genl_info *info)
5102 {
5103         struct devlink *devlink = info->user_ptr[0];
5104         struct devlink_health_reporter *reporter;
5105         int err;
5106 
5107         reporter = devlink_health_reporter_get_from_info(devlink, info);
5108         if (!reporter)
5109                 return -EINVAL;
5110 
5111         err = devlink_health_reporter_recover(reporter, NULL);
5112 
5113         devlink_health_reporter_put(reporter);
5114         return err;
5115 }
5116 
5117 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
5118                                                         struct genl_info *info)
5119 {
5120         struct devlink *devlink = info->user_ptr[0];
5121         struct devlink_health_reporter *reporter;
5122         struct devlink_fmsg *fmsg;
5123         int err;
5124 
5125         reporter = devlink_health_reporter_get_from_info(devlink, info);
5126         if (!reporter)
5127                 return -EINVAL;
5128 
5129         if (!reporter->ops->diagnose) {
5130                 devlink_health_reporter_put(reporter);
5131                 return -EOPNOTSUPP;
5132         }
5133 
5134         fmsg = devlink_fmsg_alloc();
5135         if (!fmsg) {
5136                 devlink_health_reporter_put(reporter);
5137                 return -ENOMEM;
5138         }
5139 
5140         err = devlink_fmsg_obj_nest_start(fmsg);
5141         if (err)
5142                 goto out;
5143 
5144         err = reporter->ops->diagnose(reporter, fmsg);
5145         if (err)
5146                 goto out;
5147 
5148         err = devlink_fmsg_obj_nest_end(fmsg);
5149         if (err)
5150                 goto out;
5151 
5152         err = devlink_fmsg_snd(fmsg, info,
5153                                DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
5154 
5155 out:
5156         devlink_fmsg_free(fmsg);
5157         devlink_health_reporter_put(reporter);
5158         return err;
5159 }
5160 
5161 static int
5162 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
5163                                                struct netlink_callback *cb)
5164 {
5165         struct devlink_health_reporter *reporter;
5166         u64 start = cb->args[0];
5167         int err;
5168 
5169         reporter = devlink_health_reporter_get_from_cb(cb);
5170         if (!reporter)
5171                 return -EINVAL;
5172 
5173         if (!reporter->ops->dump) {
5174                 err = -EOPNOTSUPP;
5175                 goto out;
5176         }
5177         mutex_lock(&reporter->dump_lock);
5178         if (!start) {
5179                 err = devlink_health_do_dump(reporter, NULL);
5180                 if (err)
5181                         goto unlock;
5182                 cb->args[1] = reporter->dump_ts;
5183         }
5184         if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) {
5185                 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
5186                 err = -EAGAIN;
5187                 goto unlock;
5188         }
5189 
5190         err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
5191                                   DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
5192 unlock:
5193         mutex_unlock(&reporter->dump_lock);
5194 out:
5195         devlink_health_reporter_put(reporter);
5196         return err;
5197 }
5198 
5199 static int
5200 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
5201                                                struct genl_info *info)
5202 {
5203         struct devlink *devlink = info->user_ptr[0];
5204         struct devlink_health_reporter *reporter;
5205 
5206         reporter = devlink_health_reporter_get_from_info(devlink, info);
5207         if (!reporter)
5208                 return -EINVAL;
5209 
5210         if (!reporter->ops->dump) {
5211                 devlink_health_reporter_put(reporter);
5212                 return -EOPNOTSUPP;
5213         }
5214 
5215         mutex_lock(&reporter->dump_lock);
5216         devlink_health_dump_clear(reporter);
5217         mutex_unlock(&reporter->dump_lock);
5218         devlink_health_reporter_put(reporter);
5219         return 0;
5220 }
5221 
5222 struct devlink_stats {
5223         u64 rx_bytes;
5224         u64 rx_packets;
5225         struct u64_stats_sync syncp;
5226 };
5227 
5228 /**
5229  * struct devlink_trap_group_item - Packet trap group attributes.
5230  * @group: Immutable packet trap group attributes.
5231  * @refcount: Number of trap items using the group.
5232  * @list: trap_group_list member.
5233  * @stats: Trap group statistics.
5234  *
5235  * Describes packet trap group attributes. Created by devlink during trap
5236  * registration.
5237  */
5238 struct devlink_trap_group_item {
5239         const struct devlink_trap_group *group;
5240         refcount_t refcount;
5241         struct list_head list;
5242         struct devlink_stats __percpu *stats;
5243 };
5244 
5245 /**
5246  * struct devlink_trap_item - Packet trap attributes.
5247  * @trap: Immutable packet trap attributes.
5248  * @group_item: Associated group item.
5249  * @list: trap_list member.
5250  * @action: Trap action.
5251  * @stats: Trap statistics.
5252  * @priv: Driver private information.
5253  *
5254  * Describes both mutable and immutable packet trap attributes. Created by
5255  * devlink during trap registration and used for all trap related operations.
5256  */
5257 struct devlink_trap_item {
5258         const struct devlink_trap *trap;
5259         struct devlink_trap_group_item *group_item;
5260         struct list_head list;
5261         enum devlink_trap_action action;
5262         struct devlink_stats __percpu *stats;
5263         void *priv;
5264 };
5265 
5266 static struct devlink_trap_item *
5267 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
5268 {
5269         struct devlink_trap_item *trap_item;
5270 
5271         list_for_each_entry(trap_item, &devlink->trap_list, list) {
5272                 if (!strcmp(trap_item->trap->name, name))
5273                         return trap_item;
5274         }
5275 
5276         return NULL;
5277 }
5278 
5279 static struct devlink_trap_item *
5280 devlink_trap_item_get_from_info(struct devlink *devlink,
5281                                 struct genl_info *info)
5282 {
5283         struct nlattr *attr;
5284 
5285         if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
5286                 return NULL;
5287         attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
5288 
5289         return devlink_trap_item_lookup(devlink, nla_data(attr));
5290 }
5291 
5292 static int
5293 devlink_trap_action_get_from_info(struct genl_info *info,
5294                                   enum devlink_trap_action *p_trap_action)
5295 {
5296         u8 val;
5297 
5298         val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
5299         switch (val) {
5300         case DEVLINK_TRAP_ACTION_DROP: /* fall-through */
5301         case DEVLINK_TRAP_ACTION_TRAP:
5302                 *p_trap_action = val;
5303                 break;
5304         default:
5305                 return -EINVAL;
5306         }
5307 
5308         return 0;
5309 }
5310 
5311 static int devlink_trap_metadata_put(struct sk_buff *msg,
5312                                      const struct devlink_trap *trap)
5313 {
5314         struct nlattr *attr;
5315 
5316         attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
5317         if (!attr)
5318                 return -EMSGSIZE;
5319 
5320         if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
5321             nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
5322                 goto nla_put_failure;
5323 
5324         nla_nest_end(msg, attr);
5325 
5326         return 0;
5327 
5328 nla_put_failure:
5329         nla_nest_cancel(msg, attr);
5330         return -EMSGSIZE;
5331 }
5332 
5333 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
5334                                     struct devlink_stats *stats)
5335 {
5336         int i;
5337 
5338         memset(stats, 0, sizeof(*stats));
5339         for_each_possible_cpu(i) {
5340                 struct devlink_stats *cpu_stats;
5341                 u64 rx_packets, rx_bytes;
5342                 unsigned int start;
5343 
5344                 cpu_stats = per_cpu_ptr(trap_stats, i);
5345                 do {
5346                         start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
5347                         rx_packets = cpu_stats->rx_packets;
5348                         rx_bytes = cpu_stats->rx_bytes;
5349                 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
5350 
5351                 stats->rx_packets += rx_packets;
5352                 stats->rx_bytes += rx_bytes;
5353         }
5354 }
5355 
5356 static int devlink_trap_stats_put(struct sk_buff *msg,
5357                                   struct devlink_stats __percpu *trap_stats)
5358 {
5359         struct devlink_stats stats;
5360         struct nlattr *attr;
5361 
5362         devlink_trap_stats_read(trap_stats, &stats);
5363 
5364         attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
5365         if (!attr)
5366                 return -EMSGSIZE;
5367 
5368         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
5369                               stats.rx_packets, DEVLINK_ATTR_PAD))
5370                 goto nla_put_failure;
5371 
5372         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
5373                               stats.rx_bytes, DEVLINK_ATTR_PAD))
5374                 goto nla_put_failure;
5375 
5376         nla_nest_end(msg, attr);
5377 
5378         return 0;
5379 
5380 nla_put_failure:
5381         nla_nest_cancel(msg, attr);
5382         return -EMSGSIZE;
5383 }
5384 
5385 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
5386                                 const struct devlink_trap_item *trap_item,
5387                                 enum devlink_command cmd, u32 portid, u32 seq,
5388                                 int flags)
5389 {
5390         struct devlink_trap_group_item *group_item = trap_item->group_item;
5391         void *hdr;
5392         int err;
5393 
5394         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5395         if (!hdr)
5396                 return -EMSGSIZE;
5397 
5398         if (devlink_nl_put_handle(msg, devlink))
5399                 goto nla_put_failure;
5400 
5401         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
5402                            group_item->group->name))
5403                 goto nla_put_failure;
5404 
5405         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
5406                 goto nla_put_failure;
5407 
5408         if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
5409                 goto nla_put_failure;
5410 
5411         if (trap_item->trap->generic &&
5412             nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
5413                 goto nla_put_failure;
5414 
5415         if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
5416                 goto nla_put_failure;
5417 
5418         err = devlink_trap_metadata_put(msg, trap_item->trap);
5419         if (err)
5420                 goto nla_put_failure;
5421 
5422         err = devlink_trap_stats_put(msg, trap_item->stats);
5423         if (err)
5424                 goto nla_put_failure;
5425 
5426         genlmsg_end(msg, hdr);
5427 
5428         return 0;
5429 
5430 nla_put_failure:
5431         genlmsg_cancel(msg, hdr);
5432         return -EMSGSIZE;
5433 }
5434 
5435 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
5436                                         struct genl_info *info)
5437 {
5438         struct netlink_ext_ack *extack = info->extack;
5439         struct devlink *devlink = info->user_ptr[0];
5440         struct devlink_trap_item *trap_item;
5441         struct sk_buff *msg;
5442         int err;
5443 
5444         if (list_empty(&devlink->trap_list))
5445                 return -EOPNOTSUPP;
5446 
5447         trap_item = devlink_trap_item_get_from_info(devlink, info);
5448         if (!trap_item) {
5449                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
5450                 return -ENOENT;
5451         }
5452 
5453         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5454         if (!msg)
5455                 return -ENOMEM;
5456 
5457         err = devlink_nl_trap_fill(msg, devlink, trap_item,
5458                                    DEVLINK_CMD_TRAP_NEW, info->snd_portid,
5459                                    info->snd_seq, 0);
5460         if (err)
5461                 goto err_trap_fill;
5462 
5463         return genlmsg_reply(msg, info);
5464 
5465 err_trap_fill:
5466         nlmsg_free(msg);
5467         return err;
5468 }
5469 
5470 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
5471                                           struct netlink_callback *cb)
5472 {
5473         struct devlink_trap_item *trap_item;
5474         struct devlink *devlink;
5475         int start = cb->args[0];
5476         int idx = 0;
5477         int err;
5478 
5479         mutex_lock(&devlink_mutex);
5480         list_for_each_entry(devlink, &devlink_list, list) {
5481                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5482                         continue;
5483                 mutex_lock(&devlink->lock);
5484                 list_for_each_entry(trap_item, &devlink->trap_list, list) {
5485                         if (idx < start) {
5486                                 idx++;
5487                                 continue;
5488                         }
5489                         err = devlink_nl_trap_fill(msg, devlink, trap_item,
5490                                                    DEVLINK_CMD_TRAP_NEW,
5491                                                    NETLINK_CB(cb->skb).portid,
5492                                                    cb->nlh->nlmsg_seq,
5493                                                    NLM_F_MULTI);
5494                         if (err) {
5495                                 mutex_unlock(&devlink->lock);
5496                                 goto out;
5497                         }
5498                         idx++;
5499                 }
5500                 mutex_unlock(&devlink->lock);
5501         }
5502 out:
5503         mutex_unlock(&devlink_mutex);
5504 
5505         cb->args[0] = idx;
5506         return msg->len;
5507 }
5508 
5509 static int __devlink_trap_action_set(struct devlink *devlink,
5510                                      struct devlink_trap_item *trap_item,
5511                                      enum devlink_trap_action trap_action,
5512                                      struct netlink_ext_ack *extack)
5513 {
5514         int err;
5515 
5516         if (trap_item->action != trap_action &&
5517             trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
5518                 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
5519                 return 0;
5520         }
5521 
5522         err = devlink->ops->trap_action_set(devlink, trap_item->trap,
5523                                             trap_action);
5524         if (err)
5525                 return err;
5526 
5527         trap_item->action = trap_action;
5528 
5529         return 0;
5530 }
5531 
5532 static int devlink_trap_action_set(struct devlink *devlink,
5533                                    struct devlink_trap_item *trap_item,
5534                                    struct genl_info *info)
5535 {
5536         enum devlink_trap_action trap_action;
5537         int err;
5538 
5539         if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
5540                 return 0;
5541 
5542         err = devlink_trap_action_get_from_info(info, &trap_action);
5543         if (err) {
5544                 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
5545                 return -EINVAL;
5546         }
5547 
5548         return __devlink_trap_action_set(devlink, trap_item, trap_action,
5549                                          info->extack);
5550 }
5551 
5552 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
5553                                         struct genl_info *info)
5554 {
5555         struct netlink_ext_ack *extack = info->extack;
5556         struct devlink *devlink = info->user_ptr[0];
5557         struct devlink_trap_item *trap_item;
5558         int err;
5559 
5560         if (list_empty(&devlink->trap_list))
5561                 return -EOPNOTSUPP;
5562 
5563         trap_item = devlink_trap_item_get_from_info(devlink, info);
5564         if (!trap_item) {
5565                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
5566                 return -ENOENT;
5567         }
5568 
5569         err = devlink_trap_action_set(devlink, trap_item, info);
5570         if (err)
5571                 return err;
5572 
5573         return 0;
5574 }
5575 
5576 static struct devlink_trap_group_item *
5577 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
5578 {
5579         struct devlink_trap_group_item *group_item;
5580 
5581         list_for_each_entry(group_item, &devlink->trap_group_list, list) {
5582                 if (!strcmp(group_item->group->name, name))
5583                         return group_item;
5584         }
5585 
5586         return NULL;
5587 }
5588 
5589 static struct devlink_trap_group_item *
5590 devlink_trap_group_item_get_from_info(struct devlink *devlink,
5591                                       struct genl_info *info)
5592 {
5593         char *name;
5594 
5595         if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
5596                 return NULL;
5597         name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
5598 
5599         return devlink_trap_group_item_lookup(devlink, name);
5600 }
5601 
5602 static int
5603 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
5604                            const struct devlink_trap_group_item *group_item,
5605                            enum devlink_command cmd, u32 portid, u32 seq,
5606                            int flags)
5607 {
5608         void *hdr;
5609         int err;
5610 
5611         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5612         if (!hdr)
5613                 return -EMSGSIZE;
5614 
5615         if (devlink_nl_put_handle(msg, devlink))
5616                 goto nla_put_failure;
5617 
5618         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
5619                            group_item->group->name))
5620                 goto nla_put_failure;
5621 
5622         if (group_item->group->generic &&
5623             nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
5624                 goto nla_put_failure;
5625 
5626         err = devlink_trap_stats_put(msg, group_item->stats);
5627         if (err)
5628                 goto nla_put_failure;
5629 
5630         genlmsg_end(msg, hdr);
5631 
5632         return 0;
5633 
5634 nla_put_failure:
5635         genlmsg_cancel(msg, hdr);
5636         return -EMSGSIZE;
5637 }
5638 
5639 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
5640                                               struct genl_info *info)
5641 {
5642         struct netlink_ext_ack *extack = info->extack;
5643         struct devlink *devlink = info->user_ptr[0];
5644         struct devlink_trap_group_item *group_item;
5645         struct sk_buff *msg;
5646         int err;
5647 
5648         if (list_empty(&devlink->trap_group_list))
5649                 return -EOPNOTSUPP;
5650 
5651         group_item = devlink_trap_group_item_get_from_info(devlink, info);
5652         if (!group_item) {
5653                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
5654                 return -ENOENT;
5655         }
5656 
5657         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5658         if (!msg)
5659                 return -ENOMEM;
5660 
5661         err = devlink_nl_trap_group_fill(msg, devlink, group_item,
5662                                          DEVLINK_CMD_TRAP_GROUP_NEW,
5663                                          info->snd_portid, info->snd_seq, 0);
5664         if (err)
5665                 goto err_trap_group_fill;
5666 
5667         return genlmsg_reply(msg, info);
5668 
5669 err_trap_group_fill:
5670         nlmsg_free(msg);
5671         return err;
5672 }
5673 
5674 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
5675                                                 struct netlink_callback *cb)
5676 {
5677         enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
5678         struct devlink_trap_group_item *group_item;
5679         u32 portid = NETLINK_CB(cb->skb).portid;
5680         struct devlink *devlink;
5681         int start = cb->args[0];
5682         int idx = 0;
5683         int err;
5684 
5685         mutex_lock(&devlink_mutex);
5686         list_for_each_entry(devlink, &devlink_list, list) {
5687                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
5688                         continue;
5689                 mutex_lock(&devlink->lock);
5690                 list_for_each_entry(group_item, &devlink->trap_group_list,
5691                                     list) {
5692                         if (idx < start) {
5693                                 idx++;
5694                                 continue;
5695                         }
5696                         err = devlink_nl_trap_group_fill(msg, devlink,
5697                                                          group_item, cmd,
5698                                                          portid,
5699                                                          cb->nlh->nlmsg_seq,
5700                                                          NLM_F_MULTI);
5701                         if (err) {
5702                                 mutex_unlock(&devlink->lock);
5703                                 goto out;
5704                         }
5705                         idx++;
5706                 }
5707                 mutex_unlock(&devlink->lock);
5708         }
5709 out:
5710         mutex_unlock(&devlink_mutex);
5711 
5712         cb->args[0] = idx;
5713         return msg->len;
5714 }
5715 
5716 static int
5717 __devlink_trap_group_action_set(struct devlink *devlink,
5718                                 struct devlink_trap_group_item *group_item,
5719                                 enum devlink_trap_action trap_action,
5720                                 struct netlink_ext_ack *extack)
5721 {
5722         const char *group_name = group_item->group->name;
5723         struct devlink_trap_item *trap_item;
5724         int err;
5725 
5726         list_for_each_entry(trap_item, &devlink->trap_list, list) {
5727                 if (strcmp(trap_item->trap->group.name, group_name))
5728                         continue;
5729                 err = __devlink_trap_action_set(devlink, trap_item,
5730                                                 trap_action, extack);
5731                 if (err)
5732                         return err;
5733         }
5734 
5735         return 0;
5736 }
5737 
5738 static int
5739 devlink_trap_group_action_set(struct devlink *devlink,
5740                               struct devlink_trap_group_item *group_item,
5741                               struct genl_info *info)
5742 {
5743         enum devlink_trap_action trap_action;
5744         int err;
5745 
5746         if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
5747                 return 0;
5748 
5749         err = devlink_trap_action_get_from_info(info, &trap_action);
5750         if (err) {
5751                 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
5752                 return -EINVAL;
5753         }
5754 
5755         err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
5756                                               info->extack);
5757         if (err)
5758                 return err;
5759 
5760         return 0;
5761 }
5762 
5763 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
5764                                               struct genl_info *info)
5765 {
5766         struct netlink_ext_ack *extack = info->extack;
5767         struct devlink *devlink = info->user_ptr[0];
5768         struct devlink_trap_group_item *group_item;
5769         int err;
5770 
5771         if (list_empty(&devlink->trap_group_list))
5772                 return -EOPNOTSUPP;
5773 
5774         group_item = devlink_trap_group_item_get_from_info(devlink, info);
5775         if (!group_item) {
5776                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
5777                 return -ENOENT;
5778         }
5779 
5780         err = devlink_trap_group_action_set(devlink, group_item, info);
5781         if (err)
5782                 return err;
5783 
5784         return 0;
5785 }
5786 
5787 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
5788         [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
5789         [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
5790         [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
5791         [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
5792         [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
5793         [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
5794         [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
5795         [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
5796         [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
5797         [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
5798         [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
5799         [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
5800         [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
5801         [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
5802         [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
5803         [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
5804         [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
5805         [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
5806         [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
5807         [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
5808         [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
5809         [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
5810         [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
5811         [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
5812         [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 },
5813         [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 },
5814         [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
5815         [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
5816         [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
5817         [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
5818         [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
5819         [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
5820         [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
5821         [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
5822 };
5823 
5824 static const struct genl_ops devlink_nl_ops[] = {
5825         {
5826                 .cmd = DEVLINK_CMD_GET,
5827                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5828                 .doit = devlink_nl_cmd_get_doit,
5829                 .dumpit = devlink_nl_cmd_get_dumpit,
5830                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5831                 /* can be retrieved by unprivileged users */
5832         },
5833         {
5834                 .cmd = DEVLINK_CMD_PORT_GET,
5835                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5836                 .doit = devlink_nl_cmd_port_get_doit,
5837                 .dumpit = devlink_nl_cmd_port_get_dumpit,
5838                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5839                 /* can be retrieved by unprivileged users */
5840         },
5841         {
5842                 .cmd = DEVLINK_CMD_PORT_SET,
5843                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5844                 .doit = devlink_nl_cmd_port_set_doit,
5845                 .flags = GENL_ADMIN_PERM,
5846                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5847         },
5848         {
5849                 .cmd = DEVLINK_CMD_PORT_SPLIT,
5850                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5851                 .doit = devlink_nl_cmd_port_split_doit,
5852                 .flags = GENL_ADMIN_PERM,
5853                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5854                                   DEVLINK_NL_FLAG_NO_LOCK,
5855         },
5856         {
5857                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
5858                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5859                 .doit = devlink_nl_cmd_port_unsplit_doit,
5860                 .flags = GENL_ADMIN_PERM,
5861                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5862                                   DEVLINK_NL_FLAG_NO_LOCK,
5863         },
5864         {
5865                 .cmd = DEVLINK_CMD_SB_GET,
5866                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5867                 .doit = devlink_nl_cmd_sb_get_doit,
5868                 .dumpit = devlink_nl_cmd_sb_get_dumpit,
5869                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5870                                   DEVLINK_NL_FLAG_NEED_SB,
5871                 /* can be retrieved by unprivileged users */
5872         },
5873         {
5874                 .cmd = DEVLINK_CMD_SB_POOL_GET,
5875                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5876                 .doit = devlink_nl_cmd_sb_pool_get_doit,
5877                 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
5878                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5879                                   DEVLINK_NL_FLAG_NEED_SB,
5880                 /* can be retrieved by unprivileged users */
5881         },
5882         {
5883                 .cmd = DEVLINK_CMD_SB_POOL_SET,
5884                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5885                 .doit = devlink_nl_cmd_sb_pool_set_doit,
5886                 .flags = GENL_ADMIN_PERM,
5887                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5888                                   DEVLINK_NL_FLAG_NEED_SB,
5889         },
5890         {
5891                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
5892                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5893                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
5894                 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
5895                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5896                                   DEVLINK_NL_FLAG_NEED_SB,
5897                 /* can be retrieved by unprivileged users */
5898         },
5899         {
5900                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
5901                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5902                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
5903                 .flags = GENL_ADMIN_PERM,
5904                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5905                                   DEVLINK_NL_FLAG_NEED_SB,
5906         },
5907         {
5908                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
5909                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5910                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
5911                 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
5912                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5913                                   DEVLINK_NL_FLAG_NEED_SB,
5914                 /* can be retrieved by unprivileged users */
5915         },
5916         {
5917                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
5918                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5919                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
5920                 .flags = GENL_ADMIN_PERM,
5921                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5922                                   DEVLINK_NL_FLAG_NEED_SB,
5923         },
5924         {
5925                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
5926                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5927                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
5928                 .flags = GENL_ADMIN_PERM,
5929                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5930                                   DEVLINK_NL_FLAG_NEED_SB,
5931         },
5932         {
5933                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
5934                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5935                 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
5936                 .flags = GENL_ADMIN_PERM,
5937                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5938                                   DEVLINK_NL_FLAG_NEED_SB,
5939         },
5940         {
5941                 .cmd = DEVLINK_CMD_ESWITCH_GET,
5942                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5943                 .doit = devlink_nl_cmd_eswitch_get_doit,
5944                 .flags = GENL_ADMIN_PERM,
5945                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5946         },
5947         {
5948                 .cmd = DEVLINK_CMD_ESWITCH_SET,
5949                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5950                 .doit = devlink_nl_cmd_eswitch_set_doit,
5951                 .flags = GENL_ADMIN_PERM,
5952                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5953                                   DEVLINK_NL_FLAG_NO_LOCK,
5954         },
5955         {
5956                 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
5957                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5958                 .doit = devlink_nl_cmd_dpipe_table_get,
5959                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5960                 /* can be retrieved by unprivileged users */
5961         },
5962         {
5963                 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
5964                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5965                 .doit = devlink_nl_cmd_dpipe_entries_get,
5966                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5967                 /* can be retrieved by unprivileged users */
5968         },
5969         {
5970                 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
5971                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5972                 .doit = devlink_nl_cmd_dpipe_headers_get,
5973                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5974                 /* can be retrieved by unprivileged users */
5975         },
5976         {
5977                 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
5978                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5979                 .doit = devlink_nl_cmd_dpipe_table_counters_set,
5980                 .flags = GENL_ADMIN_PERM,
5981                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5982         },
5983         {
5984                 .cmd = DEVLINK_CMD_RESOURCE_SET,
5985                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5986                 .doit = devlink_nl_cmd_resource_set,
5987                 .flags = GENL_ADMIN_PERM,
5988                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5989         },
5990         {
5991                 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
5992                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5993                 .doit = devlink_nl_cmd_resource_dump,
5994                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5995                 /* can be retrieved by unprivileged users */
5996         },
5997         {
5998                 .cmd = DEVLINK_CMD_RELOAD,
5999                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6000                 .doit = devlink_nl_cmd_reload,
6001                 .flags = GENL_ADMIN_PERM,
6002                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6003                                   DEVLINK_NL_FLAG_NO_LOCK,
6004         },
6005         {
6006                 .cmd = DEVLINK_CMD_PARAM_GET,
6007                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6008                 .doit = devlink_nl_cmd_param_get_doit,
6009                 .dumpit = devlink_nl_cmd_param_get_dumpit,
6010                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6011                 /* can be retrieved by unprivileged users */
6012         },
6013         {
6014                 .cmd = DEVLINK_CMD_PARAM_SET,
6015                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6016                 .doit = devlink_nl_cmd_param_set_doit,
6017                 .flags = GENL_ADMIN_PERM,
6018                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6019         },
6020         {
6021                 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
6022                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6023                 .doit = devlink_nl_cmd_port_param_get_doit,
6024                 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
6025                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6026                 /* can be retrieved by unprivileged users */
6027         },
6028         {
6029                 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
6030                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6031                 .doit = devlink_nl_cmd_port_param_set_doit,
6032                 .flags = GENL_ADMIN_PERM,
6033                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
6034         },
6035         {
6036                 .cmd = DEVLINK_CMD_REGION_GET,
6037                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6038                 .doit = devlink_nl_cmd_region_get_doit,
6039                 .dumpit = devlink_nl_cmd_region_get_dumpit,
6040                 .flags = GENL_ADMIN_PERM,
6041                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6042         },
6043         {
6044                 .cmd = DEVLINK_CMD_REGION_DEL,
6045                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6046                 .doit = devlink_nl_cmd_region_del,
6047                 .flags = GENL_ADMIN_PERM,
6048                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6049         },
6050         {
6051                 .cmd = DEVLINK_CMD_REGION_READ,
6052                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6053                 .dumpit = devlink_nl_cmd_region_read_dumpit,
6054                 .flags = GENL_ADMIN_PERM,
6055                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6056         },
6057         {
6058                 .cmd = DEVLINK_CMD_INFO_GET,
6059                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6060                 .doit = devlink_nl_cmd_info_get_doit,
6061                 .dumpit = devlink_nl_cmd_info_get_dumpit,
6062                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6063                 /* can be retrieved by unprivileged users */
6064         },
6065         {
6066                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
6067                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6068                 .doit = devlink_nl_cmd_health_reporter_get_doit,
6069                 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
6070                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6071                                   DEVLINK_NL_FLAG_NO_LOCK,
6072                 /* can be retrieved by unprivileged users */
6073         },
6074         {
6075                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
6076                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6077                 .doit = devlink_nl_cmd_health_reporter_set_doit,
6078                 .flags = GENL_ADMIN_PERM,
6079                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6080                                   DEVLINK_NL_FLAG_NO_LOCK,
6081         },
6082         {
6083                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
6084                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6085                 .doit = devlink_nl_cmd_health_reporter_recover_doit,
6086                 .flags = GENL_ADMIN_PERM,
6087                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6088                                   DEVLINK_NL_FLAG_NO_LOCK,
6089         },
6090         {
6091                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
6092                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6093                 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
6094                 .flags = GENL_ADMIN_PERM,
6095                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6096                                   DEVLINK_NL_FLAG_NO_LOCK,
6097         },
6098         {
6099                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
6100                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6101                 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
6102                 .flags = GENL_ADMIN_PERM,
6103                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6104                                   DEVLINK_NL_FLAG_NO_LOCK,
6105         },
6106         {
6107                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
6108                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6109                 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
6110                 .flags = GENL_ADMIN_PERM,
6111                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
6112                                   DEVLINK_NL_FLAG_NO_LOCK,
6113         },
6114         {
6115                 .cmd = DEVLINK_CMD_FLASH_UPDATE,
6116                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6117                 .doit = devlink_nl_cmd_flash_update,
6118                 .flags = GENL_ADMIN_PERM,
6119                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6120         },
6121         {
6122                 .cmd = DEVLINK_CMD_TRAP_GET,
6123                 .doit = devlink_nl_cmd_trap_get_doit,
6124                 .dumpit = devlink_nl_cmd_trap_get_dumpit,
6125                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6126                 /* can be retrieved by unprivileged users */
6127         },
6128         {
6129                 .cmd = DEVLINK_CMD_TRAP_SET,
6130                 .doit = devlink_nl_cmd_trap_set_doit,
6131                 .flags = GENL_ADMIN_PERM,
6132                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6133         },
6134         {
6135                 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
6136                 .doit = devlink_nl_cmd_trap_group_get_doit,
6137                 .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
6138                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6139                 /* can be retrieved by unprivileged users */
6140         },
6141         {
6142                 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
6143                 .doit = devlink_nl_cmd_trap_group_set_doit,
6144                 .flags = GENL_ADMIN_PERM,
6145                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
6146         },
6147 };
6148 
6149 static struct genl_family devlink_nl_family __ro_after_init = {
6150         .name           = DEVLINK_GENL_NAME,
6151         .version        = DEVLINK_GENL_VERSION,
6152         .maxattr        = DEVLINK_ATTR_MAX,
6153         .policy = devlink_nl_policy,
6154         .netnsok        = true,
6155         .pre_doit       = devlink_nl_pre_doit,
6156         .post_doit      = devlink_nl_post_doit,
6157         .module         = THIS_MODULE,
6158         .ops            = devlink_nl_ops,
6159         .n_ops          = ARRAY_SIZE(devlink_nl_ops),
6160         .mcgrps         = devlink_nl_mcgrps,
6161         .n_mcgrps       = ARRAY_SIZE(devlink_nl_mcgrps),
6162 };
6163 
6164 /**
6165  *      devlink_alloc - Allocate new devlink instance resources
6166  *
6167  *      @ops: ops
6168  *      @priv_size: size of user private data
6169  *
6170  *      Allocate new devlink instance resources, including devlink index
6171  *      and name.
6172  */
6173 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
6174 {
6175         struct devlink *devlink;
6176 
6177         if (WARN_ON(!ops))
6178                 return NULL;
6179 
6180         devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
6181         if (!devlink)
6182                 return NULL;
6183         devlink->ops = ops;
6184         devlink_net_set(devlink, &init_net);
6185         INIT_LIST_HEAD(&devlink->port_list);
6186         INIT_LIST_HEAD(&devlink->sb_list);
6187         INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
6188         INIT_LIST_HEAD(&devlink->resource_list);
6189         INIT_LIST_HEAD(&devlink->param_list);
6190         INIT_LIST_HEAD(&devlink->region_list);
6191         INIT_LIST_HEAD(&devlink->reporter_list);
6192         INIT_LIST_HEAD(&devlink->trap_list);
6193         INIT_LIST_HEAD(&devlink->trap_group_list);
6194         mutex_init(&devlink->lock);
6195         mutex_init(&devlink->reporters_lock);
6196         return devlink;
6197 }
6198 EXPORT_SYMBOL_GPL(devlink_alloc);
6199 
6200 /**
6201  *      devlink_register - Register devlink instance
6202  *
6203  *      @devlink: devlink
6204  *      @dev: parent device
6205  */
6206 int devlink_register(struct devlink *devlink, struct device *dev)
6207 {
6208         mutex_lock(&devlink_mutex);
6209         devlink->dev = dev;
6210         list_add_tail(&devlink->list, &devlink_list);
6211         devlink_notify(devlink, DEVLINK_CMD_NEW);
6212         mutex_unlock(&devlink_mutex);
6213         return 0;
6214 }
6215 EXPORT_SYMBOL_GPL(devlink_register);
6216 
6217 /**
6218  *      devlink_unregister - Unregister devlink instance
6219  *
6220  *      @devlink: devlink
6221  */
6222 void devlink_unregister(struct devlink *devlink)
6223 {
6224         mutex_lock(&devlink_mutex);
6225         WARN_ON(devlink_reload_supported(devlink) &&
6226                 devlink->reload_enabled);
6227         devlink_notify(devlink, DEVLINK_CMD_DEL);
6228         list_del(&devlink->list);
6229         mutex_unlock(&devlink_mutex);
6230 }
6231 EXPORT_SYMBOL_GPL(devlink_unregister);
6232 
6233 /**
6234  *      devlink_reload_enable - Enable reload of devlink instance
6235  *
6236  *      @devlink: devlink
6237  *
6238  *      Should be called at end of device initialization
6239  *      process when reload operation is supported.
6240  */
6241 void devlink_reload_enable(struct devlink *devlink)
6242 {
6243         mutex_lock(&devlink_mutex);
6244         devlink->reload_enabled = true;
6245         mutex_unlock(&devlink_mutex);
6246 }
6247 EXPORT_SYMBOL_GPL(devlink_reload_enable);
6248 
6249 /**
6250  *      devlink_reload_disable - Disable reload of devlink instance
6251  *
6252  *      @devlink: devlink
6253  *
6254  *      Should be called at the beginning of device cleanup
6255  *      process when reload operation is supported.
6256  */
6257 void devlink_reload_disable(struct devlink *devlink)
6258 {
6259         mutex_lock(&devlink_mutex);
6260         /* Mutex is taken which ensures that no reload operation is in
6261          * progress while setting up forbidded flag.
6262          */
6263         devlink->reload_enabled = false;
6264         mutex_unlock(&devlink_mutex);
6265 }
6266 EXPORT_SYMBOL_GPL(devlink_reload_disable);
6267 
6268 /**
6269  *      devlink_free - Free devlink instance resources
6270  *
6271  *      @devlink: devlink
6272  */
6273 void devlink_free(struct devlink *devlink)
6274 {
6275         mutex_destroy(&devlink->reporters_lock);
6276         mutex_destroy(&devlink->lock);
6277         WARN_ON(!list_empty(&devlink->trap_group_list));
6278         WARN_ON(!list_empty(&devlink->trap_list));
6279         WARN_ON(!list_empty(&devlink->reporter_list));
6280         WARN_ON(!list_empty(&devlink->region_list));
6281         WARN_ON(!list_empty(&devlink->param_list));
6282         WARN_ON(!list_empty(&devlink->resource_list));
6283         WARN_ON(!list_empty(&devlink->dpipe_table_list));
6284         WARN_ON(!list_empty(&devlink->sb_list));
6285         WARN_ON(!list_empty(&devlink->port_list));
6286 
6287         kfree(devlink);
6288 }
6289 EXPORT_SYMBOL_GPL(devlink_free);
6290 
6291 static void devlink_port_type_warn(struct work_struct *work)
6292 {
6293         WARN(true, "Type was not set for devlink port.");
6294 }
6295 
6296 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
6297 {
6298         /* Ignore CPU and DSA flavours. */
6299         return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
6300                devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA;
6301 }
6302 
6303 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
6304 
6305 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
6306 {
6307         if (!devlink_port_type_should_warn(devlink_port))
6308                 return;
6309         /* Schedule a work to WARN in case driver does not set port
6310          * type within timeout.
6311          */
6312         schedule_delayed_work(&devlink_port->type_warn_dw,
6313                               DEVLINK_PORT_TYPE_WARN_TIMEOUT);
6314 }
6315 
6316 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
6317 {
6318         if (!devlink_port_type_should_warn(devlink_port))
6319                 return;
6320         cancel_delayed_work_sync(&devlink_port->type_warn_dw);
6321 }
6322 
6323 /**
6324  *      devlink_port_register - Register devlink port
6325  *
6326  *      @devlink: devlink
6327  *      @devlink_port: devlink port
6328  *      @port_index: driver-specific numerical identifier of the port
6329  *
6330  *      Register devlink port with provided port index. User can use
6331  *      any indexing, even hw-related one. devlink_port structure
6332  *      is convenient to be embedded inside user driver private structure.
6333  *      Note that the caller should take care of zeroing the devlink_port
6334  *      structure.
6335  */
6336 int devlink_port_register(struct devlink *devlink,
6337                           struct devlink_port *devlink_port,
6338                           unsigned int port_index)
6339 {
6340         mutex_lock(&devlink->lock);
6341         if (devlink_port_index_exists(devlink, port_index)) {
6342                 mutex_unlock(&devlink->lock);
6343                 return -EEXIST;
6344         }
6345         devlink_port->devlink = devlink;
6346         devlink_port->index = port_index;
6347         devlink_port->registered = true;
6348         spin_lock_init(&devlink_port->type_lock);
6349         list_add_tail(&devlink_port->list, &devlink->port_list);
6350         INIT_LIST_HEAD(&devlink_port->param_list);
6351         mutex_unlock(&devlink->lock);
6352         INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
6353         devlink_port_type_warn_schedule(devlink_port);
6354         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
6355         return 0;
6356 }
6357 EXPORT_SYMBOL_GPL(devlink_port_register);
6358 
6359 /**
6360  *      devlink_port_unregister - Unregister devlink port
6361  *
6362  *      @devlink_port: devlink port
6363  */
6364 void devlink_port_unregister(struct devlink_port *devlink_port)
6365 {
6366         struct devlink *devlink = devlink_port->devlink;
6367 
6368         devlink_port_type_warn_cancel(devlink_port);
6369         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
6370         mutex_lock(&devlink->lock);
6371         list_del(&devlink_port->list);
6372         mutex_unlock(&devlink->lock);
6373 }
6374 EXPORT_SYMBOL_GPL(devlink_port_unregister);
6375 
6376 static void __devlink_port_type_set(struct devlink_port *devlink_port,
6377                                     enum devlink_port_type type,
6378                                     void *type_dev)
6379 {
6380         if (WARN_ON(!devlink_port->registered))
6381                 return;
6382         devlink_port_type_warn_cancel(devlink_port);
6383         spin_lock_bh(&devlink_port->type_lock);
6384         devlink_port->type = type;
6385         devlink_port->type_dev = type_dev;
6386         spin_unlock_bh(&devlink_port->type_lock);
6387         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
6388 }
6389 
6390 /**
6391  *      devlink_port_type_eth_set - Set port type to Ethernet
6392  *
6393  *      @devlink_port: devlink port
6394  *      @netdev: related netdevice
6395  */
6396 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
6397                                struct net_device *netdev)
6398 {
6399         const struct net_device_ops *ops = netdev->netdev_ops;
6400 
6401         /* If driver registers devlink port, it should set devlink port
6402          * attributes accordingly so the compat functions are called
6403          * and the original ops are not used.
6404          */
6405         if (ops->ndo_get_phys_port_name) {
6406                 /* Some drivers use the same set of ndos for netdevs
6407                  * that have devlink_port registered and also for
6408                  * those who don't. Make sure that ndo_get_phys_port_name
6409                  * returns -EOPNOTSUPP here in case it is defined.
6410                  * Warn if not.
6411                  */
6412                 char name[IFNAMSIZ];
6413                 int err;
6414 
6415                 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
6416                 WARN_ON(err != -EOPNOTSUPP);
6417         }
6418         if (ops->ndo_get_port_parent_id) {
6419                 /* Some drivers use the same set of ndos for netdevs
6420                  * that have devlink_port registered and also for
6421                  * those who don't. Make sure that ndo_get_port_parent_id
6422                  * returns -EOPNOTSUPP here in case it is defined.
6423                  * Warn if not.
6424                  */
6425                 struct netdev_phys_item_id ppid;
6426                 int err;
6427 
6428                 err = ops->ndo_get_port_parent_id(netdev, &ppid);
6429                 WARN_ON(err != -EOPNOTSUPP);
6430         }
6431         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
6432 }
6433 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
6434 
6435 /**
6436  *      devlink_port_type_ib_set - Set port type to InfiniBand
6437  *
6438  *      @devlink_port: devlink port
6439  *      @ibdev: related IB device
6440  */
6441 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
6442                               struct ib_device *ibdev)
6443 {
6444         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
6445 }
6446 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
6447 
6448 /**
6449  *      devlink_port_type_clear - Clear port type
6450  *
6451  *      @devlink_port: devlink port
6452  */
6453 void devlink_port_type_clear(struct devlink_port *devlink_port)
6454 {
6455         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
6456         devlink_port_type_warn_schedule(devlink_port);
6457 }
6458 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
6459 
6460 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
6461                                     enum devlink_port_flavour flavour,
6462                                     const unsigned char *switch_id,
6463                                     unsigned char switch_id_len)
6464 {
6465         struct devlink_port_attrs *attrs = &devlink_port->attrs;
6466 
6467         if (WARN_ON(devlink_port->registered))
6468                 return -EEXIST;
6469         attrs->set = true;
6470         attrs->flavour = flavour;
6471         if (switch_id) {
6472                 attrs->switch_port = true;
6473                 if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
6474                         switch_id_len = MAX_PHYS_ITEM_ID_LEN;
6475                 memcpy(attrs->switch_id.id, switch_id, switch_id_len);
6476                 attrs->switch_id.id_len = switch_id_len;
6477         } else {
6478                 attrs->switch_port = false;
6479         }
6480         return 0;
6481 }
6482 
6483 /**
6484  *      devlink_port_attrs_set - Set port attributes
6485  *
6486  *      @devlink_port: devlink port
6487  *      @flavour: flavour of the port
6488  *      @port_number: number of the port that is facing user, for example
6489  *                    the front panel port number
6490  *      @split: indicates if this is split port
6491  *      @split_subport_number: if the port is split, this is the number
6492  *                             of subport.
6493  *      @switch_id: if the port is part of switch, this is buffer with ID,
6494  *                  otwerwise this is NULL
6495  *      @switch_id_len: length of the switch_id buffer
6496  */
6497 void devlink_port_attrs_set(struct devlink_port *devlink_port,
6498                             enum devlink_port_flavour flavour,
6499                             u32 port_number, bool split,
6500                             u32 split_subport_number,
6501                             const unsigned char *switch_id,
6502                             unsigned char switch_id_len)
6503 {
6504         struct devlink_port_attrs *attrs = &devlink_port->attrs;
6505         int ret;
6506 
6507         ret = __devlink_port_attrs_set(devlink_port, flavour,
6508                                        switch_id, switch_id_len);
6509         if (ret)
6510                 return;
6511         attrs->split = split;
6512         attrs->phys.port_number = port_number;
6513         attrs->phys.split_subport_number = split_subport_number;
6514 }
6515 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
6516 
6517 /**
6518  *      devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
6519  *
6520  *      @devlink_port: devlink port
6521  *      @pf: associated PF for the devlink port instance
6522  *      @switch_id: if the port is part of switch, this is buffer with ID,
6523  *                  otherwise this is NULL
6524  *      @switch_id_len: length of the switch_id buffer
6525  */
6526 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,
6527                                    const unsigned char *switch_id,
6528                                    unsigned char switch_id_len, u16 pf)
6529 {
6530         struct devlink_port_attrs *attrs = &devlink_port->attrs;
6531         int ret;
6532 
6533         ret = __devlink_port_attrs_set(devlink_port,
6534                                        DEVLINK_PORT_FLAVOUR_PCI_PF,
6535                                        switch_id, switch_id_len);
6536         if (ret)
6537                 return;
6538 
6539         attrs->pci_pf.pf = pf;
6540 }
6541 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
6542 
6543 /**
6544  *      devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
6545  *
6546  *      @devlink_port: devlink port
6547  *      @pf: associated PF for the devlink port instance
6548  *      @vf: associated VF of a PF for the devlink port instance
6549  *      @switch_id: if the port is part of switch, this is buffer with ID,
6550  *                  otherwise this is NULL
6551  *      @switch_id_len: length of the switch_id buffer
6552  */
6553 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
6554                                    const unsigned char *switch_id,
6555                                    unsigned char switch_id_len,
6556                                    u16 pf, u16 vf)
6557 {
6558         struct devlink_port_attrs *attrs = &devlink_port->attrs;
6559         int ret;
6560 
6561         ret = __devlink_port_attrs_set(devlink_port,
6562                                        DEVLINK_PORT_FLAVOUR_PCI_VF,
6563                                        switch_id, switch_id_len);
6564         if (ret)
6565                 return;
6566         attrs->pci_vf.pf = pf;
6567         attrs->pci_vf.vf = vf;
6568 }
6569 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
6570 
6571 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
6572                                              char *name, size_t len)
6573 {
6574         struct devlink_port_attrs *attrs = &devlink_port->attrs;
6575         int n = 0;
6576 
6577         if (!attrs->set)
6578                 return -EOPNOTSUPP;
6579 
6580         switch (attrs->flavour) {
6581         case DEVLINK_PORT_FLAVOUR_PHYSICAL:
6582                 if (!attrs->split)
6583                         n = snprintf(name, len, "p%u", attrs->phys.port_number);
6584                 else
6585                         n = snprintf(name, len, "p%us%u",
6586                                      attrs->phys.port_number,
6587                                      attrs->phys.split_subport_number);
6588                 break;
6589         case DEVLINK_PORT_FLAVOUR_CPU:
6590         case DEVLINK_PORT_FLAVOUR_DSA:
6591                 /* As CPU and DSA ports do not have a netdevice associated
6592                  * case should not ever happen.
6593                  */
6594                 WARN_ON(1);
6595                 return -EINVAL;
6596         case DEVLINK_PORT_FLAVOUR_PCI_PF:
6597                 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
6598                 break;
6599         case DEVLINK_PORT_FLAVOUR_PCI_VF:
6600                 n = snprintf(name, len, "pf%uvf%u",
6601                              attrs->pci_vf.pf, attrs->pci_vf.vf);
6602                 break;
6603         }
6604 
6605         if (n >= len)
6606                 return -EINVAL;
6607 
6608         return 0;
6609 }
6610 
6611 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
6612                         u32 size, u16 ingress_pools_count,
6613                         u16 egress_pools_count, u16 ingress_tc_count,
6614                         u16 egress_tc_count)
6615 {
6616         struct devlink_sb *devlink_sb;
6617         int err = 0;
6618 
6619         mutex_lock(&devlink->lock);
6620         if (devlink_sb_index_exists(devlink, sb_index)) {
6621                 err = -EEXIST;
6622                 goto unlock;
6623         }
6624 
6625         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
6626         if (!devlink_sb) {
6627                 err = -ENOMEM;
6628                 goto unlock;
6629         }
6630         devlink_sb->index = sb_index;
6631         devlink_sb->size = size;
6632         devlink_sb->ingress_pools_count = ingress_pools_count;
6633         devlink_sb->egress_pools_count = egress_pools_count;
6634         devlink_sb->ingress_tc_count = ingress_tc_count;
6635         devlink_sb->egress_tc_count = egress_tc_count;
6636         list_add_tail(&devlink_sb->list, &devlink->sb_list);
6637 unlock:
6638         mutex_unlock(&devlink->lock);
6639         return err;
6640 }
6641 EXPORT_SYMBOL_GPL(devlink_sb_register);
6642 
6643 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
6644 {
6645         struct devlink_sb *devlink_sb;
6646 
6647         mutex_lock(&devlink->lock);
6648         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
6649         WARN_ON(!devlink_sb);
6650         list_del(&devlink_sb->list);
6651         mutex_unlock(&devlink->lock);
6652         kfree(devlink_sb);
6653 }
6654 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
6655 
6656 /**
6657  *      devlink_dpipe_headers_register - register dpipe headers
6658  *
6659  *      @devlink: devlink
6660  *      @dpipe_headers: dpipe header array
6661  *
6662  *      Register the headers supported by hardware.
6663  */
6664 int devlink_dpipe_headers_register(struct devlink *devlink,
6665                                    struct devlink_dpipe_headers *dpipe_headers)
6666 {
6667         mutex_lock(&devlink->lock);
6668         devlink->dpipe_headers = dpipe_headers;
6669         mutex_unlock(&devlink->lock);
6670         return 0;
6671 }
6672 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
6673 
6674 /**
6675  *      devlink_dpipe_headers_unregister - unregister dpipe headers
6676  *
6677  *      @devlink: devlink
6678  *
6679  *      Unregister the headers supported by hardware.
6680  */
6681 void devlink_dpipe_headers_unregister(struct devlink *devlink)
6682 {
6683         mutex_lock(&devlink->lock);
6684         devlink->dpipe_headers = NULL;
6685         mutex_unlock(&devlink->lock);
6686 }
6687 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
6688 
6689 /**
6690  *      devlink_dpipe_table_counter_enabled - check if counter allocation
6691  *                                            required
6692  *      @devlink: devlink
6693  *      @table_name: tables name
6694  *
6695  *      Used by driver to check if counter allocation is required.
6696  *      After counter allocation is turned on the table entries
6697  *      are updated to include counter statistics.
6698  *
6699  *      After that point on the driver must respect the counter
6700  *      state so that each entry added to the table is added
6701  *      with a counter.
6702  */
6703 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
6704                                          const char *table_name)
6705 {
6706         struct devlink_dpipe_table *table;
6707         bool enabled;
6708 
6709         rcu_read_lock();
6710         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
6711                                          table_name);
6712         enabled = false;
6713         if (table)
6714                 enabled = table->counters_enabled;
6715         rcu_read_unlock();
6716         return enabled;
6717 }
6718 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
6719 
6720 /**
6721  *      devlink_dpipe_table_register - register dpipe table
6722  *
6723  *      @devlink: devlink
6724  *      @table_name: table name
6725  *      @table_ops: table ops
6726  *      @priv: priv
6727  *      @counter_control_extern: external control for counters
6728  */
6729 int devlink_dpipe_table_register(struct devlink *devlink,
6730                                  const char *table_name,
6731                                  struct devlink_dpipe_table_ops *table_ops,
6732                                  void *priv, bool counter_control_extern)
6733 {
6734         struct devlink_dpipe_table *table;
6735 
6736         if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
6737                 return -EEXIST;
6738 
6739         if (WARN_ON(!table_ops->size_get))
6740                 return -EINVAL;
6741 
6742         table = kzalloc(sizeof(*table), GFP_KERNEL);
6743         if (!table)
6744                 return -ENOMEM;
6745 
6746         table->name = table_name;
6747         table->table_ops = table_ops;
6748         table->priv = priv;
6749         table->counter_control_extern = counter_control_extern;
6750 
6751         mutex_lock(&devlink->lock);
6752         list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
6753         mutex_unlock(&devlink->lock);
6754         return 0;
6755 }
6756 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
6757 
6758 /**
6759  *      devlink_dpipe_table_unregister - unregister dpipe table
6760  *
6761  *      @devlink: devlink
6762  *      @table_name: table name
6763  */
6764 void devlink_dpipe_table_unregister(struct devlink *devlink,
6765                                     const char *table_name)
6766 {
6767         struct devlink_dpipe_table *table;
6768 
6769         mutex_lock(&devlink->lock);
6770         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
6771                                          table_name);
6772         if (!table)
6773                 goto unlock;
6774         list_del_rcu(&table->list);
6775         mutex_unlock(&devlink->lock);
6776         kfree_rcu(table, rcu);
6777         return;
6778 unlock:
6779         mutex_unlock(&devlink->lock);
6780 }
6781 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
6782 
6783 /**
6784  *      devlink_resource_register - devlink resource register
6785  *
6786  *      @devlink: devlink
6787  *      @resource_name: resource's name
6788  *      @resource_size: resource's size
6789  *      @resource_id: resource's id
6790  *      @parent_resource_id: resource's parent id
6791  *      @size_params: size parameters
6792  */
6793 int devlink_resource_register(struct devlink *devlink,
6794                               const char *resource_name,
6795                               u64 resource_size,
6796                               u64 resource_id,
6797                               u64 parent_resource_id,
6798                               const struct devlink_resource_size_params *size_params)
6799 {
6800         struct devlink_resource *resource;
6801         struct list_head *resource_list;
6802         bool top_hierarchy;
6803         int err = 0;
6804 
6805         top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
6806 
6807         mutex_lock(&devlink->lock);
6808         resource = devlink_resource_find(devlink, NULL, resource_id);
6809         if (resource) {
6810                 err = -EINVAL;
6811                 goto out;
6812         }
6813 
6814         resource = kzalloc(sizeof(*resource), GFP_KERNEL);
6815         if (!resource) {
6816                 err = -ENOMEM;
6817                 goto out;
6818         }
6819 
6820         if (top_hierarchy) {
6821                 resource_list = &devlink->resource_list;
6822         } else {
6823                 struct devlink_resource *parent_resource;
6824 
6825                 parent_resource = devlink_resource_find(devlink, NULL,
6826                                                         parent_resource_id);
6827                 if (parent_resource) {
6828                         resource_list = &parent_resource->resource_list;
6829                         resource->parent = parent_resource;
6830                 } else {
6831                         kfree(resource);
6832                         err = -EINVAL;
6833                         goto out;
6834                 }
6835         }
6836 
6837         resource->name = resource_name;
6838         resource->size = resource_size;
6839         resource->size_new = resource_size;
6840         resource->id = resource_id;
6841         resource->size_valid = true;
6842         memcpy(&resource->size_params, size_params,
6843                sizeof(resource->size_params));
6844         INIT_LIST_HEAD(&resource->resource_list);
6845         list_add_tail(&resource->list, resource_list);
6846 out:
6847         mutex_unlock(&devlink->lock);
6848         return err;
6849 }
6850 EXPORT_SYMBOL_GPL(devlink_resource_register);
6851 
6852 /**
6853  *      devlink_resources_unregister - free all resources
6854  *
6855  *      @devlink: devlink
6856  *      @resource: resource
6857  */
6858 void devlink_resources_unregister(struct devlink *devlink,
6859                                   struct devlink_resource *resource)
6860 {
6861         struct devlink_resource *tmp, *child_resource;
6862         struct list_head *resource_list;
6863 
6864         if (resource)
6865                 resource_list = &resource->resource_list;
6866         else
6867                 resource_list = &devlink->resource_list;
6868 
6869         if (!resource)
6870                 mutex_lock(&devlink->lock);
6871 
6872         list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
6873                 devlink_resources_unregister(devlink, child_resource);
6874                 list_del(&child_resource->list);
6875                 kfree(child_resource);
6876         }
6877 
6878         if (!resource)
6879                 mutex_unlock(&devlink->lock);
6880 }
6881 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
6882 
6883 /**
6884  *      devlink_resource_size_get - get and update size
6885  *
6886  *      @devlink: devlink
6887  *      @resource_id: the requested resource id
6888  *      @p_resource_size: ptr to update
6889  */
6890 int devlink_resource_size_get(struct devlink *devlink,
6891                               u64 resource_id,
6892                               u64 *p_resource_size)
6893 {
6894         struct devlink_resource *resource;
6895         int err = 0;
6896 
6897         mutex_lock(&devlink->lock);
6898         resource = devlink_resource_find(devlink, NULL, resource_id);
6899         if (!resource) {
6900                 err = -EINVAL;
6901                 goto out;
6902         }
6903         *p_resource_size = resource->size_new;
6904         resource->size = resource->size_new;
6905 out:
6906         mutex_unlock(&devlink->lock);
6907         return err;
6908 }
6909 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
6910 
6911 /**
6912  *      devlink_dpipe_table_resource_set - set the resource id
6913  *
6914  *      @devlink: devlink
6915  *      @table_name: table name
6916  *      @resource_id: resource id
6917  *      @resource_units: number of resource's units consumed per table's entry
6918  */
6919 int devlink_dpipe_table_resource_set(struct devlink *devlink,
6920                                      const char *table_name, u64 resource_id,
6921                                      u64 resource_units)
6922 {
6923         struct devlink_dpipe_table *table;
6924         int err = 0;
6925 
6926         mutex_lock(&devlink->lock);
6927         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
6928                                          table_name);
6929         if (!table) {
6930                 err = -EINVAL;
6931                 goto out;
6932         }
6933         table->resource_id = resource_id;
6934         table->resource_units = resource_units;
6935         table->resource_valid = true;
6936 out:
6937         mutex_unlock(&devlink->lock);
6938         return err;
6939 }
6940 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
6941 
6942 /**
6943  *      devlink_resource_occ_get_register - register occupancy getter
6944  *
6945  *      @devlink: devlink
6946  *      @resource_id: resource id
6947  *      @occ_get: occupancy getter callback
6948  *      @occ_get_priv: occupancy getter callback priv
6949  */
6950 void devlink_resource_occ_get_register(struct devlink *devlink,
6951                                        u64 resource_id,
6952                                        devlink_resource_occ_get_t *occ_get,
6953                                        void *occ_get_priv)
6954 {
6955         struct devlink_resource *resource;
6956 
6957         mutex_lock(&devlink->lock);
6958         resource = devlink_resource_find(devlink, NULL, resource_id);
6959         if (WARN_ON(!resource))
6960                 goto out;
6961         WARN_ON(resource->occ_get);
6962 
6963         resource->occ_get = occ_get;
6964         resource->occ_get_priv = occ_get_priv;
6965 out:
6966         mutex_unlock(&devlink->lock);
6967 }
6968 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
6969 
6970 /**
6971  *      devlink_resource_occ_get_unregister - unregister occupancy getter
6972  *
6973  *      @devlink: devlink
6974  *      @resource_id: resource id
6975  */
6976 void devlink_resource_occ_get_unregister(struct devlink *devlink,
6977                                          u64 resource_id)
6978 {
6979         struct devlink_resource *resource;
6980 
6981         mutex_lock(&devlink->lock);
6982         resource = devlink_resource_find(devlink, NULL, resource_id);
6983         if (WARN_ON(!resource))
6984                 goto out;
6985         WARN_ON(!resource->occ_get);
6986 
6987         resource->occ_get = NULL;
6988         resource->occ_get_priv = NULL;
6989 out:
6990         mutex_unlock(&devlink->lock);
6991 }
6992 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
6993 
6994 static int devlink_param_verify(const struct devlink_param *param)
6995 {
6996         if (!param || !param->name || !param->supported_cmodes)
6997                 return -EINVAL;
6998         if (param->generic)
6999                 return devlink_param_generic_verify(param);
7000         else
7001                 return devlink_param_driver_verify(param);
7002 }
7003 
7004 static int __devlink_params_register(struct devlink *devlink,
7005                                      unsigned int port_index,
7006                                      struct list_head *param_list,
7007                                      const struct devlink_param *params,
7008                                      size_t params_count,
7009                                      enum devlink_command reg_cmd,
7010                                      enum devlink_command unreg_cmd)
7011 {
7012         const struct devlink_param *param = params;
7013         int i;
7014         int err;
7015 
7016         mutex_lock(&devlink->lock);
7017         for (i = 0; i < params_count; i++, param++) {
7018                 err = devlink_param_verify(param);
7019                 if (err)
7020                         goto rollback;
7021 
7022                 err = devlink_param_register_one(devlink, port_index,
7023                                                  param_list, param, reg_cmd);
7024                 if (err)
7025                         goto rollback;
7026         }
7027 
7028         mutex_unlock(&devlink->lock);
7029         return 0;
7030 
7031 rollback:
7032         if (!i)
7033                 goto unlock;
7034         for (param--; i > 0; i--, param--)
7035                 devlink_param_unregister_one(devlink, port_index, param_list,
7036                                              param, unreg_cmd);
7037 unlock:
7038         mutex_unlock(&devlink->lock);
7039         return err;
7040 }
7041 
7042 static void __devlink_params_unregister(struct devlink *devlink,
7043                                         unsigned int port_index,
7044                                         struct list_head *param_list,
7045                                         const struct devlink_param *params,
7046                                         size_t params_count,
7047                                         enum devlink_command cmd)
7048 {
7049         const struct devlink_param *param = params;
7050         int i;
7051 
7052         mutex_lock(&devlink->lock);
7053         for (i = 0; i < params_count; i++, param++)
7054                 devlink_param_unregister_one(devlink, 0, param_list, param,
7055                                              cmd);
7056         mutex_unlock(&devlink->lock);
7057 }
7058 
7059 /**
7060  *      devlink_params_register - register configuration parameters
7061  *
7062  *      @devlink: devlink
7063  *      @params: configuration parameters array
7064  *      @params_count: number of parameters provided
7065  *
7066  *      Register the configuration parameters supported by the driver.
7067  */
7068 int devlink_params_register(struct devlink *devlink,
7069                             const struct devlink_param *params,
7070                             size_t params_count)
7071 {
7072         return __devlink_params_register(devlink, 0, &devlink->param_list,
7073                                          params, params_count,
7074                                          DEVLINK_CMD_PARAM_NEW,
7075                                          DEVLINK_CMD_PARAM_DEL);
7076 }
7077 EXPORT_SYMBOL_GPL(devlink_params_register);
7078 
7079 /**
7080  *      devlink_params_unregister - unregister configuration parameters
7081  *      @devlink: devlink
7082  *      @params: configuration parameters to unregister
7083  *      @params_count: number of parameters provided
7084  */
7085 void devlink_params_unregister(struct devlink *devlink,
7086                                const struct devlink_param *params,
7087                                size_t params_count)
7088 {
7089         return __devlink_params_unregister(devlink, 0, &devlink->param_list,
7090                                            params, params_count,
7091                                            DEVLINK_CMD_PARAM_DEL);
7092 }
7093 EXPORT_SYMBOL_GPL(devlink_params_unregister);
7094 
7095 /**
7096  *      devlink_params_publish - publish configuration parameters
7097  *
7098  *      @devlink: devlink
7099  *
7100  *      Publish previously registered configuration parameters.
7101  */
7102 void devlink_params_publish(struct devlink *devlink)
7103 {
7104         struct devlink_param_item *param_item;
7105 
7106         list_for_each_entry(param_item, &devlink->param_list, list) {
7107                 if (param_item->published)
7108                         continue;
7109                 param_item->published = true;
7110                 devlink_param_notify(devlink, 0, param_item,
7111                                      DEVLINK_CMD_PARAM_NEW);
7112         }
7113 }
7114 EXPORT_SYMBOL_GPL(devlink_params_publish);
7115 
7116 /**
7117  *      devlink_params_unpublish - unpublish configuration parameters
7118  *
7119  *      @devlink: devlink
7120  *
7121  *      Unpublish previously registered configuration parameters.
7122  */
7123 void devlink_params_unpublish(struct devlink *devlink)
7124 {
7125         struct devlink_param_item *param_item;
7126 
7127         list_for_each_entry(param_item, &devlink->param_list, list) {
7128                 if (!param_item->published)
7129                         continue;
7130                 param_item->published = false;
7131                 devlink_param_notify(devlink, 0, param_item,
7132                                      DEVLINK_CMD_PARAM_DEL);
7133         }
7134 }
7135 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
7136 
7137 /**
7138  *      devlink_port_params_register - register port configuration parameters
7139  *
7140  *      @devlink_port: devlink port
7141  *      @params: configuration parameters array
7142  *      @params_count: number of parameters provided
7143  *
7144  *      Register the configuration parameters supported by the port.
7145  */
7146 int devlink_port_params_register(struct devlink_port *devlink_port,
7147                                  const struct devlink_param *params,
7148                                  size_t params_count)
7149 {
7150         return __devlink_params_register(devlink_port->devlink,
7151                                          devlink_port->index,
7152                                          &devlink_port->param_list, params,
7153                                          params_count,
7154                                          DEVLINK_CMD_PORT_PARAM_NEW,
7155                                          DEVLINK_CMD_PORT_PARAM_DEL);
7156 }
7157 EXPORT_SYMBOL_GPL(devlink_port_params_register);
7158 
7159 /**
7160  *      devlink_port_params_unregister - unregister port configuration
7161  *      parameters
7162  *
7163  *      @devlink_port: devlink port
7164  *      @params: configuration parameters array
7165  *      @params_count: number of parameters provided
7166  */
7167 void devlink_port_params_unregister(struct devlink_port *devlink_port,
7168                                     const struct devlink_param *params,
7169                                     size_t params_count)
7170 {
7171         return __devlink_params_unregister(devlink_port->devlink,
7172                                            devlink_port->index,
7173                                            &devlink_port->param_list,
7174                                            params, params_count,
7175                                            DEVLINK_CMD_PORT_PARAM_DEL);
7176 }
7177 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
7178 
7179 static int
7180 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
7181                                      union devlink_param_value *init_val)
7182 {
7183         struct devlink_param_item *param_item;
7184 
7185         param_item = devlink_param_find_by_id(param_list, param_id);
7186         if (!param_item)
7187                 return -EINVAL;
7188 
7189         if (!param_item->driverinit_value_valid ||
7190             !devlink_param_cmode_is_supported(param_item->param,
7191                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
7192                 return -EOPNOTSUPP;
7193 
7194         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
7195                 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
7196         else
7197                 *init_val = param_item->driverinit_value;
7198 
7199         return 0;
7200 }
7201 
7202 static int
7203 __devlink_param_driverinit_value_set(struct devlink *devlink,
7204                                      unsigned int port_index,
7205                                      struct list_head *param_list, u32 param_id,
7206                                      union devlink_param_value init_val,
7207                                      enum devlink_command cmd)
7208 {
7209         struct devlink_param_item *param_item;
7210 
7211         param_item = devlink_param_find_by_id(param_list, param_id);
7212         if (!param_item)
7213                 return -EINVAL;
7214 
7215         if (!devlink_param_cmode_is_supported(param_item->param,
7216                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
7217                 return -EOPNOTSUPP;
7218 
7219         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
7220                 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
7221         else
7222                 param_item->driverinit_value = init_val;
7223         param_item->driverinit_value_valid = true;
7224 
7225         devlink_param_notify(devlink, port_index, param_item, cmd);
7226         return 0;
7227 }
7228 
7229 /**
7230  *      devlink_param_driverinit_value_get - get configuration parameter
7231  *                                           value for driver initializing
7232  *
7233  *      @devlink: devlink
7234  *      @param_id: parameter ID
7235  *      @init_val: value of parameter in driverinit configuration mode
7236  *
7237  *      This function should be used by the driver to get driverinit
7238  *      configuration for initialization after reload command.
7239  */
7240 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
7241                                        union devlink_param_value *init_val)
7242 {
7243         if (!devlink_reload_supported(devlink))
7244                 return -EOPNOTSUPP;
7245 
7246         return __devlink_param_driverinit_value_get(&devlink->param_list,
7247                                                     param_id, init_val);
7248 }
7249 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
7250 
7251 /**
7252  *      devlink_param_driverinit_value_set - set value of configuration
7253  *                                           parameter for driverinit
7254  *                                           configuration mode
7255  *
7256  *      @devlink: devlink
7257  *      @param_id: parameter ID
7258  *      @init_val: value of parameter to set for driverinit configuration mode
7259  *
7260  *      This function should be used by the driver to set driverinit
7261  *      configuration mode default value.
7262  */
7263 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
7264                                        union devlink_param_value init_val)
7265 {
7266         return __devlink_param_driverinit_value_set(devlink, 0,
7267                                                     &devlink->param_list,
7268                                                     param_id, init_val,
7269                                                     DEVLINK_CMD_PARAM_NEW);
7270 }
7271 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
7272 
7273 /**
7274  *      devlink_port_param_driverinit_value_get - get configuration parameter
7275  *                                              value for driver initializing
7276  *
7277  *      @devlink_port: devlink_port
7278  *      @param_id: parameter ID
7279  *      @init_val: value of parameter in driverinit configuration mode
7280  *
7281  *      This function should be used by the driver to get driverinit
7282  *      configuration for initialization after reload command.
7283  */
7284 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
7285                                             u32 param_id,
7286                                             union devlink_param_value *init_val)
7287 {
7288         struct devlink *devlink = devlink_port->devlink;
7289 
7290         if (!devlink_reload_supported(devlink))
7291                 return -EOPNOTSUPP;
7292 
7293         return __devlink_param_driverinit_value_get(&devlink_port->param_list,
7294                                                     param_id, init_val);
7295 }
7296 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
7297 
7298 /**
7299  *     devlink_port_param_driverinit_value_set - set value of configuration
7300  *                                               parameter for driverinit
7301  *                                               configuration mode
7302  *
7303  *     @devlink_port: devlink_port
7304  *     @param_id: parameter ID
7305  *     @init_val: value of parameter to set for driverinit configuration mode
7306  *
7307  *     This function should be used by the driver to set driverinit
7308  *     configuration mode default value.
7309  */
7310 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
7311                                             u32 param_id,
7312                                             union devlink_param_value init_val)
7313 {
7314         return __devlink_param_driverinit_value_set(devlink_port->devlink,
7315                                                     devlink_port->index,
7316                                                     &devlink_port->param_list,
7317                                                     param_id, init_val,
7318                                                     DEVLINK_CMD_PORT_PARAM_NEW);
7319 }
7320 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
7321 
7322 /**
7323  *      devlink_param_value_changed - notify devlink on a parameter's value
7324  *                                    change. Should be called by the driver
7325  *                                    right after the change.
7326  *
7327  *      @devlink: devlink
7328  *      @param_id: parameter ID
7329  *
7330  *      This function should be used by the driver to notify devlink on value
7331  *      change, excluding driverinit configuration mode.
7332  *      For driverinit configuration mode driver should use the function
7333  */
7334 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
7335 {
7336         struct devlink_param_item *param_item;
7337 
7338         param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
7339         WARN_ON(!param_item);
7340 
7341         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
7342 }
7343 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
7344 
7345 /**
7346  *     devlink_port_param_value_changed - notify devlink on a parameter's value
7347  *                                      change. Should be called by the driver
7348  *                                      right after the change.
7349  *
7350  *     @devlink_port: devlink_port
7351  *     @param_id: parameter ID
7352  *
7353  *     This function should be used by the driver to notify devlink on value
7354  *     change, excluding driverinit configuration mode.
7355  *     For driverinit configuration mode driver should use the function
7356  *     devlink_port_param_driverinit_value_set() instead.
7357  */
7358 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
7359                                       u32 param_id)
7360 {
7361         struct devlink_param_item *param_item;
7362 
7363         param_item = devlink_param_find_by_id(&devlink_port->param_list,
7364                                               param_id);
7365         WARN_ON(!param_item);
7366 
7367         devlink_param_notify(devlink_port->devlink, devlink_port->index,
7368                              param_item, DEVLINK_CMD_PORT_PARAM_NEW);
7369 }
7370 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
7371 
7372 /**
7373  *      devlink_param_value_str_fill - Safely fill-up the string preventing
7374  *                                     from overflow of the preallocated buffer
7375  *
7376  *      @dst_val: destination devlink_param_value
7377  *      @src: source buffer
7378  */
7379 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
7380                                   const char *src)
7381 {
7382         size_t len;
7383 
7384         len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
7385         WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
7386 }
7387 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
7388 
7389 /**
7390  *      devlink_region_create - create a new address region
7391  *
7392  *      @devlink: devlink
7393  *      @region_name: region name
7394  *      @region_max_snapshots: Maximum supported number of snapshots for region
7395  *      @region_size: size of region
7396  */
7397 struct devlink_region *devlink_region_create(struct devlink *devlink,
7398                                              const char *region_name,
7399                                              u32 region_max_snapshots,
7400                                              u64 region_size)
7401 {
7402         struct devlink_region *region;
7403         int err = 0;
7404 
7405         mutex_lock(&devlink->lock);
7406 
7407         if (devlink_region_get_by_name(devlink, region_name)) {
7408                 err = -EEXIST;
7409                 goto unlock;
7410         }
7411 
7412         region = kzalloc(sizeof(*region), GFP_KERNEL);
7413         if (!region) {
7414                 err = -ENOMEM;
7415                 goto unlock;
7416         }
7417 
7418         region->devlink = devlink;
7419         region->max_snapshots = region_max_snapshots;
7420         region->name = region_name;
7421         region->size = region_size;
7422         INIT_LIST_HEAD(&region->snapshot_list);
7423         list_add_tail(&region->list, &devlink->region_list);
7424         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
7425 
7426         mutex_unlock(&devlink->lock);
7427         return region;
7428 
7429 unlock:
7430         mutex_unlock(&devlink->lock);
7431         return ERR_PTR(err);
7432 }
7433 EXPORT_SYMBOL_GPL(devlink_region_create);
7434 
7435 /**
7436  *      devlink_region_destroy - destroy address region
7437  *
7438  *      @region: devlink region to destroy
7439  */
7440 void devlink_region_destroy(struct devlink_region *region)
7441 {
7442         struct devlink *devlink = region->devlink;
7443         struct devlink_snapshot *snapshot, *ts;
7444 
7445         mutex_lock(&devlink->lock);
7446 
7447         /* Free all snapshots of region */
7448         list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
7449                 devlink_region_snapshot_del(region, snapshot);
7450 
7451         list_del(&region->list);
7452 
7453         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
7454         mutex_unlock(&devlink->lock);
7455         kfree(region);
7456 }
7457 EXPORT_SYMBOL_GPL(devlink_region_destroy);
7458 
7459 /**
7460  *      devlink_region_shapshot_id_get - get snapshot ID
7461  *
7462  *      This callback should be called when adding a new snapshot,
7463  *      Driver should use the same id for multiple snapshots taken
7464  *      on multiple regions at the same time/by the same trigger.
7465  *
7466  *      @devlink: devlink
7467  */
7468 u32 devlink_region_shapshot_id_get(struct devlink *devlink)
7469 {
7470         u32 id;
7471 
7472         mutex_lock(&devlink->lock);
7473         id = ++devlink->snapshot_id;
7474         mutex_unlock(&devlink->lock);
7475 
7476         return id;
7477 }
7478 EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get);
7479 
7480 /**
7481  *      devlink_region_snapshot_create - create a new snapshot
7482  *      This will add a new snapshot of a region. The snapshot
7483  *      will be stored on the region struct and can be accessed
7484  *      from devlink. This is useful for future analyses of snapshots.
7485  *      Multiple snapshots can be created on a region.
7486  *      The @snapshot_id should be obtained using the getter function.
7487  *
7488  *      @region: devlink region of the snapshot
7489  *      @data: snapshot data
7490  *      @snapshot_id: snapshot id to be created
7491  *      @data_destructor: pointer to destructor function to free data
7492  */
7493 int devlink_region_snapshot_create(struct devlink_region *region,
7494                                    u8 *data, u32 snapshot_id,
7495                                    devlink_snapshot_data_dest_t *data_destructor)
7496 {
7497         struct devlink *devlink = region->devlink;
7498         struct devlink_snapshot *snapshot;
7499         int err;
7500 
7501         mutex_lock(&devlink->lock);
7502 
7503         /* check if region can hold one more snapshot */
7504         if (region->cur_snapshots == region->max_snapshots) {
7505                 err = -ENOMEM;
7506                 goto unlock;
7507         }
7508 
7509         if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
7510                 err = -EEXIST;
7511                 goto unlock;
7512         }
7513 
7514         snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
7515         if (!snapshot) {
7516                 err = -ENOMEM;
7517                 goto unlock;
7518         }
7519 
7520         snapshot->id = snapshot_id;
7521         snapshot->region = region;
7522         snapshot->data = data;
7523         snapshot->data_destructor = data_destructor;
7524 
7525         list_add_tail(&snapshot->list, &region->snapshot_list);
7526 
7527         region->cur_snapshots++;
7528 
7529         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
7530         mutex_unlock(&devlink->lock);
7531         return 0;
7532 
7533 unlock:
7534         mutex_unlock(&devlink->lock);
7535         return err;
7536 }
7537 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
7538 
7539 #define DEVLINK_TRAP(_id, _type)                                              \
7540         {                                                                     \
7541                 .type = DEVLINK_TRAP_TYPE_##_type,                            \
7542                 .id = DEVLINK_TRAP_GENERIC_ID_##_id,                          \
7543                 .name = DEVLINK_TRAP_GENERIC_NAME_##_id,                      \
7544         }
7545 
7546 static const struct devlink_trap devlink_trap_generic[] = {
7547         DEVLINK_TRAP(SMAC_MC, DROP),
7548         DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
7549         DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
7550         DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
7551         DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
7552         DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
7553         DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
7554         DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
7555         DEVLINK_TRAP(TAIL_DROP, DROP),
7556 };
7557 
7558 #define DEVLINK_TRAP_GROUP(_id)                                               \
7559         {                                                                     \
7560                 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id,                    \
7561                 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id,                \
7562         }
7563 
7564 static const struct devlink_trap_group devlink_trap_group_generic[] = {
7565         DEVLINK_TRAP_GROUP(L2_DROPS),
7566         DEVLINK_TRAP_GROUP(L3_DROPS),
7567         DEVLINK_TRAP_GROUP(BUFFER_DROPS),
7568 };
7569 
7570 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
7571 {
7572         if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
7573                 return -EINVAL;
7574 
7575         if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
7576                 return -EINVAL;
7577 
7578         if (trap->type != devlink_trap_generic[trap->id].type)
7579                 return -EINVAL;
7580 
7581         return 0;
7582 }
7583 
7584 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
7585 {
7586         int i;
7587 
7588         if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
7589                 return -EINVAL;
7590 
7591         for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
7592                 if (!strcmp(trap->name, devlink_trap_generic[i].name))
7593                         return -EEXIST;
7594         }
7595 
7596         return 0;
7597 }
7598 
7599 static int devlink_trap_verify(const struct devlink_trap *trap)
7600 {
7601         if (!trap || !trap->name || !trap->group.name)
7602                 return -EINVAL;
7603 
7604         if (trap->generic)
7605                 return devlink_trap_generic_verify(trap);
7606         else
7607                 return devlink_trap_driver_verify(trap);
7608 }
7609 
7610 static int
7611 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
7612 {
7613         if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
7614                 return -EINVAL;
7615 
7616         if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
7617                 return -EINVAL;
7618 
7619         return 0;
7620 }
7621 
7622 static int
7623 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
7624 {
7625         int i;
7626 
7627         if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
7628                 return -EINVAL;
7629 
7630         for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
7631                 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
7632                         return -EEXIST;
7633         }
7634 
7635         return 0;
7636 }
7637 
7638 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
7639 {
7640         if (group->generic)
7641                 return devlink_trap_group_generic_verify(group);
7642         else
7643                 return devlink_trap_group_driver_verify(group);
7644 }
7645 
7646 static void
7647 devlink_trap_group_notify(struct devlink *devlink,
7648                           const struct devlink_trap_group_item *group_item,
7649                           enum devlink_command cmd)
7650 {
7651         struct sk_buff *msg;
7652         int err;
7653 
7654         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
7655                      cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
7656 
7657         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7658         if (!msg)
7659                 return;
7660 
7661         err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
7662                                          0);
7663         if (err) {
7664                 nlmsg_free(msg);
7665                 return;
7666         }
7667 
7668         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
7669                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7670 }
7671 
7672 static struct devlink_trap_group_item *
7673 devlink_trap_group_item_create(struct devlink *devlink,
7674                                const struct devlink_trap_group *group)
7675 {
7676         struct devlink_trap_group_item *group_item;
7677         int err;
7678 
7679         err = devlink_trap_group_verify(group);
7680         if (err)
7681                 return ERR_PTR(err);
7682 
7683         group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
7684         if (!group_item)
7685                 return ERR_PTR(-ENOMEM);
7686 
7687         group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
7688         if (!group_item->stats) {
7689                 err = -ENOMEM;
7690                 goto err_stats_alloc;
7691         }
7692 
7693         group_item->group = group;
7694         refcount_set(&group_item->refcount, 1);
7695 
7696         if (devlink->ops->trap_group_init) {
7697                 err = devlink->ops->trap_group_init(devlink, group);
7698                 if (err)
7699                         goto err_group_init;
7700         }
7701 
7702         list_add_tail(&group_item->list, &devlink->trap_group_list);
7703         devlink_trap_group_notify(devlink, group_item,
7704                                   DEVLINK_CMD_TRAP_GROUP_NEW);
7705 
7706         return group_item;
7707 
7708 err_group_init:
7709         free_percpu(group_item->stats);
7710 err_stats_alloc:
7711         kfree(group_item);
7712         return ERR_PTR(err);
7713 }
7714 
7715 static void
7716 devlink_trap_group_item_destroy(struct devlink *devlink,
7717                                 struct devlink_trap_group_item *group_item)
7718 {
7719         devlink_trap_group_notify(devlink, group_item,
7720                                   DEVLINK_CMD_TRAP_GROUP_DEL);
7721         list_del(&group_item->list);
7722         free_percpu(group_item->stats);
7723         kfree(group_item);
7724 }
7725 
7726 static struct devlink_trap_group_item *
7727 devlink_trap_group_item_get(struct devlink *devlink,
7728                             const struct devlink_trap_group *group)
7729 {
7730         struct devlink_trap_group_item *group_item;
7731 
7732         group_item = devlink_trap_group_item_lookup(devlink, group->name);
7733         if (group_item) {
7734                 refcount_inc(&group_item->refcount);
7735                 return group_item;
7736         }
7737 
7738         return devlink_trap_group_item_create(devlink, group);
7739 }
7740 
7741 static void
7742 devlink_trap_group_item_put(struct devlink *devlink,
7743                             struct devlink_trap_group_item *group_item)
7744 {
7745         if (!refcount_dec_and_test(&group_item->refcount))
7746                 return;
7747 
7748         devlink_trap_group_item_destroy(devlink, group_item);
7749 }
7750 
7751 static int
7752 devlink_trap_item_group_link(struct devlink *devlink,
7753                              struct devlink_trap_item *trap_item)
7754 {
7755         struct devlink_trap_group_item *group_item;
7756 
7757         group_item = devlink_trap_group_item_get(devlink,
7758                                                  &trap_item->trap->group);
7759         if (IS_ERR(group_item))
7760                 return PTR_ERR(group_item);
7761 
7762         trap_item->group_item = group_item;
7763 
7764         return 0;
7765 }
7766 
7767 static void
7768 devlink_trap_item_group_unlink(struct devlink *devlink,
7769                                struct devlink_trap_item *trap_item)
7770 {
7771         devlink_trap_group_item_put(devlink, trap_item->group_item);
7772 }
7773 
7774 static void devlink_trap_notify(struct devlink *devlink,
7775                                 const struct devlink_trap_item *trap_item,
7776                                 enum devlink_command cmd)
7777 {
7778         struct sk_buff *msg;
7779         int err;
7780 
7781         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
7782                      cmd != DEVLINK_CMD_TRAP_DEL);
7783 
7784         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7785         if (!msg)
7786                 return;
7787 
7788         err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
7789         if (err) {
7790                 nlmsg_free(msg);
7791                 return;
7792         }
7793 
7794         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
7795                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7796 }
7797 
7798 static int
7799 devlink_trap_register(struct devlink *devlink,
7800                       const struct devlink_trap *trap, void *priv)
7801 {
7802         struct devlink_trap_item *trap_item;
7803         int err;
7804 
7805         if (devlink_trap_item_lookup(devlink, trap->name))
7806                 return -EEXIST;
7807 
7808         trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
7809         if (!trap_item)
7810                 return -ENOMEM;
7811 
7812         trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
7813         if (!trap_item->stats) {
7814                 err = -ENOMEM;
7815                 goto err_stats_alloc;
7816         }
7817 
7818         trap_item->trap = trap;
7819         trap_item->action = trap->init_action;
7820         trap_item->priv = priv;
7821 
7822         err = devlink_trap_item_group_link(devlink, trap_item);
7823         if (err)
7824                 goto err_group_link;
7825 
7826         err = devlink->ops->trap_init(devlink, trap, trap_item);
7827         if (err)
7828                 goto err_trap_init;
7829 
7830         list_add_tail(&trap_item->list, &devlink->trap_list);
7831         devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
7832 
7833         return 0;
7834 
7835 err_trap_init:
7836         devlink_trap_item_group_unlink(devlink, trap_item);
7837 err_group_link:
7838         free_percpu(trap_item->stats);
7839 err_stats_alloc:
7840         kfree(trap_item);
7841         return err;
7842 }
7843 
7844 static void devlink_trap_unregister(struct devlink *devlink,
7845                                     const struct devlink_trap *trap)
7846 {
7847         struct devlink_trap_item *trap_item;
7848 
7849         trap_item = devlink_trap_item_lookup(devlink, trap->name);
7850         if (WARN_ON_ONCE(!trap_item))
7851                 return;
7852 
7853         devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
7854         list_del(&trap_item->list);
7855         if (devlink->ops->trap_fini)
7856                 devlink->ops->trap_fini(devlink, trap, trap_item);
7857         devlink_trap_item_group_unlink(devlink, trap_item);
7858         free_percpu(trap_item->stats);
7859         kfree(trap_item);
7860 }
7861 
7862 static void devlink_trap_disable(struct devlink *devlink,
7863                                  const struct devlink_trap *trap)
7864 {
7865         struct devlink_trap_item *trap_item;
7866 
7867         trap_item = devlink_trap_item_lookup(devlink, trap->name);
7868         if (WARN_ON_ONCE(!trap_item))
7869                 return;
7870 
7871         devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP);
7872         trap_item->action = DEVLINK_TRAP_ACTION_DROP;
7873 }
7874 
7875 /**
7876  * devlink_traps_register - Register packet traps with devlink.
7877  * @devlink: devlink.
7878  * @traps: Packet traps.
7879  * @traps_count: Count of provided packet traps.
7880  * @priv: Driver private information.
7881  *
7882  * Return: Non-zero value on failure.
7883  */
7884 int devlink_traps_register(struct devlink *devlink,
7885                            const struct devlink_trap *traps,
7886                            size_t traps_count, void *priv)
7887 {
7888         int i, err;
7889 
7890         if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
7891                 return -EINVAL;
7892 
7893         mutex_lock(&devlink->lock);
7894         for (i = 0; i < traps_count; i++) {
7895                 const struct devlink_trap *trap = &traps[i];
7896 
7897                 err = devlink_trap_verify(trap);
7898                 if (err)
7899                         goto err_trap_verify;
7900 
7901                 err = devlink_trap_register(devlink, trap, priv);
7902                 if (err)
7903                         goto err_trap_register;
7904         }
7905         mutex_unlock(&devlink->lock);
7906 
7907         return 0;
7908 
7909 err_trap_register:
7910 err_trap_verify:
7911         for (i--; i >= 0; i--)
7912                 devlink_trap_unregister(devlink, &traps[i]);
7913         mutex_unlock(&devlink->lock);
7914         return err;
7915 }
7916 EXPORT_SYMBOL_GPL(devlink_traps_register);
7917 
7918 /**
7919  * devlink_traps_unregister - Unregister packet traps from devlink.
7920  * @devlink: devlink.
7921  * @traps: Packet traps.
7922  * @traps_count: Count of provided packet traps.
7923  */
7924 void devlink_traps_unregister(struct devlink *devlink,
7925                               const struct devlink_trap *traps,
7926                               size_t traps_count)
7927 {
7928         int i;
7929 
7930         mutex_lock(&devlink->lock);
7931         /* Make sure we do not have any packets in-flight while unregistering
7932          * traps by disabling all of them and waiting for a grace period.
7933          */
7934         for (i = traps_count - 1; i >= 0; i--)
7935                 devlink_trap_disable(devlink, &traps[i]);
7936         synchronize_rcu();
7937         for (i = traps_count - 1; i >= 0; i--)
7938                 devlink_trap_unregister(devlink, &traps[i]);
7939         mutex_unlock(&devlink->lock);
7940 }
7941 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
7942 
7943 static void
7944 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
7945                           size_t skb_len)
7946 {
7947         struct devlink_stats *stats;
7948 
7949         stats = this_cpu_ptr(trap_stats);
7950         u64_stats_update_begin(&stats->syncp);
7951         stats->rx_bytes += skb_len;
7952         stats->rx_packets++;
7953         u64_stats_update_end(&stats->syncp);
7954 }
7955 
7956 static void
7957 devlink_trap_report_metadata_fill(struct net_dm_hw_metadata *hw_metadata,
7958                                   const struct devlink_trap_item *trap_item,
7959                                   struct devlink_port *in_devlink_port)
7960 {
7961         struct devlink_trap_group_item *group_item = trap_item->group_item;
7962 
7963         hw_metadata->trap_group_name = group_item->group->name;
7964         hw_metadata->trap_name = trap_item->trap->name;
7965 
7966         spin_lock(&in_devlink_port->type_lock);
7967         if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
7968                 hw_metadata->input_dev = in_devlink_port->type_dev;
7969         spin_unlock(&in_devlink_port->type_lock);
7970 }
7971 
7972 /**
7973  * devlink_trap_report - Report trapped packet to drop monitor.
7974  * @devlink: devlink.
7975  * @skb: Trapped packet.
7976  * @trap_ctx: Trap context.
7977  * @in_devlink_port: Input devlink port.
7978  */
7979 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
7980                          void *trap_ctx, struct devlink_port *in_devlink_port)
7981 {
7982         struct devlink_trap_item *trap_item = trap_ctx;
7983         struct net_dm_hw_metadata hw_metadata = {};
7984 
7985         devlink_trap_stats_update(trap_item->stats, skb->len);
7986         devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
7987 
7988         devlink_trap_report_metadata_fill(&hw_metadata, trap_item,
7989                                           in_devlink_port);
7990         net_dm_hw_report(skb, &hw_metadata);
7991 }
7992 EXPORT_SYMBOL_GPL(devlink_trap_report);
7993 
7994 /**
7995  * devlink_trap_ctx_priv - Trap context to driver private information.
7996  * @trap_ctx: Trap context.
7997  *
7998  * Return: Driver private information passed during registration.
7999  */
8000 void *devlink_trap_ctx_priv(void *trap_ctx)
8001 {
8002         struct devlink_trap_item *trap_item = trap_ctx;
8003 
8004         return trap_item->priv;
8005 }
8006 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
8007 
8008 static void __devlink_compat_running_version(struct devlink *devlink,
8009                                              char *buf, size_t len)
8010 {
8011         const struct nlattr *nlattr;
8012         struct devlink_info_req req;
8013         struct sk_buff *msg;
8014         int rem, err;
8015 
8016         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8017         if (!msg)
8018                 return;
8019 
8020         req.msg = msg;
8021         err = devlink->ops->info_get(devlink, &req, NULL);
8022         if (err)
8023                 goto free_msg;
8024 
8025         nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
8026                 const struct nlattr *kv;
8027                 int rem_kv;
8028 
8029                 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
8030                         continue;
8031 
8032                 nla_for_each_nested(kv, nlattr, rem_kv) {
8033                         if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
8034                                 continue;
8035 
8036                         strlcat(buf, nla_data(kv), len);
8037                         strlcat(buf, " ", len);
8038                 }
8039         }
8040 free_msg:
8041         nlmsg_free(msg);
8042 }
8043 
8044 void devlink_compat_running_version(struct net_device *dev,
8045                                     char *buf, size_t len)
8046 {
8047         struct devlink *devlink;
8048 
8049         dev_hold(dev);
8050         rtnl_unlock();
8051 
8052         devlink = netdev_to_devlink(dev);
8053         if (!devlink || !devlink->ops->info_get)
8054                 goto out;
8055 
8056         mutex_lock(&devlink->lock);
8057         __devlink_compat_running_version(devlink, buf, len);
8058         mutex_unlock(&devlink->lock);
8059 
8060 out:
8061         rtnl_lock();
8062         dev_put(dev);
8063 }
8064 
8065 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
8066 {
8067         struct devlink *devlink;
8068         int ret;
8069 
8070         dev_hold(dev);
8071         rtnl_unlock();
8072 
8073         devlink = netdev_to_devlink(dev);
8074         if (!devlink || !devlink->ops->flash_update) {
8075                 ret = -EOPNOTSUPP;
8076                 goto out;
8077         }
8078 
8079         mutex_lock(&devlink->lock);
8080         ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
8081         mutex_unlock(&devlink->lock);
8082 
8083 out:
8084         rtnl_lock();
8085         dev_put(dev);
8086 
8087         return ret;
8088 }
8089 
8090 int devlink_compat_phys_port_name_get(struct net_device *dev,
8091                                       char *name, size_t len)
8092 {
8093         struct devlink_port *devlink_port;
8094 
8095         /* RTNL mutex is held here which ensures that devlink_port
8096          * instance cannot disappear in the middle. No need to take
8097          * any devlink lock as only permanent values are accessed.
8098          */
8099         ASSERT_RTNL();
8100 
8101         devlink_port = netdev_to_devlink_port(dev);
8102         if (!devlink_port)
8103                 return -EOPNOTSUPP;
8104 
8105         return __devlink_port_phys_port_name_get(devlink_port, name, len);
8106 }
8107 
8108 int devlink_compat_switch_id_get(struct net_device *dev,
8109                                  struct netdev_phys_item_id *ppid)
8110 {
8111         struct devlink_port *devlink_port;
8112 
8113         /* Caller must hold RTNL mutex or reference to dev, which ensures that
8114          * devlink_port instance cannot disappear in the middle. No need to take
8115          * any devlink lock as only permanent values are accessed.
8116          */
8117         devlink_port = netdev_to_devlink_port(dev);
8118         if (!devlink_port || !devlink_port->attrs.switch_port)
8119                 return -EOPNOTSUPP;
8120 
8121         memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
8122 
8123         return 0;
8124 }
8125 
8126 static int __init devlink_init(void)
8127 {
8128         return genl_register_family(&devlink_nl_family);
8129 }
8130 
8131 subsys_initcall(devlink_init);

/* [<][>][^][v][top][bottom][index][help] */