1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5 */ 6 7 #include <net/genetlink.h> 8 #include <net/sock.h> 9 10 #include "devl_internal.h" 11 12 #define DEVLINK_NL_FLAG_NEED_PORT BIT(0) 13 #define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1) 14 #define DEVLINK_NL_FLAG_NEED_DEV_LOCK BIT(2) 15 #define DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV BIT(3) 16 17 static const struct genl_multicast_group devlink_nl_mcgrps[] = { 18 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME }, 19 }; 20 21 struct devlink_nl_sock_priv { 22 struct devlink_obj_desc __rcu *flt; 23 spinlock_t flt_lock; /* Protects flt. */ 24 }; 25 26 static void devlink_nl_sock_priv_init(void *priv) 27 { 28 struct devlink_nl_sock_priv *sk_priv = priv; 29 30 spin_lock_init(&sk_priv->flt_lock); 31 } 32 33 static void devlink_nl_sock_priv_destroy(void *priv) 34 { 35 struct devlink_nl_sock_priv *sk_priv = priv; 36 struct devlink_obj_desc *flt; 37 38 flt = rcu_dereference_protected(sk_priv->flt, true); 39 kfree_rcu(flt, rcu); 40 } 41 42 int devlink_nl_notify_filter_set_doit(struct sk_buff *skb, 43 struct genl_info *info) 44 { 45 struct devlink_nl_sock_priv *sk_priv; 46 struct nlattr **attrs = info->attrs; 47 struct devlink_obj_desc *flt; 48 size_t data_offset = 0; 49 size_t data_size = 0; 50 char *pos; 51 52 if (attrs[DEVLINK_ATTR_BUS_NAME]) 53 data_size = size_add(data_size, 54 nla_len(attrs[DEVLINK_ATTR_BUS_NAME]) + 1); 55 if (attrs[DEVLINK_ATTR_DEV_NAME]) 56 data_size = size_add(data_size, 57 nla_len(attrs[DEVLINK_ATTR_DEV_NAME]) + 1); 58 59 flt = kzalloc(size_add(sizeof(*flt), data_size), GFP_KERNEL); 60 if (!flt) 61 return -ENOMEM; 62 63 pos = (char *) flt->data; 64 if (attrs[DEVLINK_ATTR_BUS_NAME]) { 65 data_offset += nla_strscpy(pos, 66 attrs[DEVLINK_ATTR_BUS_NAME], 67 data_size) + 1; 68 flt->bus_name = pos; 69 pos += data_offset; 70 } 71 if (attrs[DEVLINK_ATTR_DEV_NAME]) { 72 nla_strscpy(pos, attrs[DEVLINK_ATTR_DEV_NAME], 73 data_size - data_offset); 74 flt->dev_name = pos; 75 } 76 77 if (attrs[DEVLINK_ATTR_INDEX]) { 78 flt->devlink_index = nla_get_uint(attrs[DEVLINK_ATTR_INDEX]); 79 flt->devlink_index_valid = true; 80 } 81 82 if (attrs[DEVLINK_ATTR_PORT_INDEX]) { 83 flt->port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); 84 flt->port_index_valid = true; 85 } 86 87 /* Don't attach empty filter. */ 88 if (!flt->bus_name && !flt->dev_name && 89 !flt->devlink_index_valid && !flt->port_index_valid) { 90 kfree(flt); 91 flt = NULL; 92 } 93 94 sk_priv = genl_sk_priv_get(&devlink_nl_family, NETLINK_CB(skb).sk); 95 if (IS_ERR(sk_priv)) { 96 kfree(flt); 97 return PTR_ERR(sk_priv); 98 } 99 spin_lock(&sk_priv->flt_lock); 100 flt = rcu_replace_pointer(sk_priv->flt, flt, 101 lockdep_is_held(&sk_priv->flt_lock)); 102 spin_unlock(&sk_priv->flt_lock); 103 kfree_rcu(flt, rcu); 104 return 0; 105 } 106 107 static bool devlink_obj_desc_match(const struct devlink_obj_desc *desc, 108 const struct devlink_obj_desc *flt) 109 { 110 if (desc->devlink_index_valid && flt->devlink_index_valid && 111 desc->devlink_index != flt->devlink_index) 112 return false; 113 if (desc->bus_name && flt->bus_name && 114 strcmp(desc->bus_name, flt->bus_name)) 115 return false; 116 if (desc->dev_name && flt->dev_name && 117 strcmp(desc->dev_name, flt->dev_name)) 118 return false; 119 if (desc->port_index_valid && flt->port_index_valid && 120 desc->port_index != flt->port_index) 121 return false; 122 return true; 123 } 124 125 int devlink_nl_notify_filter(struct sock *dsk, struct sk_buff *skb, void *data) 126 { 127 struct devlink_obj_desc *desc = data; 128 struct devlink_nl_sock_priv *sk_priv; 129 struct devlink_obj_desc *flt; 130 int ret = 0; 131 132 rcu_read_lock(); 133 sk_priv = __genl_sk_priv_get(&devlink_nl_family, dsk); 134 if (!IS_ERR_OR_NULL(sk_priv)) { 135 flt = rcu_dereference(sk_priv->flt); 136 if (flt) 137 ret = !devlink_obj_desc_match(desc, flt); 138 } 139 rcu_read_unlock(); 140 return ret; 141 } 142 143 int devlink_nl_put_nested_handle(struct sk_buff *msg, struct net *net, 144 struct devlink *devlink, int attrtype) 145 { 146 struct nlattr *nested_attr; 147 struct net *devl_net; 148 149 nested_attr = nla_nest_start(msg, attrtype); 150 if (!nested_attr) 151 return -EMSGSIZE; 152 if (devlink_nl_put_handle(msg, devlink)) 153 goto nla_put_failure; 154 155 rcu_read_lock(); 156 devl_net = read_pnet_rcu(&devlink->_net); 157 if (!net_eq(net, devl_net)) { 158 int id = peernet2id_alloc(net, devl_net, GFP_ATOMIC); 159 160 rcu_read_unlock(); 161 if (nla_put_s32(msg, DEVLINK_ATTR_NETNS_ID, id)) 162 return -EMSGSIZE; 163 } else { 164 rcu_read_unlock(); 165 } 166 167 nla_nest_end(msg, nested_attr); 168 return 0; 169 170 nla_put_failure: 171 nla_nest_cancel(msg, nested_attr); 172 return -EMSGSIZE; 173 } 174 175 int devlink_nl_msg_reply_and_new(struct sk_buff **msg, struct genl_info *info) 176 { 177 int err; 178 179 if (*msg) { 180 err = genlmsg_reply(*msg, info); 181 if (err) 182 return err; 183 } 184 *msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 185 if (!*msg) 186 return -ENOMEM; 187 return 0; 188 } 189 190 struct devlink * 191 devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs, 192 bool dev_lock) 193 { 194 struct devlink *devlink; 195 unsigned long index; 196 char *busname; 197 char *devname; 198 199 if (attrs[DEVLINK_ATTR_INDEX]) { 200 if (attrs[DEVLINK_ATTR_BUS_NAME] || 201 attrs[DEVLINK_ATTR_DEV_NAME]) 202 return ERR_PTR(-EINVAL); 203 index = nla_get_u32(attrs[DEVLINK_ATTR_INDEX]); 204 devlink = devlinks_xa_lookup_get(net, index); 205 if (!devlink) 206 return ERR_PTR(-ENODEV); 207 goto found; 208 } 209 210 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME]) 211 return ERR_PTR(-EINVAL); 212 213 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]); 214 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); 215 216 if (!strcmp(busname, DEVLINK_INDEX_BUS_NAME)) { 217 if (kstrtoul(devname, 10, &index)) 218 return ERR_PTR(-ENODEV); 219 devlink = devlinks_xa_lookup_get(net, index); 220 if (!devlink) 221 return ERR_PTR(-ENODEV); 222 goto found; 223 } 224 225 devlinks_xa_for_each_registered_get(net, index, devlink) { 226 if (strcmp(devlink_bus_name(devlink), busname) == 0 && 227 strcmp(devlink_dev_name(devlink), devname) == 0) 228 goto found; 229 devlink_put(devlink); 230 } 231 232 return ERR_PTR(-ENODEV); 233 234 found: 235 devl_dev_lock(devlink, dev_lock); 236 if (devl_is_registered(devlink)) 237 return devlink; 238 devl_dev_unlock(devlink, dev_lock); 239 devlink_put(devlink); 240 return ERR_PTR(-ENODEV); 241 } 242 243 struct devlink * 244 devlink_get_parent_from_attrs_lock(struct net *net, struct nlattr **attrs) 245 { 246 unsigned int maxtype = ARRAY_SIZE(devlink_dl_parent_dev_nl_policy) - 1; 247 struct devlink *devlink; 248 struct nlattr **tb; 249 int err; 250 251 if (!attrs[DEVLINK_ATTR_PARENT_DEV]) 252 return ERR_PTR(-EINVAL); 253 254 tb = kcalloc(maxtype + 1, sizeof(*tb), GFP_KERNEL); 255 if (!tb) 256 return ERR_PTR(-ENOMEM); 257 258 err = nla_parse_nested(tb, maxtype, attrs[DEVLINK_ATTR_PARENT_DEV], 259 devlink_dl_parent_dev_nl_policy, NULL); 260 if (err) 261 goto out; 262 263 devlink = devlink_get_from_attrs_lock(net, tb, false); 264 kfree(tb); 265 return devlink; 266 out: 267 kfree(tb); 268 return ERR_PTR(err); 269 } 270 271 static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info, 272 u8 flags) 273 { 274 bool parent_dev = flags & DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV; 275 bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK; 276 struct devlink *devlink, *parent_devlink = NULL; 277 struct net *net = genl_info_net(info); 278 struct nlattr **attrs = info->attrs; 279 struct devlink_port *devlink_port; 280 int err; 281 282 if (parent_dev && attrs[DEVLINK_ATTR_PARENT_DEV]) { 283 parent_devlink = devlink_get_parent_from_attrs_lock(net, attrs); 284 if (IS_ERR(parent_devlink)) 285 return PTR_ERR(parent_devlink); 286 devlink_nl_ctx(info)->parent_devlink = parent_devlink; 287 /* Drop the parent devlink lock but don't release the reference. 288 * This will keep it alive until the end of the request. 289 */ 290 devl_unlock(parent_devlink); 291 } 292 293 devlink = devlink_get_from_attrs_lock(net, attrs, dev_lock); 294 if (IS_ERR(devlink)) { 295 err = PTR_ERR(devlink); 296 goto parent_put; 297 } 298 devlink_nl_ctx(info)->devlink = devlink; 299 if (flags & DEVLINK_NL_FLAG_NEED_PORT) { 300 devlink_port = devlink_port_get_from_info(devlink, info); 301 if (IS_ERR(devlink_port)) { 302 err = PTR_ERR(devlink_port); 303 goto unlock; 304 } 305 devlink_nl_ctx(info)->devlink_port = devlink_port; 306 } else if (flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) { 307 devlink_port = devlink_port_get_from_info(devlink, info); 308 if (!IS_ERR(devlink_port)) 309 devlink_nl_ctx(info)->devlink_port = devlink_port; 310 } 311 return 0; 312 313 unlock: 314 devl_dev_unlock(devlink, dev_lock); 315 devlink_put(devlink); 316 parent_put: 317 if (parent_dev && parent_devlink) 318 devlink_put(parent_devlink); 319 return err; 320 } 321 322 int devlink_nl_pre_doit(const struct genl_split_ops *ops, 323 struct sk_buff *skb, struct genl_info *info) 324 { 325 return __devlink_nl_pre_doit(skb, info, 0); 326 } 327 328 int devlink_nl_pre_doit_port(const struct genl_split_ops *ops, 329 struct sk_buff *skb, struct genl_info *info) 330 { 331 return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_PORT); 332 } 333 334 int devlink_nl_pre_doit_dev_lock(const struct genl_split_ops *ops, 335 struct sk_buff *skb, struct genl_info *info) 336 { 337 return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEV_LOCK); 338 } 339 340 int devlink_nl_pre_doit_port_optional(const struct genl_split_ops *ops, 341 struct sk_buff *skb, 342 struct genl_info *info) 343 { 344 return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT); 345 } 346 347 int devlink_nl_pre_doit_parent_dev_optional(const struct genl_split_ops *ops, 348 struct sk_buff *skb, 349 struct genl_info *info) 350 { 351 return __devlink_nl_pre_doit(skb, info, 352 DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV); 353 } 354 355 static void __devlink_nl_post_doit(struct sk_buff *skb, struct genl_info *info, 356 u8 flags) 357 { 358 bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK; 359 struct devlink *devlink; 360 361 devlink = devlink_nl_ctx(info)->devlink; 362 devl_dev_unlock(devlink, dev_lock); 363 devlink_put(devlink); 364 if (devlink_nl_ctx(info)->parent_devlink) 365 devlink_put(devlink_nl_ctx(info)->parent_devlink); 366 } 367 368 void devlink_nl_post_doit(const struct genl_split_ops *ops, 369 struct sk_buff *skb, struct genl_info *info) 370 { 371 __devlink_nl_post_doit(skb, info, 0); 372 } 373 374 void 375 devlink_nl_post_doit_dev_lock(const struct genl_split_ops *ops, 376 struct sk_buff *skb, struct genl_info *info) 377 { 378 __devlink_nl_post_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEV_LOCK); 379 } 380 381 void 382 devlink_nl_post_doit_parent_dev_optional(const struct genl_split_ops *ops, 383 struct sk_buff *skb, 384 struct genl_info *info) 385 { 386 __devlink_nl_post_doit(skb, info, DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV); 387 } 388 389 static int devlink_nl_inst_single_dumpit(struct sk_buff *msg, 390 struct netlink_callback *cb, int flags, 391 devlink_nl_dump_one_func_t *dump_one, 392 struct nlattr **attrs) 393 { 394 struct devlink *devlink; 395 int err; 396 397 devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), attrs, false); 398 if (IS_ERR(devlink)) 399 return PTR_ERR(devlink); 400 err = dump_one(msg, devlink, cb, flags | NLM_F_DUMP_FILTERED); 401 402 devl_unlock(devlink); 403 devlink_put(devlink); 404 405 if (err != -EMSGSIZE) 406 return err; 407 return msg->len; 408 } 409 410 static int devlink_nl_inst_iter_dumpit(struct sk_buff *msg, 411 struct netlink_callback *cb, int flags, 412 devlink_nl_dump_one_func_t *dump_one) 413 { 414 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 415 struct devlink *devlink; 416 int err = 0; 417 418 while ((devlink = devlinks_xa_find_get(sock_net(msg->sk), 419 &state->instance))) { 420 devl_lock(devlink); 421 422 if (devl_is_registered(devlink)) 423 err = dump_one(msg, devlink, cb, flags); 424 else 425 err = 0; 426 427 devl_unlock(devlink); 428 devlink_put(devlink); 429 430 if (err) 431 break; 432 433 state->instance++; 434 435 /* restart sub-object walk for the next instance */ 436 state->idx = 0; 437 state->port_ctx.index = 0; 438 state->port_ctx.index_valid = false; 439 } 440 441 if (err != -EMSGSIZE) 442 return err; 443 return msg->len; 444 } 445 446 int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb, 447 devlink_nl_dump_one_func_t *dump_one) 448 { 449 const struct genl_info *info = genl_info_dump(cb); 450 struct nlattr **attrs = info->attrs; 451 int flags = NLM_F_MULTI; 452 453 if (attrs && 454 (attrs[DEVLINK_ATTR_BUS_NAME] || attrs[DEVLINK_ATTR_DEV_NAME] || 455 attrs[DEVLINK_ATTR_INDEX])) 456 return devlink_nl_inst_single_dumpit(msg, cb, flags, dump_one, 457 attrs); 458 else 459 return devlink_nl_inst_iter_dumpit(msg, cb, flags, dump_one); 460 } 461 462 struct genl_family devlink_nl_family __ro_after_init = { 463 .name = DEVLINK_GENL_NAME, 464 .version = DEVLINK_GENL_VERSION, 465 .netnsok = true, 466 .parallel_ops = true, 467 .module = THIS_MODULE, 468 .split_ops = devlink_nl_ops, 469 .n_split_ops = ARRAY_SIZE(devlink_nl_ops), 470 .resv_start_op = DEVLINK_CMD_SELFTESTS_RUN + 1, 471 .mcgrps = devlink_nl_mcgrps, 472 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 473 .sock_priv_size = sizeof(struct devlink_nl_sock_priv), 474 .sock_priv_init = devlink_nl_sock_priv_init, 475 .sock_priv_destroy = devlink_nl_sock_priv_destroy, 476 }; 477