Merge pull request #17 from Tencent/ipvs-avoid-drop-first-packet-by-reusing-conntrack

ipvs: avoid drop first packet by reusing conntrack
This commit is contained in:
gxm-newtonf 2020-06-23 21:56:39 +08:00 committed by GitHub
commit f23f5f6fbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 2 deletions

View File

@ -43,6 +43,29 @@ conn_reuse_mode - INTEGER
balancer in Direct Routing mode. This bit helps on adding new
real servers to a very busy cluster.
conn_reuse_old_conntrack - BOOLEAN
- 0 - disabled
- not 0 - enabled (default)
If set, when a new TCP syn packet hit an old ipvs connection
table and need reschedule to a new dest: if
1) the packet use conntrack
2) the old ipvs connection table is not a master control
connection (E.g the command connection of passived FTP)
3) the old ipvs connection table been not controlled by any
connections (E.g the data connection of passived FTP)
ipvs Will not release the old conntrack, just let the conntrack
reopen the old session as it is a new one. This is an optimization
option selectable by the system administrator.
If not set, when a new TCP syn packet hit an old ipvs connection
table and need reschedule to a new dest: if
1) the packet use conntrack
ipvs just drop this syn packet, expire the old connection by timer.
This will cause the client tcp syn to retransmit.
Only has effect when conn_reuse_mode not 0.
conntrack - BOOLEAN
0 - disabled (default)
not 0 - enabled

View File

@ -951,6 +951,7 @@ struct netns_ipvs {
int sysctl_pmtu_disc;
int sysctl_backup_only;
int sysctl_conn_reuse_mode;
int sysctl_conn_reuse_old_conntrack;
int sysctl_schedule_icmp;
int sysctl_ignore_tunneled;
int sysctl_ignore_no_rs_error;
@ -1079,6 +1080,11 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
return ipvs->sysctl_conn_reuse_mode;
}
static inline int sysctl_conn_reuse_old_conntrack(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_conn_reuse_old_conntrack;
}
static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_schedule_icmp;
@ -1171,6 +1177,11 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
return 1;
}
static inline int sysctl_conn_reuse_old_conntrack(struct netns_ipvs *ipvs)
{
return 1;
}
static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
{
return 0;

View File

@ -2004,7 +2004,7 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
cp = NULL;
}
if (conn_reuse_mode && !iph.fragoffs && is_new_conn(skb, &iph) && cp) {
bool uses_ct = false, resched = false;
bool uses_ct = false, resched = false, drop = false;
if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest &&
unlikely(!atomic_read(&cp->dest->weight))) {
@ -2024,10 +2024,17 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
}
if (resched) {
if (uses_ct) {
if (likely(!atomic_read(&cp->n_control) && !cp->control) &&
likely(sysctl_conn_reuse_old_conntrack(ipvs)))
cp->flags &= ~IP_VS_CONN_F_NFCT;
else
drop = true;
}
if (!atomic_read(&cp->n_control))
ip_vs_conn_expire_now(cp);
__ip_vs_conn_put(cp);
if (uses_ct)
if (drop)
return NF_DROP;
cp = NULL;
}

View File

@ -3997,7 +3997,9 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
tbl[idx++].data = &ipvs->sysctl_pmtu_disc;
tbl[idx++].data = &ipvs->sysctl_backup_only;
ipvs->sysctl_conn_reuse_mode = 1;
ipvs->sysctl_conn_reuse_old_conntrack = 1;
tbl[idx++].data = &ipvs->sysctl_conn_reuse_mode;
tbl[idx++].data = &ipvs->sysctl_conn_reuse_old_conntrack;
tbl[idx++].data = &ipvs->sysctl_schedule_icmp;
tbl[idx++].data = &ipvs->sysctl_ignore_tunneled;
tbl[idx++].data = &ipvs->sysctl_ignore_no_rs_error;