Skip to content

Commit

Permalink
[IPVS]: Create synced connections with their real state
Browse files Browse the repository at this point in the history
With this patch the synced connections are created with their real state,
which can be changed on the next synchronizations if necessary. This way
on fail-over all the connections will be treated according to their actual
state, causing no scheduling problems (the active and the nonactive
connections have different weights in the schedulers).
The backwards compatibility is preserved and the existing tools will show
the true connection states even on the backup director.

Signed-off-by: Rumen G. Bogdanovski <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
rbogdanovski authored and davem330 committed Jan 28, 2008
1 parent 7a4fbb1 commit b209639
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
16 changes: 14 additions & 2 deletions net/ipv4/ipvs/ip_vs_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,15 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
atomic_inc(&dest->refcnt);

/* Bind with the destination and its corresponding transmitter */
cp->flags |= atomic_read(&dest->conn_flags);
if ((cp->flags & IP_VS_CONN_F_SYNC) &&
(!(cp->flags & IP_VS_CONN_F_TEMPLATE)))
/* if the connection is not template and is created
* by sync, preserve the activity flag.
*/
cp->flags |= atomic_read(&dest->conn_flags) &
(~IP_VS_CONN_F_INACTIVE);
else
cp->flags |= atomic_read(&dest->conn_flags);
cp->dest = dest;

IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
Expand All @@ -412,7 +420,11 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
/* It is a normal connection, so increase the inactive
connection counter because it is in TCP SYNRECV
state (inactive) or other protocol inacive state */
atomic_inc(&dest->inactconns);
if ((cp->flags & IP_VS_CONN_F_SYNC) &&
(!(cp->flags & IP_VS_CONN_F_INACTIVE)))
atomic_inc(&dest->activeconns);
else
atomic_inc(&dest->inactconns);
} else {
/* It is a persistent connection/template, so increase
the peristent connection counter */
Expand Down
32 changes: 27 additions & 5 deletions net/ipv4/ipvs/ip_vs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) | 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,
Expand All @@ -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,
Expand All @@ -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) {
Expand All @@ -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];
Expand All @@ -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);
Expand Down

0 comments on commit b209639

Please sign in to comment.