xref: /aosp_15_r20/external/iptables/extensions/libxt_connmark.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1*a71a9546SAutomerger Merge Worker /* Shared library add-on to iptables to add connmark matching support.
2*a71a9546SAutomerger Merge Worker  *
3*a71a9546SAutomerger Merge Worker  * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
4*a71a9546SAutomerger Merge Worker  * by Henrik Nordstrom <[email protected]>
5*a71a9546SAutomerger Merge Worker  *
6*a71a9546SAutomerger Merge Worker  * Version 1.1
7*a71a9546SAutomerger Merge Worker  *
8*a71a9546SAutomerger Merge Worker  * This program is free software; you can redistribute it and/or modify
9*a71a9546SAutomerger Merge Worker  * it under the terms of the GNU General Public License as published by
10*a71a9546SAutomerger Merge Worker  * the Free Software Foundation; either version 2 of the License, or
11*a71a9546SAutomerger Merge Worker  * (at your option) any later version.
12*a71a9546SAutomerger Merge Worker  *
13*a71a9546SAutomerger Merge Worker  * This program is distributed in the hope that it will be useful,
14*a71a9546SAutomerger Merge Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*a71a9546SAutomerger Merge Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*a71a9546SAutomerger Merge Worker  * GNU General Public License for more details.
17*a71a9546SAutomerger Merge Worker  *
18*a71a9546SAutomerger Merge Worker  * You should have received a copy of the GNU General Public License
19*a71a9546SAutomerger Merge Worker  * along with this program; if not, write to the Free Software
20*a71a9546SAutomerger Merge Worker  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21*a71a9546SAutomerger Merge Worker  */
22*a71a9546SAutomerger Merge Worker #include <stdbool.h>
23*a71a9546SAutomerger Merge Worker #include <stdint.h>
24*a71a9546SAutomerger Merge Worker #include <stdio.h>
25*a71a9546SAutomerger Merge Worker #include <xtables.h>
26*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_connmark.h>
27*a71a9546SAutomerger Merge Worker 
28*a71a9546SAutomerger Merge Worker struct xt_connmark_info {
29*a71a9546SAutomerger Merge Worker 	unsigned long mark, mask;
30*a71a9546SAutomerger Merge Worker 	uint8_t invert;
31*a71a9546SAutomerger Merge Worker };
32*a71a9546SAutomerger Merge Worker 
33*a71a9546SAutomerger Merge Worker enum {
34*a71a9546SAutomerger Merge Worker 	O_MARK = 0,
35*a71a9546SAutomerger Merge Worker };
36*a71a9546SAutomerger Merge Worker 
37*a71a9546SAutomerger Merge Worker static void connmark_mt_help(void)
38*a71a9546SAutomerger Merge Worker {
39*a71a9546SAutomerger Merge Worker 	printf(
40*a71a9546SAutomerger Merge Worker "connmark match options:\n"
41*a71a9546SAutomerger Merge Worker "[!] --mark value[/mask]    Match ctmark value with optional mask\n");
42*a71a9546SAutomerger Merge Worker }
43*a71a9546SAutomerger Merge Worker 
44*a71a9546SAutomerger Merge Worker static const struct xt_option_entry connmark_mt_opts[] = {
45*a71a9546SAutomerger Merge Worker 	{.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32,
46*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_MAND | XTOPT_INVERT},
47*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
48*a71a9546SAutomerger Merge Worker };
49*a71a9546SAutomerger Merge Worker 
50*a71a9546SAutomerger Merge Worker static void connmark_mt_parse(struct xt_option_call *cb)
51*a71a9546SAutomerger Merge Worker {
52*a71a9546SAutomerger Merge Worker 	struct xt_connmark_mtinfo1 *info = cb->data;
53*a71a9546SAutomerger Merge Worker 
54*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
55*a71a9546SAutomerger Merge Worker 	if (cb->invert)
56*a71a9546SAutomerger Merge Worker 		info->invert = true;
57*a71a9546SAutomerger Merge Worker 	info->mark = cb->val.mark;
58*a71a9546SAutomerger Merge Worker 	info->mask = cb->val.mask;
59*a71a9546SAutomerger Merge Worker }
60*a71a9546SAutomerger Merge Worker 
61*a71a9546SAutomerger Merge Worker static void connmark_parse(struct xt_option_call *cb)
62*a71a9546SAutomerger Merge Worker {
63*a71a9546SAutomerger Merge Worker 	struct xt_connmark_info *markinfo = cb->data;
64*a71a9546SAutomerger Merge Worker 
65*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
66*a71a9546SAutomerger Merge Worker 	markinfo->mark = cb->val.mark;
67*a71a9546SAutomerger Merge Worker 	markinfo->mask = cb->val.mask;
68*a71a9546SAutomerger Merge Worker 	if (cb->invert)
69*a71a9546SAutomerger Merge Worker 		markinfo->invert = 1;
70*a71a9546SAutomerger Merge Worker }
71*a71a9546SAutomerger Merge Worker 
72*a71a9546SAutomerger Merge Worker static void
73*a71a9546SAutomerger Merge Worker connmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
74*a71a9546SAutomerger Merge Worker {
75*a71a9546SAutomerger Merge Worker 	const struct xt_connmark_info *info = (const void *)match->data;
76*a71a9546SAutomerger Merge Worker 
77*a71a9546SAutomerger Merge Worker 	printf(" CONNMARK match ");
78*a71a9546SAutomerger Merge Worker 	if (info->invert)
79*a71a9546SAutomerger Merge Worker 		printf("!");
80*a71a9546SAutomerger Merge Worker 
81*a71a9546SAutomerger Merge Worker 	xtables_print_mark_mask(info->mark, info->mask);
82*a71a9546SAutomerger Merge Worker }
83*a71a9546SAutomerger Merge Worker 
84*a71a9546SAutomerger Merge Worker static void
85*a71a9546SAutomerger Merge Worker connmark_mt_print(const void *ip, const struct xt_entry_match *match,
86*a71a9546SAutomerger Merge Worker 		  int numeric)
87*a71a9546SAutomerger Merge Worker {
88*a71a9546SAutomerger Merge Worker 	const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
89*a71a9546SAutomerger Merge Worker 
90*a71a9546SAutomerger Merge Worker 	printf(" connmark match ");
91*a71a9546SAutomerger Merge Worker 	if (info->invert)
92*a71a9546SAutomerger Merge Worker 		printf("!");
93*a71a9546SAutomerger Merge Worker 
94*a71a9546SAutomerger Merge Worker 	xtables_print_mark_mask(info->mark, info->mask);
95*a71a9546SAutomerger Merge Worker }
96*a71a9546SAutomerger Merge Worker 
97*a71a9546SAutomerger Merge Worker static void connmark_save(const void *ip, const struct xt_entry_match *match)
98*a71a9546SAutomerger Merge Worker {
99*a71a9546SAutomerger Merge Worker 	const struct xt_connmark_info *info = (const void *)match->data;
100*a71a9546SAutomerger Merge Worker 
101*a71a9546SAutomerger Merge Worker 	if (info->invert)
102*a71a9546SAutomerger Merge Worker 		printf(" !");
103*a71a9546SAutomerger Merge Worker 
104*a71a9546SAutomerger Merge Worker 	printf(" --mark");
105*a71a9546SAutomerger Merge Worker 	xtables_print_mark_mask(info->mark, info->mask);
106*a71a9546SAutomerger Merge Worker }
107*a71a9546SAutomerger Merge Worker 
108*a71a9546SAutomerger Merge Worker static void
109*a71a9546SAutomerger Merge Worker connmark_mt_save(const void *ip, const struct xt_entry_match *match)
110*a71a9546SAutomerger Merge Worker {
111*a71a9546SAutomerger Merge Worker 	const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
112*a71a9546SAutomerger Merge Worker 
113*a71a9546SAutomerger Merge Worker 	if (info->invert)
114*a71a9546SAutomerger Merge Worker 		printf(" !");
115*a71a9546SAutomerger Merge Worker 
116*a71a9546SAutomerger Merge Worker 	printf(" --mark");
117*a71a9546SAutomerger Merge Worker 	xtables_print_mark_mask(info->mark, info->mask);
118*a71a9546SAutomerger Merge Worker }
119*a71a9546SAutomerger Merge Worker 
120*a71a9546SAutomerger Merge Worker static void print_mark_xlate(unsigned int mark, unsigned int mask,
121*a71a9546SAutomerger Merge Worker 			     struct xt_xlate *xl, uint32_t op)
122*a71a9546SAutomerger Merge Worker {
123*a71a9546SAutomerger Merge Worker 	if (mask != 0xffffffffU)
124*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, " and 0x%x %s 0x%x", mask,
125*a71a9546SAutomerger Merge Worker 			   op == XT_OP_EQ ? "==" : "!=", mark);
126*a71a9546SAutomerger Merge Worker 	else
127*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, " %s0x%x",
128*a71a9546SAutomerger Merge Worker 			   op == XT_OP_EQ ? "" : "!= ", mark);
129*a71a9546SAutomerger Merge Worker }
130*a71a9546SAutomerger Merge Worker 
131*a71a9546SAutomerger Merge Worker static int connmark_xlate(struct xt_xlate *xl,
132*a71a9546SAutomerger Merge Worker 			  const struct xt_xlate_mt_params *params)
133*a71a9546SAutomerger Merge Worker {
134*a71a9546SAutomerger Merge Worker 	const struct xt_connmark_info *info = (const void *)params->match->data;
135*a71a9546SAutomerger Merge Worker 	enum xt_op op = XT_OP_EQ;
136*a71a9546SAutomerger Merge Worker 
137*a71a9546SAutomerger Merge Worker 	if (info->invert)
138*a71a9546SAutomerger Merge Worker 		op = XT_OP_NEQ;
139*a71a9546SAutomerger Merge Worker 
140*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "ct mark");
141*a71a9546SAutomerger Merge Worker 	print_mark_xlate(info->mark, info->mask, xl, op);
142*a71a9546SAutomerger Merge Worker 
143*a71a9546SAutomerger Merge Worker 	return 1;
144*a71a9546SAutomerger Merge Worker }
145*a71a9546SAutomerger Merge Worker 
146*a71a9546SAutomerger Merge Worker static int
147*a71a9546SAutomerger Merge Worker connmark_mt_xlate(struct xt_xlate *xl,
148*a71a9546SAutomerger Merge Worker 		  const struct xt_xlate_mt_params *params)
149*a71a9546SAutomerger Merge Worker {
150*a71a9546SAutomerger Merge Worker 	const struct xt_connmark_mtinfo1 *info =
151*a71a9546SAutomerger Merge Worker 		(const void *)params->match->data;
152*a71a9546SAutomerger Merge Worker 	enum xt_op op = XT_OP_EQ;
153*a71a9546SAutomerger Merge Worker 
154*a71a9546SAutomerger Merge Worker 	if (info->invert)
155*a71a9546SAutomerger Merge Worker 		op = XT_OP_NEQ;
156*a71a9546SAutomerger Merge Worker 
157*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "ct mark");
158*a71a9546SAutomerger Merge Worker 	print_mark_xlate(info->mark, info->mask, xl, op);
159*a71a9546SAutomerger Merge Worker 
160*a71a9546SAutomerger Merge Worker 	return 1;
161*a71a9546SAutomerger Merge Worker }
162*a71a9546SAutomerger Merge Worker 
163*a71a9546SAutomerger Merge Worker static struct xtables_match connmark_mt_reg[] = {
164*a71a9546SAutomerger Merge Worker 	{
165*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_UNSPEC,
166*a71a9546SAutomerger Merge Worker 		.name          = "connmark",
167*a71a9546SAutomerger Merge Worker 		.revision      = 0,
168*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
169*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_connmark_info)),
170*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)),
171*a71a9546SAutomerger Merge Worker 		.help          = connmark_mt_help,
172*a71a9546SAutomerger Merge Worker 		.print         = connmark_print,
173*a71a9546SAutomerger Merge Worker 		.save          = connmark_save,
174*a71a9546SAutomerger Merge Worker 		.x6_parse      = connmark_parse,
175*a71a9546SAutomerger Merge Worker 		.x6_options    = connmark_mt_opts,
176*a71a9546SAutomerger Merge Worker 		.xlate	       = connmark_xlate,
177*a71a9546SAutomerger Merge Worker 	},
178*a71a9546SAutomerger Merge Worker 	{
179*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
180*a71a9546SAutomerger Merge Worker 		.name          = "connmark",
181*a71a9546SAutomerger Merge Worker 		.revision      = 1,
182*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_UNSPEC,
183*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
184*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
185*a71a9546SAutomerger Merge Worker 		.help          = connmark_mt_help,
186*a71a9546SAutomerger Merge Worker 		.print         = connmark_mt_print,
187*a71a9546SAutomerger Merge Worker 		.save          = connmark_mt_save,
188*a71a9546SAutomerger Merge Worker 		.x6_parse      = connmark_mt_parse,
189*a71a9546SAutomerger Merge Worker 		.x6_options    = connmark_mt_opts,
190*a71a9546SAutomerger Merge Worker 		.xlate	       = connmark_mt_xlate,
191*a71a9546SAutomerger Merge Worker 	},
192*a71a9546SAutomerger Merge Worker };
193*a71a9546SAutomerger Merge Worker 
194*a71a9546SAutomerger Merge Worker void _init(void)
195*a71a9546SAutomerger Merge Worker {
196*a71a9546SAutomerger Merge Worker 	xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
197*a71a9546SAutomerger Merge Worker }
198