class_obj.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * lib/route/class.c Queueing Classes
  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-2006 Thomas Graf <tgraf@suug.ch>
  10. */
  11. /**
  12. * @ingroup class
  13. * @defgroup class_obj Class Object
  14. * @{
  15. */
  16. #include <netlink-local.h>
  17. #include <netlink-tc.h>
  18. #include <netlink/netlink.h>
  19. #include <netlink/route/tc.h>
  20. #include <netlink/route/class.h>
  21. #include <netlink/route/class-modules.h>
  22. #include <netlink/route/qdisc.h>
  23. #include <netlink/route/classifier.h>
  24. #include <netlink/utils.h>
  25. static void class_free_data(struct nl_object *obj)
  26. {
  27. struct rtnl_class *class = (struct rtnl_class *) obj;
  28. struct rtnl_class_ops *cops;
  29. tca_free_data((struct rtnl_tca *) class);
  30. cops = rtnl_class_lookup_ops(class);
  31. if (cops && cops->co_free_data)
  32. cops->co_free_data(class);
  33. }
  34. static int class_clone(struct nl_object *_dst, struct nl_object *_src)
  35. {
  36. struct rtnl_class *dst = nl_object_priv(_dst);
  37. struct rtnl_class *src = nl_object_priv(_src);
  38. struct rtnl_class_ops *cops;
  39. int err;
  40. err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
  41. if (err < 0)
  42. goto errout;
  43. cops = rtnl_class_lookup_ops(src);
  44. if (cops && cops->co_clone)
  45. err = cops->co_clone(dst, src);
  46. errout:
  47. return err;
  48. }
  49. static int class_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
  50. {
  51. struct rtnl_class *class = (struct rtnl_class *) obj;
  52. struct rtnl_class_ops *cops;
  53. int line = tca_dump_brief((struct rtnl_tca *) class, "class", p, 0);
  54. cops = rtnl_class_lookup_ops(class);
  55. if (cops && cops->co_dump[NL_DUMP_BRIEF])
  56. line = cops->co_dump[NL_DUMP_BRIEF](class, p, line);
  57. dp_dump(p, "\n");
  58. return line;
  59. }
  60. static int class_dump_full(struct nl_object *obj, struct nl_dump_params *p)
  61. {
  62. struct rtnl_class *class = (struct rtnl_class *) obj;
  63. struct rtnl_class_ops *cops;
  64. int line;
  65. line = class_dump_brief(obj, p);
  66. line = tca_dump_full((struct rtnl_tca *) class, p, line);
  67. if (class->c_info) {
  68. char buf[32];
  69. dp_dump(p, "child-qdisc %s ",
  70. rtnl_tc_handle2str(class->c_info, buf, sizeof(buf)));
  71. }
  72. cops = rtnl_class_lookup_ops(class);
  73. if (cops && cops->co_dump[NL_DUMP_FULL])
  74. line = cops->co_dump[NL_DUMP_FULL](class, p, line);
  75. else if (!class->c_info)
  76. dp_dump(p, "noop (no leaf qdisc)");
  77. dp_dump(p, "\n");
  78. return line;
  79. }
  80. static int class_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
  81. {
  82. struct rtnl_class *class = (struct rtnl_class *) obj;
  83. struct rtnl_class_ops *cops;
  84. int line;
  85. line = class_dump_full(obj, p);
  86. line = tca_dump_stats((struct rtnl_tca *) class, p, line);
  87. dp_dump(p, "\n");
  88. cops = rtnl_class_lookup_ops(class);
  89. if (cops && cops->co_dump[NL_DUMP_STATS])
  90. line = cops->co_dump[NL_DUMP_STATS](class, p, line);
  91. return line;
  92. }
  93. /**
  94. * @name Allocation/Freeing
  95. * @{
  96. */
  97. struct rtnl_class *rtnl_class_alloc(void)
  98. {
  99. return (struct rtnl_class *) nl_object_alloc(&class_obj_ops);
  100. }
  101. void rtnl_class_put(struct rtnl_class *class)
  102. {
  103. nl_object_put((struct nl_object *) class);
  104. }
  105. /** @} */
  106. /**
  107. * @name Leaf Qdisc
  108. * @{
  109. */
  110. /**
  111. * Lookup the leaf qdisc of a class
  112. * @arg class the parent class
  113. * @arg cache a qdisc cache including at laest all qdiscs of the
  114. * interface the specified class is attached to
  115. * @return The qdisc from the cache or NULL if the class has no leaf qdisc
  116. */
  117. struct rtnl_qdisc *rtnl_class_leaf_qdisc(struct rtnl_class *class,
  118. struct nl_cache *cache)
  119. {
  120. struct rtnl_qdisc *leaf;
  121. if (!class->c_info)
  122. return NULL;
  123. leaf = rtnl_qdisc_get_by_parent(cache, class->c_ifindex,
  124. class->c_handle);
  125. if (!leaf || leaf->q_handle != class->c_info)
  126. return NULL;
  127. return leaf;
  128. }
  129. /** @} */
  130. /**
  131. * @name Iterators
  132. * @{
  133. */
  134. /**
  135. * Call a callback for each child of a class
  136. * @arg class the parent class
  137. * @arg cache a class cache including all classes of the interface
  138. * the specified class is attached to
  139. * @arg cb callback function
  140. * @arg arg argument to be passed to callback function
  141. */
  142. void rtnl_class_foreach_child(struct rtnl_class *class, struct nl_cache *cache,
  143. void (*cb)(struct nl_object *, void *), void *arg)
  144. {
  145. struct rtnl_class *filter;
  146. filter = rtnl_class_alloc();
  147. if (!filter)
  148. return;
  149. rtnl_class_set_parent(filter, class->c_handle);
  150. rtnl_class_set_ifindex(filter, class->c_ifindex);
  151. rtnl_class_set_kind(filter, class->c_kind);
  152. nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
  153. rtnl_class_put(filter);
  154. }
  155. /**
  156. * Call a callback for each classifier attached to the class
  157. * @arg class the parent class
  158. * @arg cache a filter cache including at least all the filters
  159. * attached to the specified class
  160. * @arg cb callback function
  161. * @arg arg argument to be passed to callback function
  162. */
  163. void rtnl_class_foreach_cls(struct rtnl_class *class, struct nl_cache *cache,
  164. void (*cb)(struct nl_object *, void *), void *arg)
  165. {
  166. struct rtnl_cls *filter;
  167. filter = rtnl_cls_alloc();
  168. if (!filter)
  169. return;
  170. rtnl_cls_set_ifindex(filter, class->c_ifindex);
  171. rtnl_cls_set_parent(filter, class->c_parent);
  172. nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
  173. rtnl_cls_put(filter);
  174. }
  175. /** @} */
  176. /**
  177. * @name Attributes
  178. * @{
  179. */
  180. void rtnl_class_set_ifindex(struct rtnl_class *class, int ifindex)
  181. {
  182. tca_set_ifindex((struct rtnl_tca *) class, ifindex);
  183. }
  184. int rtnl_class_get_ifindex(struct rtnl_class *class)
  185. {
  186. return tca_get_ifindex((struct rtnl_tca *) class);
  187. }
  188. void rtnl_class_set_handle(struct rtnl_class *class, uint32_t handle)
  189. {
  190. tca_set_handle((struct rtnl_tca *) class, handle);
  191. }
  192. uint32_t rtnl_class_get_handle(struct rtnl_class *class)
  193. {
  194. return tca_get_handle((struct rtnl_tca *) class);
  195. }
  196. void rtnl_class_set_parent(struct rtnl_class *class, uint32_t parent)
  197. {
  198. tca_set_parent((struct rtnl_tca *) class, parent);
  199. }
  200. uint32_t rtnl_class_get_parent(struct rtnl_class *class)
  201. {
  202. return tca_get_parent((struct rtnl_tca *) class);
  203. }
  204. void rtnl_class_set_kind(struct rtnl_class *class, const char *name)
  205. {
  206. tca_set_kind((struct rtnl_tca *) class, name);
  207. class->c_ops = __rtnl_class_lookup_ops(name);
  208. }
  209. char *rtnl_class_get_kind(struct rtnl_class *class)
  210. {
  211. return tca_get_kind((struct rtnl_tca *) class);
  212. }
  213. uint64_t rtnl_class_get_stat(struct rtnl_class *class,
  214. enum rtnl_tc_stats_id id)
  215. {
  216. return tca_get_stat((struct rtnl_tca *) class, id);
  217. }
  218. /** @} */
  219. struct nl_object_ops class_obj_ops = {
  220. .oo_name = "route/class",
  221. .oo_size = sizeof(struct rtnl_class),
  222. .oo_free_data = class_free_data,
  223. .oo_clone = class_clone,
  224. .oo_dump[NL_DUMP_BRIEF] = class_dump_brief,
  225. .oo_dump[NL_DUMP_FULL] = class_dump_full,
  226. .oo_dump[NL_DUMP_STATS] = class_dump_stats,
  227. .oo_compare = tca_compare,
  228. .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE),
  229. };
  230. /** @} */