red.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * lib/route/qdisc/red.c RED Qdisc
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
  10. */
  11. /**
  12. * @ingroup qdisc
  13. * @defgroup qdisc_red Random Early Detection (RED)
  14. * @brief
  15. * @{
  16. */
  17. #include <netlink-private/netlink.h>
  18. #include <netlink-private/tc.h>
  19. #include <netlink/netlink.h>
  20. #include <netlink/utils.h>
  21. #include <netlink-private/route/tc-api.h>
  22. #include <netlink/route/qdisc.h>
  23. #include <netlink/route/qdisc/red.h>
  24. /** @cond SKIP */
  25. #define RED_ATTR_LIMIT 0x01
  26. #define RED_ATTR_QTH_MIN 0x02
  27. #define RED_ATTR_QTH_MAX 0x04
  28. #define RED_ATTR_FLAGS 0x08
  29. #define RED_ATTR_WLOG 0x10
  30. #define RED_ATTR_PLOG 0x20
  31. #define RED_ATTR_SCELL_LOG 0x40
  32. /** @endcond */
  33. static struct nla_policy red_policy[TCA_RED_MAX+1] = {
  34. [TCA_RED_PARMS] = { .minlen = sizeof(struct tc_red_qopt) },
  35. };
  36. static int red_msg_parser(struct rtnl_tc *tc, void *data)
  37. {
  38. struct nlattr *tb[TCA_RED_MAX+1];
  39. struct rtnl_red *red = data;
  40. struct tc_red_qopt *opts;
  41. int err;
  42. if (!(tc->ce_mask & TCA_ATTR_OPTS))
  43. return 0;
  44. err = tca_parse(tb, TCA_RED_MAX, tc, red_policy);
  45. if (err < 0)
  46. return err;
  47. if (!tb[TCA_RED_PARMS])
  48. return -NLE_MISSING_ATTR;
  49. opts = nla_data(tb[TCA_RED_PARMS]);
  50. red->qr_limit = opts->limit;
  51. red->qr_qth_min = opts->qth_min;
  52. red->qr_qth_max = opts->qth_max;
  53. red->qr_flags = opts->flags;
  54. red->qr_wlog = opts->Wlog;
  55. red->qr_plog = opts->Plog;
  56. red->qr_scell_log = opts->Scell_log;
  57. red->qr_mask = (RED_ATTR_LIMIT | RED_ATTR_QTH_MIN | RED_ATTR_QTH_MAX |
  58. RED_ATTR_FLAGS | RED_ATTR_WLOG | RED_ATTR_PLOG |
  59. RED_ATTR_SCELL_LOG);
  60. return 0;
  61. }
  62. static void red_dump_line(struct rtnl_tc *tc, void *data,
  63. struct nl_dump_params *p)
  64. {
  65. struct rtnl_red *red = data;
  66. if (red) {
  67. /* XXX: limit, min, max, flags */
  68. }
  69. }
  70. static void red_dump_details(struct rtnl_tc *tc, void *data,
  71. struct nl_dump_params *p)
  72. {
  73. struct rtnl_red *red = data;
  74. if (red) {
  75. /* XXX: wlog, plog, scell_log */
  76. }
  77. }
  78. static void red_dump_stats(struct rtnl_tc *tc, void *data,
  79. struct nl_dump_params *p)
  80. {
  81. struct rtnl_red *red = data;
  82. if (red) {
  83. /* XXX: xstats */
  84. }
  85. }
  86. static int red_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
  87. {
  88. struct rtnl_red *red = data;
  89. if (!red)
  90. BUG();
  91. #if 0
  92. memset(&opts, 0, sizeof(opts));
  93. opts.quantum = sfq->qs_quantum;
  94. opts.perturb_period = sfq->qs_perturb;
  95. opts.limit = sfq->qs_limit;
  96. if (nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD) < 0)
  97. goto errout;
  98. #endif
  99. return -NLE_OPNOTSUPP;
  100. }
  101. /**
  102. * @name Attribute Access
  103. * @{
  104. */
  105. /**
  106. * Set limit of RED qdisc.
  107. * @arg qdisc RED qdisc to be modified.
  108. * @arg limit New limit in number of packets.
  109. * @return 0 on success or a negative error code.
  110. */
  111. void rtnl_red_set_limit(struct rtnl_qdisc *qdisc, int limit)
  112. {
  113. struct rtnl_red *red;
  114. if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
  115. BUG();
  116. red->qr_limit = limit;
  117. red->qr_mask |= RED_ATTR_LIMIT;
  118. }
  119. /**
  120. * Get limit of RED qdisc.
  121. * @arg qdisc RED qdisc.
  122. * @return Limit or a negative error code.
  123. */
  124. int rtnl_red_get_limit(struct rtnl_qdisc *qdisc)
  125. {
  126. struct rtnl_red *red;
  127. if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
  128. BUG();
  129. if (red->qr_mask & RED_ATTR_LIMIT)
  130. return red->qr_limit;
  131. else
  132. return -NLE_NOATTR;
  133. }
  134. /** @} */
  135. static struct rtnl_tc_ops red_ops = {
  136. .to_kind = "red",
  137. .to_type = RTNL_TC_TYPE_QDISC,
  138. .to_size = sizeof(struct rtnl_red),
  139. .to_msg_parser = red_msg_parser,
  140. .to_dump = {
  141. [NL_DUMP_LINE] = red_dump_line,
  142. [NL_DUMP_DETAILS] = red_dump_details,
  143. [NL_DUMP_STATS] = red_dump_stats,
  144. },
  145. .to_msg_fill = red_msg_fill,
  146. };
  147. static void __init red_init(void)
  148. {
  149. rtnl_tc_register(&red_ops);
  150. }
  151. static void __exit red_exit(void)
  152. {
  153. rtnl_tc_unregister(&red_ops);
  154. }
  155. /** @} */