*
*/
#include <linux/module.h>
+#include <linux/config.h>
#include <linux/proc_fs.h>
#include <linux/jhash.h>
#include <linux/bitops.h>
struct clusterip_config *c;
char buffer[16];
- c = kzalloc(sizeof(*c), GFP_ATOMIC);
+ c = kmalloc(sizeof(*c), GFP_ATOMIC);
if (!c)
return NULL;
+ memset(c, 0, sizeof(*c));
c->dev = dev;
c->clusterip = ip;
memcpy(&c->clustermac, &i->clustermac, ETH_ALEN);
struct iphdr *iph = skb->nh.iph;
unsigned long hashval;
u_int16_t sport, dport;
- u_int16_t *ports;
+ struct tcphdr *th;
+ struct udphdr *uh;
+ struct icmphdr *ih;
switch (iph->protocol) {
case IPPROTO_TCP:
+ th = (void *)iph+iph->ihl*4;
+ sport = ntohs(th->source);
+ dport = ntohs(th->dest);
+ break;
case IPPROTO_UDP:
- case IPPROTO_SCTP:
- case IPPROTO_DCCP:
+ uh = (void *)iph+iph->ihl*4;
+ sport = ntohs(uh->source);
+ dport = ntohs(uh->dest);
+ break;
case IPPROTO_ICMP:
- ports = (void *)iph+iph->ihl*4;
- sport = ports[0];
- dport = ports[1];
+ ih = (void *)iph+iph->ihl*4;
+ sport = ntohs(ih->un.echo.id);
+ dport = (ih->type<<8)|ih->code;
break;
default:
if (net_ratelimit()) {
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
- const struct xt_target *target,
const void *targinfo,
void *userinfo)
{
static int
checkentry(const char *tablename,
const void *e_void,
- const struct xt_target *target,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
struct clusterip_config *config;
+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_clusterip_tgt_info))) {
+ printk(KERN_WARNING "CLUSTERIP: targinfosize %u != %Zu\n",
+ targinfosize,
+ IPT_ALIGN(sizeof(struct ipt_clusterip_tgt_info)));
+ return 0;
+ }
+
if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP &&
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
}
/* drop reference count of cluster config when rule is deleted */
-static void destroy(const struct xt_target *target, void *targinfo,
- unsigned int targinfosize)
+static void destroy(void *matchinfo, unsigned int matchinfosize)
{
- struct ipt_clusterip_tgt_info *cipinfo = targinfo;
+ struct ipt_clusterip_tgt_info *cipinfo = matchinfo;
/* if no more entries are referencing the config, remove it
* from the list and destroy the proc entry */
clusterip_config_put(cipinfo->config);
}
-static struct ipt_target clusterip_tgt = {
- .name = "CLUSTERIP",
- .target = target,
- .targetsize = sizeof(struct ipt_clusterip_tgt_info),
- .checkentry = checkentry,
- .destroy = destroy,
- .me = THIS_MODULE
+static struct ipt_target clusterip_tgt = {
+ .name = "CLUSTERIP",
+ .target = &target,
+ .checkentry = &checkentry,
+ .destroy = &destroy,
+ .me = THIS_MODULE
};
#endif /* CONFIG_PROC_FS */
-static int __init ipt_clusterip_init(void)
+static int init_or_cleanup(int fini)
{
int ret;
- ret = ipt_register_target(&clusterip_tgt);
- if (ret < 0)
- return ret;
+ if (fini)
+ goto cleanup;
- ret = nf_register_hook(&cip_arp_ops);
- if (ret < 0)
+ if (ipt_register_target(&clusterip_tgt)) {
+ ret = -EINVAL;
+ goto cleanup_none;
+ }
+
+ if (nf_register_hook(&cip_arp_ops) < 0) {
+ ret = -EINVAL;
goto cleanup_target;
+ }
#ifdef CONFIG_PROC_FS
clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net);
printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n",
CLUSTERIP_VERSION);
- return 0;
-cleanup_hook:
- nf_unregister_hook(&cip_arp_ops);
-cleanup_target:
- ipt_unregister_target(&clusterip_tgt);
- return ret;
-}
+ return 0;
-static void __exit ipt_clusterip_fini(void)
-{
+cleanup:
printk(KERN_NOTICE "ClusterIP Version %s unloading\n",
CLUSTERIP_VERSION);
#ifdef CONFIG_PROC_FS
remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent);
#endif
+cleanup_hook:
nf_unregister_hook(&cip_arp_ops);
+cleanup_target:
ipt_unregister_target(&clusterip_tgt);
+cleanup_none:
+ return -EINVAL;
+}
+
+static int __init init(void)
+{
+ return init_or_cleanup(0);
+}
+
+static void __exit fini(void)
+{
+ init_or_cleanup(1);
}
-module_init(ipt_clusterip_init);
-module_exit(ipt_clusterip_fini);
+module_init(init);
+module_exit(fini);