1 /* Shared library add-on to iptables to add CLUSTERIP target support.
2 * (C) 2003 by Harald Welte <laforge@gnumonks.org>
4 * Development of this code was funded by SuSE AG, http://www.suse.com/
12 #if defined(__GLIBC__) && __GLIBC__ == 2
13 #include <net/ethernet.h>
15 #include <linux/if_ether.h>
19 #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
21 static void CLUSTERIP_help(void)
24 "CLUSTERIP target options:\n"
25 " --new Create a new ClusterIP\n"
26 " --hashmode <mode> Specify hashing mode\n"
28 " sourceip-sourceport\n"
29 " sourceip-sourceport-destport\n"
30 " --clustermac <mac> Set clusterIP MAC address\n"
31 " --total-nodes <num> Set number of total nodes in cluster\n"
32 " --local-node <num> Set the local node number\n"
33 " --hash-init <num> Set init value of the Jenkins hash\n");
36 #define PARAM_NEW 0x0001
37 #define PARAM_HMODE 0x0002
38 #define PARAM_MAC 0x0004
39 #define PARAM_TOTALNODE 0x0008
40 #define PARAM_LOCALNODE 0x0010
41 #define PARAM_HASHINIT 0x0020
43 static const struct option CLUSTERIP_opts
[] = {
44 { "new", 0, NULL
, '1' },
45 { "hashmode", 1, NULL
, '2' },
46 { "clustermac", 1, NULL
, '3' },
47 { "total-nodes", 1, NULL
, '4' },
48 { "local-node", 1, NULL
, '5' },
49 { "hash-init", 1, NULL
, '6' },
54 parse_mac(const char *mac
, char *macbuf
)
58 if (strlen(mac
) != ETH_ALEN
*3-1)
59 xtables_error(PARAMETER_PROBLEM
, "Bad mac address \"%s\"", mac
);
61 for (i
= 0; i
< ETH_ALEN
; i
++) {
65 number
= strtol(mac
+ i
*3, &end
, 16);
67 if (end
== mac
+ i
*3 + 2
72 xtables_error(PARAMETER_PROBLEM
,
73 "Bad mac address `%s'", mac
);
77 static int CLUSTERIP_parse(int c
, char **argv
, int invert
, unsigned int *flags
,
78 const void *entry
, struct xt_entry_target
**target
)
80 struct ipt_clusterip_tgt_info
*cipinfo
81 = (struct ipt_clusterip_tgt_info
*)(*target
)->data
;
86 cipinfo
->flags
|= CLUSTERIP_FLAG_NEW
;
87 if (*flags
& PARAM_NEW
)
88 xtables_error(PARAMETER_PROBLEM
, "Can only specify \"--new\" once\n");
92 if (!(*flags
& PARAM_NEW
))
93 xtables_error(PARAMETER_PROBLEM
, "Can only specify hashmode combined with \"--new\"\n");
94 if (*flags
& PARAM_HMODE
)
95 xtables_error(PARAMETER_PROBLEM
, "Can only specify hashmode once\n");
96 if (!strcmp(optarg
, "sourceip"))
97 cipinfo
->hash_mode
= CLUSTERIP_HASHMODE_SIP
;
98 else if (!strcmp(optarg
, "sourceip-sourceport"))
99 cipinfo
->hash_mode
= CLUSTERIP_HASHMODE_SIP_SPT
;
100 else if (!strcmp(optarg
, "sourceip-sourceport-destport"))
101 cipinfo
->hash_mode
= CLUSTERIP_HASHMODE_SIP_SPT_DPT
;
103 xtables_error(PARAMETER_PROBLEM
, "Unknown hashmode \"%s\"\n",
105 *flags
|= PARAM_HMODE
;
108 if (!(*flags
& PARAM_NEW
))
109 xtables_error(PARAMETER_PROBLEM
, "Can only specify MAC combined with \"--new\"\n");
110 if (*flags
& PARAM_MAC
)
111 xtables_error(PARAMETER_PROBLEM
, "Can only specify MAC once\n");
112 parse_mac(optarg
, (char *)cipinfo
->clustermac
);
113 if (!(cipinfo
->clustermac
[0] & 0x01))
114 xtables_error(PARAMETER_PROBLEM
, "MAC has to be a multicast ethernet address\n");
118 if (!(*flags
& PARAM_NEW
))
119 xtables_error(PARAMETER_PROBLEM
, "Can only specify node number combined with \"--new\"\n");
120 if (*flags
& PARAM_TOTALNODE
)
121 xtables_error(PARAMETER_PROBLEM
, "Can only specify total node number once\n");
122 if (!xtables_strtoui(optarg
, NULL
, &num
, 1, CLUSTERIP_MAX_NODES
))
123 xtables_error(PARAMETER_PROBLEM
, "Unable to parse \"%s\"\n", optarg
);
124 cipinfo
->num_total_nodes
= num
;
125 *flags
|= PARAM_TOTALNODE
;
128 if (!(*flags
& PARAM_NEW
))
129 xtables_error(PARAMETER_PROBLEM
, "Can only specify node number combined with \"--new\"\n");
130 if (*flags
& PARAM_LOCALNODE
)
131 xtables_error(PARAMETER_PROBLEM
, "Can only specify local node number once\n");
132 if (!xtables_strtoui(optarg
, NULL
, &num
, 1, CLUSTERIP_MAX_NODES
))
133 xtables_error(PARAMETER_PROBLEM
, "Unable to parse \"%s\"\n", optarg
);
134 cipinfo
->num_local_nodes
= 1;
135 cipinfo
->local_nodes
[0] = num
;
136 *flags
|= PARAM_LOCALNODE
;
139 if (!(*flags
& PARAM_NEW
))
140 xtables_error(PARAMETER_PROBLEM
, "Can only specify hash init value combined with \"--new\"\n");
141 if (*flags
& PARAM_HASHINIT
)
142 xtables_error(PARAMETER_PROBLEM
, "Can specify hash init value only once\n");
143 if (!xtables_strtoui(optarg
, NULL
, &num
, 0, UINT_MAX
))
144 xtables_error(PARAMETER_PROBLEM
, "Unable to parse \"%s\"\n", optarg
);
145 cipinfo
->hash_initval
= num
;
146 *flags
|= PARAM_HASHINIT
;
155 static void CLUSTERIP_check(unsigned int flags
)
160 if ((flags
& (PARAM_NEW
|PARAM_HMODE
|PARAM_MAC
|PARAM_TOTALNODE
|PARAM_LOCALNODE
))
161 == (PARAM_NEW
|PARAM_HMODE
|PARAM_MAC
|PARAM_TOTALNODE
|PARAM_LOCALNODE
))
164 xtables_error(PARAMETER_PROBLEM
, "CLUSTERIP target: Invalid parameter combination\n");
167 static char *hashmode2str(enum clusterip_hashmode mode
)
171 case CLUSTERIP_HASHMODE_SIP
:
174 case CLUSTERIP_HASHMODE_SIP_SPT
:
175 retstr
= "sourceip-sourceport";
177 case CLUSTERIP_HASHMODE_SIP_SPT_DPT
:
178 retstr
= "sourceip-sourceport-destport";
181 retstr
= "unknown-error";
187 static char *mac2str(const u_int8_t mac
[ETH_ALEN
])
189 static char buf
[ETH_ALEN
*3];
190 sprintf(buf
, "%02X:%02X:%02X:%02X:%02X:%02X",
191 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
195 static void CLUSTERIP_print(const void *ip
,
196 const struct xt_entry_target
*target
, int numeric
)
198 const struct ipt_clusterip_tgt_info
*cipinfo
=
199 (const struct ipt_clusterip_tgt_info
*)target
->data
;
201 if (!cipinfo
->flags
& CLUSTERIP_FLAG_NEW
) {
206 printf("CLUSTERIP hashmode=%s clustermac=%s total_nodes=%u local_node=%u hash_init=%u",
207 hashmode2str(cipinfo
->hash_mode
),
208 mac2str(cipinfo
->clustermac
),
209 cipinfo
->num_total_nodes
,
210 cipinfo
->local_nodes
[0],
211 cipinfo
->hash_initval
);
214 static void CLUSTERIP_save(const void *ip
, const struct xt_entry_target
*target
)
216 const struct ipt_clusterip_tgt_info
*cipinfo
=
217 (const struct ipt_clusterip_tgt_info
*)target
->data
;
219 /* if this is not a new entry, we don't need to save target
221 if (!cipinfo
->flags
& CLUSTERIP_FLAG_NEW
)
224 printf("--new --hashmode %s --clustermac %s --total-nodes %d --local-node %d --hash-init %u",
225 hashmode2str(cipinfo
->hash_mode
),
226 mac2str(cipinfo
->clustermac
),
227 cipinfo
->num_total_nodes
,
228 cipinfo
->local_nodes
[0],
229 cipinfo
->hash_initval
);
232 static struct xtables_target clusterip_tg_reg
= {
234 .version
= XTABLES_VERSION
,
235 .family
= NFPROTO_IPV4
,
236 .size
= XT_ALIGN(sizeof(struct ipt_clusterip_tgt_info
)),
237 .userspacesize
= offsetof(struct ipt_clusterip_tgt_info
, config
),
238 .help
= CLUSTERIP_help
,
239 .parse
= CLUSTERIP_parse
,
240 .final_check
= CLUSTERIP_check
,
241 .print
= CLUSTERIP_print
,
242 .save
= CLUSTERIP_save
,
243 .extra_opts
= CLUSTERIP_opts
,
248 xtables_register_target(&clusterip_tg_reg
);