rate.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  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 "devl_internal.h"
  7. static inline bool
  8. devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
  9. {
  10. return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
  11. }
  12. bool devlink_rate_is_node(const struct devlink_rate *devlink_rate)
  13. {
  14. return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
  15. }
  16. static struct devlink_rate *
  17. devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
  18. {
  19. struct devlink_rate *devlink_rate;
  20. struct devlink_port *devlink_port;
  21. devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
  22. if (IS_ERR(devlink_port))
  23. return ERR_CAST(devlink_port);
  24. devlink_rate = devlink_port->devlink_rate;
  25. return devlink_rate ?: ERR_PTR(-ENODEV);
  26. }
  27. static struct devlink_rate *
  28. devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
  29. {
  30. struct devlink_rate *devlink_rate;
  31. list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
  32. if (devlink_rate_is_node(devlink_rate) &&
  33. !strcmp(node_name, devlink_rate->name))
  34. return devlink_rate;
  35. }
  36. return ERR_PTR(-ENODEV);
  37. }
  38. static struct devlink_rate *
  39. devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
  40. {
  41. const char *rate_node_name;
  42. size_t len;
  43. if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
  44. return ERR_PTR(-EINVAL);
  45. rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
  46. len = strlen(rate_node_name);
  47. /* Name cannot be empty or decimal number */
  48. if (!len || strspn(rate_node_name, "0123456789") == len)
  49. return ERR_PTR(-EINVAL);
  50. return devlink_rate_node_get_by_name(devlink, rate_node_name);
  51. }
  52. static struct devlink_rate *
  53. devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
  54. {
  55. return devlink_rate_node_get_from_attrs(devlink, info->attrs);
  56. }
  57. static struct devlink_rate *
  58. devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
  59. {
  60. struct nlattr **attrs = info->attrs;
  61. if (attrs[DEVLINK_ATTR_PORT_INDEX])
  62. return devlink_rate_leaf_get_from_info(devlink, info);
  63. else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
  64. return devlink_rate_node_get_from_info(devlink, info);
  65. else
  66. return ERR_PTR(-EINVAL);
  67. }
  68. static int devlink_rate_put_tc_bws(struct sk_buff *msg, u32 *tc_bw)
  69. {
  70. struct nlattr *nla_tc_bw;
  71. int i;
  72. for (i = 0; i < DEVLINK_RATE_TCS_MAX; i++) {
  73. nla_tc_bw = nla_nest_start(msg, DEVLINK_ATTR_RATE_TC_BWS);
  74. if (!nla_tc_bw)
  75. return -EMSGSIZE;
  76. if (nla_put_u8(msg, DEVLINK_RATE_TC_ATTR_INDEX, i) ||
  77. nla_put_u32(msg, DEVLINK_RATE_TC_ATTR_BW, tc_bw[i]))
  78. goto nla_put_failure;
  79. nla_nest_end(msg, nla_tc_bw);
  80. }
  81. return 0;
  82. nla_put_failure:
  83. nla_nest_cancel(msg, nla_tc_bw);
  84. return -EMSGSIZE;
  85. }
  86. static int devlink_nl_rate_fill(struct sk_buff *msg,
  87. struct devlink_rate *devlink_rate,
  88. enum devlink_command cmd, u32 portid, u32 seq,
  89. int flags, struct netlink_ext_ack *extack)
  90. {
  91. struct devlink *devlink = devlink_rate->devlink;
  92. void *hdr;
  93. hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
  94. if (!hdr)
  95. return -EMSGSIZE;
  96. if (devlink_nl_put_handle(msg, devlink))
  97. goto nla_put_failure;
  98. if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
  99. goto nla_put_failure;
  100. if (devlink_rate_is_leaf(devlink_rate)) {
  101. if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
  102. devlink_rate->devlink_port->index))
  103. goto nla_put_failure;
  104. } else if (devlink_rate_is_node(devlink_rate)) {
  105. if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
  106. devlink_rate->name))
  107. goto nla_put_failure;
  108. }
  109. if (devlink_nl_put_u64(msg, DEVLINK_ATTR_RATE_TX_SHARE,
  110. devlink_rate->tx_share))
  111. goto nla_put_failure;
  112. if (devlink_nl_put_u64(msg, DEVLINK_ATTR_RATE_TX_MAX,
  113. devlink_rate->tx_max))
  114. goto nla_put_failure;
  115. if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
  116. devlink_rate->tx_priority))
  117. goto nla_put_failure;
  118. if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
  119. devlink_rate->tx_weight))
  120. goto nla_put_failure;
  121. if (devlink_rate->parent)
  122. if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
  123. devlink_rate->parent->name))
  124. goto nla_put_failure;
  125. if (devlink_rate_put_tc_bws(msg, devlink_rate->tc_bw))
  126. goto nla_put_failure;
  127. genlmsg_end(msg, hdr);
  128. return 0;
  129. nla_put_failure:
  130. genlmsg_cancel(msg, hdr);
  131. return -EMSGSIZE;
  132. }
  133. static void devlink_rate_notify(struct devlink_rate *devlink_rate,
  134. enum devlink_command cmd)
  135. {
  136. struct devlink *devlink = devlink_rate->devlink;
  137. struct sk_buff *msg;
  138. int err;
  139. WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
  140. if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink))
  141. return;
  142. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  143. if (!msg)
  144. return;
  145. err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
  146. if (err) {
  147. nlmsg_free(msg);
  148. return;
  149. }
  150. devlink_nl_notify_send(devlink, msg);
  151. }
  152. void devlink_rates_notify_register(struct devlink *devlink)
  153. {
  154. struct devlink_rate *rate_node;
  155. list_for_each_entry(rate_node, &devlink->rate_list, list)
  156. devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
  157. }
  158. void devlink_rates_notify_unregister(struct devlink *devlink)
  159. {
  160. struct devlink_rate *rate_node;
  161. list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
  162. devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
  163. }
  164. static int
  165. devlink_nl_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
  166. struct netlink_callback *cb, int flags)
  167. {
  168. struct devlink_nl_dump_state *state = devlink_dump_state(cb);
  169. struct devlink_rate *devlink_rate;
  170. int idx = 0;
  171. int err = 0;
  172. list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
  173. enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
  174. u32 id = NETLINK_CB(cb->skb).portid;
  175. if (idx < state->idx) {
  176. idx++;
  177. continue;
  178. }
  179. err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
  180. cb->nlh->nlmsg_seq, flags, NULL);
  181. if (err) {
  182. state->idx = idx;
  183. break;
  184. }
  185. idx++;
  186. }
  187. return err;
  188. }
  189. int devlink_nl_rate_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
  190. {
  191. return devlink_nl_dumpit(skb, cb, devlink_nl_rate_get_dump_one);
  192. }
  193. int devlink_nl_rate_get_doit(struct sk_buff *skb, struct genl_info *info)
  194. {
  195. struct devlink *devlink = info->user_ptr[0];
  196. struct devlink_rate *devlink_rate;
  197. struct sk_buff *msg;
  198. int err;
  199. devlink_rate = devlink_rate_get_from_info(devlink, info);
  200. if (IS_ERR(devlink_rate))
  201. return PTR_ERR(devlink_rate);
  202. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  203. if (!msg)
  204. return -ENOMEM;
  205. err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
  206. info->snd_portid, info->snd_seq, 0,
  207. info->extack);
  208. if (err) {
  209. nlmsg_free(msg);
  210. return err;
  211. }
  212. return genlmsg_reply(msg, info);
  213. }
  214. static bool
  215. devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
  216. struct devlink_rate *parent)
  217. {
  218. while (parent) {
  219. if (parent == devlink_rate)
  220. return true;
  221. parent = parent->parent;
  222. }
  223. return false;
  224. }
  225. static int
  226. devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
  227. struct genl_info *info,
  228. struct nlattr *nla_parent)
  229. {
  230. struct devlink *devlink = devlink_rate->devlink;
  231. const char *parent_name = nla_data(nla_parent);
  232. const struct devlink_ops *ops = devlink->ops;
  233. size_t len = strlen(parent_name);
  234. struct devlink_rate *parent;
  235. int err = -EOPNOTSUPP;
  236. parent = devlink_rate->parent;
  237. if (parent && !len) {
  238. if (devlink_rate_is_leaf(devlink_rate))
  239. err = ops->rate_leaf_parent_set(devlink_rate, NULL,
  240. devlink_rate->priv, NULL,
  241. info->extack);
  242. else if (devlink_rate_is_node(devlink_rate))
  243. err = ops->rate_node_parent_set(devlink_rate, NULL,
  244. devlink_rate->priv, NULL,
  245. info->extack);
  246. if (err)
  247. return err;
  248. refcount_dec(&parent->refcnt);
  249. devlink_rate->parent = NULL;
  250. } else if (len) {
  251. parent = devlink_rate_node_get_by_name(devlink, parent_name);
  252. if (IS_ERR(parent))
  253. return -ENODEV;
  254. if (parent == devlink_rate) {
  255. NL_SET_ERR_MSG(info->extack, "Parent to self is not allowed");
  256. return -EINVAL;
  257. }
  258. if (devlink_rate_is_node(devlink_rate) &&
  259. devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
  260. NL_SET_ERR_MSG(info->extack, "Node is already a parent of parent node.");
  261. return -EEXIST;
  262. }
  263. if (devlink_rate_is_leaf(devlink_rate))
  264. err = ops->rate_leaf_parent_set(devlink_rate, parent,
  265. devlink_rate->priv, parent->priv,
  266. info->extack);
  267. else if (devlink_rate_is_node(devlink_rate))
  268. err = ops->rate_node_parent_set(devlink_rate, parent,
  269. devlink_rate->priv, parent->priv,
  270. info->extack);
  271. if (err)
  272. return err;
  273. if (devlink_rate->parent)
  274. /* we're reassigning to other parent in this case */
  275. refcount_dec(&devlink_rate->parent->refcnt);
  276. refcount_inc(&parent->refcnt);
  277. devlink_rate->parent = parent;
  278. }
  279. return 0;
  280. }
  281. static int devlink_nl_rate_tc_bw_parse(struct nlattr *parent_nest, u32 *tc_bw,
  282. unsigned long *bitmap,
  283. struct netlink_ext_ack *extack)
  284. {
  285. struct nlattr *tb[DEVLINK_RATE_TC_ATTR_MAX + 1];
  286. u8 tc_index;
  287. int err;
  288. err = nla_parse_nested(tb, DEVLINK_RATE_TC_ATTR_MAX, parent_nest,
  289. devlink_dl_rate_tc_bws_nl_policy, extack);
  290. if (err)
  291. return err;
  292. if (!tb[DEVLINK_RATE_TC_ATTR_INDEX]) {
  293. NL_SET_ERR_ATTR_MISS(extack, parent_nest,
  294. DEVLINK_RATE_TC_ATTR_INDEX);
  295. return -EINVAL;
  296. }
  297. tc_index = nla_get_u8(tb[DEVLINK_RATE_TC_ATTR_INDEX]);
  298. if (!tb[DEVLINK_RATE_TC_ATTR_BW]) {
  299. NL_SET_ERR_ATTR_MISS(extack, parent_nest,
  300. DEVLINK_RATE_TC_ATTR_BW);
  301. return -EINVAL;
  302. }
  303. if (test_and_set_bit(tc_index, bitmap)) {
  304. NL_SET_ERR_MSG_FMT(extack,
  305. "Duplicate traffic class index specified (%u)",
  306. tc_index);
  307. return -EINVAL;
  308. }
  309. tc_bw[tc_index] = nla_get_u32(tb[DEVLINK_RATE_TC_ATTR_BW]);
  310. return 0;
  311. }
  312. static int devlink_nl_rate_tc_bw_set(struct devlink_rate *devlink_rate,
  313. struct genl_info *info)
  314. {
  315. DECLARE_BITMAP(bitmap, DEVLINK_RATE_TCS_MAX) = {};
  316. struct devlink *devlink = devlink_rate->devlink;
  317. const struct devlink_ops *ops = devlink->ops;
  318. u32 tc_bw[DEVLINK_RATE_TCS_MAX] = {};
  319. int rem, err = -EOPNOTSUPP, i;
  320. struct nlattr *attr;
  321. nlmsg_for_each_attr_type(attr, DEVLINK_ATTR_RATE_TC_BWS, info->nlhdr,
  322. GENL_HDRLEN, rem) {
  323. err = devlink_nl_rate_tc_bw_parse(attr, tc_bw, bitmap,
  324. info->extack);
  325. if (err)
  326. return err;
  327. }
  328. for (i = 0; i < DEVLINK_RATE_TCS_MAX; i++) {
  329. if (!test_bit(i, bitmap)) {
  330. NL_SET_ERR_MSG_FMT(info->extack,
  331. "Bandwidth values must be specified for all %u traffic classes",
  332. DEVLINK_RATE_TCS_MAX);
  333. return -EINVAL;
  334. }
  335. }
  336. if (devlink_rate_is_leaf(devlink_rate))
  337. err = ops->rate_leaf_tc_bw_set(devlink_rate, devlink_rate->priv,
  338. tc_bw, info->extack);
  339. else if (devlink_rate_is_node(devlink_rate))
  340. err = ops->rate_node_tc_bw_set(devlink_rate, devlink_rate->priv,
  341. tc_bw, info->extack);
  342. if (err)
  343. return err;
  344. memcpy(devlink_rate->tc_bw, tc_bw, sizeof(tc_bw));
  345. return 0;
  346. }
  347. static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
  348. const struct devlink_ops *ops,
  349. struct genl_info *info)
  350. {
  351. struct nlattr *nla_parent, **attrs = info->attrs;
  352. int err = -EOPNOTSUPP;
  353. u32 priority;
  354. u32 weight;
  355. u64 rate;
  356. if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
  357. rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
  358. if (devlink_rate_is_leaf(devlink_rate))
  359. err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
  360. rate, info->extack);
  361. else if (devlink_rate_is_node(devlink_rate))
  362. err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
  363. rate, info->extack);
  364. if (err)
  365. return err;
  366. devlink_rate->tx_share = rate;
  367. }
  368. if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
  369. rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
  370. if (devlink_rate_is_leaf(devlink_rate))
  371. err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
  372. rate, info->extack);
  373. else if (devlink_rate_is_node(devlink_rate))
  374. err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
  375. rate, info->extack);
  376. if (err)
  377. return err;
  378. devlink_rate->tx_max = rate;
  379. }
  380. if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) {
  381. priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]);
  382. if (devlink_rate_is_leaf(devlink_rate))
  383. err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv,
  384. priority, info->extack);
  385. else if (devlink_rate_is_node(devlink_rate))
  386. err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv,
  387. priority, info->extack);
  388. if (err)
  389. return err;
  390. devlink_rate->tx_priority = priority;
  391. }
  392. if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) {
  393. weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]);
  394. if (devlink_rate_is_leaf(devlink_rate))
  395. err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv,
  396. weight, info->extack);
  397. else if (devlink_rate_is_node(devlink_rate))
  398. err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv,
  399. weight, info->extack);
  400. if (err)
  401. return err;
  402. devlink_rate->tx_weight = weight;
  403. }
  404. nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
  405. if (nla_parent) {
  406. err = devlink_nl_rate_parent_node_set(devlink_rate, info,
  407. nla_parent);
  408. if (err)
  409. return err;
  410. }
  411. if (attrs[DEVLINK_ATTR_RATE_TC_BWS]) {
  412. err = devlink_nl_rate_tc_bw_set(devlink_rate, info);
  413. if (err)
  414. return err;
  415. }
  416. return 0;
  417. }
  418. static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
  419. struct genl_info *info,
  420. enum devlink_rate_type type)
  421. {
  422. struct nlattr **attrs = info->attrs;
  423. if (type == DEVLINK_RATE_TYPE_LEAF) {
  424. if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
  425. NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the leafs");
  426. return false;
  427. }
  428. if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
  429. NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the leafs");
  430. return false;
  431. }
  432. if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
  433. !ops->rate_leaf_parent_set) {
  434. NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the leafs");
  435. return false;
  436. }
  437. if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) {
  438. NL_SET_ERR_MSG_ATTR(info->extack,
  439. attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
  440. "TX priority set isn't supported for the leafs");
  441. return false;
  442. }
  443. if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) {
  444. NL_SET_ERR_MSG_ATTR(info->extack,
  445. attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
  446. "TX weight set isn't supported for the leafs");
  447. return false;
  448. }
  449. if (attrs[DEVLINK_ATTR_RATE_TC_BWS] &&
  450. !ops->rate_leaf_tc_bw_set) {
  451. NL_SET_ERR_MSG_ATTR(info->extack,
  452. attrs[DEVLINK_ATTR_RATE_TC_BWS],
  453. "TC bandwidth set isn't supported for the leafs");
  454. return false;
  455. }
  456. } else if (type == DEVLINK_RATE_TYPE_NODE) {
  457. if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
  458. NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the nodes");
  459. return false;
  460. }
  461. if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
  462. NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the nodes");
  463. return false;
  464. }
  465. if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
  466. !ops->rate_node_parent_set) {
  467. NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the nodes");
  468. return false;
  469. }
  470. if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) {
  471. NL_SET_ERR_MSG_ATTR(info->extack,
  472. attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
  473. "TX priority set isn't supported for the nodes");
  474. return false;
  475. }
  476. if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) {
  477. NL_SET_ERR_MSG_ATTR(info->extack,
  478. attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
  479. "TX weight set isn't supported for the nodes");
  480. return false;
  481. }
  482. if (attrs[DEVLINK_ATTR_RATE_TC_BWS] &&
  483. !ops->rate_node_tc_bw_set) {
  484. NL_SET_ERR_MSG_ATTR(info->extack,
  485. attrs[DEVLINK_ATTR_RATE_TC_BWS],
  486. "TC bandwidth set isn't supported for the nodes");
  487. return false;
  488. }
  489. } else {
  490. WARN(1, "Unknown type of rate object");
  491. return false;
  492. }
  493. return true;
  494. }
  495. int devlink_nl_rate_set_doit(struct sk_buff *skb, struct genl_info *info)
  496. {
  497. struct devlink *devlink = info->user_ptr[0];
  498. struct devlink_rate *devlink_rate;
  499. const struct devlink_ops *ops;
  500. int err;
  501. devlink_rate = devlink_rate_get_from_info(devlink, info);
  502. if (IS_ERR(devlink_rate))
  503. return PTR_ERR(devlink_rate);
  504. ops = devlink->ops;
  505. if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
  506. return -EOPNOTSUPP;
  507. err = devlink_nl_rate_set(devlink_rate, ops, info);
  508. if (!err)
  509. devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
  510. return err;
  511. }
  512. int devlink_nl_rate_new_doit(struct sk_buff *skb, struct genl_info *info)
  513. {
  514. struct devlink *devlink = info->user_ptr[0];
  515. struct devlink_rate *rate_node;
  516. const struct devlink_ops *ops;
  517. int err;
  518. ops = devlink->ops;
  519. if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
  520. NL_SET_ERR_MSG(info->extack, "Rate nodes aren't supported");
  521. return -EOPNOTSUPP;
  522. }
  523. if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
  524. return -EOPNOTSUPP;
  525. rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
  526. if (!IS_ERR(rate_node))
  527. return -EEXIST;
  528. else if (rate_node == ERR_PTR(-EINVAL))
  529. return -EINVAL;
  530. rate_node = kzalloc_obj(*rate_node);
  531. if (!rate_node)
  532. return -ENOMEM;
  533. rate_node->devlink = devlink;
  534. rate_node->type = DEVLINK_RATE_TYPE_NODE;
  535. rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
  536. if (!rate_node->name) {
  537. err = -ENOMEM;
  538. goto err_strdup;
  539. }
  540. err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
  541. if (err)
  542. goto err_node_new;
  543. err = devlink_nl_rate_set(rate_node, ops, info);
  544. if (err)
  545. goto err_rate_set;
  546. refcount_set(&rate_node->refcnt, 1);
  547. list_add(&rate_node->list, &devlink->rate_list);
  548. devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
  549. return 0;
  550. err_rate_set:
  551. ops->rate_node_del(rate_node, rate_node->priv, info->extack);
  552. err_node_new:
  553. kfree(rate_node->name);
  554. err_strdup:
  555. kfree(rate_node);
  556. return err;
  557. }
  558. int devlink_nl_rate_del_doit(struct sk_buff *skb, struct genl_info *info)
  559. {
  560. struct devlink *devlink = info->user_ptr[0];
  561. struct devlink_rate *rate_node;
  562. int err;
  563. rate_node = devlink_rate_node_get_from_info(devlink, info);
  564. if (IS_ERR(rate_node))
  565. return PTR_ERR(rate_node);
  566. if (refcount_read(&rate_node->refcnt) > 1) {
  567. NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node.");
  568. return -EBUSY;
  569. }
  570. devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
  571. err = devlink->ops->rate_node_del(rate_node, rate_node->priv,
  572. info->extack);
  573. if (rate_node->parent)
  574. refcount_dec(&rate_node->parent->refcnt);
  575. list_del(&rate_node->list);
  576. kfree(rate_node->name);
  577. kfree(rate_node);
  578. return err;
  579. }
  580. int devlink_rates_check(struct devlink *devlink,
  581. bool (*rate_filter)(const struct devlink_rate *),
  582. struct netlink_ext_ack *extack)
  583. {
  584. struct devlink_rate *devlink_rate;
  585. list_for_each_entry(devlink_rate, &devlink->rate_list, list)
  586. if (!rate_filter || rate_filter(devlink_rate)) {
  587. if (extack)
  588. NL_SET_ERR_MSG(extack, "Rate node(s) exists.");
  589. return -EBUSY;
  590. }
  591. return 0;
  592. }
  593. /**
  594. * devl_rate_node_create - create devlink rate node
  595. * @devlink: devlink instance
  596. * @priv: driver private data
  597. * @node_name: name of the resulting node
  598. * @parent: parent devlink_rate struct
  599. *
  600. * Create devlink rate object of type node
  601. */
  602. struct devlink_rate *
  603. devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
  604. struct devlink_rate *parent)
  605. {
  606. struct devlink_rate *rate_node;
  607. rate_node = devlink_rate_node_get_by_name(devlink, node_name);
  608. if (!IS_ERR(rate_node))
  609. return ERR_PTR(-EEXIST);
  610. rate_node = kzalloc_obj(*rate_node);
  611. if (!rate_node)
  612. return ERR_PTR(-ENOMEM);
  613. if (parent) {
  614. rate_node->parent = parent;
  615. refcount_inc(&rate_node->parent->refcnt);
  616. }
  617. rate_node->type = DEVLINK_RATE_TYPE_NODE;
  618. rate_node->devlink = devlink;
  619. rate_node->priv = priv;
  620. rate_node->name = kstrdup(node_name, GFP_KERNEL);
  621. if (!rate_node->name) {
  622. kfree(rate_node);
  623. return ERR_PTR(-ENOMEM);
  624. }
  625. refcount_set(&rate_node->refcnt, 1);
  626. list_add(&rate_node->list, &devlink->rate_list);
  627. devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
  628. return rate_node;
  629. }
  630. EXPORT_SYMBOL_GPL(devl_rate_node_create);
  631. /**
  632. * devl_rate_leaf_create - create devlink rate leaf
  633. * @devlink_port: devlink port object to create rate object on
  634. * @priv: driver private data
  635. * @parent: parent devlink_rate struct
  636. *
  637. * Create devlink rate object of type leaf on provided @devlink_port.
  638. */
  639. int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
  640. struct devlink_rate *parent)
  641. {
  642. struct devlink *devlink = devlink_port->devlink;
  643. struct devlink_rate *devlink_rate;
  644. devl_assert_locked(devlink_port->devlink);
  645. if (WARN_ON(devlink_port->devlink_rate))
  646. return -EBUSY;
  647. devlink_rate = kzalloc_obj(*devlink_rate);
  648. if (!devlink_rate)
  649. return -ENOMEM;
  650. if (parent) {
  651. devlink_rate->parent = parent;
  652. refcount_inc(&devlink_rate->parent->refcnt);
  653. }
  654. devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
  655. devlink_rate->devlink = devlink;
  656. devlink_rate->devlink_port = devlink_port;
  657. devlink_rate->priv = priv;
  658. list_add_tail(&devlink_rate->list, &devlink->rate_list);
  659. devlink_port->devlink_rate = devlink_rate;
  660. devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
  661. return 0;
  662. }
  663. EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
  664. /**
  665. * devl_rate_leaf_destroy - destroy devlink rate leaf
  666. *
  667. * @devlink_port: devlink port linked to the rate object
  668. *
  669. * Destroy the devlink rate object of type leaf on provided @devlink_port.
  670. */
  671. void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
  672. {
  673. struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
  674. devl_assert_locked(devlink_port->devlink);
  675. if (!devlink_rate)
  676. return;
  677. devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
  678. if (devlink_rate->parent)
  679. refcount_dec(&devlink_rate->parent->refcnt);
  680. list_del(&devlink_rate->list);
  681. devlink_port->devlink_rate = NULL;
  682. kfree(devlink_rate);
  683. }
  684. EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
  685. /**
  686. * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
  687. * @devlink: devlink instance
  688. *
  689. * Unset parent for all rate objects and destroy all rate nodes
  690. * on specified device.
  691. */
  692. void devl_rate_nodes_destroy(struct devlink *devlink)
  693. {
  694. const struct devlink_ops *ops = devlink->ops;
  695. struct devlink_rate *devlink_rate, *tmp;
  696. devl_assert_locked(devlink);
  697. list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
  698. if (!devlink_rate->parent)
  699. continue;
  700. if (devlink_rate_is_leaf(devlink_rate))
  701. ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
  702. NULL, NULL);
  703. else if (devlink_rate_is_node(devlink_rate))
  704. ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
  705. NULL, NULL);
  706. refcount_dec(&devlink_rate->parent->refcnt);
  707. devlink_rate->parent = NULL;
  708. }
  709. list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
  710. if (devlink_rate_is_node(devlink_rate)) {
  711. ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
  712. list_del(&devlink_rate->list);
  713. kfree(devlink_rate->name);
  714. kfree(devlink_rate);
  715. }
  716. }
  717. }
  718. EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);