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