|
@@ -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);
|
|
p = (char *)buffer + sizeof(struct ip_vs_sync_mesg);
|
|
for (i=0; i<m->nr_conns; i++) {
|
|
for (i=0; i<m->nr_conns; i++) {
|
|
- unsigned flags;
|
|
|
|
|
|
+ unsigned flags, state;
|
|
|
|
|
|
s = (struct ip_vs_sync_conn *)p;
|
|
s = (struct ip_vs_sync_conn *)p;
|
|
flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
|
|
flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
|
|
|
|
+ state = ntohs(s->state);
|
|
if (!(flags & IP_VS_CONN_F_TEMPLATE))
|
|
if (!(flags & IP_VS_CONN_F_TEMPLATE))
|
|
cp = ip_vs_conn_in_get(s->protocol,
|
|
cp = ip_vs_conn_in_get(s->protocol,
|
|
s->caddr, s->cport,
|
|
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,
|
|
dest = ip_vs_find_dest(s->daddr, s->dport,
|
|
s->vaddr, s->vport,
|
|
s->vaddr, s->vport,
|
|
s->protocol);
|
|
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,
|
|
cp = ip_vs_conn_new(s->protocol,
|
|
s->caddr, s->cport,
|
|
s->caddr, s->cport,
|
|
s->vaddr, s->vport,
|
|
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");
|
|
IP_VS_ERR("ip_vs_conn_new failed\n");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- cp->state = ntohs(s->state);
|
|
|
|
|
|
+ cp->state = state;
|
|
} else if (!cp->dest) {
|
|
} else if (!cp->dest) {
|
|
dest = ip_vs_try_bind_dest(cp);
|
|
dest = ip_vs_try_bind_dest(cp);
|
|
if (!dest) {
|
|
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;
|
|
cp->flags = flags | IP_VS_CONN_F_HASHED;
|
|
} else
|
|
} else
|
|
atomic_dec(&dest->refcnt);
|
|
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) {
|
|
if (flags & IP_VS_CONN_F_SEQ_MASK) {
|
|
opt = (struct ip_vs_sync_conn_options *)&s[1];
|
|
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;
|
|
p += SIMPLE_CONN_SIZE;
|
|
|
|
|
|
atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
|
|
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);
|
|
pp = ip_vs_proto_get(s->protocol);
|
|
cp->timeout = pp->timeout_table[cp->state];
|
|
cp->timeout = pp->timeout_table[cp->state];
|
|
ip_vs_conn_put(cp);
|
|
ip_vs_conn_put(cp);
|