xref: /aosp_15_r20/external/iptables/extensions/libxt_MARK.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1*a71a9546SAutomerger Merge Worker #include <getopt.h>
2*a71a9546SAutomerger Merge Worker #include <stdbool.h>
3*a71a9546SAutomerger Merge Worker #include <stdio.h>
4*a71a9546SAutomerger Merge Worker #include <xtables.h>
5*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_MARK.h>
6*a71a9546SAutomerger Merge Worker 
7*a71a9546SAutomerger Merge Worker /* Version 0 */
8*a71a9546SAutomerger Merge Worker struct xt_mark_target_info {
9*a71a9546SAutomerger Merge Worker 	unsigned long mark;
10*a71a9546SAutomerger Merge Worker };
11*a71a9546SAutomerger Merge Worker 
12*a71a9546SAutomerger Merge Worker /* Version 1 */
13*a71a9546SAutomerger Merge Worker enum {
14*a71a9546SAutomerger Merge Worker 	XT_MARK_SET=0,
15*a71a9546SAutomerger Merge Worker 	XT_MARK_AND,
16*a71a9546SAutomerger Merge Worker 	XT_MARK_OR,
17*a71a9546SAutomerger Merge Worker };
18*a71a9546SAutomerger Merge Worker 
19*a71a9546SAutomerger Merge Worker struct xt_mark_target_info_v1 {
20*a71a9546SAutomerger Merge Worker 	unsigned long mark;
21*a71a9546SAutomerger Merge Worker 	uint8_t mode;
22*a71a9546SAutomerger Merge Worker };
23*a71a9546SAutomerger Merge Worker 
24*a71a9546SAutomerger Merge Worker enum {
25*a71a9546SAutomerger Merge Worker 	O_SET_MARK = 0,
26*a71a9546SAutomerger Merge Worker 	O_AND_MARK,
27*a71a9546SAutomerger Merge Worker 	O_OR_MARK,
28*a71a9546SAutomerger Merge Worker 	O_XOR_MARK,
29*a71a9546SAutomerger Merge Worker 	O_SET_XMARK,
30*a71a9546SAutomerger Merge Worker 	F_SET_MARK  = 1 << O_SET_MARK,
31*a71a9546SAutomerger Merge Worker 	F_AND_MARK  = 1 << O_AND_MARK,
32*a71a9546SAutomerger Merge Worker 	F_OR_MARK   = 1 << O_OR_MARK,
33*a71a9546SAutomerger Merge Worker 	F_XOR_MARK  = 1 << O_XOR_MARK,
34*a71a9546SAutomerger Merge Worker 	F_SET_XMARK = 1 << O_SET_XMARK,
35*a71a9546SAutomerger Merge Worker 	F_ANY       = F_SET_MARK | F_AND_MARK | F_OR_MARK |
36*a71a9546SAutomerger Merge Worker 	              F_XOR_MARK | F_SET_XMARK,
37*a71a9546SAutomerger Merge Worker };
38*a71a9546SAutomerger Merge Worker 
MARK_help(void)39*a71a9546SAutomerger Merge Worker static void MARK_help(void)
40*a71a9546SAutomerger Merge Worker {
41*a71a9546SAutomerger Merge Worker 	printf(
42*a71a9546SAutomerger Merge Worker "MARK target options:\n"
43*a71a9546SAutomerger Merge Worker "  --set-mark value                   Set nfmark value\n"
44*a71a9546SAutomerger Merge Worker "  --and-mark value                   Binary AND the nfmark with value\n"
45*a71a9546SAutomerger Merge Worker "  --or-mark  value                   Binary OR  the nfmark with value\n");
46*a71a9546SAutomerger Merge Worker }
47*a71a9546SAutomerger Merge Worker 
48*a71a9546SAutomerger Merge Worker static const struct xt_option_entry MARK_opts[] = {
49*a71a9546SAutomerger Merge Worker 	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32,
50*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
51*a71a9546SAutomerger Merge Worker 	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
52*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
53*a71a9546SAutomerger Merge Worker 	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
54*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
55*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
56*a71a9546SAutomerger Merge Worker };
57*a71a9546SAutomerger Merge Worker 
58*a71a9546SAutomerger Merge Worker static const struct xt_option_entry mark_tg_opts[] = {
59*a71a9546SAutomerger Merge Worker 	{.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
60*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
61*a71a9546SAutomerger Merge Worker 	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
62*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
63*a71a9546SAutomerger Merge Worker 	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
64*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
65*a71a9546SAutomerger Merge Worker 	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
66*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
67*a71a9546SAutomerger Merge Worker 	{.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
68*a71a9546SAutomerger Merge Worker 	 .excl = F_ANY},
69*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
70*a71a9546SAutomerger Merge Worker };
71*a71a9546SAutomerger Merge Worker 
mark_tg_help(void)72*a71a9546SAutomerger Merge Worker static void mark_tg_help(void)
73*a71a9546SAutomerger Merge Worker {
74*a71a9546SAutomerger Merge Worker 	printf(
75*a71a9546SAutomerger Merge Worker "MARK target options:\n"
76*a71a9546SAutomerger Merge Worker "  --set-xmark value[/mask]  Clear bits in mask and XOR value into nfmark\n"
77*a71a9546SAutomerger Merge Worker "  --set-mark value[/mask]   Clear bits in mask and OR value into nfmark\n"
78*a71a9546SAutomerger Merge Worker "  --and-mark bits           Binary AND the nfmark with bits\n"
79*a71a9546SAutomerger Merge Worker "  --or-mark bits            Binary OR the nfmark with bits\n"
80*a71a9546SAutomerger Merge Worker "  --xor-mark bits           Binary XOR the nfmark with bits\n");
81*a71a9546SAutomerger Merge Worker }
82*a71a9546SAutomerger Merge Worker 
MARK_parse_v0(struct xt_option_call * cb)83*a71a9546SAutomerger Merge Worker static void MARK_parse_v0(struct xt_option_call *cb)
84*a71a9546SAutomerger Merge Worker {
85*a71a9546SAutomerger Merge Worker 	struct xt_mark_target_info *markinfo = cb->data;
86*a71a9546SAutomerger Merge Worker 
87*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
88*a71a9546SAutomerger Merge Worker 	switch (cb->entry->id) {
89*a71a9546SAutomerger Merge Worker 	case O_SET_MARK:
90*a71a9546SAutomerger Merge Worker 		markinfo->mark = cb->val.mark;
91*a71a9546SAutomerger Merge Worker 		break;
92*a71a9546SAutomerger Merge Worker 	default:
93*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM,
94*a71a9546SAutomerger Merge Worker 			   "MARK target: kernel too old for --%s",
95*a71a9546SAutomerger Merge Worker 			   cb->entry->name);
96*a71a9546SAutomerger Merge Worker 	}
97*a71a9546SAutomerger Merge Worker }
98*a71a9546SAutomerger Merge Worker 
MARK_check(struct xt_fcheck_call * cb)99*a71a9546SAutomerger Merge Worker static void MARK_check(struct xt_fcheck_call *cb)
100*a71a9546SAutomerger Merge Worker {
101*a71a9546SAutomerger Merge Worker 	if (cb->xflags == 0)
102*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM,
103*a71a9546SAutomerger Merge Worker 		           "MARK target: Parameter --set/and/or-mark"
104*a71a9546SAutomerger Merge Worker 			   " is required");
105*a71a9546SAutomerger Merge Worker }
106*a71a9546SAutomerger Merge Worker 
MARK_parse_v1(struct xt_option_call * cb)107*a71a9546SAutomerger Merge Worker static void MARK_parse_v1(struct xt_option_call *cb)
108*a71a9546SAutomerger Merge Worker {
109*a71a9546SAutomerger Merge Worker 	struct xt_mark_target_info_v1 *markinfo = cb->data;
110*a71a9546SAutomerger Merge Worker 
111*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
112*a71a9546SAutomerger Merge Worker 	switch (cb->entry->id) {
113*a71a9546SAutomerger Merge Worker 	case O_SET_MARK:
114*a71a9546SAutomerger Merge Worker 	        markinfo->mode = XT_MARK_SET;
115*a71a9546SAutomerger Merge Worker 		break;
116*a71a9546SAutomerger Merge Worker 	case O_AND_MARK:
117*a71a9546SAutomerger Merge Worker 	        markinfo->mode = XT_MARK_AND;
118*a71a9546SAutomerger Merge Worker 		break;
119*a71a9546SAutomerger Merge Worker 	case O_OR_MARK:
120*a71a9546SAutomerger Merge Worker 	        markinfo->mode = XT_MARK_OR;
121*a71a9546SAutomerger Merge Worker 		break;
122*a71a9546SAutomerger Merge Worker 	}
123*a71a9546SAutomerger Merge Worker 	markinfo->mark = cb->val.u32;
124*a71a9546SAutomerger Merge Worker }
125*a71a9546SAutomerger Merge Worker 
mark_tg_parse(struct xt_option_call * cb)126*a71a9546SAutomerger Merge Worker static void mark_tg_parse(struct xt_option_call *cb)
127*a71a9546SAutomerger Merge Worker {
128*a71a9546SAutomerger Merge Worker 	struct xt_mark_tginfo2 *info = cb->data;
129*a71a9546SAutomerger Merge Worker 
130*a71a9546SAutomerger Merge Worker 	xtables_option_parse(cb);
131*a71a9546SAutomerger Merge Worker 	switch (cb->entry->id) {
132*a71a9546SAutomerger Merge Worker 	case O_SET_XMARK:
133*a71a9546SAutomerger Merge Worker 		info->mark = cb->val.mark;
134*a71a9546SAutomerger Merge Worker 		info->mask = cb->val.mask;
135*a71a9546SAutomerger Merge Worker 		break;
136*a71a9546SAutomerger Merge Worker 	case O_SET_MARK:
137*a71a9546SAutomerger Merge Worker 		info->mark = cb->val.mark;
138*a71a9546SAutomerger Merge Worker 		info->mask = cb->val.mark | cb->val.mask;
139*a71a9546SAutomerger Merge Worker 		break;
140*a71a9546SAutomerger Merge Worker 	case O_AND_MARK:
141*a71a9546SAutomerger Merge Worker 		info->mark = 0;
142*a71a9546SAutomerger Merge Worker 		info->mask = ~cb->val.u32;
143*a71a9546SAutomerger Merge Worker 		break;
144*a71a9546SAutomerger Merge Worker 	case O_OR_MARK:
145*a71a9546SAutomerger Merge Worker 		info->mark = info->mask = cb->val.u32;
146*a71a9546SAutomerger Merge Worker 		break;
147*a71a9546SAutomerger Merge Worker 	case O_XOR_MARK:
148*a71a9546SAutomerger Merge Worker 		info->mark = cb->val.u32;
149*a71a9546SAutomerger Merge Worker 		info->mask = 0;
150*a71a9546SAutomerger Merge Worker 		break;
151*a71a9546SAutomerger Merge Worker 	}
152*a71a9546SAutomerger Merge Worker }
153*a71a9546SAutomerger Merge Worker 
mark_tg_check(struct xt_fcheck_call * cb)154*a71a9546SAutomerger Merge Worker static void mark_tg_check(struct xt_fcheck_call *cb)
155*a71a9546SAutomerger Merge Worker {
156*a71a9546SAutomerger Merge Worker 	if (cb->xflags == 0)
157*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, "
158*a71a9546SAutomerger Merge Worker 		           "--{and,or,xor,set}-mark options is required");
159*a71a9546SAutomerger Merge Worker }
160*a71a9546SAutomerger Merge Worker 
161*a71a9546SAutomerger Merge Worker static void
print_mark(unsigned long mark)162*a71a9546SAutomerger Merge Worker print_mark(unsigned long mark)
163*a71a9546SAutomerger Merge Worker {
164*a71a9546SAutomerger Merge Worker 	printf(" 0x%lx", mark);
165*a71a9546SAutomerger Merge Worker }
166*a71a9546SAutomerger Merge Worker 
MARK_print_v0(const void * ip,const struct xt_entry_target * target,int numeric)167*a71a9546SAutomerger Merge Worker static void MARK_print_v0(const void *ip,
168*a71a9546SAutomerger Merge Worker                           const struct xt_entry_target *target, int numeric)
169*a71a9546SAutomerger Merge Worker {
170*a71a9546SAutomerger Merge Worker 	const struct xt_mark_target_info *markinfo =
171*a71a9546SAutomerger Merge Worker 		(const struct xt_mark_target_info *)target->data;
172*a71a9546SAutomerger Merge Worker 	printf(" MARK set");
173*a71a9546SAutomerger Merge Worker 	print_mark(markinfo->mark);
174*a71a9546SAutomerger Merge Worker }
175*a71a9546SAutomerger Merge Worker 
MARK_save_v0(const void * ip,const struct xt_entry_target * target)176*a71a9546SAutomerger Merge Worker static void MARK_save_v0(const void *ip, const struct xt_entry_target *target)
177*a71a9546SAutomerger Merge Worker {
178*a71a9546SAutomerger Merge Worker 	const struct xt_mark_target_info *markinfo =
179*a71a9546SAutomerger Merge Worker 		(const struct xt_mark_target_info *)target->data;
180*a71a9546SAutomerger Merge Worker 
181*a71a9546SAutomerger Merge Worker 	printf(" --set-mark");
182*a71a9546SAutomerger Merge Worker 	print_mark(markinfo->mark);
183*a71a9546SAutomerger Merge Worker }
184*a71a9546SAutomerger Merge Worker 
MARK_print_v1(const void * ip,const struct xt_entry_target * target,int numeric)185*a71a9546SAutomerger Merge Worker static void MARK_print_v1(const void *ip, const struct xt_entry_target *target,
186*a71a9546SAutomerger Merge Worker                           int numeric)
187*a71a9546SAutomerger Merge Worker {
188*a71a9546SAutomerger Merge Worker 	const struct xt_mark_target_info_v1 *markinfo =
189*a71a9546SAutomerger Merge Worker 		(const struct xt_mark_target_info_v1 *)target->data;
190*a71a9546SAutomerger Merge Worker 
191*a71a9546SAutomerger Merge Worker 	switch (markinfo->mode) {
192*a71a9546SAutomerger Merge Worker 	case XT_MARK_SET:
193*a71a9546SAutomerger Merge Worker 		printf(" MARK set");
194*a71a9546SAutomerger Merge Worker 		break;
195*a71a9546SAutomerger Merge Worker 	case XT_MARK_AND:
196*a71a9546SAutomerger Merge Worker 		printf(" MARK and");
197*a71a9546SAutomerger Merge Worker 		break;
198*a71a9546SAutomerger Merge Worker 	case XT_MARK_OR:
199*a71a9546SAutomerger Merge Worker 		printf(" MARK or");
200*a71a9546SAutomerger Merge Worker 		break;
201*a71a9546SAutomerger Merge Worker 	}
202*a71a9546SAutomerger Merge Worker 	print_mark(markinfo->mark);
203*a71a9546SAutomerger Merge Worker }
204*a71a9546SAutomerger Merge Worker 
mark_tg_print(const void * ip,const struct xt_entry_target * target,int numeric)205*a71a9546SAutomerger Merge Worker static void mark_tg_print(const void *ip, const struct xt_entry_target *target,
206*a71a9546SAutomerger Merge Worker                           int numeric)
207*a71a9546SAutomerger Merge Worker {
208*a71a9546SAutomerger Merge Worker 	const struct xt_mark_tginfo2 *info = (const void *)target->data;
209*a71a9546SAutomerger Merge Worker 
210*a71a9546SAutomerger Merge Worker 	if (info->mark == 0)
211*a71a9546SAutomerger Merge Worker 		printf(" MARK and 0x%x", (unsigned int)(uint32_t)~info->mask);
212*a71a9546SAutomerger Merge Worker 	else if (info->mark == info->mask)
213*a71a9546SAutomerger Merge Worker 		printf(" MARK or 0x%x", info->mark);
214*a71a9546SAutomerger Merge Worker 	else if (info->mask == 0)
215*a71a9546SAutomerger Merge Worker 		printf(" MARK xor 0x%x", info->mark);
216*a71a9546SAutomerger Merge Worker 	else if (info->mask == 0xffffffffU)
217*a71a9546SAutomerger Merge Worker 		printf(" MARK set 0x%x", info->mark);
218*a71a9546SAutomerger Merge Worker 	else
219*a71a9546SAutomerger Merge Worker 		printf(" MARK xset 0x%x/0x%x", info->mark, info->mask);
220*a71a9546SAutomerger Merge Worker }
221*a71a9546SAutomerger Merge Worker 
MARK_save_v1(const void * ip,const struct xt_entry_target * target)222*a71a9546SAutomerger Merge Worker static void MARK_save_v1(const void *ip, const struct xt_entry_target *target)
223*a71a9546SAutomerger Merge Worker {
224*a71a9546SAutomerger Merge Worker 	const struct xt_mark_target_info_v1 *markinfo =
225*a71a9546SAutomerger Merge Worker 		(const struct xt_mark_target_info_v1 *)target->data;
226*a71a9546SAutomerger Merge Worker 
227*a71a9546SAutomerger Merge Worker 	switch (markinfo->mode) {
228*a71a9546SAutomerger Merge Worker 	case XT_MARK_SET:
229*a71a9546SAutomerger Merge Worker 		printf(" --set-mark");
230*a71a9546SAutomerger Merge Worker 		break;
231*a71a9546SAutomerger Merge Worker 	case XT_MARK_AND:
232*a71a9546SAutomerger Merge Worker 		printf(" --and-mark");
233*a71a9546SAutomerger Merge Worker 		break;
234*a71a9546SAutomerger Merge Worker 	case XT_MARK_OR:
235*a71a9546SAutomerger Merge Worker 		printf(" --or-mark");
236*a71a9546SAutomerger Merge Worker 		break;
237*a71a9546SAutomerger Merge Worker 	}
238*a71a9546SAutomerger Merge Worker 	print_mark(markinfo->mark);
239*a71a9546SAutomerger Merge Worker }
240*a71a9546SAutomerger Merge Worker 
mark_tg_save(const void * ip,const struct xt_entry_target * target)241*a71a9546SAutomerger Merge Worker static void mark_tg_save(const void *ip, const struct xt_entry_target *target)
242*a71a9546SAutomerger Merge Worker {
243*a71a9546SAutomerger Merge Worker 	const struct xt_mark_tginfo2 *info = (const void *)target->data;
244*a71a9546SAutomerger Merge Worker 
245*a71a9546SAutomerger Merge Worker 	printf(" --set-xmark 0x%x/0x%x", info->mark, info->mask);
246*a71a9546SAutomerger Merge Worker }
247*a71a9546SAutomerger Merge Worker 
mark_tg_arp_save(const void * ip,const struct xt_entry_target * target)248*a71a9546SAutomerger Merge Worker static void mark_tg_arp_save(const void *ip, const struct xt_entry_target *target)
249*a71a9546SAutomerger Merge Worker {
250*a71a9546SAutomerger Merge Worker 	const struct xt_mark_tginfo2 *info = (const void *)target->data;
251*a71a9546SAutomerger Merge Worker 
252*a71a9546SAutomerger Merge Worker 	if (info->mark == 0)
253*a71a9546SAutomerger Merge Worker 		printf(" --and-mark %x", (unsigned int)(uint32_t)~info->mask);
254*a71a9546SAutomerger Merge Worker 	else if (info->mark == info->mask)
255*a71a9546SAutomerger Merge Worker 		printf(" --or-mark %x", info->mark);
256*a71a9546SAutomerger Merge Worker 	else
257*a71a9546SAutomerger Merge Worker 		printf(" --set-mark %x", info->mark);
258*a71a9546SAutomerger Merge Worker }
259*a71a9546SAutomerger Merge Worker 
mark_tg_arp_print(const void * ip,const struct xt_entry_target * target,int numeric)260*a71a9546SAutomerger Merge Worker static void mark_tg_arp_print(const void *ip,
261*a71a9546SAutomerger Merge Worker 			      const struct xt_entry_target *target, int numeric)
262*a71a9546SAutomerger Merge Worker {
263*a71a9546SAutomerger Merge Worker 	mark_tg_arp_save(ip, target);
264*a71a9546SAutomerger Merge Worker }
265*a71a9546SAutomerger Merge Worker 
266*a71a9546SAutomerger Merge Worker #define MARK_OPT 1
267*a71a9546SAutomerger Merge Worker #define AND_MARK_OPT 2
268*a71a9546SAutomerger Merge Worker #define OR_MARK_OPT 3
269*a71a9546SAutomerger Merge Worker 
270*a71a9546SAutomerger Merge Worker static struct option mark_tg_arp_opts[] = {
271*a71a9546SAutomerger Merge Worker 	{ .name = "set-mark", .has_arg = required_argument, .flag = 0, .val = MARK_OPT },
272*a71a9546SAutomerger Merge Worker 	{ .name = "and-mark", .has_arg = required_argument, .flag = 0, .val = AND_MARK_OPT },
273*a71a9546SAutomerger Merge Worker 	{ .name = "or-mark", .has_arg = required_argument, .flag = 0, .val =  OR_MARK_OPT },
274*a71a9546SAutomerger Merge Worker 	{ .name = NULL}
275*a71a9546SAutomerger Merge Worker };
276*a71a9546SAutomerger Merge Worker 
277*a71a9546SAutomerger Merge Worker static int
mark_tg_arp_parse(int c,char ** argv,int invert,unsigned int * flags,const void * entry,struct xt_entry_target ** target)278*a71a9546SAutomerger Merge Worker mark_tg_arp_parse(int c, char **argv, int invert, unsigned int *flags,
279*a71a9546SAutomerger Merge Worker 		  const void *entry, struct xt_entry_target **target)
280*a71a9546SAutomerger Merge Worker {
281*a71a9546SAutomerger Merge Worker 	struct xt_mark_tginfo2 *info =
282*a71a9546SAutomerger Merge Worker 		(struct xt_mark_tginfo2 *)(*target)->data;
283*a71a9546SAutomerger Merge Worker 	int i;
284*a71a9546SAutomerger Merge Worker 
285*a71a9546SAutomerger Merge Worker 	switch (c) {
286*a71a9546SAutomerger Merge Worker 	case MARK_OPT:
287*a71a9546SAutomerger Merge Worker 		if (sscanf(argv[optind-1], "%x", &i) != 1) {
288*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
289*a71a9546SAutomerger Merge Worker 				"Bad mark value `%s'", optarg);
290*a71a9546SAutomerger Merge Worker 			return 0;
291*a71a9546SAutomerger Merge Worker 		}
292*a71a9546SAutomerger Merge Worker 		info->mark = i;
293*a71a9546SAutomerger Merge Worker 		if (*flags)
294*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
295*a71a9546SAutomerger Merge Worker 				"MARK: Can't specify --set-mark twice");
296*a71a9546SAutomerger Merge Worker 		*flags = 1;
297*a71a9546SAutomerger Merge Worker 		break;
298*a71a9546SAutomerger Merge Worker 	case AND_MARK_OPT:
299*a71a9546SAutomerger Merge Worker 		if (sscanf(argv[optind-1], "%x", &i) != 1) {
300*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
301*a71a9546SAutomerger Merge Worker 				"Bad mark value `%s'", optarg);
302*a71a9546SAutomerger Merge Worker 			return 0;
303*a71a9546SAutomerger Merge Worker 		}
304*a71a9546SAutomerger Merge Worker 		info->mark = 0;
305*a71a9546SAutomerger Merge Worker 		info->mask = ~i;
306*a71a9546SAutomerger Merge Worker 		if (*flags)
307*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
308*a71a9546SAutomerger Merge Worker 				"MARK: Can't specify --and-mark twice");
309*a71a9546SAutomerger Merge Worker 		*flags = 1;
310*a71a9546SAutomerger Merge Worker 		break;
311*a71a9546SAutomerger Merge Worker 	case OR_MARK_OPT:
312*a71a9546SAutomerger Merge Worker 		if (sscanf(argv[optind-1], "%x", &i) != 1) {
313*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
314*a71a9546SAutomerger Merge Worker 				"Bad mark value `%s'", optarg);
315*a71a9546SAutomerger Merge Worker 			return 0;
316*a71a9546SAutomerger Merge Worker 		}
317*a71a9546SAutomerger Merge Worker 		info->mark = info->mask = i;
318*a71a9546SAutomerger Merge Worker 		if (*flags)
319*a71a9546SAutomerger Merge Worker 			xtables_error(PARAMETER_PROBLEM,
320*a71a9546SAutomerger Merge Worker 				"MARK: Can't specify --or-mark twice");
321*a71a9546SAutomerger Merge Worker 		*flags = 1;
322*a71a9546SAutomerger Merge Worker 		break;
323*a71a9546SAutomerger Merge Worker 	default:
324*a71a9546SAutomerger Merge Worker 		return 0;
325*a71a9546SAutomerger Merge Worker 	}
326*a71a9546SAutomerger Merge Worker 	return 1;
327*a71a9546SAutomerger Merge Worker }
328*a71a9546SAutomerger Merge Worker 
mark_tg_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)329*a71a9546SAutomerger Merge Worker static int mark_tg_xlate(struct xt_xlate *xl,
330*a71a9546SAutomerger Merge Worker 			 const struct xt_xlate_tg_params *params)
331*a71a9546SAutomerger Merge Worker {
332*a71a9546SAutomerger Merge Worker 	const struct xt_mark_tginfo2 *info = (const void *)params->target->data;
333*a71a9546SAutomerger Merge Worker 
334*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "meta mark set ");
335*a71a9546SAutomerger Merge Worker 
336*a71a9546SAutomerger Merge Worker 	if (info->mask == 0xffffffffU)
337*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "0x%x ", info->mark);
338*a71a9546SAutomerger Merge Worker 	else if (info->mark == 0)
339*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "mark and 0x%x ", ~info->mask);
340*a71a9546SAutomerger Merge Worker 	else if (info->mark == info->mask)
341*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "mark or 0x%x ", info->mark);
342*a71a9546SAutomerger Merge Worker 	else if (info->mask == 0)
343*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "mark xor 0x%x ", info->mark);
344*a71a9546SAutomerger Merge Worker 	else
345*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "mark and 0x%x xor 0x%x ", ~info->mask,
346*a71a9546SAutomerger Merge Worker 			     info->mark);
347*a71a9546SAutomerger Merge Worker 
348*a71a9546SAutomerger Merge Worker 	return 1;
349*a71a9546SAutomerger Merge Worker }
350*a71a9546SAutomerger Merge Worker 
MARK_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)351*a71a9546SAutomerger Merge Worker static int MARK_xlate(struct xt_xlate *xl,
352*a71a9546SAutomerger Merge Worker 		      const struct xt_xlate_tg_params *params)
353*a71a9546SAutomerger Merge Worker {
354*a71a9546SAutomerger Merge Worker 	const struct xt_mark_target_info_v1 *markinfo =
355*a71a9546SAutomerger Merge Worker 		(const struct xt_mark_target_info_v1 *)params->target->data;
356*a71a9546SAutomerger Merge Worker 
357*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "meta mark set ");
358*a71a9546SAutomerger Merge Worker 
359*a71a9546SAutomerger Merge Worker 	switch(markinfo->mode) {
360*a71a9546SAutomerger Merge Worker 	case XT_MARK_SET:
361*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "0x%x ", (uint32_t)markinfo->mark);
362*a71a9546SAutomerger Merge Worker 		break;
363*a71a9546SAutomerger Merge Worker 	case XT_MARK_AND:
364*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "mark and 0x%x ", (uint32_t)markinfo->mark);
365*a71a9546SAutomerger Merge Worker 		break;
366*a71a9546SAutomerger Merge Worker 	case XT_MARK_OR:
367*a71a9546SAutomerger Merge Worker 		xt_xlate_add(xl, "mark or 0x%x ", (uint32_t)markinfo->mark);
368*a71a9546SAutomerger Merge Worker 		break;
369*a71a9546SAutomerger Merge Worker 	default:
370*a71a9546SAutomerger Merge Worker 		return 0;
371*a71a9546SAutomerger Merge Worker 	}
372*a71a9546SAutomerger Merge Worker 
373*a71a9546SAutomerger Merge Worker 	return 1;
374*a71a9546SAutomerger Merge Worker }
375*a71a9546SAutomerger Merge Worker 
376*a71a9546SAutomerger Merge Worker static struct xtables_target mark_tg_reg[] = {
377*a71a9546SAutomerger Merge Worker 	{
378*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_UNSPEC,
379*a71a9546SAutomerger Merge Worker 		.name          = "MARK",
380*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
381*a71a9546SAutomerger Merge Worker 		.revision      = 0,
382*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_mark_target_info)),
383*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)),
384*a71a9546SAutomerger Merge Worker 		.help          = MARK_help,
385*a71a9546SAutomerger Merge Worker 		.print         = MARK_print_v0,
386*a71a9546SAutomerger Merge Worker 		.save          = MARK_save_v0,
387*a71a9546SAutomerger Merge Worker 		.x6_parse      = MARK_parse_v0,
388*a71a9546SAutomerger Merge Worker 		.x6_fcheck     = MARK_check,
389*a71a9546SAutomerger Merge Worker 		.x6_options    = MARK_opts,
390*a71a9546SAutomerger Merge Worker 	},
391*a71a9546SAutomerger Merge Worker 	{
392*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_IPV4,
393*a71a9546SAutomerger Merge Worker 		.name          = "MARK",
394*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
395*a71a9546SAutomerger Merge Worker 		.revision      = 1,
396*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
397*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
398*a71a9546SAutomerger Merge Worker 		.help          = MARK_help,
399*a71a9546SAutomerger Merge Worker 		.print         = MARK_print_v1,
400*a71a9546SAutomerger Merge Worker 		.save          = MARK_save_v1,
401*a71a9546SAutomerger Merge Worker 		.x6_parse      = MARK_parse_v1,
402*a71a9546SAutomerger Merge Worker 		.x6_fcheck     = MARK_check,
403*a71a9546SAutomerger Merge Worker 		.x6_options    = MARK_opts,
404*a71a9546SAutomerger Merge Worker 		.xlate	       = MARK_xlate,
405*a71a9546SAutomerger Merge Worker 	},
406*a71a9546SAutomerger Merge Worker 	{
407*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
408*a71a9546SAutomerger Merge Worker 		.name          = "MARK",
409*a71a9546SAutomerger Merge Worker 		.revision      = 2,
410*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_UNSPEC,
411*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
412*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
413*a71a9546SAutomerger Merge Worker 		.help          = mark_tg_help,
414*a71a9546SAutomerger Merge Worker 		.print         = mark_tg_print,
415*a71a9546SAutomerger Merge Worker 		.save          = mark_tg_save,
416*a71a9546SAutomerger Merge Worker 		.x6_parse      = mark_tg_parse,
417*a71a9546SAutomerger Merge Worker 		.x6_fcheck     = mark_tg_check,
418*a71a9546SAutomerger Merge Worker 		.x6_options    = mark_tg_opts,
419*a71a9546SAutomerger Merge Worker 		.xlate	       = mark_tg_xlate,
420*a71a9546SAutomerger Merge Worker 	},
421*a71a9546SAutomerger Merge Worker 	{
422*a71a9546SAutomerger Merge Worker 		.version       = XTABLES_VERSION,
423*a71a9546SAutomerger Merge Worker 		.name          = "MARK",
424*a71a9546SAutomerger Merge Worker 		.revision      = 2,
425*a71a9546SAutomerger Merge Worker 		.family        = NFPROTO_ARP,
426*a71a9546SAutomerger Merge Worker 		.size          = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
427*a71a9546SAutomerger Merge Worker 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
428*a71a9546SAutomerger Merge Worker 		.help          = mark_tg_help,
429*a71a9546SAutomerger Merge Worker 		.print         = mark_tg_arp_print,
430*a71a9546SAutomerger Merge Worker 		.save          = mark_tg_arp_save,
431*a71a9546SAutomerger Merge Worker 		.parse         = mark_tg_arp_parse,
432*a71a9546SAutomerger Merge Worker 		.extra_opts    = mark_tg_arp_opts,
433*a71a9546SAutomerger Merge Worker 	},
434*a71a9546SAutomerger Merge Worker };
435*a71a9546SAutomerger Merge Worker 
_init(void)436*a71a9546SAutomerger Merge Worker void _init(void)
437*a71a9546SAutomerger Merge Worker {
438*a71a9546SAutomerger Merge Worker 	xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
439*a71a9546SAutomerger Merge Worker }
440