144d362409d5469aed47d19e7908d19bd194493aThomas Graf/*
244d362409d5469aed47d19e7908d19bd194493aThomas Graf * lib/route/class.c            Queueing Classes
344d362409d5469aed47d19e7908d19bd194493aThomas Graf *
444d362409d5469aed47d19e7908d19bd194493aThomas Graf *	This library is free software; you can redistribute it and/or
544d362409d5469aed47d19e7908d19bd194493aThomas Graf *	modify it under the terms of the GNU Lesser General Public
644d362409d5469aed47d19e7908d19bd194493aThomas Graf *	License as published by the Free Software Foundation version 2.1
744d362409d5469aed47d19e7908d19bd194493aThomas Graf *	of the License.
844d362409d5469aed47d19e7908d19bd194493aThomas Graf *
944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */
1144d362409d5469aed47d19e7908d19bd194493aThomas Graf
1244d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
1344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @ingroup class
1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup class_obj Class Object
1544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{
1644d362409d5469aed47d19e7908d19bd194493aThomas Graf */
1744d362409d5469aed47d19e7908d19bd194493aThomas Graf
1844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-local.h>
1944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-tc.h>
2044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h>
2144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/tc.h>
2244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/class.h>
2344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/class-modules.h>
2444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/qdisc.h>
2544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/classifier.h>
2644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/utils.h>
2744d362409d5469aed47d19e7908d19bd194493aThomas Graf
2844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void class_free_data(struct nl_object *obj)
2944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
3044d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class *class = (struct rtnl_class *) obj;
3144d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class_ops *cops;
3244d362409d5469aed47d19e7908d19bd194493aThomas Graf
3344d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_free_data((struct rtnl_tca *) class);
3444d362409d5469aed47d19e7908d19bd194493aThomas Graf
3544d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_class_lookup_ops(class);
3644d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cops && cops->co_free_data)
3744d362409d5469aed47d19e7908d19bd194493aThomas Graf		cops->co_free_data(class);
3844d362409d5469aed47d19e7908d19bd194493aThomas Graf}
3944d362409d5469aed47d19e7908d19bd194493aThomas Graf
4044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int class_clone(struct nl_object *_dst, struct nl_object *_src)
4144d362409d5469aed47d19e7908d19bd194493aThomas Graf{
4244d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class *dst = nl_object_priv(_dst);
4344d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class *src = nl_object_priv(_src);
4444d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class_ops *cops;
4544d362409d5469aed47d19e7908d19bd194493aThomas Graf	int err;
4644d362409d5469aed47d19e7908d19bd194493aThomas Graf
4744d362409d5469aed47d19e7908d19bd194493aThomas Graf	err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
4844d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (err < 0)
4944d362409d5469aed47d19e7908d19bd194493aThomas Graf		goto errout;
5044d362409d5469aed47d19e7908d19bd194493aThomas Graf
5144d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_class_lookup_ops(src);
5244d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cops && cops->co_clone)
5344d362409d5469aed47d19e7908d19bd194493aThomas Graf		err = cops->co_clone(dst, src);
5444d362409d5469aed47d19e7908d19bd194493aThomas Graferrout:
5544d362409d5469aed47d19e7908d19bd194493aThomas Graf	return err;
5644d362409d5469aed47d19e7908d19bd194493aThomas Graf}
5744d362409d5469aed47d19e7908d19bd194493aThomas Graf
58d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void class_dump_line(struct nl_object *obj, struct nl_dump_params *p)
5944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
6044d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class *class = (struct rtnl_class *) obj;
6144d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class_ops *cops;
6244d362409d5469aed47d19e7908d19bd194493aThomas Graf
63d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	tca_dump_line((struct rtnl_tca *) class, "class", p);
6444d362409d5469aed47d19e7908d19bd194493aThomas Graf
6544d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_class_lookup_ops(class);
66d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	if (cops && cops->co_dump[NL_DUMP_LINE])
67d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		cops->co_dump[NL_DUMP_LINE](class, p);
68d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	nl_dump(p, "\n");
6944d362409d5469aed47d19e7908d19bd194493aThomas Graf}
7044d362409d5469aed47d19e7908d19bd194493aThomas Graf
71d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void class_dump_details(struct nl_object *obj, struct nl_dump_params *p)
7244d362409d5469aed47d19e7908d19bd194493aThomas Graf{
7344d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class *class = (struct rtnl_class *) obj;
7444d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class_ops *cops;
7544d362409d5469aed47d19e7908d19bd194493aThomas Graf
76d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	class_dump_line(obj, p);
77d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	tca_dump_details((struct rtnl_tca *) class, p);
7844d362409d5469aed47d19e7908d19bd194493aThomas Graf
7944d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (class->c_info) {
8044d362409d5469aed47d19e7908d19bd194493aThomas Graf		char buf[32];
81d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		nl_dump(p, "child-qdisc %s ",
8244d362409d5469aed47d19e7908d19bd194493aThomas Graf			rtnl_tc_handle2str(class->c_info, buf, sizeof(buf)));
8344d362409d5469aed47d19e7908d19bd194493aThomas Graf	}
8444d362409d5469aed47d19e7908d19bd194493aThomas Graf
8544d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_class_lookup_ops(class);
86d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	if (cops && cops->co_dump[NL_DUMP_DETAILS])
87d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		cops->co_dump[NL_DUMP_DETAILS](class, p);
8844d362409d5469aed47d19e7908d19bd194493aThomas Graf	else if (!class->c_info)
89d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		nl_dump(p, "noop (no leaf qdisc)");
9044d362409d5469aed47d19e7908d19bd194493aThomas Graf
91d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	nl_dump(p, "\n");
9244d362409d5469aed47d19e7908d19bd194493aThomas Graf}
9344d362409d5469aed47d19e7908d19bd194493aThomas Graf
94d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void class_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
9544d362409d5469aed47d19e7908d19bd194493aThomas Graf{
9644d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class *class = (struct rtnl_class *) obj;
9744d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class_ops *cops;
9844d362409d5469aed47d19e7908d19bd194493aThomas Graf
99d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	class_dump_details(obj, p);
100d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	tca_dump_stats((struct rtnl_tca *) class, p);
101d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	nl_dump(p, "\n");
10244d362409d5469aed47d19e7908d19bd194493aThomas Graf
10344d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_class_lookup_ops(class);
10444d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cops && cops->co_dump[NL_DUMP_STATS])
105d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		cops->co_dump[NL_DUMP_STATS](class, p);
10644d362409d5469aed47d19e7908d19bd194493aThomas Graf}
10744d362409d5469aed47d19e7908d19bd194493aThomas Graf
10844d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
10944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing
11044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{
11144d362409d5469aed47d19e7908d19bd194493aThomas Graf */
11244d362409d5469aed47d19e7908d19bd194493aThomas Graf
11344d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_class *rtnl_class_alloc(void)
11444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
11544d362409d5469aed47d19e7908d19bd194493aThomas Graf	return (struct rtnl_class *) nl_object_alloc(&class_obj_ops);
11644d362409d5469aed47d19e7908d19bd194493aThomas Graf}
11744d362409d5469aed47d19e7908d19bd194493aThomas Graf
11844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_class_put(struct rtnl_class *class)
11944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
12044d362409d5469aed47d19e7908d19bd194493aThomas Graf	nl_object_put((struct nl_object *) class);
12144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
12244d362409d5469aed47d19e7908d19bd194493aThomas Graf
12344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
12444d362409d5469aed47d19e7908d19bd194493aThomas Graf
12544d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
12644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Leaf Qdisc
12744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{
12844d362409d5469aed47d19e7908d19bd194493aThomas Graf */
12944d362409d5469aed47d19e7908d19bd194493aThomas Graf
13044d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
13144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Lookup the leaf qdisc of a class
13244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg class		the parent class
13344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache		a qdisc cache including at laest all qdiscs of the
13444d362409d5469aed47d19e7908d19bd194493aThomas Graf *                      interface the specified class is attached to
13544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return The qdisc from the cache or NULL if the class has no leaf qdisc
13644d362409d5469aed47d19e7908d19bd194493aThomas Graf */
13744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_qdisc *rtnl_class_leaf_qdisc(struct rtnl_class *class,
13844d362409d5469aed47d19e7908d19bd194493aThomas Graf					 struct nl_cache *cache)
13944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
14044d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_qdisc *leaf;
14144d362409d5469aed47d19e7908d19bd194493aThomas Graf
14244d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (!class->c_info)
14344d362409d5469aed47d19e7908d19bd194493aThomas Graf		return NULL;
14444d362409d5469aed47d19e7908d19bd194493aThomas Graf
14544d362409d5469aed47d19e7908d19bd194493aThomas Graf	leaf = rtnl_qdisc_get_by_parent(cache, class->c_ifindex,
14644d362409d5469aed47d19e7908d19bd194493aThomas Graf					class->c_handle);
14744d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (!leaf || leaf->q_handle != class->c_info)
14844d362409d5469aed47d19e7908d19bd194493aThomas Graf		return NULL;
14944d362409d5469aed47d19e7908d19bd194493aThomas Graf
15044d362409d5469aed47d19e7908d19bd194493aThomas Graf	return leaf;
15144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
15244d362409d5469aed47d19e7908d19bd194493aThomas Graf
15344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
15444d362409d5469aed47d19e7908d19bd194493aThomas Graf
15544d362409d5469aed47d19e7908d19bd194493aThomas Graf
15644d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
15744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Iterators
15844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{
15944d362409d5469aed47d19e7908d19bd194493aThomas Graf */
16044d362409d5469aed47d19e7908d19bd194493aThomas Graf
16144d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
16244d362409d5469aed47d19e7908d19bd194493aThomas Graf * Call a callback for each child of a class
16344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg class		the parent class
16444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache		a class cache including all classes of the interface
16544d362409d5469aed47d19e7908d19bd194493aThomas Graf *                      the specified class is attached to
16644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cb              callback function
16744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg arg             argument to be passed to callback function
16844d362409d5469aed47d19e7908d19bd194493aThomas Graf */
16944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_class_foreach_child(struct rtnl_class *class, struct nl_cache *cache,
17044d362409d5469aed47d19e7908d19bd194493aThomas Graf			      void (*cb)(struct nl_object *, void *), void *arg)
17144d362409d5469aed47d19e7908d19bd194493aThomas Graf{
17244d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_class *filter;
17344d362409d5469aed47d19e7908d19bd194493aThomas Graf
17444d362409d5469aed47d19e7908d19bd194493aThomas Graf	filter = rtnl_class_alloc();
17544d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (!filter)
17644d362409d5469aed47d19e7908d19bd194493aThomas Graf		return;
17744d362409d5469aed47d19e7908d19bd194493aThomas Graf
17844d362409d5469aed47d19e7908d19bd194493aThomas Graf	rtnl_class_set_parent(filter, class->c_handle);
17944d362409d5469aed47d19e7908d19bd194493aThomas Graf	rtnl_class_set_ifindex(filter, class->c_ifindex);
18044d362409d5469aed47d19e7908d19bd194493aThomas Graf	rtnl_class_set_kind(filter, class->c_kind);
18144d362409d5469aed47d19e7908d19bd194493aThomas Graf
18244d362409d5469aed47d19e7908d19bd194493aThomas Graf	nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
18344d362409d5469aed47d19e7908d19bd194493aThomas Graf	rtnl_class_put(filter);
18444d362409d5469aed47d19e7908d19bd194493aThomas Graf}
18544d362409d5469aed47d19e7908d19bd194493aThomas Graf
18644d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
18744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Call a callback for each classifier attached to the class
18844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg class		the parent class
18944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache		a filter cache including at least all the filters
19044d362409d5469aed47d19e7908d19bd194493aThomas Graf *                      attached to the specified class
19144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cb              callback function
19244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg arg             argument to be passed to callback function
19344d362409d5469aed47d19e7908d19bd194493aThomas Graf */
19444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_class_foreach_cls(struct rtnl_class *class, struct nl_cache *cache,
19544d362409d5469aed47d19e7908d19bd194493aThomas Graf			    void (*cb)(struct nl_object *, void *), void *arg)
19644d362409d5469aed47d19e7908d19bd194493aThomas Graf{
19744d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls *filter;
19844d362409d5469aed47d19e7908d19bd194493aThomas Graf
19944d362409d5469aed47d19e7908d19bd194493aThomas Graf	filter = rtnl_cls_alloc();
20044d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (!filter)
20144d362409d5469aed47d19e7908d19bd194493aThomas Graf		return;
20244d362409d5469aed47d19e7908d19bd194493aThomas Graf
20344d362409d5469aed47d19e7908d19bd194493aThomas Graf	rtnl_cls_set_ifindex(filter, class->c_ifindex);
20444d362409d5469aed47d19e7908d19bd194493aThomas Graf	rtnl_cls_set_parent(filter, class->c_parent);
20544d362409d5469aed47d19e7908d19bd194493aThomas Graf
20644d362409d5469aed47d19e7908d19bd194493aThomas Graf	nl_cache_foreach_filter(cache, (struct nl_object *) filter, cb, arg);
20744d362409d5469aed47d19e7908d19bd194493aThomas Graf	rtnl_cls_put(filter);
20844d362409d5469aed47d19e7908d19bd194493aThomas Graf}
20944d362409d5469aed47d19e7908d19bd194493aThomas Graf
21044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
21144d362409d5469aed47d19e7908d19bd194493aThomas Graf
21244d362409d5469aed47d19e7908d19bd194493aThomas Graf
21344d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
21444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes
21544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{
21644d362409d5469aed47d19e7908d19bd194493aThomas Graf */
21744d362409d5469aed47d19e7908d19bd194493aThomas Graf
21844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_class_set_ifindex(struct rtnl_class *class, int ifindex)
21944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
22044d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_set_ifindex((struct rtnl_tca *) class, ifindex);
22144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
22244d362409d5469aed47d19e7908d19bd194493aThomas Graf
22344d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_class_get_ifindex(struct rtnl_class *class)
22444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
22544d362409d5469aed47d19e7908d19bd194493aThomas Graf	return tca_get_ifindex((struct rtnl_tca *) class);
22644d362409d5469aed47d19e7908d19bd194493aThomas Graf}
22744d362409d5469aed47d19e7908d19bd194493aThomas Graf
22844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_class_set_handle(struct rtnl_class *class, uint32_t handle)
22944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
23044d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_set_handle((struct rtnl_tca *) class, handle);
23144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
23244d362409d5469aed47d19e7908d19bd194493aThomas Graf
23344d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t rtnl_class_get_handle(struct rtnl_class *class)
23444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
23544d362409d5469aed47d19e7908d19bd194493aThomas Graf	return tca_get_handle((struct rtnl_tca *) class);
23644d362409d5469aed47d19e7908d19bd194493aThomas Graf}
23744d362409d5469aed47d19e7908d19bd194493aThomas Graf
23844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_class_set_parent(struct rtnl_class *class, uint32_t parent)
23944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
24044d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_set_parent((struct rtnl_tca *) class, parent);
24144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
24244d362409d5469aed47d19e7908d19bd194493aThomas Graf
24344d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t rtnl_class_get_parent(struct rtnl_class *class)
24444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
24544d362409d5469aed47d19e7908d19bd194493aThomas Graf	return tca_get_parent((struct rtnl_tca *) class);
24644d362409d5469aed47d19e7908d19bd194493aThomas Graf}
24744d362409d5469aed47d19e7908d19bd194493aThomas Graf
24844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_class_set_kind(struct rtnl_class *class, const char *name)
24944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
25044d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_set_kind((struct rtnl_tca *) class, name);
25144d362409d5469aed47d19e7908d19bd194493aThomas Graf	class->c_ops = __rtnl_class_lookup_ops(name);
25244d362409d5469aed47d19e7908d19bd194493aThomas Graf}
25344d362409d5469aed47d19e7908d19bd194493aThomas Graf
25444d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_class_get_kind(struct rtnl_class *class)
25544d362409d5469aed47d19e7908d19bd194493aThomas Graf{
25644d362409d5469aed47d19e7908d19bd194493aThomas Graf	return tca_get_kind((struct rtnl_tca *) class);
25744d362409d5469aed47d19e7908d19bd194493aThomas Graf}
25844d362409d5469aed47d19e7908d19bd194493aThomas Graf
25944d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t rtnl_class_get_stat(struct rtnl_class *class,
26044d362409d5469aed47d19e7908d19bd194493aThomas Graf			     enum rtnl_tc_stats_id id)
26144d362409d5469aed47d19e7908d19bd194493aThomas Graf{
26244d362409d5469aed47d19e7908d19bd194493aThomas Graf	return tca_get_stat((struct rtnl_tca *) class, id);
26344d362409d5469aed47d19e7908d19bd194493aThomas Graf}
26444d362409d5469aed47d19e7908d19bd194493aThomas Graf
26544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
26644d362409d5469aed47d19e7908d19bd194493aThomas Graf
26744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_object_ops class_obj_ops = {
26844d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_name		= "route/class",
26944d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_size		= sizeof(struct rtnl_class),
27044d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_free_data         	= class_free_data,
27144d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_clone		= class_clone,
272d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	.oo_dump = {
273d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	    [NL_DUMP_LINE]	= class_dump_line,
274d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	    [NL_DUMP_DETAILS]	= class_dump_details,
275d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	    [NL_DUMP_STATS]	= class_dump_stats,
276d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	},
27744d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_compare		= tca_compare,
27844d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_id_attrs		= (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE),
27944d362409d5469aed47d19e7908d19bd194493aThomas Graf};
28044d362409d5469aed47d19e7908d19bd194493aThomas Graf
28144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
282