libnl 1.1
|
00001 /* 00002 * lib/route/class.c Queueing Classes 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup class 00014 * @defgroup class_obj Class Object 00015 * @{ 00016 */ 00017 00018 #include <netlink-local.h> 00019 #include <netlink-tc.h> 00020 #include <netlink/netlink.h> 00021 #include <netlink/route/tc.h> 00022 #include <netlink/route/class.h> 00023 #include <netlink/route/class-modules.h> 00024 #include <netlink/route/qdisc.h> 00025 #include <netlink/route/classifier.h> 00026 #include <netlink/utils.h> 00027 00028 static void class_free_data(struct nl_object *obj) 00029 { 00030 struct rtnl_class *class = (struct rtnl_class *) obj; 00031 struct rtnl_class_ops *cops; 00032 00033 tca_free_data((struct rtnl_tca *) class); 00034 00035 cops = rtnl_class_lookup_ops(class); 00036 if (cops && cops->co_free_data) 00037 cops->co_free_data(class); 00038 } 00039 00040 static int class_clone(struct nl_object *_dst, struct nl_object *_src) 00041 { 00042 struct rtnl_class *dst = nl_object_priv(_dst); 00043 struct rtnl_class *src = nl_object_priv(_src); 00044 struct rtnl_class_ops *cops; 00045 int err; 00046 00047 err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src); 00048 if (err < 0) 00049 goto errout; 00050 00051 cops = rtnl_class_lookup_ops(src); 00052 if (cops && cops->co_clone) 00053 err = cops->co_clone(dst, src); 00054 errout: 00055 return err; 00056 } 00057 00058 static int class_dump_brief(struct nl_object *obj, struct nl_dump_params *p) 00059 { 00060 struct rtnl_class *class = (struct rtnl_class *) obj; 00061 struct rtnl_class_ops *cops; 00062 00063 int line = tca_dump_brief((struct rtnl_tca *) class, "class", p, 0); 00064 00065 cops = rtnl_class_lookup_ops(class); 00066 if (cops && cops->co_dump[NL_DUMP_BRIEF]) 00067 line = cops->co_dump[NL_DUMP_BRIEF](class, p, line); 00068 dp_dump(p, "\n"); 00069 00070 return line; 00071 } 00072 00073 static int class_dump_full(struct nl_object *obj, struct nl_dump_params *p) 00074 { 00075 struct rtnl_class *class = (struct rtnl_class *) obj; 00076 struct rtnl_class_ops *cops; 00077 int line; 00078 00079 line = class_dump_brief(obj, p); 00080 line = tca_dump_full((struct rtnl_tca *) class, p, line); 00081 00082 if (class->c_info) { 00083 char buf[32]; 00084 dp_dump(p, "child-qdisc %s ", 00085 rtnl_tc_handle2str(class->c_info, buf, sizeof(buf))); 00086 } 00087 00088 cops = rtnl_class_lookup_ops(class); 00089 if (cops && cops->co_dump[NL_DUMP_FULL]) 00090 line = cops->co_dump[NL_DUMP_FULL](class, p, line); 00091 else if (!class->c_info) 00092 dp_dump(p, "noop (no leaf qdisc)"); 00093 00094 dp_dump(p, "\n"); 00095 00096 return line; 00097 } 00098 00099 static int class_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 00100 { 00101 struct rtnl_class *class = (struct rtnl_class *) obj; 00102 struct rtnl_class_ops *cops; 00103 int line; 00104 00105 line = class_dump_full(obj, p); 00106 line = tca_dump_stats((struct rtnl_tca *) class, p, line); 00107 dp_dump(p, "\n"); 00108 00109 cops = rtnl_class_lookup_ops(class); 00110 if (cops && cops->co_dump[NL_DUMP_STATS]) 00111 line = cops->co_dump[NL_DUMP_STATS](class, p, line); 00112 00113 return line; 00114 } 00115 00116 /** 00117 * @name Allocation/Freeing 00118 * @{ 00119 */ 00120 00121 struct rtnl_class *rtnl_class_alloc(void) 00122 { 00123 return (struct rtnl_class *) nl_object_alloc(&class_obj_ops); 00124 } 00125 00126 void rtnl_class_put(struct rtnl_class *class) 00127 { 00128 nl_object_put((struct nl_object *) class); 00129 } 00130 00131 /** @} */ 00132 00133 /** 00134 * @name Leaf Qdisc 00135 * @{ 00136 */ 00137 00138 /** 00139 * Lookup the leaf qdisc of a class 00140 * @arg class the parent class 00141 * @arg cache a qdisc cache including at laest all qdiscs of the 00142 * interface the specified class is attached to 00143 * @return The qdisc from the cache or NULL if the class has no leaf qdisc 00144 */ 00145 struct rtnl_qdisc *rtnl_class_leaf_qdisc(struct rtnl_class *class, 00146 struct nl_cache *cache) 00147 { 00148 struct rtnl_qdisc *leaf; 00149 00150 if (!class->c_info) 00151 return NULL; 00152 00153 leaf = rtnl_qdisc_get_by_parent(cache, class->c_ifindex, 00154 class->c_handle); 00155 if (!leaf || leaf->q_handle != class->c_info) 00156 return NULL; 00157 00158 return leaf; 00159 } 00160 00161 /** @} */ 00162 00163 00164 /** 00165 * @name Iterators 00166 * @{ 00167 */ 00168 00169 /** 00170 * Call a callback for each child of a class 00171 * @arg class the parent class 00172 * @arg cache a class cache including all classes of the interface 00173 * the specified class is attached to 00174 * @arg cb callback function 00175 * @arg arg argument to be passed to callback function 00176 */ 00177 void rtnl_class_foreach_child(struct rtnl_class *class, struct nl_cache *cache, 00178 void (*cb)(struct nl_object *, void *), void *arg) 00179 { 00180 struct rtnl_class *filter; 00181 00182 filter = rtnl_class_alloc(); 00183 if (!filter) 00184 return; 00185 00186 rtnl_class_set_parent(filter, class->c_handle); 00187 rtnl_class_set_ifindex(filter, class->c_ifindex); 00188 rtnl_class_set_kind(filter, class->c_kind); 00189 00190 nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg); 00191 rtnl_class_put(filter); 00192 } 00193 00194 /** 00195 * Call a callback for each classifier attached to the class 00196 * @arg class the parent class 00197 * @arg cache a filter cache including at least all the filters 00198 * attached to the specified class 00199 * @arg cb callback function 00200 * @arg arg argument to be passed to callback function 00201 */ 00202 void rtnl_class_foreach_cls(struct rtnl_class *class, struct nl_cache *cache, 00203 void (*cb)(struct nl_object *, void *), void *arg) 00204 { 00205 struct rtnl_cls *filter; 00206 00207 filter = rtnl_cls_alloc(); 00208 if (!filter) 00209 return; 00210 00211 rtnl_cls_set_ifindex(filter, class->c_ifindex); 00212 rtnl_cls_set_parent(filter, class->c_parent); 00213 00214 nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg); 00215 rtnl_cls_put(filter); 00216 } 00217 00218 /** @} */ 00219 00220 00221 /** 00222 * @name Attributes 00223 * @{ 00224 */ 00225 00226 void rtnl_class_set_ifindex(struct rtnl_class *class, int ifindex) 00227 { 00228 tca_set_ifindex((struct rtnl_tca *) class, ifindex); 00229 } 00230 00231 int rtnl_class_get_ifindex(struct rtnl_class *class) 00232 { 00233 return tca_get_ifindex((struct rtnl_tca *) class); 00234 } 00235 00236 void rtnl_class_set_handle(struct rtnl_class *class, uint32_t handle) 00237 { 00238 tca_set_handle((struct rtnl_tca *) class, handle); 00239 } 00240 00241 uint32_t rtnl_class_get_handle(struct rtnl_class *class) 00242 { 00243 return tca_get_handle((struct rtnl_tca *) class); 00244 } 00245 00246 void rtnl_class_set_parent(struct rtnl_class *class, uint32_t parent) 00247 { 00248 tca_set_parent((struct rtnl_tca *) class, parent); 00249 } 00250 00251 uint32_t rtnl_class_get_parent(struct rtnl_class *class) 00252 { 00253 return tca_get_parent((struct rtnl_tca *) class); 00254 } 00255 00256 void rtnl_class_set_kind(struct rtnl_class *class, const char *name) 00257 { 00258 tca_set_kind((struct rtnl_tca *) class, name); 00259 class->c_ops = __rtnl_class_lookup_ops(name); 00260 } 00261 00262 char *rtnl_class_get_kind(struct rtnl_class *class) 00263 { 00264 return tca_get_kind((struct rtnl_tca *) class); 00265 } 00266 00267 uint64_t rtnl_class_get_stat(struct rtnl_class *class, 00268 enum rtnl_tc_stats_id id) 00269 { 00270 return tca_get_stat((struct rtnl_tca *) class, id); 00271 } 00272 00273 /** @} */ 00274 00275 struct nl_object_ops class_obj_ops = { 00276 .oo_name = "route/class", 00277 .oo_size = sizeof(struct rtnl_class), 00278 .oo_free_data = class_free_data, 00279 .oo_clone = class_clone, 00280 .oo_dump[NL_DUMP_BRIEF] = class_dump_brief, 00281 .oo_dump[NL_DUMP_FULL] = class_dump_full, 00282 .oo_dump[NL_DUMP_STATS] = class_dump_stats, 00283 .oo_compare = tca_compare, 00284 .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), 00285 }; 00286 00287 /** @} */