ipvs: queue delayed work to expire no destination connections if expire_nodest_conn=1
When expire_nodest_conn=1 and a destination is deleted, IPVS does not expire the existing connections until the next matching incoming packet. If there are many connection entries from a single client to a single destination, many packets may get dropped before all the connections are expired (more likely with lots of UDP traffic). An optimization can be made where upon deletion of a destination, IPVS queues up delayed work to immediately expire any connections with a deleted destination. This ensures any reused source ports from a client (within the IPVS timeouts) are scheduled to new real servers instead of silently dropped. Signed-off-by: Andrew Sy Kim <kim.andrewsy@gmail.com> Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
committed by
Pablo Neira Ayuso
parent
336f531ab1
commit
35dfb01314
@@ -14,6 +14,7 @@
|
||||
#include <linux/spinlock.h> /* for struct rwlock_t */
|
||||
#include <linux/atomic.h> /* for struct atomic_t */
|
||||
#include <linux/refcount.h> /* for struct refcount_t */
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/timer.h>
|
||||
@@ -886,6 +887,8 @@ struct netns_ipvs {
|
||||
atomic_t conn_out_counter;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
/* delayed work for expiring no dest connections */
|
||||
struct delayed_work expire_nodest_conn_work;
|
||||
/* 1/rate drop and drop-entry variables */
|
||||
struct delayed_work defense_work; /* Work handler */
|
||||
int drop_rate;
|
||||
@@ -1051,6 +1054,11 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
|
||||
return ipvs->sysctl_conn_reuse_mode;
|
||||
}
|
||||
|
||||
static inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
|
||||
{
|
||||
return ipvs->sysctl_expire_nodest_conn;
|
||||
}
|
||||
|
||||
static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
|
||||
{
|
||||
return ipvs->sysctl_schedule_icmp;
|
||||
@@ -1138,6 +1146,11 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int sysctl_expire_nodest_conn(struct netns_ipvs *ipvs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
|
||||
{
|
||||
return 0;
|
||||
@@ -1507,6 +1520,22 @@ static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
|
||||
static inline int ip_vs_todrop(struct netns_ipvs *ipvs) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
/* Enqueue delayed work for expiring no dest connections
|
||||
* Only run when sysctl_expire_nodest=1
|
||||
*/
|
||||
static inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs)
|
||||
{
|
||||
if (sysctl_expire_nodest_conn(ipvs))
|
||||
queue_delayed_work(system_long_wq,
|
||||
&ipvs->expire_nodest_conn_work, 1);
|
||||
}
|
||||
|
||||
void ip_vs_expire_nodest_conn_flush(struct netns_ipvs *ipvs);
|
||||
#else
|
||||
static inline void ip_vs_enqueue_expire_nodest_conns(struct netns_ipvs *ipvs) {}
|
||||
#endif
|
||||
|
||||
#define IP_VS_DFWD_METHOD(dest) (atomic_read(&(dest)->conn_flags) & \
|
||||
IP_VS_CONN_F_FWD_MASK)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user