netlink.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. #include <net/genetlink.h>
  7. #include <net/sock.h>
  8. #include "devl_internal.h"
  9. #define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
  10. #define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
  11. #define DEVLINK_NL_FLAG_NEED_DEV_LOCK BIT(2)
  12. static const struct genl_multicast_group devlink_nl_mcgrps[] = {
  13. [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
  14. };
  15. struct devlink_nl_sock_priv {
  16. struct devlink_obj_desc __rcu *flt;
  17. spinlock_t flt_lock; /* Protects flt. */
  18. };
  19. static void devlink_nl_sock_priv_init(void *priv)
  20. {
  21. struct devlink_nl_sock_priv *sk_priv = priv;
  22. spin_lock_init(&sk_priv->flt_lock);
  23. }
  24. static void devlink_nl_sock_priv_destroy(void *priv)
  25. {
  26. struct devlink_nl_sock_priv *sk_priv = priv;
  27. struct devlink_obj_desc *flt;
  28. flt = rcu_dereference_protected(sk_priv->flt, true);
  29. kfree_rcu(flt, rcu);
  30. }
  31. int devlink_nl_notify_filter_set_doit(struct sk_buff *skb,
  32. struct genl_info *info)
  33. {
  34. struct devlink_nl_sock_priv *sk_priv;
  35. struct nlattr **attrs = info->attrs;
  36. struct devlink_obj_desc *flt;
  37. size_t data_offset = 0;
  38. size_t data_size = 0;
  39. char *pos;
  40. if (attrs[DEVLINK_ATTR_BUS_NAME])
  41. data_size = size_add(data_size,
  42. nla_len(attrs[DEVLINK_ATTR_BUS_NAME]) + 1);
  43. if (attrs[DEVLINK_ATTR_DEV_NAME])
  44. data_size = size_add(data_size,
  45. nla_len(attrs[DEVLINK_ATTR_DEV_NAME]) + 1);
  46. flt = kzalloc(size_add(sizeof(*flt), data_size), GFP_KERNEL);
  47. if (!flt)
  48. return -ENOMEM;
  49. pos = (char *) flt->data;
  50. if (attrs[DEVLINK_ATTR_BUS_NAME]) {
  51. data_offset += nla_strscpy(pos,
  52. attrs[DEVLINK_ATTR_BUS_NAME],
  53. data_size) + 1;
  54. flt->bus_name = pos;
  55. pos += data_offset;
  56. }
  57. if (attrs[DEVLINK_ATTR_DEV_NAME]) {
  58. nla_strscpy(pos, attrs[DEVLINK_ATTR_DEV_NAME],
  59. data_size - data_offset);
  60. flt->dev_name = pos;
  61. }
  62. if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
  63. flt->port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
  64. flt->port_index_valid = true;
  65. }
  66. /* Don't attach empty filter. */
  67. if (!flt->bus_name && !flt->dev_name && !flt->port_index_valid) {
  68. kfree(flt);
  69. flt = NULL;
  70. }
  71. sk_priv = genl_sk_priv_get(&devlink_nl_family, NETLINK_CB(skb).sk);
  72. if (IS_ERR(sk_priv)) {
  73. kfree(flt);
  74. return PTR_ERR(sk_priv);
  75. }
  76. spin_lock(&sk_priv->flt_lock);
  77. flt = rcu_replace_pointer(sk_priv->flt, flt,
  78. lockdep_is_held(&sk_priv->flt_lock));
  79. spin_unlock(&sk_priv->flt_lock);
  80. kfree_rcu(flt, rcu);
  81. return 0;
  82. }
  83. static bool devlink_obj_desc_match(const struct devlink_obj_desc *desc,
  84. const struct devlink_obj_desc *flt)
  85. {
  86. if (desc->bus_name && flt->bus_name &&
  87. strcmp(desc->bus_name, flt->bus_name))
  88. return false;
  89. if (desc->dev_name && flt->dev_name &&
  90. strcmp(desc->dev_name, flt->dev_name))
  91. return false;
  92. if (desc->port_index_valid && flt->port_index_valid &&
  93. desc->port_index != flt->port_index)
  94. return false;
  95. return true;
  96. }
  97. int devlink_nl_notify_filter(struct sock *dsk, struct sk_buff *skb, void *data)
  98. {
  99. struct devlink_obj_desc *desc = data;
  100. struct devlink_nl_sock_priv *sk_priv;
  101. struct devlink_obj_desc *flt;
  102. int ret = 0;
  103. rcu_read_lock();
  104. sk_priv = __genl_sk_priv_get(&devlink_nl_family, dsk);
  105. if (!IS_ERR_OR_NULL(sk_priv)) {
  106. flt = rcu_dereference(sk_priv->flt);
  107. if (flt)
  108. ret = !devlink_obj_desc_match(desc, flt);
  109. }
  110. rcu_read_unlock();
  111. return ret;
  112. }
  113. int devlink_nl_put_nested_handle(struct sk_buff *msg, struct net *net,
  114. struct devlink *devlink, int attrtype)
  115. {
  116. struct nlattr *nested_attr;
  117. struct net *devl_net;
  118. nested_attr = nla_nest_start(msg, attrtype);
  119. if (!nested_attr)
  120. return -EMSGSIZE;
  121. if (devlink_nl_put_handle(msg, devlink))
  122. goto nla_put_failure;
  123. rcu_read_lock();
  124. devl_net = read_pnet_rcu(&devlink->_net);
  125. if (!net_eq(net, devl_net)) {
  126. int id = peernet2id_alloc(net, devl_net, GFP_ATOMIC);
  127. rcu_read_unlock();
  128. if (nla_put_s32(msg, DEVLINK_ATTR_NETNS_ID, id))
  129. return -EMSGSIZE;
  130. } else {
  131. rcu_read_unlock();
  132. }
  133. nla_nest_end(msg, nested_attr);
  134. return 0;
  135. nla_put_failure:
  136. nla_nest_cancel(msg, nested_attr);
  137. return -EMSGSIZE;
  138. }
  139. int devlink_nl_msg_reply_and_new(struct sk_buff **msg, struct genl_info *info)
  140. {
  141. int err;
  142. if (*msg) {
  143. err = genlmsg_reply(*msg, info);
  144. if (err)
  145. return err;
  146. }
  147. *msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
  148. if (!*msg)
  149. return -ENOMEM;
  150. return 0;
  151. }
  152. struct devlink *
  153. devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
  154. bool dev_lock)
  155. {
  156. struct devlink *devlink;
  157. unsigned long index;
  158. char *busname;
  159. char *devname;
  160. if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
  161. return ERR_PTR(-EINVAL);
  162. busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
  163. devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
  164. devlinks_xa_for_each_registered_get(net, index, devlink) {
  165. if (strcmp(devlink->dev->bus->name, busname) == 0 &&
  166. strcmp(dev_name(devlink->dev), devname) == 0) {
  167. devl_dev_lock(devlink, dev_lock);
  168. if (devl_is_registered(devlink))
  169. return devlink;
  170. devl_dev_unlock(devlink, dev_lock);
  171. }
  172. devlink_put(devlink);
  173. }
  174. return ERR_PTR(-ENODEV);
  175. }
  176. static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info,
  177. u8 flags)
  178. {
  179. bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK;
  180. struct devlink_port *devlink_port;
  181. struct devlink *devlink;
  182. int err;
  183. devlink = devlink_get_from_attrs_lock(genl_info_net(info), info->attrs,
  184. dev_lock);
  185. if (IS_ERR(devlink))
  186. return PTR_ERR(devlink);
  187. info->user_ptr[0] = devlink;
  188. if (flags & DEVLINK_NL_FLAG_NEED_PORT) {
  189. devlink_port = devlink_port_get_from_info(devlink, info);
  190. if (IS_ERR(devlink_port)) {
  191. err = PTR_ERR(devlink_port);
  192. goto unlock;
  193. }
  194. info->user_ptr[1] = devlink_port;
  195. } else if (flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
  196. devlink_port = devlink_port_get_from_info(devlink, info);
  197. if (!IS_ERR(devlink_port))
  198. info->user_ptr[1] = devlink_port;
  199. }
  200. return 0;
  201. unlock:
  202. devl_dev_unlock(devlink, dev_lock);
  203. devlink_put(devlink);
  204. return err;
  205. }
  206. int devlink_nl_pre_doit(const struct genl_split_ops *ops,
  207. struct sk_buff *skb, struct genl_info *info)
  208. {
  209. return __devlink_nl_pre_doit(skb, info, 0);
  210. }
  211. int devlink_nl_pre_doit_port(const struct genl_split_ops *ops,
  212. struct sk_buff *skb, struct genl_info *info)
  213. {
  214. return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_PORT);
  215. }
  216. int devlink_nl_pre_doit_dev_lock(const struct genl_split_ops *ops,
  217. struct sk_buff *skb, struct genl_info *info)
  218. {
  219. return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEV_LOCK);
  220. }
  221. int devlink_nl_pre_doit_port_optional(const struct genl_split_ops *ops,
  222. struct sk_buff *skb,
  223. struct genl_info *info)
  224. {
  225. return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT);
  226. }
  227. static void __devlink_nl_post_doit(struct sk_buff *skb, struct genl_info *info,
  228. u8 flags)
  229. {
  230. bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK;
  231. struct devlink *devlink;
  232. devlink = info->user_ptr[0];
  233. devl_dev_unlock(devlink, dev_lock);
  234. devlink_put(devlink);
  235. }
  236. void devlink_nl_post_doit(const struct genl_split_ops *ops,
  237. struct sk_buff *skb, struct genl_info *info)
  238. {
  239. __devlink_nl_post_doit(skb, info, 0);
  240. }
  241. void
  242. devlink_nl_post_doit_dev_lock(const struct genl_split_ops *ops,
  243. struct sk_buff *skb, struct genl_info *info)
  244. {
  245. __devlink_nl_post_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEV_LOCK);
  246. }
  247. static int devlink_nl_inst_single_dumpit(struct sk_buff *msg,
  248. struct netlink_callback *cb, int flags,
  249. devlink_nl_dump_one_func_t *dump_one,
  250. struct nlattr **attrs)
  251. {
  252. struct devlink *devlink;
  253. int err;
  254. devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), attrs, false);
  255. if (IS_ERR(devlink))
  256. return PTR_ERR(devlink);
  257. err = dump_one(msg, devlink, cb, flags | NLM_F_DUMP_FILTERED);
  258. devl_unlock(devlink);
  259. devlink_put(devlink);
  260. if (err != -EMSGSIZE)
  261. return err;
  262. return msg->len;
  263. }
  264. static int devlink_nl_inst_iter_dumpit(struct sk_buff *msg,
  265. struct netlink_callback *cb, int flags,
  266. devlink_nl_dump_one_func_t *dump_one)
  267. {
  268. struct devlink_nl_dump_state *state = devlink_dump_state(cb);
  269. struct devlink *devlink;
  270. int err = 0;
  271. while ((devlink = devlinks_xa_find_get(sock_net(msg->sk),
  272. &state->instance))) {
  273. devl_lock(devlink);
  274. if (devl_is_registered(devlink))
  275. err = dump_one(msg, devlink, cb, flags);
  276. else
  277. err = 0;
  278. devl_unlock(devlink);
  279. devlink_put(devlink);
  280. if (err)
  281. break;
  282. state->instance++;
  283. /* restart sub-object walk for the next instance */
  284. state->idx = 0;
  285. }
  286. if (err != -EMSGSIZE)
  287. return err;
  288. return msg->len;
  289. }
  290. int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
  291. devlink_nl_dump_one_func_t *dump_one)
  292. {
  293. const struct genl_info *info = genl_info_dump(cb);
  294. struct nlattr **attrs = info->attrs;
  295. int flags = NLM_F_MULTI;
  296. if (attrs &&
  297. (attrs[DEVLINK_ATTR_BUS_NAME] || attrs[DEVLINK_ATTR_DEV_NAME]))
  298. return devlink_nl_inst_single_dumpit(msg, cb, flags, dump_one,
  299. attrs);
  300. else
  301. return devlink_nl_inst_iter_dumpit(msg, cb, flags, dump_one);
  302. }
  303. struct genl_family devlink_nl_family __ro_after_init = {
  304. .name = DEVLINK_GENL_NAME,
  305. .version = DEVLINK_GENL_VERSION,
  306. .netnsok = true,
  307. .parallel_ops = true,
  308. .module = THIS_MODULE,
  309. .split_ops = devlink_nl_ops,
  310. .n_split_ops = ARRAY_SIZE(devlink_nl_ops),
  311. .resv_start_op = DEVLINK_CMD_SELFTESTS_RUN + 1,
  312. .mcgrps = devlink_nl_mcgrps,
  313. .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
  314. .sock_priv_size = sizeof(struct devlink_nl_sock_priv),
  315. .sock_priv_init = devlink_nl_sock_priv_init,
  316. .sock_priv_destroy = devlink_nl_sock_priv_destroy,
  317. };