Skip to content

Commit cdcc5e9

Browse files
Julian Anastasovummakynes
authored andcommitted
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 <[email protected]> Tested-by: Aleksey Chudov <[email protected]> Signed-off-by: Simon Horman <[email protected]>
1 parent 882a844 commit cdcc5e9

File tree

2 files changed

+28
-42
lines changed

2 files changed

+28
-42
lines changed

include/linux/ip_vs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */
9090
#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */
9191

92+
/* Initial bits allowed in backup server */
9293
#define IP_VS_CONN_F_BACKUP_MASK (IP_VS_CONN_F_FWD_MASK | \
9394
IP_VS_CONN_F_NOOUTPUT | \
9495
IP_VS_CONN_F_INACTIVE | \
@@ -97,6 +98,10 @@
9798
IP_VS_CONN_F_TEMPLATE \
9899
)
99100

101+
/* Bits allowed to update in backup server */
102+
#define IP_VS_CONN_F_BACKUP_UPD_MASK (IP_VS_CONN_F_INACTIVE | \
103+
IP_VS_CONN_F_SEQ_MASK)
104+
100105
/* Flags that are not sent to backup server start from bit 16 */
101106
#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */
102107

net/netfilter/ipvs/ip_vs_sync.c

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -731,9 +731,30 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
731731
else
732732
cp = ip_vs_ct_in_get(param);
733733

734-
if (cp && param->pe_data) /* Free pe_data */
734+
if (cp) {
735+
/* Free pe_data */
735736
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 {
737758
/*
738759
* Find the appropriate destination for the connection.
739760
* 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,
742763
dest = ip_vs_find_dest(net, type, daddr, dport, param->vaddr,
743764
param->vport, protocol, fwmark, flags);
744765

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-
}
757766
cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark);
758767
if (dest)
759768
atomic_dec(&dest->refcnt);
@@ -763,34 +772,6 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
763772
IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
764773
return;
765774
}
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-
}
794775
}
795776

796777
if (opt)

0 commit comments

Comments
 (0)