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>
This commit is contained in:
parent
882a844bd5
commit
cdcc5e905d
|
@ -89,6 +89,7 @@
|
||||||
#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */
|
#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */
|
||||||
#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */
|
#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */
|
||||||
|
|
||||||
|
/* Initial bits allowed in backup server */
|
||||||
#define IP_VS_CONN_F_BACKUP_MASK (IP_VS_CONN_F_FWD_MASK | \
|
#define IP_VS_CONN_F_BACKUP_MASK (IP_VS_CONN_F_FWD_MASK | \
|
||||||
IP_VS_CONN_F_NOOUTPUT | \
|
IP_VS_CONN_F_NOOUTPUT | \
|
||||||
IP_VS_CONN_F_INACTIVE | \
|
IP_VS_CONN_F_INACTIVE | \
|
||||||
|
@ -97,6 +98,10 @@
|
||||||
IP_VS_CONN_F_TEMPLATE \
|
IP_VS_CONN_F_TEMPLATE \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* Bits allowed to update in backup server */
|
||||||
|
#define IP_VS_CONN_F_BACKUP_UPD_MASK (IP_VS_CONN_F_INACTIVE | \
|
||||||
|
IP_VS_CONN_F_SEQ_MASK)
|
||||||
|
|
||||||
/* Flags that are not sent to backup server start from bit 16 */
|
/* Flags that are not sent to backup server start from bit 16 */
|
||||||
#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */
|
#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */
|
||||||
|
|
||||||
|
|
|
@ -731,9 +731,30 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
|
||||||
else
|
else
|
||||||
cp = ip_vs_ct_in_get(param);
|
cp = ip_vs_ct_in_get(param);
|
||||||
|
|
||||||
if (cp && param->pe_data) /* Free pe_data */
|
if (cp) {
|
||||||
|
/* Free pe_data */
|
||||||
kfree(param->pe_data);
|
kfree(param->pe_data);
|
||||||
if (!cp) {
|
|
||||||
|
dest = cp->dest;
|
||||||
|
if ((cp->flags ^ flags) & IP_VS_CONN_F_INACTIVE &&
|
||||||
|
!(flags & IP_VS_CONN_F_TEMPLATE) && dest) {
|
||||||
|
if (flags & IP_VS_CONN_F_INACTIVE) {
|
||||||
|
atomic_dec(&dest->activeconns);
|
||||||
|
atomic_inc(&dest->inactconns);
|
||||||
|
} else {
|
||||||
|
atomic_inc(&dest->activeconns);
|
||||||
|
atomic_dec(&dest->inactconns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flags &= IP_VS_CONN_F_BACKUP_UPD_MASK;
|
||||||
|
flags |= cp->flags & ~IP_VS_CONN_F_BACKUP_UPD_MASK;
|
||||||
|
cp->flags = flags;
|
||||||
|
if (!dest) {
|
||||||
|
dest = ip_vs_try_bind_dest(cp);
|
||||||
|
if (dest)
|
||||||
|
atomic_dec(&dest->refcnt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* Find the appropriate destination for the connection.
|
* Find the appropriate destination for the connection.
|
||||||
* If it is not found the connection will remain unbound
|
* 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,
|
||||||
dest = ip_vs_find_dest(net, type, daddr, dport, param->vaddr,
|
dest = ip_vs_find_dest(net, type, daddr, dport, param->vaddr,
|
||||||
param->vport, protocol, fwmark, flags);
|
param->vport, protocol, fwmark, flags);
|
||||||
|
|
||||||
/* Set the approprite ativity flag */
|
|
||||||
if (protocol == IPPROTO_TCP) {
|
|
||||||
if (state != IP_VS_TCP_S_ESTABLISHED)
|
|
||||||
flags |= IP_VS_CONN_F_INACTIVE;
|
|
||||||
else
|
|
||||||
flags &= ~IP_VS_CONN_F_INACTIVE;
|
|
||||||
} else if (protocol == IPPROTO_SCTP) {
|
|
||||||
if (state != IP_VS_SCTP_S_ESTABLISHED)
|
|
||||||
flags |= IP_VS_CONN_F_INACTIVE;
|
|
||||||
else
|
|
||||||
flags &= ~IP_VS_CONN_F_INACTIVE;
|
|
||||||
}
|
|
||||||
cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark);
|
cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark);
|
||||||
if (dest)
|
if (dest)
|
||||||
atomic_dec(&dest->refcnt);
|
atomic_dec(&dest->refcnt);
|
||||||
|
@ -763,34 +772,6 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
|
||||||
IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
|
IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (!cp->dest) {
|
|
||||||
dest = ip_vs_try_bind_dest(cp);
|
|
||||||
if (dest)
|
|
||||||
atomic_dec(&dest->refcnt);
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
} else if ((cp->dest) && (cp->protocol == IPPROTO_SCTP) &&
|
|
||||||
(cp->state != state)) {
|
|
||||||
dest = cp->dest;
|
|
||||||
if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
|
|
||||||
(state != IP_VS_SCTP_S_ESTABLISHED)) {
|
|
||||||
atomic_dec(&dest->activeconns);
|
|
||||||
atomic_inc(&dest->inactconns);
|
|
||||||
cp->flags &= ~IP_VS_CONN_F_INACTIVE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt)
|
if (opt)
|
||||||
|
|
Loading…
Reference in a new issue