xref: /aosp_15_r20/external/libnl/lib/route/cls/basic.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2008-2013 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker  * @ingroup cls
8*4dc78e53SAndroid Build Coastguard Worker  * @defgroup cls_basic Basic Classifier
9*4dc78e53SAndroid Build Coastguard Worker  *
10*4dc78e53SAndroid Build Coastguard Worker  * @par Introduction
11*4dc78e53SAndroid Build Coastguard Worker  * The basic classifier is the simplest form of a classifier. It does
12*4dc78e53SAndroid Build Coastguard Worker  * not have any special classification capabilities, instead it can be
13*4dc78e53SAndroid Build Coastguard Worker  * used to classify exclusively based on extended matches or to
14*4dc78e53SAndroid Build Coastguard Worker  * create a "catch-all" filter.
15*4dc78e53SAndroid Build Coastguard Worker  *
16*4dc78e53SAndroid Build Coastguard Worker  * @{
17*4dc78e53SAndroid Build Coastguard Worker  */
18*4dc78e53SAndroid Build Coastguard Worker 
19*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
20*4dc78e53SAndroid Build Coastguard Worker 
21*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
22*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/classifier.h>
23*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/action.h>
24*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/basic.h>
25*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/ematch.h>
26*4dc78e53SAndroid Build Coastguard Worker 
27*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
28*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-route/nl-route.h"
29*4dc78e53SAndroid Build Coastguard Worker 
30*4dc78e53SAndroid Build Coastguard Worker struct rtnl_basic
31*4dc78e53SAndroid Build Coastguard Worker {
32*4dc78e53SAndroid Build Coastguard Worker 	uint32_t			b_target;
33*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_ematch_tree *	b_ematch;
34*4dc78e53SAndroid Build Coastguard Worker 	int				b_mask;
35*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_act *		b_act;
36*4dc78e53SAndroid Build Coastguard Worker };
37*4dc78e53SAndroid Build Coastguard Worker 
38*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
39*4dc78e53SAndroid Build Coastguard Worker #define BASIC_ATTR_TARGET	0x001
40*4dc78e53SAndroid Build Coastguard Worker #define BASIC_ATTR_EMATCH	0x002
41*4dc78e53SAndroid Build Coastguard Worker #define BASIC_ATTR_ACTION	0x004
42*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
43*4dc78e53SAndroid Build Coastguard Worker 
44*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy basic_policy[TCA_BASIC_MAX+1] = {
45*4dc78e53SAndroid Build Coastguard Worker 	[TCA_BASIC_CLASSID]	= { .type = NLA_U32 },
46*4dc78e53SAndroid Build Coastguard Worker 	[TCA_BASIC_EMATCHES]	= { .type = NLA_NESTED },
47*4dc78e53SAndroid Build Coastguard Worker };
48*4dc78e53SAndroid Build Coastguard Worker 
basic_clone(void * _dst,void * _src)49*4dc78e53SAndroid Build Coastguard Worker static int basic_clone(void *_dst, void *_src)
50*4dc78e53SAndroid Build Coastguard Worker {
51*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_OPNOTSUPP;
52*4dc78e53SAndroid Build Coastguard Worker }
53*4dc78e53SAndroid Build Coastguard Worker 
basic_free_data(struct rtnl_tc * tc,void * data)54*4dc78e53SAndroid Build Coastguard Worker static void basic_free_data(struct rtnl_tc *tc, void *data)
55*4dc78e53SAndroid Build Coastguard Worker {
56*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b = data;
57*4dc78e53SAndroid Build Coastguard Worker 
58*4dc78e53SAndroid Build Coastguard Worker 	if (!b)
59*4dc78e53SAndroid Build Coastguard Worker 		return;
60*4dc78e53SAndroid Build Coastguard Worker 
61*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_act)
62*4dc78e53SAndroid Build Coastguard Worker 		rtnl_act_put_all(&b->b_act);
63*4dc78e53SAndroid Build Coastguard Worker 	rtnl_ematch_tree_free(b->b_ematch);
64*4dc78e53SAndroid Build Coastguard Worker }
65*4dc78e53SAndroid Build Coastguard Worker 
basic_msg_parser(struct rtnl_tc * tc,void * data)66*4dc78e53SAndroid Build Coastguard Worker static int basic_msg_parser(struct rtnl_tc *tc, void *data)
67*4dc78e53SAndroid Build Coastguard Worker {
68*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *tb[TCA_BASIC_MAX + 1];
69*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b = data;
70*4dc78e53SAndroid Build Coastguard Worker 	int err;
71*4dc78e53SAndroid Build Coastguard Worker 
72*4dc78e53SAndroid Build Coastguard Worker 	err = tca_parse(tb, TCA_BASIC_MAX, tc, basic_policy);
73*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0)
74*4dc78e53SAndroid Build Coastguard Worker 		return err;
75*4dc78e53SAndroid Build Coastguard Worker 
76*4dc78e53SAndroid Build Coastguard Worker 	if (tb[TCA_BASIC_CLASSID]) {
77*4dc78e53SAndroid Build Coastguard Worker 		b->b_target = nla_get_u32(tb[TCA_BASIC_CLASSID]);
78*4dc78e53SAndroid Build Coastguard Worker 		b->b_mask |= BASIC_ATTR_TARGET;
79*4dc78e53SAndroid Build Coastguard Worker 	}
80*4dc78e53SAndroid Build Coastguard Worker 
81*4dc78e53SAndroid Build Coastguard Worker 	if (tb[TCA_BASIC_EMATCHES]) {
82*4dc78e53SAndroid Build Coastguard Worker 		if ((err = rtnl_ematch_parse_attr(tb[TCA_BASIC_EMATCHES],
83*4dc78e53SAndroid Build Coastguard Worker 					     &b->b_ematch)) < 0)
84*4dc78e53SAndroid Build Coastguard Worker 			return err;
85*4dc78e53SAndroid Build Coastguard Worker 
86*4dc78e53SAndroid Build Coastguard Worker 		if (b->b_ematch)
87*4dc78e53SAndroid Build Coastguard Worker 			b->b_mask |= BASIC_ATTR_EMATCH;
88*4dc78e53SAndroid Build Coastguard Worker 	}
89*4dc78e53SAndroid Build Coastguard Worker 	if (tb[TCA_BASIC_ACT]) {
90*4dc78e53SAndroid Build Coastguard Worker 		b->b_mask |= BASIC_ATTR_ACTION;
91*4dc78e53SAndroid Build Coastguard Worker 		err = rtnl_act_parse(&b->b_act, tb[TCA_BASIC_ACT]);
92*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
93*4dc78e53SAndroid Build Coastguard Worker 			return err;
94*4dc78e53SAndroid Build Coastguard Worker 	}
95*4dc78e53SAndroid Build Coastguard Worker 
96*4dc78e53SAndroid Build Coastguard Worker 	return 0;
97*4dc78e53SAndroid Build Coastguard Worker }
98*4dc78e53SAndroid Build Coastguard Worker 
basic_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)99*4dc78e53SAndroid Build Coastguard Worker static void basic_dump_line(struct rtnl_tc *tc, void *data,
100*4dc78e53SAndroid Build Coastguard Worker 			    struct nl_dump_params *p)
101*4dc78e53SAndroid Build Coastguard Worker {
102*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b = data;
103*4dc78e53SAndroid Build Coastguard Worker 	char buf[32];
104*4dc78e53SAndroid Build Coastguard Worker 
105*4dc78e53SAndroid Build Coastguard Worker 	if (!b)
106*4dc78e53SAndroid Build Coastguard Worker 		return;
107*4dc78e53SAndroid Build Coastguard Worker 
108*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_mask & BASIC_ATTR_EMATCH)
109*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " ematch");
110*4dc78e53SAndroid Build Coastguard Worker 	else
111*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " match-all");
112*4dc78e53SAndroid Build Coastguard Worker 
113*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_mask & BASIC_ATTR_TARGET)
114*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " target %s",
115*4dc78e53SAndroid Build Coastguard Worker 			rtnl_tc_handle2str(b->b_target, buf, sizeof(buf)));
116*4dc78e53SAndroid Build Coastguard Worker }
117*4dc78e53SAndroid Build Coastguard Worker 
basic_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)118*4dc78e53SAndroid Build Coastguard Worker static void basic_dump_details(struct rtnl_tc *tc, void *data,
119*4dc78e53SAndroid Build Coastguard Worker 			       struct nl_dump_params *p)
120*4dc78e53SAndroid Build Coastguard Worker {
121*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b = data;
122*4dc78e53SAndroid Build Coastguard Worker 
123*4dc78e53SAndroid Build Coastguard Worker 	if (!b)
124*4dc78e53SAndroid Build Coastguard Worker 		return;
125*4dc78e53SAndroid Build Coastguard Worker 
126*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_mask & BASIC_ATTR_EMATCH) {
127*4dc78e53SAndroid Build Coastguard Worker 		nl_dump_line(p, "    ematch ");
128*4dc78e53SAndroid Build Coastguard Worker 		rtnl_ematch_tree_dump(b->b_ematch, p);
129*4dc78e53SAndroid Build Coastguard Worker 	} else
130*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, "no options.\n");
131*4dc78e53SAndroid Build Coastguard Worker }
132*4dc78e53SAndroid Build Coastguard Worker 
basic_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)133*4dc78e53SAndroid Build Coastguard Worker static int basic_msg_fill(struct rtnl_tc *tc, void *data,
134*4dc78e53SAndroid Build Coastguard Worker 			  struct nl_msg *msg)
135*4dc78e53SAndroid Build Coastguard Worker {
136*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b = data;
137*4dc78e53SAndroid Build Coastguard Worker 
138*4dc78e53SAndroid Build Coastguard Worker 	if (!b)
139*4dc78e53SAndroid Build Coastguard Worker 		return 0;
140*4dc78e53SAndroid Build Coastguard Worker 
141*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_mask & BASIC_ATTR_TARGET)
142*4dc78e53SAndroid Build Coastguard Worker 		NLA_PUT_U32(msg, TCA_BASIC_CLASSID, b->b_target);
143*4dc78e53SAndroid Build Coastguard Worker 
144*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_mask & BASIC_ATTR_EMATCH &&
145*4dc78e53SAndroid Build Coastguard Worker 	    rtnl_ematch_fill_attr(msg, TCA_BASIC_EMATCHES, b->b_ematch) < 0)
146*4dc78e53SAndroid Build Coastguard Worker 		goto nla_put_failure;
147*4dc78e53SAndroid Build Coastguard Worker 
148*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_mask & BASIC_ATTR_ACTION) {
149*4dc78e53SAndroid Build Coastguard Worker 		int err;
150*4dc78e53SAndroid Build Coastguard Worker 
151*4dc78e53SAndroid Build Coastguard Worker 		err = rtnl_act_fill(msg, TCA_BASIC_ACT, b->b_act);
152*4dc78e53SAndroid Build Coastguard Worker 		if (err)
153*4dc78e53SAndroid Build Coastguard Worker 			return err;
154*4dc78e53SAndroid Build Coastguard Worker 	}
155*4dc78e53SAndroid Build Coastguard Worker 
156*4dc78e53SAndroid Build Coastguard Worker 	return 0;
157*4dc78e53SAndroid Build Coastguard Worker 
158*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
159*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_NOMEM;
160*4dc78e53SAndroid Build Coastguard Worker }
161*4dc78e53SAndroid Build Coastguard Worker 
162*4dc78e53SAndroid Build Coastguard Worker /**
163*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Modifications
164*4dc78e53SAndroid Build Coastguard Worker  * @{
165*4dc78e53SAndroid Build Coastguard Worker  */
166*4dc78e53SAndroid Build Coastguard Worker 
rtnl_basic_set_target(struct rtnl_cls * cls,uint32_t target)167*4dc78e53SAndroid Build Coastguard Worker void rtnl_basic_set_target(struct rtnl_cls *cls, uint32_t target)
168*4dc78e53SAndroid Build Coastguard Worker {
169*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b;
170*4dc78e53SAndroid Build Coastguard Worker 
171*4dc78e53SAndroid Build Coastguard Worker 	if (!(b = rtnl_tc_data(TC_CAST(cls))))
172*4dc78e53SAndroid Build Coastguard Worker 		return;
173*4dc78e53SAndroid Build Coastguard Worker 
174*4dc78e53SAndroid Build Coastguard Worker 	b->b_target = target;
175*4dc78e53SAndroid Build Coastguard Worker 	b->b_mask |= BASIC_ATTR_TARGET;
176*4dc78e53SAndroid Build Coastguard Worker }
177*4dc78e53SAndroid Build Coastguard Worker 
rtnl_basic_get_target(struct rtnl_cls * cls)178*4dc78e53SAndroid Build Coastguard Worker uint32_t rtnl_basic_get_target(struct rtnl_cls *cls)
179*4dc78e53SAndroid Build Coastguard Worker {
180*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b;
181*4dc78e53SAndroid Build Coastguard Worker 
182*4dc78e53SAndroid Build Coastguard Worker 	if (!(b = rtnl_tc_data(TC_CAST(cls))))
183*4dc78e53SAndroid Build Coastguard Worker 		return 0;
184*4dc78e53SAndroid Build Coastguard Worker 
185*4dc78e53SAndroid Build Coastguard Worker 	return b->b_target;
186*4dc78e53SAndroid Build Coastguard Worker }
187*4dc78e53SAndroid Build Coastguard Worker 
rtnl_basic_set_ematch(struct rtnl_cls * cls,struct rtnl_ematch_tree * tree)188*4dc78e53SAndroid Build Coastguard Worker void rtnl_basic_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
189*4dc78e53SAndroid Build Coastguard Worker {
190*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b;
191*4dc78e53SAndroid Build Coastguard Worker 
192*4dc78e53SAndroid Build Coastguard Worker 	if (!(b = rtnl_tc_data(TC_CAST(cls))))
193*4dc78e53SAndroid Build Coastguard Worker 		return;
194*4dc78e53SAndroid Build Coastguard Worker 
195*4dc78e53SAndroid Build Coastguard Worker 	if (b->b_ematch) {
196*4dc78e53SAndroid Build Coastguard Worker 		rtnl_ematch_tree_free(b->b_ematch);
197*4dc78e53SAndroid Build Coastguard Worker 		b->b_mask &= ~BASIC_ATTR_EMATCH;
198*4dc78e53SAndroid Build Coastguard Worker 	}
199*4dc78e53SAndroid Build Coastguard Worker 
200*4dc78e53SAndroid Build Coastguard Worker 	b->b_ematch = tree;
201*4dc78e53SAndroid Build Coastguard Worker 
202*4dc78e53SAndroid Build Coastguard Worker 	if (tree)
203*4dc78e53SAndroid Build Coastguard Worker 		b->b_mask |= BASIC_ATTR_EMATCH;
204*4dc78e53SAndroid Build Coastguard Worker }
205*4dc78e53SAndroid Build Coastguard Worker 
rtnl_basic_get_ematch(struct rtnl_cls * cls)206*4dc78e53SAndroid Build Coastguard Worker struct rtnl_ematch_tree *rtnl_basic_get_ematch(struct rtnl_cls *cls)
207*4dc78e53SAndroid Build Coastguard Worker {
208*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b;
209*4dc78e53SAndroid Build Coastguard Worker 
210*4dc78e53SAndroid Build Coastguard Worker 	if (!(b = rtnl_tc_data(TC_CAST(cls))))
211*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
212*4dc78e53SAndroid Build Coastguard Worker 
213*4dc78e53SAndroid Build Coastguard Worker 	return b->b_ematch;
214*4dc78e53SAndroid Build Coastguard Worker }
215*4dc78e53SAndroid Build Coastguard Worker 
rtnl_basic_add_action(struct rtnl_cls * cls,struct rtnl_act * act)216*4dc78e53SAndroid Build Coastguard Worker int rtnl_basic_add_action(struct rtnl_cls *cls, struct rtnl_act *act)
217*4dc78e53SAndroid Build Coastguard Worker {
218*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b;
219*4dc78e53SAndroid Build Coastguard Worker 	int err;
220*4dc78e53SAndroid Build Coastguard Worker 
221*4dc78e53SAndroid Build Coastguard Worker 	if (!act)
222*4dc78e53SAndroid Build Coastguard Worker 		return 0;
223*4dc78e53SAndroid Build Coastguard Worker 
224*4dc78e53SAndroid Build Coastguard Worker 	if (!(b = rtnl_tc_data(TC_CAST(cls))))
225*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
226*4dc78e53SAndroid Build Coastguard Worker 
227*4dc78e53SAndroid Build Coastguard Worker 	if ((err = _rtnl_act_append_get(&b->b_act, act)) < 0)
228*4dc78e53SAndroid Build Coastguard Worker 		return err;
229*4dc78e53SAndroid Build Coastguard Worker 
230*4dc78e53SAndroid Build Coastguard Worker 	b->b_mask |= BASIC_ATTR_ACTION;
231*4dc78e53SAndroid Build Coastguard Worker 	return 0;
232*4dc78e53SAndroid Build Coastguard Worker }
233*4dc78e53SAndroid Build Coastguard Worker 
rtnl_basic_get_action(struct rtnl_cls * cls)234*4dc78e53SAndroid Build Coastguard Worker struct rtnl_act* rtnl_basic_get_action(struct rtnl_cls *cls)
235*4dc78e53SAndroid Build Coastguard Worker {
236*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b;
237*4dc78e53SAndroid Build Coastguard Worker 
238*4dc78e53SAndroid Build Coastguard Worker 	if (!(b = rtnl_tc_data_peek(TC_CAST(cls))))
239*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
240*4dc78e53SAndroid Build Coastguard Worker 
241*4dc78e53SAndroid Build Coastguard Worker 	if (!(b->b_mask & BASIC_ATTR_ACTION))
242*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
243*4dc78e53SAndroid Build Coastguard Worker 
244*4dc78e53SAndroid Build Coastguard Worker 	return b->b_act;
245*4dc78e53SAndroid Build Coastguard Worker }
246*4dc78e53SAndroid Build Coastguard Worker 
rtnl_basic_del_action(struct rtnl_cls * cls,struct rtnl_act * act)247*4dc78e53SAndroid Build Coastguard Worker int rtnl_basic_del_action(struct rtnl_cls *cls, struct rtnl_act *act)
248*4dc78e53SAndroid Build Coastguard Worker {
249*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_basic *b;
250*4dc78e53SAndroid Build Coastguard Worker 	int ret;
251*4dc78e53SAndroid Build Coastguard Worker 
252*4dc78e53SAndroid Build Coastguard Worker 	if (!act)
253*4dc78e53SAndroid Build Coastguard Worker 		return 0;
254*4dc78e53SAndroid Build Coastguard Worker 
255*4dc78e53SAndroid Build Coastguard Worker 	if (!(b = rtnl_tc_data(TC_CAST(cls))))
256*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
257*4dc78e53SAndroid Build Coastguard Worker 
258*4dc78e53SAndroid Build Coastguard Worker 	if (!(b->b_mask & BASIC_ATTR_ACTION))
259*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
260*4dc78e53SAndroid Build Coastguard Worker 	ret = rtnl_act_remove(&b->b_act, act);
261*4dc78e53SAndroid Build Coastguard Worker 	if (ret)
262*4dc78e53SAndroid Build Coastguard Worker 		return ret;
263*4dc78e53SAndroid Build Coastguard Worker 
264*4dc78e53SAndroid Build Coastguard Worker 	if (!b->b_act)
265*4dc78e53SAndroid Build Coastguard Worker 		b->b_mask &= ~BASIC_ATTR_ACTION;
266*4dc78e53SAndroid Build Coastguard Worker 	rtnl_act_put(act);
267*4dc78e53SAndroid Build Coastguard Worker 	return 0;
268*4dc78e53SAndroid Build Coastguard Worker }
269*4dc78e53SAndroid Build Coastguard Worker /** @} */
270*4dc78e53SAndroid Build Coastguard Worker 
271*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops basic_ops = {
272*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "basic",
273*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_CLS,
274*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_basic),
275*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= basic_msg_parser,
276*4dc78e53SAndroid Build Coastguard Worker 	.to_clone		= basic_clone,
277*4dc78e53SAndroid Build Coastguard Worker 	.to_free_data		= basic_free_data,
278*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= basic_msg_fill,
279*4dc78e53SAndroid Build Coastguard Worker 	.to_dump = {
280*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]	= basic_dump_line,
281*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]	= basic_dump_details,
282*4dc78e53SAndroid Build Coastguard Worker 	},
283*4dc78e53SAndroid Build Coastguard Worker };
284*4dc78e53SAndroid Build Coastguard Worker 
basic_init(void)285*4dc78e53SAndroid Build Coastguard Worker static void _nl_init basic_init(void)
286*4dc78e53SAndroid Build Coastguard Worker {
287*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&basic_ops);
288*4dc78e53SAndroid Build Coastguard Worker }
289*4dc78e53SAndroid Build Coastguard Worker 
basic_exit(void)290*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit basic_exit(void)
291*4dc78e53SAndroid Build Coastguard Worker {
292*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&basic_ops);
293*4dc78e53SAndroid Build Coastguard Worker }
294*4dc78e53SAndroid Build Coastguard Worker 
295*4dc78e53SAndroid Build Coastguard Worker /** @} */
296