1 /* Shared library add-on to iptables to add MARK target support. */
9 #include <linux/netfilter/x_tables.h>
10 #include <linux/netfilter/xt_MARK.h>
13 struct xt_mark_target_info {
24 struct xt_mark_target_info_v1 {
33 static void MARK_help(void)
36 "MARK target options:\n"
37 " --set-mark value Set nfmark value\n"
38 " --and-mark value Binary AND the nfmark with value\n"
39 " --or-mark value Binary OR the nfmark with value\n");
42 static const struct option MARK_opts[] = {
43 { "set-mark", 1, NULL, '1' },
44 { "and-mark", 1, NULL, '2' },
45 { "or-mark", 1, NULL, '3' },
49 static const struct option mark_tg_opts[] = {
50 {.name = "set-xmark", .has_arg = true, .val = 'X'},
51 {.name = "set-mark", .has_arg = true, .val = '='},
52 {.name = "and-mark", .has_arg = true, .val = '&'},
53 {.name = "or-mark", .has_arg = true, .val = '|'},
54 {.name = "xor-mark", .has_arg = true, .val = '^'},
58 static void mark_tg_help(void)
61 "MARK target options:\n"
62 " --set-xmark value[/mask] Clear bits in mask and XOR value into nfmark\n"
63 " --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n"
64 " --and-mark bits Binary AND the nfmark with bits\n"
65 " --or-mark bits Binary OR the nfmark with bits\n"
66 " --xor-mask bits Binary XOR the nfmark with bits\n"
70 /* Function which parses command options; returns true if it
73 MARK_parse_v0(int c, char **argv, int invert, unsigned int *flags,
74 const void *entry, struct xt_entry_target **target)
76 struct xt_mark_target_info *markinfo
77 = (struct xt_mark_target_info *)(*target)->data;
78 unsigned int mark = 0;
82 if (!xtables_strtoui(optarg, NULL, &mark, 0, UINT32_MAX))
83 xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
84 markinfo->mark = mark;
86 xtables_error(PARAMETER_PROBLEM,
87 "MARK target: Can't specify --set-mark twice");
91 xtables_error(PARAMETER_PROBLEM,
92 "MARK target: kernel too old for --and-mark");
94 xtables_error(PARAMETER_PROBLEM,
95 "MARK target: kernel too old for --or-mark");
103 static void MARK_check(unsigned int flags)
106 xtables_error(PARAMETER_PROBLEM,
107 "MARK target: Parameter --set/and/or-mark"
112 MARK_parse_v1(int c, char **argv, int invert, unsigned int *flags,
113 const void *entry, struct xt_entry_target **target)
115 struct xt_mark_target_info_v1 *markinfo
116 = (struct xt_mark_target_info_v1 *)(*target)->data;
117 unsigned int mark = 0;
121 markinfo->mode = XT_MARK_SET;
124 markinfo->mode = XT_MARK_AND;
127 markinfo->mode = XT_MARK_OR;
133 if (!xtables_strtoui(optarg, NULL, &mark, 0, UINT32_MAX))
134 xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
135 markinfo->mark = mark;
137 xtables_error(PARAMETER_PROBLEM,
138 "MARK target: Can't specify --set-mark twice");
144 static int mark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
145 const void *entry, struct xt_entry_target **target)
147 struct xt_mark_tginfo2 *info = (void *)(*target)->data;
148 unsigned int value, mask = UINT32_MAX;
152 case 'X': /* --set-xmark */
153 case '=': /* --set-mark */
154 xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
155 xtables_param_act(XTF_NO_INVERT, "MARK", "--set-xmark/--set-mark", invert);
156 if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX))
157 xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
159 if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
160 xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
162 xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg);
167 info->mask = value | mask;
170 case '&': /* --and-mark */
171 xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
172 xtables_param_act(XTF_NO_INVERT, "MARK", "--and-mark", invert);
173 if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX))
174 xtables_param_act(XTF_BAD_VALUE, "MARK", "--and-mark", optarg);
179 case '|': /* --or-mark */
180 xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
181 xtables_param_act(XTF_NO_INVERT, "MARK", "--or-mark", invert);
182 if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
183 xtables_param_act(XTF_BAD_VALUE, "MARK", "--or-mark", optarg);
188 case '^': /* --xor-mark */
189 xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK);
190 xtables_param_act(XTF_NO_INVERT, "MARK", "--xor-mark", invert);
191 if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
192 xtables_param_act(XTF_BAD_VALUE, "MARK", "--xor-mark", optarg);
205 static void mark_tg_check(unsigned int flags)
208 xtables_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, "
209 "--{and,or,xor,set}-mark options is required");
213 print_mark(unsigned long mark)
215 printf("0x%lx ", mark);
218 static void MARK_print_v0(const void *ip,
219 const struct xt_entry_target *target, int numeric)
221 const struct xt_mark_target_info *markinfo =
222 (const struct xt_mark_target_info *)target->data;
224 print_mark(markinfo->mark);
227 static void MARK_save_v0(const void *ip, const struct xt_entry_target *target)
229 const struct xt_mark_target_info *markinfo =
230 (const struct xt_mark_target_info *)target->data;
232 printf("--set-mark ");
233 print_mark(markinfo->mark);
236 static void MARK_print_v1(const void *ip, const struct xt_entry_target *target,
239 const struct xt_mark_target_info_v1 *markinfo =
240 (const struct xt_mark_target_info_v1 *)target->data;
242 switch (markinfo->mode) {
253 print_mark(markinfo->mark);
256 static void mark_tg_print(const void *ip, const struct xt_entry_target *target,
259 const struct xt_mark_tginfo2 *info = (const void *)target->data;
262 printf("MARK and 0x%x ", (unsigned int)(u_int32_t)~info->mask);
263 else if (info->mark == info->mask)
264 printf("MARK or 0x%x ", info->mark);
265 else if (info->mask == 0)
266 printf("MARK xor 0x%x ", info->mark);
267 else if (info->mask == 0xffffffffU)
268 printf("MARK set 0x%x ", info->mark);
270 printf("MARK xset 0x%x/0x%x ", info->mark, info->mask);
273 static void MARK_save_v1(const void *ip, const struct xt_entry_target *target)
275 const struct xt_mark_target_info_v1 *markinfo =
276 (const struct xt_mark_target_info_v1 *)target->data;
278 switch (markinfo->mode) {
280 printf("--set-mark ");
283 printf("--and-mark ");
286 printf("--or-mark ");
289 print_mark(markinfo->mark);
292 static void mark_tg_save(const void *ip, const struct xt_entry_target *target)
294 const struct xt_mark_tginfo2 *info = (const void *)target->data;
296 printf("--set-xmark 0x%x/0x%x ", info->mark, info->mask);
299 static struct xtables_target mark_tg_reg[] = {
301 .family = NFPROTO_UNSPEC,
303 .version = XTABLES_VERSION,
305 .size = XT_ALIGN(sizeof(struct xt_mark_target_info)),
306 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)),
308 .parse = MARK_parse_v0,
309 .final_check = MARK_check,
310 .print = MARK_print_v0,
311 .save = MARK_save_v0,
312 .extra_opts = MARK_opts,
315 .family = NFPROTO_IPV4,
317 .version = XTABLES_VERSION,
319 .size = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
320 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
322 .parse = MARK_parse_v1,
323 .final_check = MARK_check,
324 .print = MARK_print_v1,
325 .save = MARK_save_v1,
326 .extra_opts = MARK_opts,
329 .version = XTABLES_VERSION,
332 .family = NFPROTO_UNSPEC,
333 .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
334 .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
335 .help = mark_tg_help,
336 .parse = mark_tg_parse,
337 .final_check = mark_tg_check,
338 .print = mark_tg_print,
339 .save = mark_tg_save,
340 .extra_opts = mark_tg_opts,
346 xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));