|
@@ -1757,15 +1757,34 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
|
|
cp = pp->conn_in_get(ipvs, af, skb, &iph);
|
|
cp = pp->conn_in_get(ipvs, af, skb, &iph);
|
|
|
|
|
|
conn_reuse_mode = sysctl_conn_reuse_mode(ipvs);
|
|
conn_reuse_mode = sysctl_conn_reuse_mode(ipvs);
|
|
- if (conn_reuse_mode && !iph.fragoffs &&
|
|
|
|
- is_new_conn(skb, &iph) && cp &&
|
|
|
|
- ((unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest &&
|
|
|
|
- unlikely(!atomic_read(&cp->dest->weight))) ||
|
|
|
|
- unlikely(is_new_conn_expected(cp, conn_reuse_mode)))) {
|
|
|
|
- if (!atomic_read(&cp->n_control))
|
|
|
|
- ip_vs_conn_expire_now(cp);
|
|
|
|
- __ip_vs_conn_put(cp);
|
|
|
|
- cp = NULL;
|
|
|
|
|
|
+ if (conn_reuse_mode && !iph.fragoffs && is_new_conn(skb, &iph) && cp) {
|
|
|
|
+ bool uses_ct = false, resched = false;
|
|
|
|
+
|
|
|
|
+ if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp->dest &&
|
|
|
|
+ unlikely(!atomic_read(&cp->dest->weight))) {
|
|
|
|
+ resched = true;
|
|
|
|
+ uses_ct = ip_vs_conn_uses_conntrack(cp, skb);
|
|
|
|
+ } else if (is_new_conn_expected(cp, conn_reuse_mode)) {
|
|
|
|
+ uses_ct = ip_vs_conn_uses_conntrack(cp, skb);
|
|
|
|
+ if (!atomic_read(&cp->n_control)) {
|
|
|
|
+ resched = true;
|
|
|
|
+ } else {
|
|
|
|
+ /* Do not reschedule controlling connection
|
|
|
|
+ * that uses conntrack while it is still
|
|
|
|
+ * referenced by controlled connection(s).
|
|
|
|
+ */
|
|
|
|
+ resched = !uses_ct;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (resched) {
|
|
|
|
+ if (!atomic_read(&cp->n_control))
|
|
|
|
+ ip_vs_conn_expire_now(cp);
|
|
|
|
+ __ip_vs_conn_put(cp);
|
|
|
|
+ if (uses_ct)
|
|
|
|
+ return NF_DROP;
|
|
|
|
+ cp = NULL;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (unlikely(!cp)) {
|
|
if (unlikely(!cp)) {
|