libxt_cluster.c revision bf97128c7262f17a02fec41cdae75b472ba77f88
1/* 2 * (C) 2009 by Pablo Neira Ayuso <pablo@netfilter.org> 3 * 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. 7 */ 8#include <stdio.h> 9#include <string.h> 10#include <stdlib.h> 11#include <getopt.h> 12#include <stddef.h> 13 14#include <xtables.h> 15#include <linux/netfilter/x_tables.h> 16#include <linux/netfilter/xt_cluster.h> 17 18/* hack to keep for check */ 19static unsigned int total_nodes; 20static unsigned int node_mask; 21 22static void 23cluster_help(void) 24{ 25 printf( 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"); 31} 32 33enum { 34 CLUSTER_OPT_TOTAL_NODES, 35 CLUSTER_OPT_LOCAL_NODE, 36 CLUSTER_OPT_NODE_MASK, 37 CLUSTER_OPT_HASH_SEED, 38}; 39 40static 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 }, 45 { .name = NULL } 46}; 47 48static int 49cluster_parse(int c, char **argv, int invert, unsigned int *flags, 50 const void *entry, struct xt_entry_match **match) 51{ 52 struct xt_cluster_match_info *info = (void *)(*match)->data; 53 unsigned int num; 54 55 switch (c) { 56 case CLUSTER_OPT_TOTAL_NODES: 57 if (*flags & (1 << c)) { 58 xtables_error(PARAMETER_PROBLEM, 59 "Can only specify " 60 "`--cluster-total-nodes' once"); 61 } 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); 67 } 68 total_nodes = num; 69 info->total_nodes = total_nodes = num; 70 *flags |= 1 << c; 71 break; 72 case CLUSTER_OPT_LOCAL_NODE: 73 if (*flags & (1 << c)) { 74 xtables_error(PARAMETER_PROBLEM, 75 "Can only specify " 76 "`--cluster-local-node' once"); 77 } 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'"); 82 } 83 xtables_check_inverse(optarg, &invert, &optind, 0, argv); 84 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); 90 } 91 if (invert) 92 info->flags |= (1 << XT_CLUSTER_F_INV); 93 94 info->node_mask = node_mask = (1 << (num - 1)); 95 *flags |= 1 << c; 96 break; 97 case CLUSTER_OPT_NODE_MASK: 98 if (*flags & (1 << c)) { 99 xtables_error(PARAMETER_PROBLEM, 100 "Can only specify " 101 "`--cluster-local-node' once"); 102 } 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'"); 107 } 108 xtables_check_inverse(optarg, &invert, &optind, 0, argv); 109 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); 115 } 116 if (invert) 117 info->flags |= (1 << XT_CLUSTER_F_INV); 118 119 info->node_mask = node_mask = num; 120 *flags |= 1 << c; 121 break; 122 123 case CLUSTER_OPT_HASH_SEED: 124 if (*flags & (1 << c)) { 125 xtables_error(PARAMETER_PROBLEM, 126 "Can only specify " 127 "`--cluster-hash-seed' once"); 128 } 129 if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) { 130 xtables_error(PARAMETER_PROBLEM, 131 "Unable to parse `%s'", optarg); 132 } 133 info->hash_seed = num; 134 *flags |= 1 << c; 135 break; 136 default: 137 return 0; 138 } 139 140 return 1; 141} 142 143static void 144cluster_check(unsigned int flags) 145{ 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, 154 "cluster match: " 155 "`--cluster-local-node' " 156 "must be <= `--cluster-total-nodes'"); 157 } 158 return; 159 } 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, 168 "cluster match: " 169 "`--cluster-local-nodemask' too big " 170 "for `--cluster-total-nodes'"); 171 } 172 return; 173 } 174 if (!(flags & (1 << CLUSTER_OPT_TOTAL_NODES))) { 175 xtables_error(PARAMETER_PROBLEM, 176 "cluster match: `--cluster-total-nodes' " 177 "is missing"); 178 } 179 if (!(flags & (1 << CLUSTER_OPT_HASH_SEED))) { 180 xtables_error(PARAMETER_PROBLEM, 181 "cluster match: `--cluster-hash-seed' " 182 "is missing"); 183 } 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"); 189 } 190} 191 192static void 193cluster_print(const void *ip, const struct xt_entry_match *match, int numeric) 194{ 195 const struct xt_cluster_match_info *info = (void *)match->data; 196 197 printf("cluster "); 198 if (info->flags & XT_CLUSTER_F_INV) 199 printf("!node_mask=0x%08x ", info->node_mask); 200 else 201 printf("node_mask=0x%08x ", info->node_mask); 202 203 printf("total_nodes=%u hash_seed=0x%08x ", 204 info->total_nodes, info->hash_seed); 205} 206 207static void 208cluster_save(const void *ip, const struct xt_entry_match *match) 209{ 210 const struct xt_cluster_match_info *info = (void *)match->data; 211 212 if (info->flags & XT_CLUSTER_F_INV) 213 printf("! --cluster-local-nodemask 0x%08x ", info->node_mask); 214 else 215 printf("--cluster-local-nodemask 0x%08x ", info->node_mask); 216 217 printf("--cluster-total-nodes %u --cluster-hash-seed 0x%08x ", 218 info->total_nodes, info->hash_seed); 219} 220 221static struct xtables_match cluster_mt_reg = { 222 .family = NFPROTO_UNSPEC, 223 .name = "cluster", 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, 233}; 234 235void _init(void) 236{ 237 xtables_register_match(&cluster_mt_reg); 238} 239