2
* (C) 2009 by Pablo Neira Ayuso <pablo@netfilter.org>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 2 as
6
* published by the Free Software Foundation.
15
#include <linux/netfilter/x_tables.h>
16
#include <linux/netfilter/xt_cluster.h>
18
/* hack to keep for check */
19
static unsigned int total_nodes;
20
static unsigned int node_mask;
26
"cluster match options:\n"
27
" --cluster-total-nodes <num> Set number of total nodes in cluster\n"
28
" [!] --cluster-local-node <num> Set the local node number\n"
29
" [!] --cluster-local-nodemask <num> Set the local node mask\n"
30
" --cluster-hash-seed <num> Set seed value of the Jenkins hash\n");
34
CLUSTER_OPT_TOTAL_NODES,
35
CLUSTER_OPT_LOCAL_NODE,
36
CLUSTER_OPT_NODE_MASK,
37
CLUSTER_OPT_HASH_SEED,
40
static const struct option cluster_opts[] = {
41
{ "cluster-total-nodes", 1, NULL, CLUSTER_OPT_TOTAL_NODES },
42
{ "cluster-local-node", 1, NULL, CLUSTER_OPT_LOCAL_NODE },
43
{ "cluster-local-nodemask", 1, NULL, CLUSTER_OPT_NODE_MASK },
44
{ "cluster-hash-seed", 1, NULL, CLUSTER_OPT_HASH_SEED },
49
cluster_parse(int c, char **argv, int invert, unsigned int *flags,
50
const void *entry, struct xt_entry_match **match)
52
struct xt_cluster_match_info *info = (void *)(*match)->data;
56
case CLUSTER_OPT_TOTAL_NODES:
57
if (*flags & (1 << c)) {
58
xtables_error(PARAMETER_PROBLEM,
60
"`--cluster-total-nodes' once");
62
if (!xtables_strtoui(optarg, NULL, &num, 1,
63
XT_CLUSTER_NODES_MAX)) {
64
xtables_error(PARAMETER_PROBLEM,
65
"Unable to parse `%s' in "
66
"`--cluster-total-nodes'", optarg);
69
info->total_nodes = total_nodes = num;
72
case CLUSTER_OPT_LOCAL_NODE:
73
if (*flags & (1 << c)) {
74
xtables_error(PARAMETER_PROBLEM,
76
"`--cluster-local-node' once");
78
if (*flags & (1 << CLUSTER_OPT_NODE_MASK)) {
79
xtables_error(PARAMETER_PROBLEM, "You cannot use "
80
"`--cluster-local-nodemask' and "
81
"`--cluster-local-node'");
83
xtables_check_inverse(optarg, &invert, &optind, 0);
85
if (!xtables_strtoui(optarg, NULL, &num, 1,
86
XT_CLUSTER_NODES_MAX)) {
87
xtables_error(PARAMETER_PROBLEM,
88
"Unable to parse `%s' in "
89
"`--cluster-local-node'", optarg);
92
info->flags |= (1 << XT_CLUSTER_F_INV);
94
info->node_mask = node_mask = (1 << (num - 1));
97
case CLUSTER_OPT_NODE_MASK:
98
if (*flags & (1 << c)) {
99
xtables_error(PARAMETER_PROBLEM,
101
"`--cluster-local-node' once");
103
if (*flags & (1 << CLUSTER_OPT_LOCAL_NODE)) {
104
xtables_error(PARAMETER_PROBLEM, "You cannot use "
105
"`--cluster-local-nodemask' and "
106
"`--cluster-local-node'");
108
xtables_check_inverse(optarg, &invert, &optind, 0);
110
if (!xtables_strtoui(optarg, NULL, &num, 1,
111
XT_CLUSTER_NODES_MAX)) {
112
xtables_error(PARAMETER_PROBLEM,
113
"Unable to parse `%s' in "
114
"`--cluster-local-node'", optarg);
117
info->flags |= (1 << XT_CLUSTER_F_INV);
119
info->node_mask = node_mask = num;
123
case CLUSTER_OPT_HASH_SEED:
124
if (*flags & (1 << c)) {
125
xtables_error(PARAMETER_PROBLEM,
127
"`--cluster-hash-seed' once");
129
if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) {
130
xtables_error(PARAMETER_PROBLEM,
131
"Unable to parse `%s'", optarg);
133
info->hash_seed = num;
144
cluster_check(unsigned int flags)
146
if ((flags & ((1 << CLUSTER_OPT_TOTAL_NODES) |
147
(1 << CLUSTER_OPT_LOCAL_NODE) |
148
(1 << CLUSTER_OPT_HASH_SEED)))
149
== ((1 << CLUSTER_OPT_TOTAL_NODES) |
150
(1 << CLUSTER_OPT_LOCAL_NODE) |
151
(1 << CLUSTER_OPT_HASH_SEED))) {
152
if (node_mask >= (1ULL << total_nodes)) {
153
xtables_error(PARAMETER_PROBLEM,
155
"`--cluster-local-node' "
156
"must be <= `--cluster-total-nodes'");
160
if ((flags & ((1 << CLUSTER_OPT_TOTAL_NODES) |
161
(1 << CLUSTER_OPT_NODE_MASK) |
162
(1 << CLUSTER_OPT_HASH_SEED)))
163
== ((1 << CLUSTER_OPT_TOTAL_NODES) |
164
(1 << CLUSTER_OPT_NODE_MASK) |
165
(1 << CLUSTER_OPT_HASH_SEED))) {
166
if (node_mask >= (1ULL << total_nodes)) {
167
xtables_error(PARAMETER_PROBLEM,
169
"`--cluster-local-nodemask' too big "
170
"for `--cluster-total-nodes'");
174
if (!(flags & (1 << CLUSTER_OPT_TOTAL_NODES))) {
175
xtables_error(PARAMETER_PROBLEM,
176
"cluster match: `--cluster-total-nodes' "
179
if (!(flags & (1 << CLUSTER_OPT_HASH_SEED))) {
180
xtables_error(PARAMETER_PROBLEM,
181
"cluster match: `--cluster-hash-seed' "
184
if (!(flags & ((1 << (CLUSTER_OPT_LOCAL_NODE) |
185
(1 << (CLUSTER_OPT_NODE_MASK)))))) {
186
xtables_error(PARAMETER_PROBLEM,
187
"cluster match: `--cluster-local-node' or"
188
"`--cluster-local-nodemask' is missing");
193
cluster_print(const void *ip, const struct xt_entry_match *match, int numeric)
195
const struct xt_cluster_match_info *info = (void *)match->data;
198
if (info->flags & XT_CLUSTER_F_INV)
199
printf("!node_mask=0x%08x ", info->node_mask);
201
printf("node_mask=0x%08x ", info->node_mask);
203
printf("total_nodes=%u hash_seed=0x%08x ",
204
info->total_nodes, info->hash_seed);
208
cluster_save(const void *ip, const struct xt_entry_match *match)
210
const struct xt_cluster_match_info *info = (void *)match->data;
212
if (info->flags & XT_CLUSTER_F_INV)
213
printf("! --cluster-local-nodemask 0x%08x ", info->node_mask);
215
printf("--cluster-local-nodemask 0x%08x ", info->node_mask);
217
printf("--cluster-total-nodes %u --cluster-hash-seed 0x%08x ",
218
info->total_nodes, info->hash_seed);
221
static struct xtables_match cluster_mt_reg = {
222
.family = NFPROTO_UNSPEC,
224
.version = XTABLES_VERSION,
225
.size = XT_ALIGN(sizeof(struct xt_cluster_match_info)),
226
.userspacesize = XT_ALIGN(sizeof(struct xt_cluster_match_info)),
227
.help = cluster_help,
228
.parse = cluster_parse,
229
.final_check = cluster_check,
230
.print = cluster_print,
231
.save = cluster_save,
232
.extra_opts = cluster_opts,
237
xtables_register_match(&cluster_mt_reg);