libnl 2.0

/build/buildd/libnl2-2.0/lib/route/class_obj.c

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 void class_dump_line(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         tca_dump_line((struct rtnl_tca *) class, "class", p);
00064 
00065         cops = rtnl_class_lookup_ops(class);
00066         if (cops && cops->co_dump[NL_DUMP_LINE])
00067                 cops->co_dump[NL_DUMP_LINE](class, p);
00068         nl_dump(p, "\n");
00069 }
00070 
00071 static void class_dump_details(struct nl_object *obj, struct nl_dump_params *p)
00072 {
00073         struct rtnl_class *class = (struct rtnl_class *) obj;
00074         struct rtnl_class_ops *cops;
00075 
00076         class_dump_line(obj, p);
00077         tca_dump_details((struct rtnl_tca *) class, p);
00078         
00079         if (class->c_info) {
00080                 char buf[32];
00081                 nl_dump(p, "child-qdisc %s ",
00082                         rtnl_tc_handle2str(class->c_info, buf, sizeof(buf)));
00083         }
00084 
00085         cops = rtnl_class_lookup_ops(class);
00086         if (cops && cops->co_dump[NL_DUMP_DETAILS])
00087                 cops->co_dump[NL_DUMP_DETAILS](class, p);
00088         else if (!class->c_info)
00089                 nl_dump(p, "noop (no leaf qdisc)");
00090 
00091         nl_dump(p, "\n");
00092 }
00093 
00094 static void class_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
00095 {
00096         struct rtnl_class *class = (struct rtnl_class *) obj;
00097         struct rtnl_class_ops *cops;
00098 
00099         class_dump_details(obj, p);
00100         tca_dump_stats((struct rtnl_tca *) class, p);
00101         nl_dump(p, "\n");
00102 
00103         cops = rtnl_class_lookup_ops(class);
00104         if (cops && cops->co_dump[NL_DUMP_STATS])
00105                 cops->co_dump[NL_DUMP_STATS](class, p);
00106 }
00107 
00108 /**
00109  * @name Allocation/Freeing
00110  * @{
00111  */
00112 
00113 struct rtnl_class *rtnl_class_alloc(void)
00114 {
00115         return (struct rtnl_class *) nl_object_alloc(&class_obj_ops);
00116 }
00117 
00118 void rtnl_class_put(struct rtnl_class *class)
00119 {
00120         nl_object_put((struct nl_object *) class);
00121 }
00122 
00123 /** @} */
00124 
00125 /**
00126  * @name Leaf Qdisc
00127  * @{
00128  */
00129 
00130 /**
00131  * Lookup the leaf qdisc of a class
00132  * @arg class           the parent class
00133  * @arg cache           a qdisc cache including at laest all qdiscs of the
00134  *                      interface the specified class is attached to
00135  * @return The qdisc from the cache or NULL if the class has no leaf qdisc
00136  */
00137 struct rtnl_qdisc *rtnl_class_leaf_qdisc(struct rtnl_class *class,
00138                                          struct nl_cache *cache)
00139 {
00140         struct rtnl_qdisc *leaf;
00141 
00142         if (!class->c_info)
00143                 return NULL;
00144 
00145         leaf = rtnl_qdisc_get_by_parent(cache, class->c_ifindex,
00146                                         class->c_handle);
00147         if (!leaf || leaf->q_handle != class->c_info)
00148                 return NULL;
00149 
00150         return leaf;
00151 }
00152 
00153 /** @} */
00154 
00155 
00156 /**
00157  * @name Iterators
00158  * @{
00159  */
00160 
00161 /**
00162  * Call a callback for each child of a class
00163  * @arg class           the parent class
00164  * @arg cache           a class cache including all classes of the interface
00165  *                      the specified class is attached to
00166  * @arg cb              callback function
00167  * @arg arg             argument to be passed to callback function
00168  */
00169 void rtnl_class_foreach_child(struct rtnl_class *class, struct nl_cache *cache,
00170                               void (*cb)(struct nl_object *, void *), void *arg)
00171 {
00172         struct rtnl_class *filter;
00173         
00174         filter = rtnl_class_alloc();
00175         if (!filter)
00176                 return;
00177 
00178         rtnl_class_set_parent(filter, class->c_handle);
00179         rtnl_class_set_ifindex(filter, class->c_ifindex);
00180         rtnl_class_set_kind(filter, class->c_kind);
00181 
00182         nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
00183         rtnl_class_put(filter);
00184 }
00185 
00186 /**
00187  * Call a callback for each classifier attached to the class
00188  * @arg class           the parent class
00189  * @arg cache           a filter cache including at least all the filters
00190  *                      attached to the specified class
00191  * @arg cb              callback function
00192  * @arg arg             argument to be passed to callback function
00193  */
00194 void rtnl_class_foreach_cls(struct rtnl_class *class, struct nl_cache *cache,
00195                             void (*cb)(struct nl_object *, void *), void *arg)
00196 {
00197         struct rtnl_cls *filter;
00198 
00199         filter = rtnl_cls_alloc();
00200         if (!filter)
00201                 return;
00202 
00203         rtnl_cls_set_ifindex(filter, class->c_ifindex);
00204         rtnl_cls_set_parent(filter, class->c_parent);
00205 
00206         nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
00207         rtnl_cls_put(filter);
00208 }
00209 
00210 /** @} */
00211 
00212 
00213 /**
00214  * @name Attributes
00215  * @{
00216  */
00217 
00218 void rtnl_class_set_ifindex(struct rtnl_class *class, int ifindex)
00219 {
00220         tca_set_ifindex((struct rtnl_tca *) class, ifindex);
00221 }
00222 
00223 int rtnl_class_get_ifindex(struct rtnl_class *class)
00224 {
00225         return tca_get_ifindex((struct rtnl_tca *) class);
00226 }
00227 
00228 void rtnl_class_set_handle(struct rtnl_class *class, uint32_t handle)
00229 {
00230         tca_set_handle((struct rtnl_tca *) class, handle);
00231 }
00232 
00233 uint32_t rtnl_class_get_handle(struct rtnl_class *class)
00234 {
00235         return tca_get_handle((struct rtnl_tca *) class);
00236 }
00237 
00238 void rtnl_class_set_parent(struct rtnl_class *class, uint32_t parent)
00239 {
00240         tca_set_parent((struct rtnl_tca *) class, parent);
00241 }
00242 
00243 uint32_t rtnl_class_get_parent(struct rtnl_class *class)
00244 {
00245         return tca_get_parent((struct rtnl_tca *) class);
00246 }
00247 
00248 void rtnl_class_set_kind(struct rtnl_class *class, const char *name)
00249 {
00250         tca_set_kind((struct rtnl_tca *) class, name);
00251         class->c_ops = __rtnl_class_lookup_ops(name);
00252 }
00253 
00254 char *rtnl_class_get_kind(struct rtnl_class *class)
00255 {
00256         return tca_get_kind((struct rtnl_tca *) class);
00257 }
00258 
00259 uint64_t rtnl_class_get_stat(struct rtnl_class *class,
00260                              enum rtnl_tc_stats_id id)
00261 {
00262         return tca_get_stat((struct rtnl_tca *) class, id);
00263 }
00264 
00265 /** @} */
00266 
00267 struct nl_object_ops class_obj_ops = {
00268         .oo_name                = "route/class",
00269         .oo_size                = sizeof(struct rtnl_class),
00270         .oo_free_data           = class_free_data,
00271         .oo_clone               = class_clone,
00272         .oo_dump = {
00273             [NL_DUMP_LINE]      = class_dump_line,
00274             [NL_DUMP_DETAILS]   = class_dump_details,
00275             [NL_DUMP_STATS]     = class_dump_stats,
00276         },
00277         .oo_compare             = tca_compare,
00278         .oo_id_attrs            = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE),
00279 };
00280 
00281 /** @} */