xref: /aosp_15_r20/external/iptables/extensions/libebt_mark.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1*a71a9546SAutomerger Merge Worker /* ebt_mark
2*a71a9546SAutomerger Merge Worker  *
3*a71a9546SAutomerger Merge Worker  * Authors:
4*a71a9546SAutomerger Merge Worker  * Bart De Schuymer <[email protected]>
5*a71a9546SAutomerger Merge Worker  *
6*a71a9546SAutomerger Merge Worker  * July, 2002, September 2006
7*a71a9546SAutomerger Merge Worker  *
8*a71a9546SAutomerger Merge Worker  * Adapted by Arturo Borrero Gonzalez <[email protected]>
9*a71a9546SAutomerger Merge Worker  * to use libxtables for ebtables-compat in 2015.
10*a71a9546SAutomerger Merge Worker  */
11*a71a9546SAutomerger Merge Worker 
12*a71a9546SAutomerger Merge Worker #include <stdio.h>
13*a71a9546SAutomerger Merge Worker #include <stdlib.h>
14*a71a9546SAutomerger Merge Worker #include <string.h>
15*a71a9546SAutomerger Merge Worker #include <getopt.h>
16*a71a9546SAutomerger Merge Worker #include <xtables.h>
17*a71a9546SAutomerger Merge Worker #include <linux/netfilter_bridge/ebt_mark_t.h>
18*a71a9546SAutomerger Merge Worker #include "iptables/nft.h"
19*a71a9546SAutomerger Merge Worker #include "iptables/nft-bridge.h"
20*a71a9546SAutomerger Merge Worker 
21*a71a9546SAutomerger Merge Worker #define MARK_TARGET  '1'
22*a71a9546SAutomerger Merge Worker #define MARK_SETMARK '2'
23*a71a9546SAutomerger Merge Worker #define MARK_ORMARK  '3'
24*a71a9546SAutomerger Merge Worker #define MARK_ANDMARK '4'
25*a71a9546SAutomerger Merge Worker #define MARK_XORMARK '5'
26*a71a9546SAutomerger Merge Worker static const struct option brmark_opts[] = {
27*a71a9546SAutomerger Merge Worker 	{ .name = "mark-target",.has_arg = true,	.val = MARK_TARGET },
28*a71a9546SAutomerger Merge Worker 	/* an oldtime messup, we should have always used the scheme
29*a71a9546SAutomerger Merge Worker 	 * <extension-name>-<option> */
30*a71a9546SAutomerger Merge Worker 	{ .name = "set-mark",	.has_arg = true,	.val = MARK_SETMARK },
31*a71a9546SAutomerger Merge Worker 	{ .name = "mark-set",	.has_arg = true,	.val = MARK_SETMARK },
32*a71a9546SAutomerger Merge Worker 	{ .name = "mark-or",	.has_arg = true,	.val = MARK_ORMARK },
33*a71a9546SAutomerger Merge Worker 	{ .name = "mark-and",	.has_arg = true,	.val = MARK_ANDMARK },
34*a71a9546SAutomerger Merge Worker 	{ .name = "mark-xor",	.has_arg = true,	.val = MARK_XORMARK },
35*a71a9546SAutomerger Merge Worker 	XT_GETOPT_TABLEEND,
36*a71a9546SAutomerger Merge Worker };
37*a71a9546SAutomerger Merge Worker 
brmark_print_help(void)38*a71a9546SAutomerger Merge Worker static void brmark_print_help(void)
39*a71a9546SAutomerger Merge Worker {
40*a71a9546SAutomerger Merge Worker 	printf(
41*a71a9546SAutomerger Merge Worker 	"mark target options:\n"
42*a71a9546SAutomerger Merge Worker 	" --mark-set value     : Set nfmark value\n"
43*a71a9546SAutomerger Merge Worker 	" --mark-or  value     : Or nfmark with value (nfmark |= value)\n"
44*a71a9546SAutomerger Merge Worker 	" --mark-and value     : And nfmark with value (nfmark &= value)\n"
45*a71a9546SAutomerger Merge Worker 	" --mark-xor value     : Xor nfmark with value (nfmark ^= value)\n"
46*a71a9546SAutomerger Merge Worker 	" --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
47*a71a9546SAutomerger Merge Worker }
48*a71a9546SAutomerger Merge Worker 
brmark_init(struct xt_entry_target * target)49*a71a9546SAutomerger Merge Worker static void brmark_init(struct xt_entry_target *target)
50*a71a9546SAutomerger Merge Worker {
51*a71a9546SAutomerger Merge Worker 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
52*a71a9546SAutomerger Merge Worker 
53*a71a9546SAutomerger Merge Worker 	info->target = EBT_ACCEPT;
54*a71a9546SAutomerger Merge Worker 	info->mark = 0;
55*a71a9546SAutomerger Merge Worker }
56*a71a9546SAutomerger Merge Worker 
57*a71a9546SAutomerger Merge Worker #define OPT_MARK_TARGET   0x01
58*a71a9546SAutomerger Merge Worker #define OPT_MARK_SETMARK  0x02
59*a71a9546SAutomerger Merge Worker #define OPT_MARK_ORMARK   0x04
60*a71a9546SAutomerger Merge Worker #define OPT_MARK_ANDMARK  0x08
61*a71a9546SAutomerger Merge Worker #define OPT_MARK_XORMARK  0x10
62*a71a9546SAutomerger Merge Worker 
63*a71a9546SAutomerger Merge Worker static int
brmark_parse(int c,char ** argv,int invert,unsigned int * flags,const void * entry,struct xt_entry_target ** target)64*a71a9546SAutomerger Merge Worker brmark_parse(int c, char **argv, int invert, unsigned int *flags,
65*a71a9546SAutomerger Merge Worker 	     const void *entry, struct xt_entry_target **target)
66*a71a9546SAutomerger Merge Worker {
67*a71a9546SAutomerger Merge Worker 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)
68*a71a9546SAutomerger Merge Worker 				       (*target)->data;
69*a71a9546SAutomerger Merge Worker 	char *end;
70*a71a9546SAutomerger Merge Worker 	uint32_t mask;
71*a71a9546SAutomerger Merge Worker 
72*a71a9546SAutomerger Merge Worker 	switch (c) {
73*a71a9546SAutomerger Merge Worker 	case MARK_TARGET:
74*a71a9546SAutomerger Merge Worker 		{ unsigned int tmp;
75*a71a9546SAutomerger Merge Worker 		EBT_CHECK_OPTION(flags, OPT_MARK_TARGET);
76*a71a9546SAutomerger Merge Worker 		if (ebt_fill_target(optarg, &tmp))
77*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
78*a71a9546SAutomerger Merge Worker 				      "Illegal --mark-target target");
79*a71a9546SAutomerger Merge Worker 		/* the 4 lsb are left to designate the target */
80*a71a9546SAutomerger Merge Worker 		info->target = (info->target & ~EBT_VERDICT_BITS) |
81*a71a9546SAutomerger Merge Worker 			       (tmp & EBT_VERDICT_BITS);
82*a71a9546SAutomerger Merge Worker 		}
83*a71a9546SAutomerger Merge Worker 		return 1;
84*a71a9546SAutomerger Merge Worker 	case MARK_SETMARK:
85*a71a9546SAutomerger Merge Worker 		EBT_CHECK_OPTION(flags, OPT_MARK_SETMARK);
86*a71a9546SAutomerger Merge Worker 		mask = (OPT_MARK_ORMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
87*a71a9546SAutomerger Merge Worker 		if (*flags & mask)
88*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
89*a71a9546SAutomerger Merge Worker 				      "--mark-set cannot be used together with"
90*a71a9546SAutomerger Merge Worker 				      " specific --mark option");
91*a71a9546SAutomerger Merge Worker 		info->target = (info->target & EBT_VERDICT_BITS) |
92*a71a9546SAutomerger Merge Worker 			       MARK_SET_VALUE;
93*a71a9546SAutomerger Merge Worker 		break;
94*a71a9546SAutomerger Merge Worker 	case MARK_ORMARK:
95*a71a9546SAutomerger Merge Worker 		EBT_CHECK_OPTION(flags, OPT_MARK_ORMARK);
96*a71a9546SAutomerger Merge Worker 		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
97*a71a9546SAutomerger Merge Worker 		if (*flags & mask)
98*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
99*a71a9546SAutomerger Merge Worker 				      "--mark-or cannot be used together with"
100*a71a9546SAutomerger Merge Worker 				      " specific --mark option");
101*a71a9546SAutomerger Merge Worker 		info->target = (info->target & EBT_VERDICT_BITS) |
102*a71a9546SAutomerger Merge Worker 			       MARK_OR_VALUE;
103*a71a9546SAutomerger Merge Worker 		break;
104*a71a9546SAutomerger Merge Worker 	case MARK_ANDMARK:
105*a71a9546SAutomerger Merge Worker 		EBT_CHECK_OPTION(flags, OPT_MARK_ANDMARK);
106*a71a9546SAutomerger Merge Worker 		mask = (OPT_MARK_SETMARK|OPT_MARK_ORMARK|OPT_MARK_XORMARK);
107*a71a9546SAutomerger Merge Worker 		if (*flags & mask)
108*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
109*a71a9546SAutomerger Merge Worker 				      "--mark-and cannot be used together with"
110*a71a9546SAutomerger Merge Worker 				      " specific --mark option");
111*a71a9546SAutomerger Merge Worker 		info->target = (info->target & EBT_VERDICT_BITS) |
112*a71a9546SAutomerger Merge Worker 			       MARK_AND_VALUE;
113*a71a9546SAutomerger Merge Worker 		break;
114*a71a9546SAutomerger Merge Worker 	case MARK_XORMARK:
115*a71a9546SAutomerger Merge Worker 		EBT_CHECK_OPTION(flags, OPT_MARK_XORMARK);
116*a71a9546SAutomerger Merge Worker 		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_ORMARK);
117*a71a9546SAutomerger Merge Worker 		if (*flags & mask)
118*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
119*a71a9546SAutomerger Merge Worker 				      "--mark-xor cannot be used together with"
120*a71a9546SAutomerger Merge Worker 				      " specific --mark option");
121*a71a9546SAutomerger Merge Worker 		info->target = (info->target & EBT_VERDICT_BITS) |
122*a71a9546SAutomerger Merge Worker 			       MARK_XOR_VALUE;
123*a71a9546SAutomerger Merge Worker 		break;
124*a71a9546SAutomerger Merge Worker 	default:
125*a71a9546SAutomerger Merge Worker 		return 0;
126*a71a9546SAutomerger Merge Worker 	}
127*a71a9546SAutomerger Merge Worker 	/* mutual code */
128*a71a9546SAutomerger Merge Worker 	info->mark = strtoul(optarg, &end, 0);
129*a71a9546SAutomerger Merge Worker 	if (*end != '\0' || end == optarg)
130*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM, "Bad MARK value '%s'",
131*a71a9546SAutomerger Merge Worker 			      optarg);
132*a71a9546SAutomerger Merge Worker 
133*a71a9546SAutomerger Merge Worker 	return 1;
134*a71a9546SAutomerger Merge Worker }
135*a71a9546SAutomerger Merge Worker 
brmark_print(const void * ip,const struct xt_entry_target * target,int numeric)136*a71a9546SAutomerger Merge Worker static void brmark_print(const void *ip, const struct xt_entry_target *target,
137*a71a9546SAutomerger Merge Worker 			 int numeric)
138*a71a9546SAutomerger Merge Worker {
139*a71a9546SAutomerger Merge Worker 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
140*a71a9546SAutomerger Merge Worker 	int tmp;
141*a71a9546SAutomerger Merge Worker 
142*a71a9546SAutomerger Merge Worker 	tmp = info->target & ~EBT_VERDICT_BITS;
143*a71a9546SAutomerger Merge Worker 	if (tmp == MARK_SET_VALUE)
144*a71a9546SAutomerger Merge Worker 		printf("--mark-set");
145*a71a9546SAutomerger Merge Worker 	else if (tmp == MARK_OR_VALUE)
146*a71a9546SAutomerger Merge Worker 		printf("--mark-or");
147*a71a9546SAutomerger Merge Worker 	else if (tmp == MARK_XOR_VALUE)
148*a71a9546SAutomerger Merge Worker 		printf("--mark-xor");
149*a71a9546SAutomerger Merge Worker 	else if (tmp == MARK_AND_VALUE)
150*a71a9546SAutomerger Merge Worker 		printf("--mark-and");
151*a71a9546SAutomerger Merge Worker 	else
152*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM, "Unknown mark action");
153*a71a9546SAutomerger Merge Worker 
154*a71a9546SAutomerger Merge Worker 	printf(" 0x%lx", info->mark);
155*a71a9546SAutomerger Merge Worker 	tmp = info->target | ~EBT_VERDICT_BITS;
156*a71a9546SAutomerger Merge Worker 	printf(" --mark-target %s", ebt_target_name(tmp));
157*a71a9546SAutomerger Merge Worker }
158*a71a9546SAutomerger Merge Worker 
brmark_final_check(unsigned int flags)159*a71a9546SAutomerger Merge Worker static void brmark_final_check(unsigned int flags)
160*a71a9546SAutomerger Merge Worker {
161*a71a9546SAutomerger Merge Worker 	if (!flags)
162*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM,
163*a71a9546SAutomerger Merge Worker 			      "You must specify some option");
164*a71a9546SAutomerger Merge Worker }
165*a71a9546SAutomerger Merge Worker 
brmark_verdict(int verdict)166*a71a9546SAutomerger Merge Worker static const char* brmark_verdict(int verdict)
167*a71a9546SAutomerger Merge Worker {
168*a71a9546SAutomerger Merge Worker 	switch (verdict) {
169*a71a9546SAutomerger Merge Worker 	case EBT_ACCEPT: return "accept";
170*a71a9546SAutomerger Merge Worker 	case EBT_DROP: return "drop";
171*a71a9546SAutomerger Merge Worker 	case EBT_CONTINUE: return "continue";
172*a71a9546SAutomerger Merge Worker 	case EBT_RETURN: return "return";
173*a71a9546SAutomerger Merge Worker 	}
174*a71a9546SAutomerger Merge Worker 
175*a71a9546SAutomerger Merge Worker 	return "";
176*a71a9546SAutomerger Merge Worker }
177*a71a9546SAutomerger Merge Worker 
brmark_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)178*a71a9546SAutomerger Merge Worker static int brmark_xlate(struct xt_xlate *xl,
179*a71a9546SAutomerger Merge Worker 			const struct xt_xlate_tg_params *params)
180*a71a9546SAutomerger Merge Worker {
181*a71a9546SAutomerger Merge Worker 	const struct ebt_mark_t_info *info = (const void*)params->target->data;
182*a71a9546SAutomerger Merge Worker 	int tmp;
183*a71a9546SAutomerger Merge Worker 
184*a71a9546SAutomerger Merge Worker 	tmp = info->target & ~EBT_VERDICT_BITS;
185*a71a9546SAutomerger Merge Worker 
186*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "meta mark set ");
187*a71a9546SAutomerger Merge Worker 
188*a71a9546SAutomerger Merge Worker 	switch (tmp) {
189*a71a9546SAutomerger Merge Worker 	case MARK_SET_VALUE:
190*a71a9546SAutomerger Merge Worker 		break;
191*a71a9546SAutomerger Merge Worker 	case MARK_OR_VALUE:
192*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "meta mark or ");
193*a71a9546SAutomerger Merge Worker 		break;
194*a71a9546SAutomerger Merge Worker 	case MARK_XOR_VALUE:
195*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "meta mark xor ");
196*a71a9546SAutomerger Merge Worker 		break;
197*a71a9546SAutomerger Merge Worker 	case MARK_AND_VALUE:
198*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "meta mark and ");
199*a71a9546SAutomerger Merge Worker 		break;
200*a71a9546SAutomerger Merge Worker 	default:
201*a71a9546SAutomerger Merge Worker 		return 0;
202*a71a9546SAutomerger Merge Worker 	}
203*a71a9546SAutomerger Merge Worker 
204*a71a9546SAutomerger Merge Worker 	tmp = info->target | ~EBT_VERDICT_BITS;
205*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp));
206*a71a9546SAutomerger Merge Worker 	return 1;
207*a71a9546SAutomerger Merge Worker }
208*a71a9546SAutomerger Merge Worker 
209*a71a9546SAutomerger Merge Worker static struct xtables_target brmark_target = {
210*a71a9546SAutomerger Merge Worker 	.name		= "mark",
211*a71a9546SAutomerger Merge Worker 	.revision	= 0,
212*a71a9546SAutomerger Merge Worker 	.version	= XTABLES_VERSION,
213*a71a9546SAutomerger Merge Worker 	.family		= NFPROTO_BRIDGE,
214*a71a9546SAutomerger Merge Worker 	.size		= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
215*a71a9546SAutomerger Merge Worker 	.userspacesize	= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
216*a71a9546SAutomerger Merge Worker 	.help		= brmark_print_help,
217*a71a9546SAutomerger Merge Worker 	.init		= brmark_init,
218*a71a9546SAutomerger Merge Worker 	.parse		= brmark_parse,
219*a71a9546SAutomerger Merge Worker 	.final_check	= brmark_final_check,
220*a71a9546SAutomerger Merge Worker 	.print		= brmark_print,
221*a71a9546SAutomerger Merge Worker 	.xlate		= brmark_xlate,
222*a71a9546SAutomerger Merge Worker 	.extra_opts	= brmark_opts,
223*a71a9546SAutomerger Merge Worker };
224*a71a9546SAutomerger Merge Worker 
_init(void)225*a71a9546SAutomerger Merge Worker void _init(void)
226*a71a9546SAutomerger Merge Worker {
227*a71a9546SAutomerger Merge Worker 	xtables_register_target(&brmark_target);
228*a71a9546SAutomerger Merge Worker }
229