1cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso/* 2cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso * (C) 2009 by Pablo Neira Ayuso <pablo@netfilter.org> 3cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso * 4cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso * This program is free software; you can redistribute it and/or modify 5cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso * it under the terms of the GNU General Public License version 2 as 6cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso * published by the Free Software Foundation. 7cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso */ 8cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso#include <stdio.h> 9cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso#include <xtables.h> 10cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso#include <linux/netfilter/xt_cluster.h> 11cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 12cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusostatic void 13cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusocluster_help(void) 14cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso{ 15cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso printf( 16cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso"cluster match options:\n" 17cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso" --cluster-total-nodes <num> Set number of total nodes in cluster\n" 18cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso" [!] --cluster-local-node <num> Set the local node number\n" 19cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso" [!] --cluster-local-nodemask <num> Set the local node mask\n" 20cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso" --cluster-hash-seed <num> Set seed value of the Jenkins hash\n"); 21cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso} 22cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 23cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusoenum { 24b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt O_CL_TOTAL_NODES = 0, 25b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt O_CL_LOCAL_NODE, 26b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt O_CL_LOCAL_NODEMASK, 27b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt O_CL_HASH_SEED, 28b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt F_CL_TOTAL_NODES = 1 << O_CL_TOTAL_NODES, 29b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt F_CL_LOCAL_NODE = 1 << O_CL_LOCAL_NODE, 30b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt F_CL_LOCAL_NODEMASK = 1 << O_CL_LOCAL_NODEMASK, 31b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt F_CL_HASH_SEED = 1 << O_CL_HASH_SEED, 32cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso}; 33cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 34b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt#define s struct xt_cluster_match_info 35b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardtstatic const struct xt_option_entry cluster_opts[] = { 36b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt {.name = "cluster-total-nodes", .id = O_CL_TOTAL_NODES, 37b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .type = XTTYPE_UINT32, .min = 1, .max = XT_CLUSTER_NODES_MAX, 38b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, total_nodes)}, 39b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt {.name = "cluster-local-node", .id = O_CL_LOCAL_NODE, 40b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .excl = F_CL_LOCAL_NODEMASK, .flags = XTOPT_INVERT, 41b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .type = XTTYPE_UINT32, .min = 1, .max = XT_CLUSTER_NODES_MAX}, 42b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt {.name = "cluster-local-nodemask", .id = O_CL_LOCAL_NODEMASK, 43b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .excl = F_CL_LOCAL_NODE, .type = XTTYPE_UINT32, 44b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .min = 1, .max = XT_CLUSTER_NODES_MAX, 45b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, node_mask)}, 46b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt {.name = "cluster-hash-seed", .id = O_CL_HASH_SEED, 47b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .type = XTTYPE_UINT32, .flags = XTOPT_MAND | XTOPT_PUT, 48b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt XTOPT_POINTER(s, hash_seed)}, 49b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt XTOPT_TABLEEND, 50cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso}; 51cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 52b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardtstatic void cluster_parse(struct xt_option_call *cb) 53cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso{ 54b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt struct xt_cluster_match_info *info = cb->data; 55cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 56b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt xtables_option_parse(cb); 57b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt switch (cb->entry->id) { 58b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt case O_CL_LOCAL_NODE: 59b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt if (cb->invert) 60e76ec99b48745b0e3c8aecbc91ed5bba186cf25fPablo Neira Ayuso info->flags |= XT_CLUSTER_F_INV; 61b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt info->node_mask = 1 << (cb->val.u32 - 1); 62cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso break; 63b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt case O_CL_LOCAL_NODEMASK: 64b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt if (cb->invert) 65e76ec99b48745b0e3c8aecbc91ed5bba186cf25fPablo Neira Ayuso info->flags |= XT_CLUSTER_F_INV; 66cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso break; 67cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso } 68cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso} 69cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 70b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardtstatic void cluster_check(struct xt_fcheck_call *cb) 71cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso{ 72b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt const struct xt_cluster_match_info *info = cb->data; 73b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt unsigned int test; 74b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt 75b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt test = F_CL_TOTAL_NODES | F_CL_LOCAL_NODE | F_CL_HASH_SEED; 76b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt if ((cb->xflags & test) == test) { 77b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt if (info->node_mask >= (1ULL << info->total_nodes)) 78cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso xtables_error(PARAMETER_PROBLEM, 79cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "cluster match: " 80cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "`--cluster-local-node' " 81cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "must be <= `--cluster-total-nodes'"); 82cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso return; 83cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso } 84b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt 85b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt test = F_CL_TOTAL_NODES | F_CL_LOCAL_NODEMASK | F_CL_HASH_SEED; 86b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt if ((cb->xflags & test) == test) { 87b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt if (info->node_mask >= (1ULL << info->total_nodes)) 88cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso xtables_error(PARAMETER_PROBLEM, 89cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "cluster match: " 90cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "`--cluster-local-nodemask' too big " 91cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "for `--cluster-total-nodes'"); 92cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso return; 93cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso } 94b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt if (!(cb->xflags & (F_CL_LOCAL_NODE | F_CL_LOCAL_NODEMASK))) 95cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso xtables_error(PARAMETER_PROBLEM, 96cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "cluster match: `--cluster-local-node' or" 97cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso "`--cluster-local-nodemask' is missing"); 98cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso} 99cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 100cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusostatic void 101cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusocluster_print(const void *ip, const struct xt_entry_match *match, int numeric) 102cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso{ 103cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso const struct xt_cluster_match_info *info = (void *)match->data; 104cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 10573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" cluster "); 106cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso if (info->flags & XT_CLUSTER_F_INV) 10773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("!node_mask=0x%08x", info->node_mask); 108cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso else 10973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf("node_mask=0x%08x", info->node_mask); 110cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 11173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" total_nodes=%u hash_seed=0x%08x", 112cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso info->total_nodes, info->hash_seed); 113cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso} 114cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 115cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusostatic void 116cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusocluster_save(const void *ip, const struct xt_entry_match *match) 117cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso{ 118cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso const struct xt_cluster_match_info *info = (void *)match->data; 119cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 120cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso if (info->flags & XT_CLUSTER_F_INV) 12173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" ! --cluster-local-nodemask 0x%08x", info->node_mask); 122cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso else 12373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --cluster-local-nodemask 0x%08x", info->node_mask); 124cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 12573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" --cluster-total-nodes %u --cluster-hash-seed 0x%08x", 126cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso info->total_nodes, info->hash_seed); 127cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso} 128cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 129cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusostatic struct xtables_match cluster_mt_reg = { 13042979363f3958b4436c6d2503753c182c58e55eaJan Engelhardt .family = NFPROTO_UNSPEC, 131cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso .name = "cluster", 132cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso .version = XTABLES_VERSION, 133cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso .size = XT_ALIGN(sizeof(struct xt_cluster_match_info)), 134cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso .userspacesize = XT_ALIGN(sizeof(struct xt_cluster_match_info)), 135cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso .help = cluster_help, 136cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso .print = cluster_print, 137cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso .save = cluster_save, 138b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .x6_parse = cluster_parse, 139b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .x6_fcheck = cluster_check, 140b18ffe3636b07cd817628de81643136e4755a944Jan Engelhardt .x6_options = cluster_opts, 141cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso}; 142cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso 143cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayusovoid _init(void) 144cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso{ 145cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso xtables_register_match(&cluster_mt_reg); 146cd958a6c92c84095a439780b53832bb3aae2d512Pablo Neira Ayuso} 147