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, argv);
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, argv);
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);