Commit c95c0783 authored by yangxingwu's avatar yangxingwu Committed by Pablo Neira Ayuso

netfilter: ipvs: Fix reuse connection if RS weight is 0

We are changing expire_nodest_conn to work even for reused connections when
conn_reuse_mode=0, just as what was done with commit dc7b3eb9 ("ipvs:
Fix reuse connection if real server is dead").

For controlled and persistent connections, the new connection will get the
needed real server depending on the rules in ip_vs_check_template().

Fixes: d752c364 ("ipvs: allow rescheduling of new connections when port reuse is detected")
Co-developed-by: default avatarChuanqi Liu <legend050709@qq.com>
Signed-off-by: default avatarChuanqi Liu <legend050709@qq.com>
Signed-off-by: default avataryangxingwu <xingwu.yang@gmail.com>
Acked-by: default avatarSimon Horman <horms@verge.net.au>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 77522ff0
...@@ -37,8 +37,7 @@ conn_reuse_mode - INTEGER ...@@ -37,8 +37,7 @@ conn_reuse_mode - INTEGER
0: disable any special handling on port reuse. The new 0: disable any special handling on port reuse. The new
connection will be delivered to the same real server that was connection will be delivered to the same real server that was
servicing the previous connection. This will effectively servicing the previous connection.
disable expire_nodest_conn.
bit 1: enable rescheduling of new connections when it is safe. bit 1: enable rescheduling of new connections when it is safe.
That is, whenever expire_nodest_conn and for TCP sockets, when That is, whenever expire_nodest_conn and for TCP sockets, when
......
...@@ -1919,7 +1919,6 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state ...@@ -1919,7 +1919,6 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state
struct ip_vs_proto_data *pd; struct ip_vs_proto_data *pd;
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
int ret, pkts; int ret, pkts;
int conn_reuse_mode;
struct sock *sk; struct sock *sk;
int af = state->pf; int af = state->pf;
...@@ -1997,15 +1996,16 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state ...@@ -1997,15 +1996,16 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state
cp = INDIRECT_CALL_1(pp->conn_in_get, ip_vs_conn_in_get_proto, cp = INDIRECT_CALL_1(pp->conn_in_get, ip_vs_conn_in_get_proto,
ipvs, af, skb, &iph); ipvs, af, skb, &iph);
conn_reuse_mode = sysctl_conn_reuse_mode(ipvs); if (!iph.fragoffs && is_new_conn(skb, &iph) && cp) {
if (conn_reuse_mode && !iph.fragoffs && is_new_conn(skb, &iph) && cp) { int conn_reuse_mode = sysctl_conn_reuse_mode(ipvs);
bool old_ct = false, resched = false; bool old_ct = false, resched = false;
if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest && if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest &&
unlikely(!atomic_read(&cp->dest->weight))) { unlikely(!atomic_read(&cp->dest->weight))) {
resched = true; resched = true;
old_ct = ip_vs_conn_uses_old_conntrack(cp, skb); old_ct = ip_vs_conn_uses_old_conntrack(cp, skb);
} else if (is_new_conn_expected(cp, conn_reuse_mode)) { } else if (conn_reuse_mode &&
is_new_conn_expected(cp, conn_reuse_mode)) {
old_ct = ip_vs_conn_uses_old_conntrack(cp, skb); old_ct = ip_vs_conn_uses_old_conntrack(cp, skb);
if (!atomic_read(&cp->n_control)) { if (!atomic_read(&cp->n_control)) {
resched = true; resched = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment