aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/ipvs
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2012-04-24 16:46:38 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-05-08 13:38:31 -0400
commitcdcc5e905d59026fbf2e7f74f9cc834203b6207b (patch)
tree3f8c6440384a2d0e753d35f51e344269953a986a /net/netfilter/ipvs
parent882a844bd5b3ffa35e059f21ee920cc113985a89 (diff)
ipvs: always update some of the flags bits in backup
As the goal is to mirror the inactconns/activeconns counters in the backup server, make sure the cp->flags are updated even if cp is still not bound to dest. If cp->flags are not updated ip_vs_bind_dest will rely only on the initial flags when updating the counters. To avoid mistakes and complicated checks for protocol state rely only on the IP_VS_CONN_F_INACTIVE bit when updating the counters. Signed-off-by: Julian Anastasov <ja@ssi.bg> Tested-by: Aleksey Chudov <aleksey.chudov@gmail.com> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/netfilter/ipvs')
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c65
1 files changed, 23 insertions, 42 deletions
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index bf5e538af67..d2df694405f 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -731,9 +731,30 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
731 else 731 else
732 cp = ip_vs_ct_in_get(param); 732 cp = ip_vs_ct_in_get(param);
733 733
734 if (cp && param->pe_data) /* Free pe_data */ 734 if (cp) {
735 /* Free pe_data */
735 kfree(param->pe_data); 736 kfree(param->pe_data);
736 if (!cp) { 737
738 dest = cp->dest;
739 if ((cp->flags ^ flags) & IP_VS_CONN_F_INACTIVE &&
740 !(flags & IP_VS_CONN_F_TEMPLATE) && dest) {
741 if (flags & IP_VS_CONN_F_INACTIVE) {
742 atomic_dec(&dest->activeconns);
743 atomic_inc(&dest->inactconns);
744 } else {
745 atomic_inc(&dest->activeconns);
746 atomic_dec(&dest->inactconns);
747 }
748 }
749 flags &= IP_VS_CONN_F_BACKUP_UPD_MASK;
750 flags |= cp->flags & ~IP_VS_CONN_F_BACKUP_UPD_MASK;
751 cp->flags = flags;
752 if (!dest) {
753 dest = ip_vs_try_bind_dest(cp);
754 if (dest)
755 atomic_dec(&dest->refcnt);
756 }
757 } else {
737 /* 758 /*
738 * Find the appropriate destination for the connection. 759 * Find the appropriate destination for the connection.
739 * If it is not found the connection will remain unbound 760 * If it is not found the connection will remain unbound
@@ -742,18 +763,6 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
742 dest = ip_vs_find_dest(net, type, daddr, dport, param->vaddr, 763 dest = ip_vs_find_dest(net, type, daddr, dport, param->vaddr,
743 param->vport, protocol, fwmark, flags); 764 param->vport, protocol, fwmark, flags);
744 765
745 /* Set the approprite ativity flag */
746 if (protocol == IPPROTO_TCP) {
747 if (state != IP_VS_TCP_S_ESTABLISHED)
748 flags |= IP_VS_CONN_F_INACTIVE;
749 else
750 flags &= ~IP_VS_CONN_F_INACTIVE;
751 } else if (protocol == IPPROTO_SCTP) {
752 if (state != IP_VS_SCTP_S_ESTABLISHED)
753 flags |= IP_VS_CONN_F_INACTIVE;
754 else
755 flags &= ~IP_VS_CONN_F_INACTIVE;
756 }
757 cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark); 766 cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark);
758 if (dest) 767 if (dest)
759 atomic_dec(&dest->refcnt); 768 atomic_dec(&dest->refcnt);
@@ -763,34 +772,6 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
763 IP_VS_DBG(2, "BACKUP, add new conn. failed\n"); 772 IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
764 return; 773 return;
765 } 774 }
766 } else if (!cp->dest) {
767 dest = ip_vs_try_bind_dest(cp);
768 if (dest)
769 atomic_dec(&dest->refcnt);
770 } else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) &&
771 (cp->state != state)) {
772 /* update active/inactive flag for the connection */
773 dest = cp->dest;
774 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
775 (state != IP_VS_TCP_S_ESTABLISHED)) {
776 atomic_dec(&dest->activeconns);
777 atomic_inc(&dest->inactconns);
778 cp->flags |= IP_VS_CONN_F_INACTIVE;
779 } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
780 (state == IP_VS_TCP_S_ESTABLISHED)) {
781 atomic_inc(&dest->activeconns);
782 atomic_dec(&dest->inactconns);
783 cp->flags &= ~IP_VS_CONN_F_INACTIVE;
784 }
785 } else if ((cp->dest) && (cp->protocol == IPPROTO_SCTP) &&
786 (cp->state != state)) {
787 dest = cp->dest;
788 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
789 (state != IP_VS_SCTP_S_ESTABLISHED)) {
790 atomic_dec(&dest->activeconns);
791 atomic_inc(&dest->inactconns);
792 cp->flags &= ~IP_VS_CONN_F_INACTIVE;
793 }
794 } 775 }
795 776
796 if (opt) 777 if (opt)