12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/module.h>
16 #include <linux/bitops.h>
18 #include <linux/slab.h>
20 #include <linux/tcp.h>
21 #include <linux/udp.h>
22 #include <linux/icmp.h>
23 #include <linux/if_arp.h>
26 #include <linux/netfilter/x_tables.h>
27 #include <linux/netfilter_ipv4/ip_tables.h>
34 #define CLUSTERIP_VERSION "0.8"
77 static void clusterip_config_rcu_free(
struct rcu_head *
head)
97 list_del_rcu(&c->
list);
98 spin_unlock(&clusterip_lock);
107 #ifdef CONFIG_PROC_FS
120 list_for_each_entry_rcu(c, &clusterip_configs,
list) {
129 clusterip_config_find_get(
__be32 clusterip,
int entry)
134 c = __clusterip_config_find(clusterip);
141 rcu_read_unlock_bh();
170 clusterip_config_init_nodelist(c, i);
176 #ifdef CONFIG_PROC_FS
184 &clusterip_proc_fops, c);
192 spin_lock_bh(&clusterip_lock);
193 list_add_rcu(&c->
list, &clusterip_configs);
194 spin_unlock_bh(&clusterip_lock);
199 #ifdef CONFIG_PROC_FS
233 const struct iphdr *iph = ip_hdr(skb);
234 unsigned long hashval;
238 poff = proto_ports_offset(iph->
protocol);
243 ports = skb_header_pointer(skb, iph->ihl * 4 + poff, 4, _ports);
258 hashval = jhash_2words(
ntohl(iph->
saddr), sport,
262 hashval = jhash_3words(
ntohl(iph->
saddr), sport, dport,
301 ct = nf_ct_get(skb, &ctinfo);
316 hash = clusterip_hashfn(skb, cipinfo->
config);
337 pr_debug(
"hash=%u ct_hash=%u ", hash, ct->mark);
338 if (!clusterip_responsible(cipinfo->
config, hash)) {
365 if (e->
ip.dmsk.s_addr !=
htonl(0xffffffff) ||
366 e->
ip.dst.s_addr == 0) {
367 pr_info(
"Please specify destination IP\n");
373 config = clusterip_config_find_get(e->
ip.dst.s_addr, 1);
376 pr_info(
"no config found for %pI4, need 'new'\n",
382 if (e->
ip.iniface[0] ==
'\0') {
383 pr_info(
"Please specify an interface name\n");
389 pr_info(
"no such interface %s\n",
394 config = clusterip_config_init(cipinfo,
395 e->
ip.dst.s_addr, dev);
407 pr_info(
"cannot load conntrack support for proto=%u\n",
419 clusterip_config_entry_put(cipinfo->
config);
421 clusterip_config_put(cipinfo->
config);
427 struct compat_ipt_clusterip_tgt_info
443 .target = clusterip_tg,
444 .checkentry = clusterip_tg_check,
445 .destroy = clusterip_tg_destroy,
448 .compatsize =
sizeof(
struct compat_ipt_clusterip_tgt_info),
469 #define HBUFFERLEN 30
470 char hbuffer[HBUFFERLEN];
473 for (k=0, j=0; k < HBUFFERLEN-3 && j <
ETH_ALEN; j++) {
486 arp_mangle(
unsigned int hook,
492 struct arphdr *arp = arp_hdr(skb);
507 payload = (
void *)(arp+1);
511 c = clusterip_config_find_get(payload->
src_ip, 0);
520 pr_debug(
"not mangling arp reply on different "
521 "interface: cip'%s'-skb'%s'\n",
523 clusterip_config_put(c);
535 clusterip_config_put(c);
540 static struct nf_hook_ops cip_arp_ops __read_mostly = {
551 #ifdef CONFIG_PROC_FS
553 struct clusterip_seq_position {
560 static void *clusterip_seq_start(
struct seq_file *
s, loff_t *
pos)
565 struct clusterip_seq_position *
idx;
579 idx->bit =
ffs(local_nodes);
580 idx->val = local_nodes;
586 static void *clusterip_seq_next(
struct seq_file *s,
void *
v, loff_t *pos)
588 struct clusterip_seq_position *idx =
v;
591 if (*pos >= idx->weight) {
595 idx->bit =
ffs(idx->val);
600 static void clusterip_seq_stop(
struct seq_file *s,
void *v)
606 static int clusterip_seq_show(
struct seq_file *s,
void *v)
608 struct clusterip_seq_position *idx =
v;
615 if (idx->pos == idx->weight - 1)
622 .
start = clusterip_seq_start,
623 .next = clusterip_seq_next,
624 .stop = clusterip_seq_stop,
625 .show = clusterip_seq_show,
630 int ret =
seq_open(file, &clusterip_seq_ops);
638 clusterip_config_get(c);
644 static int clusterip_proc_release(
struct inode *inode,
struct file *file)
652 clusterip_config_put(c);
657 static ssize_t clusterip_proc_write(
struct file *file,
const char __user *
input,
658 size_t size, loff_t *ofs)
661 #define PROC_WRITELEN 10
662 char buffer[PROC_WRITELEN+1];
663 unsigned long nodenum;
665 if (size > PROC_WRITELEN)
671 if (*buffer ==
'+') {
673 if (clusterip_add_node(c, nodenum))
675 }
else if (*buffer ==
'-') {
677 if (clusterip_del_node(c, nodenum))
687 .open = clusterip_proc_open,
689 .write = clusterip_proc_write,
691 .release = clusterip_proc_release,
696 static int __init clusterip_tg_init(
void)
708 #ifdef CONFIG_PROC_FS
710 if (!clusterip_procdir) {
711 pr_err(
"Unable to proc dir entry\n");
717 pr_info(
"ClusterIP Version %s loaded successfully\n",
721 #ifdef CONFIG_PROC_FS
730 static void __exit clusterip_tg_exit(
void)
733 #ifdef CONFIG_PROC_FS