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