xref: /aosp_15_r20/external/iptables/extensions/libxt_cgroup.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1*a71a9546SAutomerger Merge Worker #include <stdio.h>
2*a71a9546SAutomerger Merge Worker #include <xtables.h>
3*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_cgroup.h>
4*a71a9546SAutomerger Merge Worker 
5*a71a9546SAutomerger Merge Worker enum {
6*a71a9546SAutomerger Merge Worker 	O_CLASSID = 0,
7*a71a9546SAutomerger Merge Worker 	O_PATH = 1,
8*a71a9546SAutomerger Merge Worker };
9*a71a9546SAutomerger Merge Worker 
cgroup_help_v0(void)10*a71a9546SAutomerger Merge Worker static void cgroup_help_v0(void)
11*a71a9546SAutomerger Merge Worker {
12*a71a9546SAutomerger Merge Worker 	printf(
13*a71a9546SAutomerger Merge Worker "cgroup match options:\n"
14*a71a9546SAutomerger Merge Worker "[!] --cgroup classid            Match cgroup classid\n");
15*a71a9546SAutomerger Merge Worker }
16*a71a9546SAutomerger Merge Worker 
cgroup_help_v1(void)17*a71a9546SAutomerger Merge Worker static void cgroup_help_v1(void)
18*a71a9546SAutomerger Merge Worker {
19*a71a9546SAutomerger Merge Worker 	printf(
20*a71a9546SAutomerger Merge Worker "cgroup match options:\n"
21*a71a9546SAutomerger Merge Worker "[!] --path path                 Recursively match path relative to cgroup2 root\n"
22*a71a9546SAutomerger Merge Worker "[!] --cgroup classid            Match cgroup classid, can't be used with --path\n");
23*a71a9546SAutomerger Merge Worker }
24*a71a9546SAutomerger Merge Worker 
25*a71a9546SAutomerger Merge Worker static const struct xt_option_entry cgroup_opts_v0[] = {
26*a71a9546SAutomerger Merge Worker 	{
27*a71a9546SAutomerger Merge Worker 		.name = "cgroup",
28*a71a9546SAutomerger Merge Worker 		.id = O_CLASSID,
29*a71a9546SAutomerger Merge Worker 		.type = XTTYPE_UINT32,
30*a71a9546SAutomerger Merge Worker 		.flags = XTOPT_INVERT | XTOPT_MAND | XTOPT_PUT,
31*a71a9546SAutomerger Merge Worker 		XTOPT_POINTER(struct xt_cgroup_info_v0, id)
32*a71a9546SAutomerger Merge Worker 	},
33*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
34*a71a9546SAutomerger Merge Worker };
35*a71a9546SAutomerger Merge Worker 
36*a71a9546SAutomerger Merge Worker static const struct xt_option_entry cgroup_opts_v1[] = {
37*a71a9546SAutomerger Merge Worker 	{
38*a71a9546SAutomerger Merge Worker 		.name = "path",
39*a71a9546SAutomerger Merge Worker 		.id = O_PATH,
40*a71a9546SAutomerger Merge Worker 		.type = XTTYPE_STRING,
41*a71a9546SAutomerger Merge Worker 		.flags = XTOPT_INVERT | XTOPT_PUT,
42*a71a9546SAutomerger Merge Worker 		XTOPT_POINTER(struct xt_cgroup_info_v1, path)
43*a71a9546SAutomerger Merge Worker 	},
44*a71a9546SAutomerger Merge Worker 	{
45*a71a9546SAutomerger Merge Worker 		.name = "cgroup",
46*a71a9546SAutomerger Merge Worker 		.id = O_CLASSID,
47*a71a9546SAutomerger Merge Worker 		.type = XTTYPE_UINT32,
48*a71a9546SAutomerger Merge Worker 		.flags = XTOPT_INVERT | XTOPT_PUT,
49*a71a9546SAutomerger Merge Worker 		XTOPT_POINTER(struct xt_cgroup_info_v1, classid)
50*a71a9546SAutomerger Merge Worker 	},
51*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
52*a71a9546SAutomerger Merge Worker };
53*a71a9546SAutomerger Merge Worker 
54*a71a9546SAutomerger Merge Worker static const struct xt_option_entry cgroup_opts_v2[] = {
55*a71a9546SAutomerger Merge Worker 	{
56*a71a9546SAutomerger Merge Worker 		.name = "path",
57*a71a9546SAutomerger Merge Worker 		.id = O_PATH,
58*a71a9546SAutomerger Merge Worker 		.type = XTTYPE_STRING,
59*a71a9546SAutomerger Merge Worker 		.flags = XTOPT_INVERT | XTOPT_PUT,
60*a71a9546SAutomerger Merge Worker 		XTOPT_POINTER(struct xt_cgroup_info_v2, path)
61*a71a9546SAutomerger Merge Worker 	},
62*a71a9546SAutomerger Merge Worker 	{
63*a71a9546SAutomerger Merge Worker 		.name = "cgroup",
64*a71a9546SAutomerger Merge Worker 		.id = O_CLASSID,
65*a71a9546SAutomerger Merge Worker 		.type = XTTYPE_UINT32,
66*a71a9546SAutomerger Merge Worker 		.flags = XTOPT_INVERT | XTOPT_PUT,
67*a71a9546SAutomerger Merge Worker 		XTOPT_POINTER(struct xt_cgroup_info_v2, classid)
68*a71a9546SAutomerger Merge Worker 	},
69*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
70*a71a9546SAutomerger Merge Worker };
71*a71a9546SAutomerger Merge Worker 
cgroup_parse_v0(struct xt_option_call * cb)72*a71a9546SAutomerger Merge Worker static void cgroup_parse_v0(struct xt_option_call *cb)
73*a71a9546SAutomerger Merge Worker {
74*a71a9546SAutomerger Merge Worker 	struct xt_cgroup_info_v0 *cgroupinfo = cb->data;
75*a71a9546SAutomerger Merge Worker 
76*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
77*a71a9546SAutomerger Merge Worker 	if (cb->invert)
78*a71a9546SAutomerger Merge Worker 		cgroupinfo->invert = true;
79*a71a9546SAutomerger Merge Worker }
80*a71a9546SAutomerger Merge Worker 
cgroup_parse_v1(struct xt_option_call * cb)81*a71a9546SAutomerger Merge Worker static void cgroup_parse_v1(struct xt_option_call *cb)
82*a71a9546SAutomerger Merge Worker {
83*a71a9546SAutomerger Merge Worker 	struct xt_cgroup_info_v1 *info = cb->data;
84*a71a9546SAutomerger Merge Worker 
85*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
86*a71a9546SAutomerger Merge Worker 
87*a71a9546SAutomerger Merge Worker 	switch (cb->entry->id) {
88*a71a9546SAutomerger Merge Worker 	case O_PATH:
89*a71a9546SAutomerger Merge Worker 		info->has_path = true;
90*a71a9546SAutomerger Merge Worker 		if (cb->invert)
91*a71a9546SAutomerger Merge Worker 			info->invert_path = true;
92*a71a9546SAutomerger Merge Worker 		break;
93*a71a9546SAutomerger Merge Worker 	case O_CLASSID:
94*a71a9546SAutomerger Merge Worker 		info->has_classid = true;
95*a71a9546SAutomerger Merge Worker 		if (cb->invert)
96*a71a9546SAutomerger Merge Worker 			info->invert_classid = true;
97*a71a9546SAutomerger Merge Worker 		break;
98*a71a9546SAutomerger Merge Worker 	}
99*a71a9546SAutomerger Merge Worker }
100*a71a9546SAutomerger Merge Worker 
cgroup_parse_v2(struct xt_option_call * cb)101*a71a9546SAutomerger Merge Worker static void cgroup_parse_v2(struct xt_option_call *cb)
102*a71a9546SAutomerger Merge Worker {
103*a71a9546SAutomerger Merge Worker 	struct xt_cgroup_info_v2 *info = cb->data;
104*a71a9546SAutomerger Merge Worker 
105*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
106*a71a9546SAutomerger Merge Worker 
107*a71a9546SAutomerger Merge Worker 	switch (cb->entry->id) {
108*a71a9546SAutomerger Merge Worker 	case O_PATH:
109*a71a9546SAutomerger Merge Worker 		info->has_path = true;
110*a71a9546SAutomerger Merge Worker 		if (cb->invert)
111*a71a9546SAutomerger Merge Worker 			info->invert_path = true;
112*a71a9546SAutomerger Merge Worker 		break;
113*a71a9546SAutomerger Merge Worker 	case O_CLASSID:
114*a71a9546SAutomerger Merge Worker 		info->has_classid = true;
115*a71a9546SAutomerger Merge Worker 		if (cb->invert)
116*a71a9546SAutomerger Merge Worker 			info->invert_classid = true;
117*a71a9546SAutomerger Merge Worker 		break;
118*a71a9546SAutomerger Merge Worker 	}
119*a71a9546SAutomerger Merge Worker }
120*a71a9546SAutomerger Merge Worker 
121*a71a9546SAutomerger Merge Worker static void
cgroup_print_v0(const void * ip,const struct xt_entry_match * match,int numeric)122*a71a9546SAutomerger Merge Worker cgroup_print_v0(const void *ip, const struct xt_entry_match *match, int numeric)
123*a71a9546SAutomerger Merge Worker {
124*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v0 *info = (void *) match->data;
125*a71a9546SAutomerger Merge Worker 
126*a71a9546SAutomerger Merge Worker 	printf(" cgroup %s%u", info->invert ? "! ":"", info->id);
127*a71a9546SAutomerger Merge Worker }
128*a71a9546SAutomerger Merge Worker 
cgroup_save_v0(const void * ip,const struct xt_entry_match * match)129*a71a9546SAutomerger Merge Worker static void cgroup_save_v0(const void *ip, const struct xt_entry_match *match)
130*a71a9546SAutomerger Merge Worker {
131*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v0 *info = (void *) match->data;
132*a71a9546SAutomerger Merge Worker 
133*a71a9546SAutomerger Merge Worker 	printf("%s --cgroup %u", info->invert ? " !" : "", info->id);
134*a71a9546SAutomerger Merge Worker }
135*a71a9546SAutomerger Merge Worker 
136*a71a9546SAutomerger Merge Worker static void
cgroup_print_v1(const void * ip,const struct xt_entry_match * match,int numeric)137*a71a9546SAutomerger Merge Worker cgroup_print_v1(const void *ip, const struct xt_entry_match *match, int numeric)
138*a71a9546SAutomerger Merge Worker {
139*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v1 *info = (void *)match->data;
140*a71a9546SAutomerger Merge Worker 
141*a71a9546SAutomerger Merge Worker 	printf(" cgroup");
142*a71a9546SAutomerger Merge Worker 	if (info->has_path)
143*a71a9546SAutomerger Merge Worker 		printf(" %s%s", info->invert_path ? "! ":"", info->path);
144*a71a9546SAutomerger Merge Worker 	if (info->has_classid)
145*a71a9546SAutomerger Merge Worker 		printf(" %s%u", info->invert_classid ? "! ":"", info->classid);
146*a71a9546SAutomerger Merge Worker }
147*a71a9546SAutomerger Merge Worker 
cgroup_save_v1(const void * ip,const struct xt_entry_match * match)148*a71a9546SAutomerger Merge Worker static void cgroup_save_v1(const void *ip, const struct xt_entry_match *match)
149*a71a9546SAutomerger Merge Worker {
150*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v1 *info = (void *)match->data;
151*a71a9546SAutomerger Merge Worker 
152*a71a9546SAutomerger Merge Worker 	if (info->has_path) {
153*a71a9546SAutomerger Merge Worker 		printf("%s --path", info->invert_path ? " !" : "");
154*a71a9546SAutomerger Merge Worker 		xtables_save_string(info->path);
155*a71a9546SAutomerger Merge Worker 	}
156*a71a9546SAutomerger Merge Worker 
157*a71a9546SAutomerger Merge Worker 	if (info->has_classid)
158*a71a9546SAutomerger Merge Worker 		printf("%s --cgroup %u", info->invert_classid ? " !" : "",
159*a71a9546SAutomerger Merge Worker 		       info->classid);
160*a71a9546SAutomerger Merge Worker }
161*a71a9546SAutomerger Merge Worker 
162*a71a9546SAutomerger Merge Worker static void
cgroup_print_v2(const void * ip,const struct xt_entry_match * match,int numeric)163*a71a9546SAutomerger Merge Worker cgroup_print_v2(const void *ip, const struct xt_entry_match *match, int numeric)
164*a71a9546SAutomerger Merge Worker {
165*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v2 *info = (void *)match->data;
166*a71a9546SAutomerger Merge Worker 
167*a71a9546SAutomerger Merge Worker 	printf(" cgroup");
168*a71a9546SAutomerger Merge Worker 	if (info->has_path)
169*a71a9546SAutomerger Merge Worker 		printf(" %s%s", info->invert_path ? "! ":"", info->path);
170*a71a9546SAutomerger Merge Worker 	if (info->has_classid)
171*a71a9546SAutomerger Merge Worker 		printf(" %s%u", info->invert_classid ? "! ":"", info->classid);
172*a71a9546SAutomerger Merge Worker }
173*a71a9546SAutomerger Merge Worker 
cgroup_save_v2(const void * ip,const struct xt_entry_match * match)174*a71a9546SAutomerger Merge Worker static void cgroup_save_v2(const void *ip, const struct xt_entry_match *match)
175*a71a9546SAutomerger Merge Worker {
176*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v2 *info = (void *)match->data;
177*a71a9546SAutomerger Merge Worker 
178*a71a9546SAutomerger Merge Worker 	if (info->has_path) {
179*a71a9546SAutomerger Merge Worker 		printf("%s --path", info->invert_path ? " !" : "");
180*a71a9546SAutomerger Merge Worker 		xtables_save_string(info->path);
181*a71a9546SAutomerger Merge Worker 	}
182*a71a9546SAutomerger Merge Worker 
183*a71a9546SAutomerger Merge Worker 	if (info->has_classid)
184*a71a9546SAutomerger Merge Worker 		printf("%s --cgroup %u", info->invert_classid ? " !" : "",
185*a71a9546SAutomerger Merge Worker 		       info->classid);
186*a71a9546SAutomerger Merge Worker }
187*a71a9546SAutomerger Merge Worker 
cgroup_xlate_v0(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)188*a71a9546SAutomerger Merge Worker static int cgroup_xlate_v0(struct xt_xlate *xl,
189*a71a9546SAutomerger Merge Worker 			   const struct xt_xlate_mt_params *params)
190*a71a9546SAutomerger Merge Worker {
191*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v0 *info = (void *)params->match->data;
192*a71a9546SAutomerger Merge Worker 
193*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "meta cgroup %s%u", info->invert ? "!= " : "",
194*a71a9546SAutomerger Merge Worker 		     info->id);
195*a71a9546SAutomerger Merge Worker 	return 1;
196*a71a9546SAutomerger Merge Worker }
197*a71a9546SAutomerger Merge Worker 
cgroup_xlate_v1(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)198*a71a9546SAutomerger Merge Worker static int cgroup_xlate_v1(struct xt_xlate *xl,
199*a71a9546SAutomerger Merge Worker 			   const struct xt_xlate_mt_params *params)
200*a71a9546SAutomerger Merge Worker {
201*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v1 *info = (void *)params->match->data;
202*a71a9546SAutomerger Merge Worker 
203*a71a9546SAutomerger Merge Worker 	if (info->has_path)
204*a71a9546SAutomerger Merge Worker 		return 0;
205*a71a9546SAutomerger Merge Worker 
206*a71a9546SAutomerger Merge Worker 	if (info->has_classid)
207*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "meta cgroup %s%u",
208*a71a9546SAutomerger Merge Worker 			     info->invert_classid ? "!= " : "",
209*a71a9546SAutomerger Merge Worker 			     info->classid);
210*a71a9546SAutomerger Merge Worker 
211*a71a9546SAutomerger Merge Worker 	return 1;
212*a71a9546SAutomerger Merge Worker }
213*a71a9546SAutomerger Merge Worker 
cgroup_xlate_v2(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)214*a71a9546SAutomerger Merge Worker static int cgroup_xlate_v2(struct xt_xlate *xl,
215*a71a9546SAutomerger Merge Worker 			   const struct xt_xlate_mt_params *params)
216*a71a9546SAutomerger Merge Worker {
217*a71a9546SAutomerger Merge Worker 	const struct xt_cgroup_info_v2 *info = (void *)params->match->data;
218*a71a9546SAutomerger Merge Worker 
219*a71a9546SAutomerger Merge Worker 	if (info->has_path)
220*a71a9546SAutomerger Merge Worker 		return 0;
221*a71a9546SAutomerger Merge Worker 
222*a71a9546SAutomerger Merge Worker 	if (info->has_classid)
223*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "meta cgroup %s%u",
224*a71a9546SAutomerger Merge Worker 			     info->invert_classid ? "!= " : "",
225*a71a9546SAutomerger Merge Worker 			     info->classid);
226*a71a9546SAutomerger Merge Worker 
227*a71a9546SAutomerger Merge Worker 	return 1;
228*a71a9546SAutomerger Merge Worker }
229*a71a9546SAutomerger Merge Worker 
230*a71a9546SAutomerger Merge Worker static struct xtables_match cgroup_match[] = {
231*a71a9546SAutomerger Merge Worker 	{
232*a71a9546SAutomerger Merge Worker 		.family		= NFPROTO_UNSPEC,
233*a71a9546SAutomerger Merge Worker 		.revision	= 0,
234*a71a9546SAutomerger Merge Worker 		.name		= "cgroup",
235*a71a9546SAutomerger Merge Worker 		.version	= XTABLES_VERSION,
236*a71a9546SAutomerger Merge Worker 		.size		= XT_ALIGN(sizeof(struct xt_cgroup_info_v0)),
237*a71a9546SAutomerger Merge Worker 		.userspacesize	= XT_ALIGN(sizeof(struct xt_cgroup_info_v0)),
238*a71a9546SAutomerger Merge Worker 		.help		= cgroup_help_v0,
239*a71a9546SAutomerger Merge Worker 		.print		= cgroup_print_v0,
240*a71a9546SAutomerger Merge Worker 		.save		= cgroup_save_v0,
241*a71a9546SAutomerger Merge Worker 		.x6_parse	= cgroup_parse_v0,
242*a71a9546SAutomerger Merge Worker 		.x6_options	= cgroup_opts_v0,
243*a71a9546SAutomerger Merge Worker 		.xlate		= cgroup_xlate_v0,
244*a71a9546SAutomerger Merge Worker 	},
245*a71a9546SAutomerger Merge Worker 	{
246*a71a9546SAutomerger Merge Worker 		.family		= NFPROTO_UNSPEC,
247*a71a9546SAutomerger Merge Worker 		.revision	= 1,
248*a71a9546SAutomerger Merge Worker 		.name		= "cgroup",
249*a71a9546SAutomerger Merge Worker 		.version	= XTABLES_VERSION,
250*a71a9546SAutomerger Merge Worker 		.size		= XT_ALIGN(sizeof(struct xt_cgroup_info_v1)),
251*a71a9546SAutomerger Merge Worker 		.userspacesize	= offsetof(struct xt_cgroup_info_v1, priv),
252*a71a9546SAutomerger Merge Worker 		.help		= cgroup_help_v1,
253*a71a9546SAutomerger Merge Worker 		.print		= cgroup_print_v1,
254*a71a9546SAutomerger Merge Worker 		.save		= cgroup_save_v1,
255*a71a9546SAutomerger Merge Worker 		.x6_parse	= cgroup_parse_v1,
256*a71a9546SAutomerger Merge Worker 		.x6_options	= cgroup_opts_v1,
257*a71a9546SAutomerger Merge Worker 		.xlate		= cgroup_xlate_v1,
258*a71a9546SAutomerger Merge Worker 	},
259*a71a9546SAutomerger Merge Worker 	{
260*a71a9546SAutomerger Merge Worker 		.family		= NFPROTO_UNSPEC,
261*a71a9546SAutomerger Merge Worker 		.revision	= 2,
262*a71a9546SAutomerger Merge Worker 		.name		= "cgroup",
263*a71a9546SAutomerger Merge Worker 		.version	= XTABLES_VERSION,
264*a71a9546SAutomerger Merge Worker 		.size		= XT_ALIGN(sizeof(struct xt_cgroup_info_v2)),
265*a71a9546SAutomerger Merge Worker 		.userspacesize	= offsetof(struct xt_cgroup_info_v2, priv),
266*a71a9546SAutomerger Merge Worker 		.help		= cgroup_help_v1,
267*a71a9546SAutomerger Merge Worker 		.print		= cgroup_print_v2,
268*a71a9546SAutomerger Merge Worker 		.save		= cgroup_save_v2,
269*a71a9546SAutomerger Merge Worker 		.x6_parse	= cgroup_parse_v2,
270*a71a9546SAutomerger Merge Worker 		.x6_options	= cgroup_opts_v2,
271*a71a9546SAutomerger Merge Worker 		.xlate		= cgroup_xlate_v2,
272*a71a9546SAutomerger Merge Worker 	},
273*a71a9546SAutomerger Merge Worker };
274*a71a9546SAutomerger Merge Worker 
_init(void)275*a71a9546SAutomerger Merge Worker void _init(void)
276*a71a9546SAutomerger Merge Worker {
277*a71a9546SAutomerger Merge Worker 	xtables_register_matches(cgroup_match, ARRAY_SIZE(cgroup_match));
278*a71a9546SAutomerger Merge Worker }
279