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