X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fipvs%2Fip_vs_sync.c;h=1bca714bda3d63c244afea44b39a9d26bb0814a9;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=80fdab71e20cf45668fee59659dc50d1018a2888;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c index 80fdab71e..1bca714bd 100644 --- a/net/ipv4/ipvs/ip_vs_sync.c +++ b/net/ipv4/ipvs/ip_vs_sync.c @@ -16,16 +16,19 @@ * Alexandre Cassen : Added master & backup support at a time. * Alexandre Cassen : Added SyncID support for incoming sync * messages filtering. + * Justin Ossevoort : Fix endian problem on sync message size. */ #include #include +#include #include #include - +#include #include #include #include /* for ip_mc_join_group */ +#include #include #include @@ -118,11 +121,11 @@ struct ip_vs_sync_buff { /* the sync_buff list head and the lock */ static LIST_HEAD(ip_vs_sync_queue); -static spinlock_t ip_vs_sync_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(ip_vs_sync_lock); /* current sync_buff for accepting new conn entries */ static struct ip_vs_sync_buff *curr_sb = NULL; -static spinlock_t curr_sb_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(curr_sb_lock); /* ipvs sync daemon state */ volatile int ip_vs_sync_state = IP_VS_STATE_NONE; @@ -279,6 +282,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) char *p; int i; + /* Convert size back to host byte order */ + m->size = ntohs(m->size); + if (buflen != m->size) { IP_VS_ERR("bogus message\n"); return; @@ -293,16 +299,24 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) p = (char *)buffer + sizeof(struct ip_vs_sync_mesg); for (i=0; inr_conns; i++) { + unsigned flags; + s = (struct ip_vs_sync_conn *)p; - cp = ip_vs_conn_in_get(s->protocol, - s->caddr, s->cport, - s->vaddr, s->vport); + flags = ntohs(s->flags); + if (!(flags & IP_VS_CONN_F_TEMPLATE)) + cp = ip_vs_conn_in_get(s->protocol, + s->caddr, s->cport, + s->vaddr, s->vport); + else + cp = ip_vs_ct_in_get(s->protocol, + s->caddr, s->cport, + s->vaddr, s->vport); if (!cp) { cp = ip_vs_conn_new(s->protocol, s->caddr, s->cport, s->vaddr, s->vport, s->daddr, s->dport, - ntohs(s->flags), NULL); + flags, NULL); if (!cp) { IP_VS_ERR("ip_vs_conn_new failed\n"); return; @@ -311,11 +325,11 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) } else if (!cp->dest) { /* it is an entry created by the synchronization */ cp->state = ntohs(s->state); - cp->flags = ntohs(s->flags) | IP_VS_CONN_F_HASHED; + cp->flags = flags | IP_VS_CONN_F_HASHED; } /* Note that we don't touch its state and flags if it is a normal entry. */ - if (ntohs(s->flags) & IP_VS_CONN_F_SEQ_MASK) { + if (flags & IP_VS_CONN_F_SEQ_MASK) { opt = (struct ip_vs_sync_conn_options *)&s[1]; memcpy(&cp->in_seq, opt, sizeof(*opt)); p += FULL_CONN_SIZE; @@ -339,7 +353,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) */ static void set_mcast_loop(struct sock *sk, u_char loop) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); /* setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)); */ lock_sock(sk); @@ -352,7 +366,7 @@ static void set_mcast_loop(struct sock *sk, u_char loop) */ static void set_mcast_ttl(struct sock *sk, u_char ttl) { - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); /* setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); */ lock_sock(sk); @@ -366,7 +380,7 @@ static void set_mcast_ttl(struct sock *sk, u_char ttl) static int set_mcast_if(struct sock *sk, char *ifname) { struct net_device *dev; - struct inet_opt *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); if ((dev = __dev_get_by_name(ifname)) == NULL) return -ENODEV; @@ -569,6 +583,19 @@ ip_vs_send_async(struct socket *sock, const char *buffer, const size_t length) return len; } +static void +ip_vs_send_sync_msg(struct socket *sock, struct ip_vs_sync_mesg *msg) +{ + int msize; + + msize = msg->size; + + /* Put size in network byte order */ + msg->size = htons(msg->size); + + if (ip_vs_send_async(sock, (char *)msg, msize) != msize) + IP_VS_ERR("ip_vs_send_async error\n"); +} static int ip_vs_receive(struct socket *sock, char *buffer, const size_t buflen) @@ -605,7 +632,6 @@ static void sync_master_loop(void) { struct socket *sock; struct ip_vs_sync_buff *sb; - struct ip_vs_sync_mesg *m; /* create the sending multicast socket */ sock = make_send_sock(); @@ -618,27 +644,20 @@ static void sync_master_loop(void) for (;;) { while ((sb=sb_dequeue())) { - m = sb->mesg; - if (ip_vs_send_async(sock, (char *)m, - m->size) != m->size) - IP_VS_ERR("ip_vs_send_async error\n"); + ip_vs_send_sync_msg(sock, sb->mesg); ip_vs_sync_buff_release(sb); } /* check if entries stay in curr_sb for 2 seconds */ if ((sb = get_curr_sync_buff(2*HZ))) { - m = sb->mesg; - if (ip_vs_send_async(sock, (char *)m, - m->size) != m->size) - IP_VS_ERR("ip_vs_send_async error\n"); + ip_vs_send_sync_msg(sock, sb->mesg); ip_vs_sync_buff_release(sb); } if (stop_master_sync) break; - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); + ssleep(1); } /* clean up the sync_buff queue */ @@ -695,8 +714,7 @@ static void sync_backup_loop(void) if (stop_backup_sync) break; - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); + ssleep(1); } /* release the sending multicast socket */ @@ -808,8 +826,7 @@ static int fork_sync_thread(void *startup) if ((pid = kernel_thread(sync_thread, startup, 0)) < 0) { IP_VS_ERR("could not create sync_thread due to %d... " "retrying.\n", pid); - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); + ssleep(1); goto repeat; } @@ -832,10 +849,10 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) ip_vs_sync_state |= state; if (state == IP_VS_STATE_MASTER) { - strcpy(ip_vs_master_mcast_ifn, mcast_ifn); + strlcpy(ip_vs_master_mcast_ifn, mcast_ifn, sizeof(ip_vs_master_mcast_ifn)); ip_vs_master_syncid = syncid; } else { - strcpy(ip_vs_backup_mcast_ifn, mcast_ifn); + strlcpy(ip_vs_backup_mcast_ifn, mcast_ifn, sizeof(ip_vs_backup_mcast_ifn)); ip_vs_backup_syncid = syncid; } @@ -843,8 +860,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) { IP_VS_ERR("could not create fork_sync_thread due to %d... " "retrying.\n", pid); - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); + ssleep(1); goto repeat; }