1 /* ebt_mark
2 *
3 * Authors:
4 * Bart De Schuymer <bdschuym@pandora.be>
5 *
6 * July, 2002, September 2006
7 *
8 * Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
9 * to use libxtables for ebtables-compat in 2015.
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <xtables.h>
16 #include <linux/netfilter_bridge/ebt_mark_t.h>
17 #include "iptables/nft.h"
18 #include "iptables/nft-bridge.h"
19
20 enum {
21 O_SET_MARK = 0,
22 O_AND_MARK,
23 O_OR_MARK,
24 O_XOR_MARK,
25 O_MARK_TARGET,
26 F_SET_MARK = 1 << O_SET_MARK,
27 F_AND_MARK = 1 << O_AND_MARK,
28 F_OR_MARK = 1 << O_OR_MARK,
29 F_XOR_MARK = 1 << O_XOR_MARK,
30 F_ANY = F_SET_MARK | F_AND_MARK | F_OR_MARK | F_XOR_MARK,
31 };
32
33 static const struct xt_option_entry brmark_opts[] = {
34 { .name = "mark-target",.id = O_MARK_TARGET, .type = XTTYPE_STRING },
35 /* an oldtime messup, we should have always used the scheme
36 * <extension-name>-<option> */
37 { .name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32,
38 .excl = F_ANY },
39 { .name = "mark-set", .id = O_SET_MARK, .type = XTTYPE_UINT32,
40 .excl = F_ANY },
41 { .name = "mark-or", .id = O_OR_MARK, .type = XTTYPE_UINT32,
42 .excl = F_ANY },
43 { .name = "mark-and", .id = O_AND_MARK, .type = XTTYPE_UINT32,
44 .excl = F_ANY },
45 { .name = "mark-xor", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
46 .excl = F_ANY },
47 XTOPT_TABLEEND,
48 };
49
brmark_print_help(void)50 static void brmark_print_help(void)
51 {
52 printf(
53 "mark target options:\n"
54 " --mark-set value : Set nfmark value\n"
55 " --mark-or value : Or nfmark with value (nfmark |= value)\n"
56 " --mark-and value : And nfmark with value (nfmark &= value)\n"
57 " --mark-xor value : Xor nfmark with value (nfmark ^= value)\n"
58 " --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
59 }
60
brmark_init(struct xt_entry_target * target)61 static void brmark_init(struct xt_entry_target *target)
62 {
63 struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
64
65 info->target = EBT_ACCEPT;
66 info->mark = 0;
67 }
68
brmark_parse(struct xt_option_call * cb)69 static void brmark_parse(struct xt_option_call *cb)
70 {
71 static const unsigned long target_orval[] = {
72 [O_SET_MARK] = MARK_SET_VALUE,
73 [O_AND_MARK] = MARK_AND_VALUE,
74 [O_OR_MARK] = MARK_OR_VALUE,
75 [O_XOR_MARK] = MARK_XOR_VALUE,
76 };
77 struct ebt_mark_t_info *info = cb->data;
78 unsigned int tmp;
79
80 xtables_option_parse(cb);
81 switch (cb->entry->id) {
82 case O_MARK_TARGET:
83 if (ebt_fill_target(cb->arg, &tmp))
84 xtables_error(PARAMETER_PROBLEM,
85 "Illegal --mark-target target");
86 /* the 4 lsb are left to designate the target */
87 info->target = (info->target & ~EBT_VERDICT_BITS) |
88 (tmp & EBT_VERDICT_BITS);
89 return;
90 case O_SET_MARK:
91 case O_OR_MARK:
92 case O_AND_MARK:
93 case O_XOR_MARK:
94 break;
95 default:
96 return;
97 }
98 /* mutual code */
99 info->mark = cb->val.u32;
100 info->target = (info->target & EBT_VERDICT_BITS) |
101 target_orval[cb->entry->id];
102 }
103
brmark_print(const void * ip,const struct xt_entry_target * target,int numeric)104 static void brmark_print(const void *ip, const struct xt_entry_target *target,
105 int numeric)
106 {
107 struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
108 int tmp;
109
110 tmp = info->target & ~EBT_VERDICT_BITS;
111 if (tmp == MARK_SET_VALUE)
112 printf("--mark-set");
113 else if (tmp == MARK_OR_VALUE)
114 printf("--mark-or");
115 else if (tmp == MARK_XOR_VALUE)
116 printf("--mark-xor");
117 else if (tmp == MARK_AND_VALUE)
118 printf("--mark-and");
119 else
120 xtables_error(PARAMETER_PROBLEM, "Unknown mark action");
121
122 printf(" 0x%lx", info->mark);
123 tmp = info->target | ~EBT_VERDICT_BITS;
124 printf(" --mark-target %s", ebt_target_name(tmp));
125 }
126
brmark_final_check(struct xt_fcheck_call * fc)127 static void brmark_final_check(struct xt_fcheck_call *fc)
128 {
129 if (!fc->xflags)
130 xtables_error(PARAMETER_PROBLEM,
131 "You must specify some option");
132 }
133
brmark_verdict(int verdict)134 static const char* brmark_verdict(int verdict)
135 {
136 switch (verdict) {
137 case EBT_ACCEPT: return "accept";
138 case EBT_DROP: return "drop";
139 case EBT_CONTINUE: return "continue";
140 case EBT_RETURN: return "return";
141 }
142
143 return "";
144 }
145
brmark_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)146 static int brmark_xlate(struct xt_xlate *xl,
147 const struct xt_xlate_tg_params *params)
148 {
149 const struct ebt_mark_t_info *info = (const void*)params->target->data;
150 int tmp;
151
152 tmp = info->target & ~EBT_VERDICT_BITS;
153
154 xt_xlate_add(xl, "meta mark set ");
155
156 switch (tmp) {
157 case MARK_SET_VALUE:
158 break;
159 case MARK_OR_VALUE:
160 xt_xlate_add(xl, "meta mark or ");
161 break;
162 case MARK_XOR_VALUE:
163 xt_xlate_add(xl, "meta mark xor ");
164 break;
165 case MARK_AND_VALUE:
166 xt_xlate_add(xl, "meta mark and ");
167 break;
168 default:
169 return 0;
170 }
171
172 tmp = info->target | ~EBT_VERDICT_BITS;
173 xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp));
174 return 1;
175 }
176
177 static struct xtables_target brmark_target = {
178 .name = "mark",
179 .revision = 0,
180 .version = XTABLES_VERSION,
181 .family = NFPROTO_BRIDGE,
182 .size = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
183 .userspacesize = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
184 .help = brmark_print_help,
185 .init = brmark_init,
186 .x6_parse = brmark_parse,
187 .x6_fcheck = brmark_final_check,
188 .print = brmark_print,
189 .xlate = brmark_xlate,
190 .x6_options = brmark_opts,
191 };
192
_init(void)193 void _init(void)
194 {
195 xtables_register_target(&brmark_target);
196 }
197