Index: ip_vs.h =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ip_vs.h,v retrieving revision 1.25 diff -u -r1.25 ip_vs.h --- ip_vs.h 2001/10/19 15:07:47 1.25 +++ ip_vs.h 2001/10/22 13:14:44 @@ -8,7 +8,7 @@ #include /* For __uXX types */ -#define IP_VS_VERSION_CODE 0x000905 +#define IP_VS_VERSION_CODE 0x000906 #define NVERSION(version) \ (version >> 16) & 0xFF, \ (version >> 8) & 0xFF, \ @@ -545,9 +545,6 @@ * IPVS core functions * (from ip_vs_core.c) */ -extern struct ip_vs_conn * ip_vs_schedule(struct ip_vs_service *svc, - struct iphdr *iph); -extern int ip_vs_proto_doff(unsigned proto, char *th, unsigned size); extern const char *ip_vs_proto_name(unsigned proto); extern unsigned int check_for_ip_vs_out(struct sk_buff **skb_p, int (*okfn)(struct sk_buff *)); @@ -676,12 +673,11 @@ */ extern int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); extern int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler); -extern int ip_vs_register_scheduler_module(struct ip_vs_scheduler *scheduler); -extern void ip_vs_unregister_scheduler_module(struct ip_vs_scheduler *scheduler); extern int ip_vs_bind_scheduler(struct ip_vs_service *svc, struct ip_vs_scheduler *scheduler); extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc); -extern struct ip_vs_scheduler *ip_vs_lookup_scheduler(const char *sched_name); +extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); +extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); /* @@ -717,8 +713,8 @@ * (from ip_vs_sync.c) */ extern int ip_vs_sync_state; -extern char mcast_ifn[IP_VS_IFNAME_MAXLEN]; -extern int start_sync_thread(struct ip_vs_rule_user *u); +extern char ip_vs_mcast_ifn[IP_VS_IFNAME_MAXLEN]; +extern int start_sync_thread(int state, char *mcast_ifn); extern int stop_sync_thread(void); extern void ip_vs_sync_conn(struct ip_vs_conn *cp); Index: ip_vs_core.c =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ip_vs_core.c,v retrieving revision 1.23 diff -u -r1.23 ip_vs_core.c --- ip_vs_core.c 2001/10/19 15:05:17 1.23 +++ ip_vs_core.c 2001/10/22 03:36:24 @@ -332,7 +332,8 @@ * It selects a server according to the virtual service, and * creates a connection entry. */ -struct ip_vs_conn *ip_vs_schedule(struct ip_vs_service *svc, struct iphdr *iph) +static struct ip_vs_conn * +ip_vs_schedule(struct ip_vs_service *svc, struct iphdr *iph) { struct ip_vs_conn *cp = NULL; struct ip_vs_dest *dest; Index: ip_vs_ctl.c =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ip_vs_ctl.c,v retrieving revision 1.21 diff -u -r1.21 ip_vs_ctl.c --- ip_vs_ctl.c 2001/09/19 01:14:24 1.21 +++ ip_vs_ctl.c 2001/10/22 13:21:18 @@ -990,12 +990,12 @@ /* * Lookup the scheduler, by 'ur->sched_name' */ - sched = ip_vs_lookup_scheduler(ur->sched_name); + sched = ip_vs_scheduler_get(ur->sched_name); if (sched == NULL) { IP_VS_INFO("Scheduler module ip_vs_%s.o not found\n", ur->sched_name); ret = -ENOENT; - goto out_err; + goto out_mod_dec; } svc = (struct ip_vs_service*) @@ -1054,11 +1054,10 @@ return 0; out_err: - if (sched->module) - __MOD_DEC_USE_COUNT(sched->module); - if (svc) { + if (svc) kfree(svc); - } + ip_vs_scheduler_put(sched); + out_mod_dec: MOD_DEC_USE_COUNT; return ret; } @@ -1076,7 +1075,7 @@ /* * Lookup the scheduler, by 'ur->sched_name' */ - sched = ip_vs_lookup_scheduler(ur->sched_name); + sched = ip_vs_scheduler_get(ur->sched_name); if (sched == NULL) { IP_VS_INFO("Scheduler module ip_vs_%s.o not found\n", ur->sched_name); @@ -1129,8 +1128,8 @@ out: write_unlock_bh(&__ip_vs_svc_lock); - if (old_sched && old_sched->module) - __MOD_DEC_USE_COUNT(old_sched->module); + if (old_sched) + ip_vs_scheduler_put(old_sched); return ret; } @@ -1644,7 +1643,7 @@ ret = ip_vs_set_timeouts(urule); goto out_unlock; } else if (cmd == IP_VS_SO_SET_STARTDAEMON) { - ret = start_sync_thread(urule); + ret = start_sync_thread(urule->state, urule->mcast_ifn); goto out_unlock; } else if (cmd == IP_VS_SO_SET_STOPDAEMON) { ret = stop_sync_thread(); @@ -1664,7 +1663,7 @@ } /* - * Lookup the exact service by (protocol, vaddr, vport) or fwmark + * Lookup the exact service by or fwmark */ if (urule->vfwmark == 0) svc = __ip_vs_service_get(urule->protocol, @@ -1672,6 +1671,12 @@ else svc = __ip_vs_svc_fwm_get(urule->vfwmark); + if (cmd != IP_VS_SO_SET_ADD + && (svc == NULL || svc->protocol != urule->protocol)) { + ret = -ESRCH; + goto out_unlock; + } + switch (cmd) { case IP_VS_SO_SET_ADD: if (svc != NULL) @@ -1680,37 +1685,20 @@ ret = ip_vs_add_service(urule, &svc); break; case IP_VS_SO_SET_EDIT: - if (svc == NULL || svc->protocol != urule->protocol) - ret = -ESRCH; - else - ret = ip_vs_edit_service(svc, urule); + ret = ip_vs_edit_service(svc, urule); break; case IP_VS_SO_SET_DEL: - if (svc == NULL || svc->protocol != urule->protocol) - ret = -ESRCH; - else { - ret = ip_vs_del_service(svc); - if (!ret) - goto out_unlock; - } + ret = ip_vs_del_service(svc); + if (!ret) + goto out_unlock; break; case IP_VS_SO_SET_ADDDEST: - if (svc == NULL || svc->protocol != urule->protocol) - ret = -ESRCH; - else - ret = ip_vs_add_dest(svc, urule); - break; + ret = ip_vs_add_dest(svc, urule); case IP_VS_SO_SET_EDITDEST: - if (svc == NULL || svc->protocol != urule->protocol) - ret = -ESRCH; - else - ret = ip_vs_edit_dest(svc, urule); + ret = ip_vs_edit_dest(svc, urule); break; case IP_VS_SO_SET_DELDEST: - if (svc == NULL || svc->protocol != urule->protocol) - ret = -ESRCH; - else - ret = ip_vs_del_dest(svc, urule); + ret = ip_vs_del_dest(svc, urule); break; default: ret = -EINVAL; @@ -1731,9 +1719,9 @@ static inline void __ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src) { - spin_lock(&src->lock); + spin_lock_bh(&src->lock); memcpy(dst, src, (char*)&src->lock - (char*)src); - spin_unlock(&src->lock); + spin_unlock_bh(&src->lock); } static inline int @@ -1977,7 +1965,7 @@ return -EINVAL; } u.state = ip_vs_sync_state; - strcpy(u.mcast_ifn, mcast_ifn); + strcpy(u.mcast_ifn, ip_vs_mcast_ifn); if (copy_to_user(user, &u, sizeof(u)) != 0) ret = -EFAULT; } Index: ip_vs_sched.c =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ip_vs_sched.c,v retrieving revision 1.10 diff -u -r1.10 ip_vs_sched.c --- ip_vs_sched.c 2001/06/04 13:51:03 1.10 +++ ip_vs_sched.c 2001/10/22 13:19:10 @@ -146,7 +146,7 @@ /* * Lookup scheduler and try to load it if it doesn't exist */ -struct ip_vs_scheduler *ip_vs_lookup_scheduler(const char *sched_name) +struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name) { struct ip_vs_scheduler *sched; @@ -168,6 +168,12 @@ return sched; } +void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler) +{ + if (scheduler->module) + __MOD_DEC_USE_COUNT(scheduler->module); +} + /* * Register a scheduler in the scheduler list @@ -194,8 +200,7 @@ */ sched = ip_vs_sched_getbyname(scheduler->name); if (sched) { - if (sched->module) - __MOD_DEC_USE_COUNT(sched->module); + ip_vs_scheduler_put(sched); MOD_DEC_USE_COUNT; IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler " "already existed in the system\n", scheduler->name); Index: ip_vs_sync.c =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ip_vs_sync.c,v retrieving revision 1.3 diff -u -r1.3 ip_vs_sync.c --- ip_vs_sync.c 2001/09/18 15:42:54 1.3 +++ ip_vs_sync.c 2001/10/24 11:15:39 @@ -281,10 +281,10 @@ /* ipvs sync daemon state */ -int ip_vs_sync_state; +int ip_vs_sync_state = IP_VS_STATE_NONE; /* multicast interface name */ -char mcast_ifn[IP_VS_IFNAME_MAXLEN]; +char ip_vs_mcast_ifn[IP_VS_IFNAME_MAXLEN]; /* multicast addr */ static struct sockaddr_in mcast_addr; @@ -363,6 +363,31 @@ } +static int bind_mcastif_addr(struct socket *sock, char *ifname) +{ + struct net_device *dev; + u32 addr; + struct sockaddr_in sin; + + if ((dev = __dev_get_by_name(ifname)) == NULL) + return -ENODEV; + + addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); + if (!addr) + IP_VS_ERR("You probably need to specify IP address on " + "multicast interface.\n"); + + IP_VS_DBG(7, "binding socket with (%s) %u.%u.%u.%u\n", + ifname, NIPQUAD(addr)); + + /* Now bind the socket with the address of multicast interface */ + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = addr; + sin.sin_port = 0; + + return sock->ops->bind(sock, (struct sockaddr*)&sin, sizeof(sin)); +} + /* * Set up sending multicast socket over UDP */ @@ -376,7 +401,7 @@ return NULL; } - if (set_mcast_if(sock->sk, mcast_ifn) < 0) { + if (set_mcast_if(sock->sk, ip_vs_mcast_ifn) < 0) { IP_VS_ERR("Error setting outbound mcast interface\n"); return NULL; } @@ -384,6 +409,11 @@ set_mcast_loop(sock->sk, 0); set_mcast_ttl(sock->sk, 1); + if (bind_mcastif_addr(sock, ip_vs_mcast_ifn) < 0) { + IP_VS_ERR("Error binding address of the mcast interface\n"); + return NULL; + } + if (sock->ops->connect(sock, (struct sockaddr*)&mcast_addr, sizeof(struct sockaddr), 0) < 0) { @@ -421,7 +451,7 @@ /* join the multicast group */ if (join_mcast_group(sock->sk, (struct in_addr*)&mcast_addr.sin_addr, - mcast_ifn) < 0) { + ip_vs_mcast_ifn) < 0) { IP_VS_ERR("Error joining to the multicast group\n"); return NULL; } @@ -642,13 +672,13 @@ return 0; } -int start_sync_thread(struct ip_vs_rule_user *ur) +int start_sync_thread(int state, char *mcast_ifn) { if (sync_pid) return -EEXIST; - ip_vs_sync_state = ur->state; - strcpy(mcast_ifn, ur->mcast_ifn); + ip_vs_sync_state = state; + strcpy(ip_vs_mcast_ifn, mcast_ifn); sync_pid = kernel_thread(sync_thread, NULL, 0); if (sync_pid < 0) Index: ipvsadm/ipvsadm.c =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ipvsadm/ipvsadm.c,v retrieving revision 1.15 diff -u -r1.15 ipvsadm.c --- ipvsadm/ipvsadm.c 2001/10/19 15:05:17 1.15 +++ ipvsadm/ipvsadm.c 2001/10/21 13:07:38 @@ -125,12 +125,12 @@ #include "libipvs/libipvs.h" #define IPVSADM_VERSION_NO "v" VERSION -#define IPVSADM_VERSION_DATE "2001/09/18" +#define IPVSADM_VERSION_DATE "2001/10/19" #define IPVSADM_VERSION IPVSADM_VERSION_NO " " IPVSADM_VERSION_DATE #define MINIMUM_IPVS_VERSION_MAJOR 0 #define MINIMUM_IPVS_VERSION_MINOR 9 -#define MINIMUM_IPVS_VERSION_PATCH 4 +#define MINIMUM_IPVS_VERSION_PATCH 5 #ifndef IPVS_VERSION #define IPVS_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))