aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c16
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c32
2 files changed, 41 insertions, 7 deletions
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 45a642edb93b..65f1ba112752 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -393,7 +393,15 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
393 atomic_inc(&dest->refcnt); 393 atomic_inc(&dest->refcnt);
394 394
395 /* Bind with the destination and its corresponding transmitter */ 395 /* Bind with the destination and its corresponding transmitter */
396 cp->flags |= atomic_read(&dest->conn_flags); 396 if ((cp->flags & IP_VS_CONN_F_SYNC) &&
397 (!(cp->flags & IP_VS_CONN_F_TEMPLATE)))
398 /* if the connection is not template and is created
399 * by sync, preserve the activity flag.
400 */
401 cp->flags |= atomic_read(&dest->conn_flags) &
402 (~IP_VS_CONN_F_INACTIVE);
403 else
404 cp->flags |= atomic_read(&dest->conn_flags);
397 cp->dest = dest; 405 cp->dest = dest;
398 406
399 IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " 407 IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
@@ -412,7 +420,11 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
412 /* It is a normal connection, so increase the inactive 420 /* It is a normal connection, so increase the inactive
413 connection counter because it is in TCP SYNRECV 421 connection counter because it is in TCP SYNRECV
414 state (inactive) or other protocol inacive state */ 422 state (inactive) or other protocol inacive state */
415 atomic_inc(&dest->inactconns); 423 if ((cp->flags & IP_VS_CONN_F_SYNC) &&
424 (!(cp->flags & IP_VS_CONN_F_INACTIVE)))
425 atomic_inc(&dest->activeconns);
426 else
427 atomic_inc(&dest->inactconns);
416 } else { 428 } else {
417 /* It is a persistent connection/template, so increase 429 /* It is a persistent connection/template, so increase
418 the peristent connection counter */ 430 the peristent connection counter */
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 47b7f8f3ae79..948378d0a755 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -305,10 +305,11 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
305 305
306 p = (char *)buffer + sizeof(struct ip_vs_sync_mesg); 306 p = (char *)buffer + sizeof(struct ip_vs_sync_mesg);
307 for (i=0; i<m->nr_conns; i++) { 307 for (i=0; i<m->nr_conns; i++) {
308 unsigned flags; 308 unsigned flags, state;
309 309
310 s = (struct ip_vs_sync_conn *)p; 310 s = (struct ip_vs_sync_conn *)p;
311 flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC; 311 flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
312 state = ntohs(s->state);
312 if (!(flags & IP_VS_CONN_F_TEMPLATE)) 313 if (!(flags & IP_VS_CONN_F_TEMPLATE))
313 cp = ip_vs_conn_in_get(s->protocol, 314 cp = ip_vs_conn_in_get(s->protocol,
314 s->caddr, s->cport, 315 s->caddr, s->cport,
@@ -326,6 +327,13 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
326 dest = ip_vs_find_dest(s->daddr, s->dport, 327 dest = ip_vs_find_dest(s->daddr, s->dport,
327 s->vaddr, s->vport, 328 s->vaddr, s->vport,
328 s->protocol); 329 s->protocol);
330 /* Set the approprite ativity flag */
331 if (s->protocol == IPPROTO_TCP) {
332 if (state != IP_VS_TCP_S_ESTABLISHED)
333 flags |= IP_VS_CONN_F_INACTIVE;
334 else
335 flags &= ~IP_VS_CONN_F_INACTIVE;
336 }
329 cp = ip_vs_conn_new(s->protocol, 337 cp = ip_vs_conn_new(s->protocol,
330 s->caddr, s->cport, 338 s->caddr, s->cport,
331 s->vaddr, s->vport, 339 s->vaddr, s->vport,
@@ -337,7 +345,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
337 IP_VS_ERR("ip_vs_conn_new failed\n"); 345 IP_VS_ERR("ip_vs_conn_new failed\n");
338 return; 346 return;
339 } 347 }
340 cp->state = ntohs(s->state); 348 cp->state = state;
341 } else if (!cp->dest) { 349 } else if (!cp->dest) {
342 dest = ip_vs_try_bind_dest(cp); 350 dest = ip_vs_try_bind_dest(cp);
343 if (!dest) { 351 if (!dest) {
@@ -346,8 +354,22 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
346 cp->flags = flags | IP_VS_CONN_F_HASHED; 354 cp->flags = flags | IP_VS_CONN_F_HASHED;
347 } else 355 } else
348 atomic_dec(&dest->refcnt); 356 atomic_dec(&dest->refcnt);
349 } /* Note that we don't touch its state and flags 357 } else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) &&
350 if it is a normal entry. */ 358 (cp->state != state)) {
359 /* update active/inactive flag for the connection */
360 dest = cp->dest;
361 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
362 (state != IP_VS_TCP_S_ESTABLISHED)) {
363 atomic_dec(&dest->activeconns);
364 atomic_inc(&dest->inactconns);
365 cp->flags |= IP_VS_CONN_F_INACTIVE;
366 } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
367 (state == IP_VS_TCP_S_ESTABLISHED)) {
368 atomic_inc(&dest->activeconns);
369 atomic_dec(&dest->inactconns);
370 cp->flags &= ~IP_VS_CONN_F_INACTIVE;
371 }
372 }
351 373
352 if (flags & IP_VS_CONN_F_SEQ_MASK) { 374 if (flags & IP_VS_CONN_F_SEQ_MASK) {
353 opt = (struct ip_vs_sync_conn_options *)&s[1]; 375 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)
357 p += SIMPLE_CONN_SIZE; 379 p += SIMPLE_CONN_SIZE;
358 380
359 atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]); 381 atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
360 cp->state = ntohs(s->state); 382 cp->state = state;
361 pp = ip_vs_proto_get(s->protocol); 383 pp = ip_vs_proto_get(s->protocol);
362 cp->timeout = pp->timeout_table[cp->state]; 384 cp->timeout = pp->timeout_table[cp->state];
363 ip_vs_conn_put(cp); 385 ip_vs_conn_put(cp);