xref: /aosp_15_r20/external/iptables/extensions/libxt_mark.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1 #include <stdbool.h>
2 #include <stdio.h>
3 #include <xtables.h>
4 #include <linux/netfilter/xt_mark.h>
5 
6 struct xt_mark_info {
7 	unsigned long mark, mask;
8 	uint8_t invert;
9 };
10 
11 enum {
12 	O_MARK = 0,
13 };
14 
mark_mt_help(void)15 static void mark_mt_help(void)
16 {
17 	printf(
18 "mark match options:\n"
19 "[!] --mark value[/mask]    Match nfmark value with optional mask\n");
20 }
21 
22 static const struct xt_option_entry mark_mt_opts[] = {
23 	{.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32,
24 	 .flags = XTOPT_MAND | XTOPT_INVERT},
25 	XTOPT_TABLEEND,
26 };
27 
mark_mt_parse(struct xt_option_call * cb)28 static void mark_mt_parse(struct xt_option_call *cb)
29 {
30 	struct xt_mark_mtinfo1 *info = cb->data;
31 
32 	xtables_option_parse(cb);
33 	if (cb->invert)
34 		info->invert = true;
35 	info->mark = cb->val.mark;
36 	info->mask = cb->val.mask;
37 }
38 
mark_parse(struct xt_option_call * cb)39 static void mark_parse(struct xt_option_call *cb)
40 {
41 	struct xt_mark_info *markinfo = cb->data;
42 
43 	xtables_option_parse(cb);
44 	if (cb->invert)
45 		markinfo->invert = 1;
46 	markinfo->mark = cb->val.mark;
47 	markinfo->mask = cb->val.mask;
48 }
49 
50 static void
mark_mt_print(const void * ip,const struct xt_entry_match * match,int numeric)51 mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
52 {
53 	const struct xt_mark_mtinfo1 *info = (const void *)match->data;
54 
55 	printf(" mark match");
56 	if (info->invert)
57 		printf(" !");
58 
59 	xtables_print_mark_mask(info->mark, info->mask);
60 }
61 
62 static void
mark_print(const void * ip,const struct xt_entry_match * match,int numeric)63 mark_print(const void *ip, const struct xt_entry_match *match, int numeric)
64 {
65 	const struct xt_mark_info *info = (const void *)match->data;
66 
67 	printf(" MARK match");
68 
69 	if (info->invert)
70 		printf(" !");
71 
72 	xtables_print_mark_mask(info->mark, info->mask);
73 }
74 
mark_mt_save(const void * ip,const struct xt_entry_match * match)75 static void mark_mt_save(const void *ip, const struct xt_entry_match *match)
76 {
77 	const struct xt_mark_mtinfo1 *info = (const void *)match->data;
78 
79 	if (info->invert)
80 		printf(" !");
81 
82 	printf(" --mark");
83 	xtables_print_mark_mask(info->mark, info->mask);
84 }
85 
86 static void
mark_save(const void * ip,const struct xt_entry_match * match)87 mark_save(const void *ip, const struct xt_entry_match *match)
88 {
89 	const struct xt_mark_info *info = (const void *)match->data;
90 
91 	if (info->invert)
92 		printf(" !");
93 
94 	printf(" --mark");
95 	xtables_print_mark_mask(info->mark, info->mask);
96 }
97 
98 static void
print_mark_xlate(struct xt_xlate * xl,unsigned int mark,unsigned int mask,uint32_t op)99 print_mark_xlate(struct xt_xlate *xl, unsigned int mark,
100 		 unsigned int mask, uint32_t op)
101 {
102 	if (mask != 0xffffffffU)
103 		xt_xlate_add(xl, " and 0x%x %s 0x%x", mask,
104 			   op == XT_OP_EQ ? "==" : "!=", mark);
105 	else
106 		xt_xlate_add(xl, " %s0x%x",
107 			   op == XT_OP_EQ ? "" : "!= ", mark);
108 }
109 
mark_mt_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)110 static int mark_mt_xlate(struct xt_xlate *xl,
111 			 const struct xt_xlate_mt_params *params)
112 {
113 	const struct xt_mark_mtinfo1 *info = (const void *)params->match->data;
114 	enum xt_op op = XT_OP_EQ;
115 
116 	if (info->invert)
117 		op = XT_OP_NEQ;
118 
119 	xt_xlate_add(xl, "mark");
120 	print_mark_xlate(xl, info->mark, info->mask, op);
121 
122 	return 1;
123 }
124 
mark_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)125 static int mark_xlate(struct xt_xlate *xl,
126 		      const struct xt_xlate_mt_params *params)
127 {
128 	const struct xt_mark_info *info = (const void *)params->match->data;
129 	enum xt_op op = XT_OP_EQ;
130 
131 	if (info->invert)
132 		op = XT_OP_NEQ;
133 
134 	xt_xlate_add(xl, "mark");
135 	print_mark_xlate(xl, info->mark, info->mask, op);
136 
137 	return 1;
138 }
139 
140 static struct xtables_match mark_mt_reg[] = {
141 	{
142 		.family        = NFPROTO_UNSPEC,
143 		.name          = "mark",
144 		.revision      = 0,
145 		.version       = XTABLES_VERSION,
146 		.size          = XT_ALIGN(sizeof(struct xt_mark_info)),
147 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_info)),
148 		.help          = mark_mt_help,
149 		.print         = mark_print,
150 		.save          = mark_save,
151 		.x6_parse      = mark_parse,
152 		.x6_options    = mark_mt_opts,
153 		.xlate	       = mark_xlate,
154 	},
155 	{
156 		.version       = XTABLES_VERSION,
157 		.name          = "mark",
158 		.revision      = 1,
159 		.family        = NFPROTO_UNSPEC,
160 		.size          = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
161 		.userspacesize = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
162 		.help          = mark_mt_help,
163 		.print         = mark_mt_print,
164 		.save          = mark_mt_save,
165 		.x6_parse      = mark_mt_parse,
166 		.x6_options    = mark_mt_opts,
167 		.xlate	       = mark_mt_xlate,
168 	},
169 };
170 
_init(void)171 void _init(void)
172 {
173 	xtables_register_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg));
174 }
175