diff options
author | Julian Anastasov <ja@ssi.bg> | 2012-04-24 16:46:38 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-05-08 13:38:31 -0400 |
commit | cdcc5e905d59026fbf2e7f74f9cc834203b6207b (patch) | |
tree | 3f8c6440384a2d0e753d35f51e344269953a986a /net/netfilter/ipvs | |
parent | 882a844bd5b3ffa35e059f21ee920cc113985a89 (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.c | 65 |
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) |