144d362409d5469aed47d19e7908d19bd194493aThomas Graf/*
244d362409d5469aed47d19e7908d19bd194493aThomas Graf * lib/route/cls_api.c       Classifier Object
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 cls
1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup cls_obj Classifier 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/utils.h>
2244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/tc.h>
2344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/classifier.h>
2444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/classifier-modules.h>
2544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/link.h>
2644d362409d5469aed47d19e7908d19bd194493aThomas Graf
2744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @cond SKIP */
2844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CLS_ATTR_PRIO		(TCA_ATTR_MAX << 1)
2944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CLS_ATTR_PROTOCOL	(TCA_ATTR_MAX << 2)
3044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @endcond */
3144d362409d5469aed47d19e7908d19bd194493aThomas Graf
3244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void cls_free_data(struct nl_object *obj)
3344d362409d5469aed47d19e7908d19bd194493aThomas Graf{
3444d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls *cls = (struct rtnl_cls *) obj;
3544d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls_ops *cops;
3644d362409d5469aed47d19e7908d19bd194493aThomas Graf
3744d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_free_data((struct rtnl_tca *) cls);
3844d362409d5469aed47d19e7908d19bd194493aThomas Graf
3944d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_cls_lookup_ops(cls);
4044d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cops && cops->co_free_data)
4144d362409d5469aed47d19e7908d19bd194493aThomas Graf		cops->co_free_data(cls);
42ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
43ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	nl_data_free(cls->c_subdata);
4444d362409d5469aed47d19e7908d19bd194493aThomas Graf}
4544d362409d5469aed47d19e7908d19bd194493aThomas Graf
4644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int cls_clone(struct nl_object *_dst, struct nl_object *_src)
4744d362409d5469aed47d19e7908d19bd194493aThomas Graf{
4844d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls *dst = nl_object_priv(_dst);
4944d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls *src = nl_object_priv(_src);
5044d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls_ops *cops;
5144d362409d5469aed47d19e7908d19bd194493aThomas Graf	int err;
5244d362409d5469aed47d19e7908d19bd194493aThomas Graf
5344d362409d5469aed47d19e7908d19bd194493aThomas Graf	err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src);
5444d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (err < 0)
5544d362409d5469aed47d19e7908d19bd194493aThomas Graf		goto errout;
5644d362409d5469aed47d19e7908d19bd194493aThomas Graf
57ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	if (src->c_subdata) {
58ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		if (!(dst->c_subdata = nl_data_clone(src->c_subdata))) {
59ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			err = -NLE_NOMEM;
60ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			goto errout;
61ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		}
62ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	}
63ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
6444d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_cls_lookup_ops(src);
6544d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cops && cops->co_clone)
6644d362409d5469aed47d19e7908d19bd194493aThomas Graf		err = cops->co_clone(dst, src);
6744d362409d5469aed47d19e7908d19bd194493aThomas Graferrout:
6844d362409d5469aed47d19e7908d19bd194493aThomas Graf	return err;
6944d362409d5469aed47d19e7908d19bd194493aThomas Graf}
7044d362409d5469aed47d19e7908d19bd194493aThomas Graf
71d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void cls_dump_line(struct nl_object *obj, struct nl_dump_params *p)
7244d362409d5469aed47d19e7908d19bd194493aThomas Graf{
7344d362409d5469aed47d19e7908d19bd194493aThomas Graf	char buf[32];
7444d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls *cls = (struct rtnl_cls *) obj;
7544d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls_ops *cops;
7644d362409d5469aed47d19e7908d19bd194493aThomas Graf
77d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	tca_dump_line((struct rtnl_tca *) cls, "cls", p);
7844d362409d5469aed47d19e7908d19bd194493aThomas Graf
79d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	nl_dump(p, " prio %u protocol %s", cls->c_prio,
8044d362409d5469aed47d19e7908d19bd194493aThomas Graf		nl_ether_proto2str(cls->c_protocol, buf, sizeof(buf)));
8144d362409d5469aed47d19e7908d19bd194493aThomas Graf
8244d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_cls_lookup_ops(cls);
83d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	if (cops && cops->co_dump[NL_DUMP_LINE])
84d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		cops->co_dump[NL_DUMP_LINE](cls, p);
85d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	nl_dump(p, "\n");
8644d362409d5469aed47d19e7908d19bd194493aThomas Graf}
8744d362409d5469aed47d19e7908d19bd194493aThomas Graf
88d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void cls_dump_details(struct nl_object *obj, struct nl_dump_params *p)
8944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
9044d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls *cls = (struct rtnl_cls *) obj;
9144d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls_ops *cops;
9244d362409d5469aed47d19e7908d19bd194493aThomas Graf
93d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	cls_dump_line(obj, p);
94d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	tca_dump_details((struct rtnl_tca *) cls, p);
9544d362409d5469aed47d19e7908d19bd194493aThomas Graf
9644d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_cls_lookup_ops(cls);
97d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	if (cops && cops->co_dump[NL_DUMP_DETAILS])
98d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		cops->co_dump[NL_DUMP_DETAILS](cls, p);
9944d362409d5469aed47d19e7908d19bd194493aThomas Graf	else
100d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		nl_dump(p, "no options\n");
10144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
10244d362409d5469aed47d19e7908d19bd194493aThomas Graf
103d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void cls_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
10444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
10544d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls *cls = (struct rtnl_cls *) obj;
10644d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct rtnl_cls_ops *cops;
10744d362409d5469aed47d19e7908d19bd194493aThomas Graf
108d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	cls_dump_details(obj, p);
109d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	tca_dump_stats((struct rtnl_tca *) cls, p);
110d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	nl_dump(p, "\n");
11144d362409d5469aed47d19e7908d19bd194493aThomas Graf
11244d362409d5469aed47d19e7908d19bd194493aThomas Graf	cops = rtnl_cls_lookup_ops(cls);
11344d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cops && cops->co_dump[NL_DUMP_STATS])
114d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		cops->co_dump[NL_DUMP_STATS](cls, p);
11544d362409d5469aed47d19e7908d19bd194493aThomas Graf}
11644d362409d5469aed47d19e7908d19bd194493aThomas Graf
11744d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
11844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing
11944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{
12044d362409d5469aed47d19e7908d19bd194493aThomas Graf */
12144d362409d5469aed47d19e7908d19bd194493aThomas Graf
12244d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_cls *rtnl_cls_alloc(void)
12344d362409d5469aed47d19e7908d19bd194493aThomas Graf{
12444d362409d5469aed47d19e7908d19bd194493aThomas Graf	return (struct rtnl_cls *) nl_object_alloc(&cls_obj_ops);
12544d362409d5469aed47d19e7908d19bd194493aThomas Graf}
12644d362409d5469aed47d19e7908d19bd194493aThomas Graf
12744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_cls_put(struct rtnl_cls *cls)
12844d362409d5469aed47d19e7908d19bd194493aThomas Graf{
12944d362409d5469aed47d19e7908d19bd194493aThomas Graf	nl_object_put((struct nl_object *) cls);
13044d362409d5469aed47d19e7908d19bd194493aThomas Graf}
13144d362409d5469aed47d19e7908d19bd194493aThomas Graf
13244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
13344d362409d5469aed47d19e7908d19bd194493aThomas Graf
13444d362409d5469aed47d19e7908d19bd194493aThomas Graf
13544d362409d5469aed47d19e7908d19bd194493aThomas Graf/**
13644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes
13744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{
13844d362409d5469aed47d19e7908d19bd194493aThomas Graf */
13944d362409d5469aed47d19e7908d19bd194493aThomas Graf
14044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_cls_set_ifindex(struct rtnl_cls *f, int ifindex)
14144d362409d5469aed47d19e7908d19bd194493aThomas Graf{
14244d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_set_ifindex((struct rtnl_tca *) f, ifindex);
14344d362409d5469aed47d19e7908d19bd194493aThomas Graf}
14444d362409d5469aed47d19e7908d19bd194493aThomas Graf
145ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Grafint rtnl_cls_get_ifindex(struct rtnl_cls *cls)
146ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf{
147ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	return cls->c_ifindex;
148ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf}
149ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
15044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_cls_set_handle(struct rtnl_cls *f, uint32_t handle)
15144d362409d5469aed47d19e7908d19bd194493aThomas Graf{
15244d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_set_handle((struct rtnl_tca *) f, handle);
15344d362409d5469aed47d19e7908d19bd194493aThomas Graf}
15444d362409d5469aed47d19e7908d19bd194493aThomas Graf
15544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_cls_set_parent(struct rtnl_cls *f, uint32_t parent)
15644d362409d5469aed47d19e7908d19bd194493aThomas Graf{
15744d362409d5469aed47d19e7908d19bd194493aThomas Graf	tca_set_parent((struct rtnl_tca *) f, parent);
15844d362409d5469aed47d19e7908d19bd194493aThomas Graf}
15944d362409d5469aed47d19e7908d19bd194493aThomas Graf
160ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Grafuint32_t rtnl_cls_get_parent(struct rtnl_cls *cls)
16144d362409d5469aed47d19e7908d19bd194493aThomas Graf{
162ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	return cls->c_parent;
163ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf}
164ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
165ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Grafint rtnl_cls_set_kind(struct rtnl_cls *cls, const char *kind)
166ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf{
167ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	if (cls->ce_mask & TCA_ATTR_KIND)
168ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		return -NLE_EXIST;
169ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
170ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	tca_set_kind((struct rtnl_tca *) cls, kind);
171ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
172ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	/* Force allocation of data */
173ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	rtnl_cls_data(cls);
174f42f195a80ffb7a5dcc355a56b8fe229692718e5Thomas Graf
175f42f195a80ffb7a5dcc355a56b8fe229692718e5Thomas Graf	return 0;
176f42f195a80ffb7a5dcc355a56b8fe229692718e5Thomas Graf}
177f42f195a80ffb7a5dcc355a56b8fe229692718e5Thomas Graf
178f42f195a80ffb7a5dcc355a56b8fe229692718e5Thomas Grafstruct rtnl_cls_ops *rtnl_cls_get_ops(struct rtnl_cls *cls)
179f42f195a80ffb7a5dcc355a56b8fe229692718e5Thomas Graf{
180f42f195a80ffb7a5dcc355a56b8fe229692718e5Thomas Graf	return cls->c_ops;
18144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
18244d362409d5469aed47d19e7908d19bd194493aThomas Graf
1835d92f9c03d85cefee5afe7f40d7ea69dfde4cf77Thomas Grafvoid rtnl_cls_set_prio(struct rtnl_cls *cls, uint16_t prio)
18444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
18544d362409d5469aed47d19e7908d19bd194493aThomas Graf	cls->c_prio = prio;
18644d362409d5469aed47d19e7908d19bd194493aThomas Graf	cls->ce_mask |= CLS_ATTR_PRIO;
18744d362409d5469aed47d19e7908d19bd194493aThomas Graf}
18844d362409d5469aed47d19e7908d19bd194493aThomas Graf
1895d92f9c03d85cefee5afe7f40d7ea69dfde4cf77Thomas Grafuint16_t rtnl_cls_get_prio(struct rtnl_cls *cls)
19044d362409d5469aed47d19e7908d19bd194493aThomas Graf{
19144d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cls->ce_mask & CLS_ATTR_PRIO)
19244d362409d5469aed47d19e7908d19bd194493aThomas Graf		return cls->c_prio;
19344d362409d5469aed47d19e7908d19bd194493aThomas Graf	else
19444d362409d5469aed47d19e7908d19bd194493aThomas Graf		return 0;
19544d362409d5469aed47d19e7908d19bd194493aThomas Graf}
19644d362409d5469aed47d19e7908d19bd194493aThomas Graf
1975d92f9c03d85cefee5afe7f40d7ea69dfde4cf77Thomas Grafvoid rtnl_cls_set_protocol(struct rtnl_cls *cls, uint16_t protocol)
19844d362409d5469aed47d19e7908d19bd194493aThomas Graf{
19944d362409d5469aed47d19e7908d19bd194493aThomas Graf	cls->c_protocol = protocol;
20044d362409d5469aed47d19e7908d19bd194493aThomas Graf	cls->ce_mask |= CLS_ATTR_PROTOCOL;
20144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
20244d362409d5469aed47d19e7908d19bd194493aThomas Graf
2035d92f9c03d85cefee5afe7f40d7ea69dfde4cf77Thomas Grafuint16_t rtnl_cls_get_protocol(struct rtnl_cls *cls)
20444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
20544d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (cls->ce_mask & CLS_ATTR_PROTOCOL)
20644d362409d5469aed47d19e7908d19bd194493aThomas Graf		return cls->c_protocol;
20744d362409d5469aed47d19e7908d19bd194493aThomas Graf	else
20844d362409d5469aed47d19e7908d19bd194493aThomas Graf		return ETH_P_ALL;
20944d362409d5469aed47d19e7908d19bd194493aThomas Graf}
21044d362409d5469aed47d19e7908d19bd194493aThomas Graf
211ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Grafvoid *rtnl_cls_data(struct rtnl_cls *cls)
212ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf{
213ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	if (!cls->c_subdata) {
214ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		struct rtnl_cls_ops *ops = cls->c_ops;
215ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
216ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		if (!ops) {
217ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			if (!cls->c_kind[0])
218ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf				BUG();
219ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
220ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			ops = __rtnl_cls_lookup_ops(cls->c_kind);
221ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			if (ops == NULL)
222ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf				return NULL;
223ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
224ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			cls->c_ops = ops;
225ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		}
226ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
227ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		if (!ops->co_size)
228ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			BUG();
229ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
230ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf		if (!(cls->c_subdata = nl_data_alloc(NULL, ops->co_size)))
231ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf			return NULL;
232ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	}
233ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
234ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	return nl_data_get(cls->c_subdata);
235ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf}
236ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf
23744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
23844d362409d5469aed47d19e7908d19bd194493aThomas Graf
23944d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_object_ops cls_obj_ops = {
24044d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_name		= "route/cls",
24144d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_size		= sizeof(struct rtnl_cls),
24244d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_free_data		= cls_free_data,
24344d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_clone		= cls_clone,
244d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	.oo_dump = {
245d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	    [NL_DUMP_LINE]	= cls_dump_line,
246d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	    [NL_DUMP_DETAILS]	= cls_dump_details,
247d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	    [NL_DUMP_STATS]	= cls_dump_stats,
248d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf	},
24944d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_compare		= tca_compare,
25044d362409d5469aed47d19e7908d19bd194493aThomas Graf	.oo_id_attrs		= (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE),
25144d362409d5469aed47d19e7908d19bd194493aThomas Graf};
25244d362409d5469aed47d19e7908d19bd194493aThomas Graf
25344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */
254