xref: /aosp_15_r20/external/libnl/lib/route/cls/cgroup.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) 2009-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_cgroup Control Groups Classifier
9*4dc78e53SAndroid Build Coastguard Worker  *
10*4dc78e53SAndroid Build Coastguard Worker  * @{
11*4dc78e53SAndroid Build Coastguard Worker  */
12*4dc78e53SAndroid Build Coastguard Worker 
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
14*4dc78e53SAndroid Build Coastguard Worker 
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
16*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/classifier.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/cgroup.h>
20*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/ematch.h>
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
23*4dc78e53SAndroid Build Coastguard Worker 
24*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
25*4dc78e53SAndroid Build Coastguard Worker struct rtnl_cgroup {
26*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_ematch_tree *cg_ematch;
27*4dc78e53SAndroid Build Coastguard Worker 	int cg_mask;
28*4dc78e53SAndroid Build Coastguard Worker };
29*4dc78e53SAndroid Build Coastguard Worker 
30*4dc78e53SAndroid Build Coastguard Worker #define CGROUP_ATTR_EMATCH      0x001
31*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
32*4dc78e53SAndroid Build Coastguard Worker 
33*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = {
34*4dc78e53SAndroid Build Coastguard Worker 	[TCA_CGROUP_EMATCHES]	= { .type = NLA_NESTED },
35*4dc78e53SAndroid Build Coastguard Worker };
36*4dc78e53SAndroid Build Coastguard Worker 
cgroup_clone(void * _dst,void * _src)37*4dc78e53SAndroid Build Coastguard Worker static int cgroup_clone(void *_dst, void *_src)
38*4dc78e53SAndroid Build Coastguard Worker {
39*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *dst = _dst, *src = _src;
40*4dc78e53SAndroid Build Coastguard Worker 
41*4dc78e53SAndroid Build Coastguard Worker 	dst->cg_ematch = NULL;
42*4dc78e53SAndroid Build Coastguard Worker 
43*4dc78e53SAndroid Build Coastguard Worker 	if (src->cg_ematch) {
44*4dc78e53SAndroid Build Coastguard Worker 		dst->cg_ematch = rtnl_ematch_tree_clone(src->cg_ematch);
45*4dc78e53SAndroid Build Coastguard Worker 		if (!dst->cg_ematch)
46*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_NOMEM;
47*4dc78e53SAndroid Build Coastguard Worker 	}
48*4dc78e53SAndroid Build Coastguard Worker 
49*4dc78e53SAndroid Build Coastguard Worker 	return 0;
50*4dc78e53SAndroid Build Coastguard Worker }
51*4dc78e53SAndroid Build Coastguard Worker 
cgroup_free_data(struct rtnl_tc * tc,void * data)52*4dc78e53SAndroid Build Coastguard Worker static void cgroup_free_data(struct rtnl_tc *tc, void *data)
53*4dc78e53SAndroid Build Coastguard Worker {
54*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *c = data;
55*4dc78e53SAndroid Build Coastguard Worker 
56*4dc78e53SAndroid Build Coastguard Worker 	if (!c)
57*4dc78e53SAndroid Build Coastguard Worker 		return;
58*4dc78e53SAndroid Build Coastguard Worker 
59*4dc78e53SAndroid Build Coastguard Worker 	rtnl_ematch_tree_free(c->cg_ematch);
60*4dc78e53SAndroid Build Coastguard Worker }
61*4dc78e53SAndroid Build Coastguard Worker 
cgroup_msg_parser(struct rtnl_tc * tc,void * data)62*4dc78e53SAndroid Build Coastguard Worker static int cgroup_msg_parser(struct rtnl_tc *tc, void *data)
63*4dc78e53SAndroid Build Coastguard Worker {
64*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *tb[TCA_CGROUP_MAX + 1];
65*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *c = data;
66*4dc78e53SAndroid Build Coastguard Worker 	int err;
67*4dc78e53SAndroid Build Coastguard Worker 
68*4dc78e53SAndroid Build Coastguard Worker 	err = tca_parse(tb, TCA_CGROUP_MAX, tc, cgroup_policy);
69*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0)
70*4dc78e53SAndroid Build Coastguard Worker 		return err;
71*4dc78e53SAndroid Build Coastguard Worker 
72*4dc78e53SAndroid Build Coastguard Worker 	if (tb[TCA_CGROUP_EMATCHES]) {
73*4dc78e53SAndroid Build Coastguard Worker 		if ((err = rtnl_ematch_parse_attr(tb[TCA_CGROUP_EMATCHES],
74*4dc78e53SAndroid Build Coastguard Worker 						  &c->cg_ematch)) < 0)
75*4dc78e53SAndroid Build Coastguard Worker 			return err;
76*4dc78e53SAndroid Build Coastguard Worker 		c->cg_mask |= CGROUP_ATTR_EMATCH;
77*4dc78e53SAndroid Build Coastguard Worker 	}
78*4dc78e53SAndroid Build Coastguard Worker 
79*4dc78e53SAndroid Build Coastguard Worker #if 0
80*4dc78e53SAndroid Build Coastguard Worker 	TODO:
81*4dc78e53SAndroid Build Coastguard Worker 	TCA_CGROUP_ACT,
82*4dc78e53SAndroid Build Coastguard Worker 	TCA_CGROUP_POLICE,
83*4dc78e53SAndroid Build Coastguard Worker #endif
84*4dc78e53SAndroid Build Coastguard Worker 
85*4dc78e53SAndroid Build Coastguard Worker 	return 0;
86*4dc78e53SAndroid Build Coastguard Worker }
87*4dc78e53SAndroid Build Coastguard Worker 
cgroup_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)88*4dc78e53SAndroid Build Coastguard Worker static void cgroup_dump_line(struct rtnl_tc *tc, void *data,
89*4dc78e53SAndroid Build Coastguard Worker 			     struct nl_dump_params *p)
90*4dc78e53SAndroid Build Coastguard Worker {
91*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *c = data;
92*4dc78e53SAndroid Build Coastguard Worker 
93*4dc78e53SAndroid Build Coastguard Worker 	if (!c)
94*4dc78e53SAndroid Build Coastguard Worker 		return;
95*4dc78e53SAndroid Build Coastguard Worker 
96*4dc78e53SAndroid Build Coastguard Worker 	if (c->cg_mask & CGROUP_ATTR_EMATCH)
97*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " ematch");
98*4dc78e53SAndroid Build Coastguard Worker 	else
99*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " match-all");
100*4dc78e53SAndroid Build Coastguard Worker }
101*4dc78e53SAndroid Build Coastguard Worker 
cgroup_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)102*4dc78e53SAndroid Build Coastguard Worker static void cgroup_dump_details(struct rtnl_tc *tc, void *data,
103*4dc78e53SAndroid Build Coastguard Worker 				struct nl_dump_params *p)
104*4dc78e53SAndroid Build Coastguard Worker {
105*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *c = data;
106*4dc78e53SAndroid Build Coastguard Worker 
107*4dc78e53SAndroid Build Coastguard Worker 	if (!c)
108*4dc78e53SAndroid Build Coastguard Worker 		return;
109*4dc78e53SAndroid Build Coastguard Worker 
110*4dc78e53SAndroid Build Coastguard Worker 	if (c->cg_mask & CGROUP_ATTR_EMATCH) {
111*4dc78e53SAndroid Build Coastguard Worker 		nl_dump_line(p, "    ematch ");
112*4dc78e53SAndroid Build Coastguard Worker 
113*4dc78e53SAndroid Build Coastguard Worker 		if (c->cg_ematch)
114*4dc78e53SAndroid Build Coastguard Worker 			rtnl_ematch_tree_dump(c->cg_ematch, p);
115*4dc78e53SAndroid Build Coastguard Worker 		else
116*4dc78e53SAndroid Build Coastguard Worker 			nl_dump(p, "<no tree>");
117*4dc78e53SAndroid Build Coastguard Worker 	} else
118*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, "no options");
119*4dc78e53SAndroid Build Coastguard Worker }
120*4dc78e53SAndroid Build Coastguard Worker 
cgroup_fill_msg(struct rtnl_tc * tc,void * data,struct nl_msg * msg)121*4dc78e53SAndroid Build Coastguard Worker static int cgroup_fill_msg(struct rtnl_tc *tc, void *data,
122*4dc78e53SAndroid Build Coastguard Worker 			   struct nl_msg *msg)
123*4dc78e53SAndroid Build Coastguard Worker {
124*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *c = data;
125*4dc78e53SAndroid Build Coastguard Worker 
126*4dc78e53SAndroid Build Coastguard Worker 	if (!c)
127*4dc78e53SAndroid Build Coastguard Worker 		BUG();
128*4dc78e53SAndroid Build Coastguard Worker 
129*4dc78e53SAndroid Build Coastguard Worker 	if (!(tc->ce_mask & TCA_ATTR_HANDLE))
130*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
131*4dc78e53SAndroid Build Coastguard Worker 
132*4dc78e53SAndroid Build Coastguard Worker 	if (c->cg_mask & CGROUP_ATTR_EMATCH)
133*4dc78e53SAndroid Build Coastguard Worker 		return rtnl_ematch_fill_attr(msg, TCA_CGROUP_EMATCHES,
134*4dc78e53SAndroid Build Coastguard Worker 					     c->cg_ematch);
135*4dc78e53SAndroid Build Coastguard Worker 
136*4dc78e53SAndroid Build Coastguard Worker 	return 0;
137*4dc78e53SAndroid Build Coastguard Worker }
138*4dc78e53SAndroid Build Coastguard Worker 
139*4dc78e53SAndroid Build Coastguard Worker 
140*4dc78e53SAndroid Build Coastguard Worker /**
141*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Modifications
142*4dc78e53SAndroid Build Coastguard Worker  * @{
143*4dc78e53SAndroid Build Coastguard Worker  */
144*4dc78e53SAndroid Build Coastguard Worker 
rtnl_cgroup_set_ematch(struct rtnl_cls * cls,struct rtnl_ematch_tree * tree)145*4dc78e53SAndroid Build Coastguard Worker void rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
146*4dc78e53SAndroid Build Coastguard Worker {
147*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *c;
148*4dc78e53SAndroid Build Coastguard Worker 
149*4dc78e53SAndroid Build Coastguard Worker 	if (!(c = rtnl_tc_data(TC_CAST(cls))))
150*4dc78e53SAndroid Build Coastguard Worker 		BUG();
151*4dc78e53SAndroid Build Coastguard Worker 
152*4dc78e53SAndroid Build Coastguard Worker 	if (c->cg_ematch) {
153*4dc78e53SAndroid Build Coastguard Worker 		rtnl_ematch_tree_free(c->cg_ematch);
154*4dc78e53SAndroid Build Coastguard Worker 		c->cg_mask &= ~CGROUP_ATTR_EMATCH;
155*4dc78e53SAndroid Build Coastguard Worker 	}
156*4dc78e53SAndroid Build Coastguard Worker 
157*4dc78e53SAndroid Build Coastguard Worker 	c->cg_ematch = tree;
158*4dc78e53SAndroid Build Coastguard Worker 
159*4dc78e53SAndroid Build Coastguard Worker 	if (tree)
160*4dc78e53SAndroid Build Coastguard Worker 		c->cg_mask |= CGROUP_ATTR_EMATCH;
161*4dc78e53SAndroid Build Coastguard Worker }
162*4dc78e53SAndroid Build Coastguard Worker 
rtnl_cgroup_get_ematch(struct rtnl_cls * cls)163*4dc78e53SAndroid Build Coastguard Worker struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls)
164*4dc78e53SAndroid Build Coastguard Worker {
165*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_cgroup *c;
166*4dc78e53SAndroid Build Coastguard Worker 
167*4dc78e53SAndroid Build Coastguard Worker 	if (!(c = rtnl_tc_data(TC_CAST(cls))))
168*4dc78e53SAndroid Build Coastguard Worker 		BUG();
169*4dc78e53SAndroid Build Coastguard Worker 
170*4dc78e53SAndroid Build Coastguard Worker 	return c->cg_ematch;
171*4dc78e53SAndroid Build Coastguard Worker }
172*4dc78e53SAndroid Build Coastguard Worker 
173*4dc78e53SAndroid Build Coastguard Worker /** @} */
174*4dc78e53SAndroid Build Coastguard Worker 
175*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops cgroup_ops = {
176*4dc78e53SAndroid Build Coastguard Worker 	.to_kind		= "cgroup",
177*4dc78e53SAndroid Build Coastguard Worker 	.to_type		= RTNL_TC_TYPE_CLS,
178*4dc78e53SAndroid Build Coastguard Worker 	.to_size		= sizeof(struct rtnl_cgroup),
179*4dc78e53SAndroid Build Coastguard Worker 	.to_clone		= cgroup_clone,
180*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser		= cgroup_msg_parser,
181*4dc78e53SAndroid Build Coastguard Worker 	.to_free_data		= cgroup_free_data,
182*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill		= cgroup_fill_msg,
183*4dc78e53SAndroid Build Coastguard Worker 	.to_dump = {
184*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]	= cgroup_dump_line,
185*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]	= cgroup_dump_details,
186*4dc78e53SAndroid Build Coastguard Worker 	},
187*4dc78e53SAndroid Build Coastguard Worker };
188*4dc78e53SAndroid Build Coastguard Worker 
cgroup_init(void)189*4dc78e53SAndroid Build Coastguard Worker static void _nl_init cgroup_init(void)
190*4dc78e53SAndroid Build Coastguard Worker {
191*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&cgroup_ops);
192*4dc78e53SAndroid Build Coastguard Worker }
193*4dc78e53SAndroid Build Coastguard Worker 
cgroup_exit(void)194*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit cgroup_exit(void)
195*4dc78e53SAndroid Build Coastguard Worker {
196*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&cgroup_ops);
197*4dc78e53SAndroid Build Coastguard Worker }
198*4dc78e53SAndroid Build Coastguard Worker 
199*4dc78e53SAndroid Build Coastguard Worker /** @} */
200