]> err.no Git - linux-2.6/blobdiff - net/ipv4/ipvs/ip_vs_sync.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-2.6] / net / ipv4 / ipvs / ip_vs_sync.c
index bd930efc18dabb27e0058adc97d20900b02a4ef2..69c56663cc9a90645cdcfab47495261f01e70e99 100644 (file)
@@ -305,10 +305,11 @@ 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; i<m->nr_conns; i++) {
-               unsigned flags;
+               unsigned flags, state;
 
                s = (struct ip_vs_sync_conn *)p;
-               flags = ntohs(s->flags);
+               flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
+               state = ntohs(s->state);
                if (!(flags & IP_VS_CONN_F_TEMPLATE))
                        cp = ip_vs_conn_in_get(s->protocol,
                                               s->caddr, s->cport,
@@ -326,6 +327,13 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                        dest = ip_vs_find_dest(s->daddr, s->dport,
                                               s->vaddr, s->vport,
                                               s->protocol);
+                       /*  Set the approprite ativity flag */
+                       if (s->protocol == IPPROTO_TCP) {
+                               if (state != IP_VS_TCP_S_ESTABLISHED)
+                                       flags |= IP_VS_CONN_F_INACTIVE;
+                               else
+                                       flags &= ~IP_VS_CONN_F_INACTIVE;
+                       }
                        cp = ip_vs_conn_new(s->protocol,
                                            s->caddr, s->cport,
                                            s->vaddr, s->vport,
@@ -337,7 +345,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                                IP_VS_ERR("ip_vs_conn_new failed\n");
                                return;
                        }
-                       cp->state = ntohs(s->state);
+                       cp->state = state;
                } else if (!cp->dest) {
                        dest = ip_vs_try_bind_dest(cp);
                        if (!dest) {
@@ -346,8 +354,22 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                                cp->flags = flags | IP_VS_CONN_F_HASHED;
                        } else
                                atomic_dec(&dest->refcnt);
-               }       /* Note that we don't touch its state and flags
-                          if it is a normal entry. */
+               } else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) &&
+                          (cp->state != state)) {
+                       /* update active/inactive flag for the connection */
+                       dest = cp->dest;
+                       if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
+                               (state != IP_VS_TCP_S_ESTABLISHED)) {
+                               atomic_dec(&dest->activeconns);
+                               atomic_inc(&dest->inactconns);
+                               cp->flags |= IP_VS_CONN_F_INACTIVE;
+                       } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
+                               (state == IP_VS_TCP_S_ESTABLISHED)) {
+                               atomic_inc(&dest->activeconns);
+                               atomic_dec(&dest->inactconns);
+                               cp->flags &= ~IP_VS_CONN_F_INACTIVE;
+                       }
+               }
 
                if (flags & IP_VS_CONN_F_SEQ_MASK) {
                        opt = (struct ip_vs_sync_conn_options *)&s[1];
@@ -357,7 +379,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                        p += SIMPLE_CONN_SIZE;
 
                atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
-               cp->state = ntohs(s->state);
+               cp->state = state;
                pp = ip_vs_proto_get(s->protocol);
                cp->timeout = pp->timeout_table[cp->state];
                ip_vs_conn_put(cp);
@@ -894,7 +916,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
        if (!tinfo)
                return -ENOMEM;
 
-       IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
+       IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current));
        IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n",
                  sizeof(struct ip_vs_sync_conn));
 
@@ -934,7 +956,7 @@ int stop_sync_thread(int state)
            (state == IP_VS_STATE_BACKUP && !sync_backup_pid))
                return -ESRCH;
 
-       IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
+       IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current));
        IP_VS_INFO("stopping sync thread %d ...\n",
                   (state == IP_VS_STATE_MASTER) ?
                   sync_master_pid : sync_backup_pid);