Commit f6340ee0 authored by Hans Schillstrom's avatar Hans Schillstrom Committed by Simon Horman

IPVS: netns, defense work timer.

This patch makes defense work timer per name-space,
A net ptr had to be added to the ipvs struct,
since it's needed by defense_work_handler.

[ horms@verge.net.au: Use cancel_delayed_work_sync() instead of
	              cancel_rearming_delayed_work(). Found during
		      merge conflict resoliution ]
Signed-off-by: default avatarHans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent a0840e2e
...@@ -877,7 +877,7 @@ extern const char * ip_vs_state_name(__u16 proto, int state); ...@@ -877,7 +877,7 @@ extern const char * ip_vs_state_name(__u16 proto, int state);
extern void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp); extern void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp);
extern int ip_vs_check_template(struct ip_vs_conn *ct); extern int ip_vs_check_template(struct ip_vs_conn *ct);
extern void ip_vs_random_dropentry(void); extern void ip_vs_random_dropentry(struct net *net);
extern int ip_vs_conn_init(void); extern int ip_vs_conn_init(void);
extern void ip_vs_conn_cleanup(void); extern void ip_vs_conn_cleanup(void);
......
...@@ -71,6 +71,7 @@ struct netns_ipvs { ...@@ -71,6 +71,7 @@ struct netns_ipvs {
int num_services; /* no of virtual services */ int num_services; /* no of virtual services */
/* 1/rate drop and drop-entry variables */ /* 1/rate drop and drop-entry variables */
struct delayed_work defense_work; /* Work handler */
int drop_rate; int drop_rate;
int drop_counter; int drop_counter;
atomic_t dropentry; atomic_t dropentry;
...@@ -129,6 +130,8 @@ struct netns_ipvs { ...@@ -129,6 +130,8 @@ struct netns_ipvs {
/* multicast interface name */ /* multicast interface name */
char master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; char master_mcast_ifn[IP_VS_IFNAME_MAXLEN];
char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
/* net name space ptr */
struct net *net; /* Needed by timer routines */
}; };
#endif /* IP_VS_H_ */ #endif /* IP_VS_H_ */
...@@ -1138,7 +1138,7 @@ static inline int todrop_entry(struct ip_vs_conn *cp) ...@@ -1138,7 +1138,7 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
} }
/* Called from keventd and must protect itself from softirqs */ /* Called from keventd and must protect itself from softirqs */
void ip_vs_random_dropentry(void) void ip_vs_random_dropentry(struct net *net)
{ {
int idx; int idx;
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
...@@ -1158,7 +1158,8 @@ void ip_vs_random_dropentry(void) ...@@ -1158,7 +1158,8 @@ void ip_vs_random_dropentry(void)
if (cp->flags & IP_VS_CONN_F_TEMPLATE) if (cp->flags & IP_VS_CONN_F_TEMPLATE)
/* connection template */ /* connection template */
continue; continue;
if (!ip_vs_conn_net_eq(cp, net))
continue;
if (cp->protocol == IPPROTO_TCP) { if (cp->protocol == IPPROTO_TCP) {
switch(cp->state) { switch(cp->state) {
case IP_VS_TCP_S_SYN_RECV: case IP_VS_TCP_S_SYN_RECV:
......
...@@ -1884,6 +1884,7 @@ static int __net_init __ip_vs_init(struct net *net) ...@@ -1884,6 +1884,7 @@ static int __net_init __ip_vs_init(struct net *net)
pr_err("%s(): no memory.\n", __func__); pr_err("%s(): no memory.\n", __func__);
return -ENOMEM; return -ENOMEM;
} }
ipvs->net = net;
/* Counters used for creating unique names */ /* Counters used for creating unique names */
ipvs->gen = atomic_read(&ipvs_netns_cnt); ipvs->gen = atomic_read(&ipvs_netns_cnt);
atomic_inc(&ipvs_netns_cnt); atomic_inc(&ipvs_netns_cnt);
......
...@@ -217,18 +217,16 @@ static void update_defense_level(struct netns_ipvs *ipvs) ...@@ -217,18 +217,16 @@ static void update_defense_level(struct netns_ipvs *ipvs)
* Timer for checking the defense * Timer for checking the defense
*/ */
#define DEFENSE_TIMER_PERIOD 1*HZ #define DEFENSE_TIMER_PERIOD 1*HZ
static void defense_work_handler(struct work_struct *work);
static DECLARE_DELAYED_WORK(defense_work, defense_work_handler);
static void defense_work_handler(struct work_struct *work) static void defense_work_handler(struct work_struct *work)
{ {
struct netns_ipvs *ipvs = net_ipvs(&init_net); struct netns_ipvs *ipvs =
container_of(work, struct netns_ipvs, defense_work.work);
update_defense_level(ipvs); update_defense_level(ipvs);
if (atomic_read(&ipvs->dropentry)) if (atomic_read(&ipvs->dropentry))
ip_vs_random_dropentry(); ip_vs_random_dropentry(ipvs->net);
schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD);
schedule_delayed_work(&defense_work, DEFENSE_TIMER_PERIOD);
} }
int int
...@@ -3564,6 +3562,9 @@ int __net_init __ip_vs_control_init(struct net *net) ...@@ -3564,6 +3562,9 @@ int __net_init __ip_vs_control_init(struct net *net)
goto err_reg; goto err_reg;
ip_vs_new_estimator(net, ipvs->tot_stats); ip_vs_new_estimator(net, ipvs->tot_stats);
ipvs->sysctl_tbl = tbl; ipvs->sysctl_tbl = tbl;
/* Schedule defense work */
INIT_DELAYED_WORK(&ipvs->defense_work, defense_work_handler);
schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD);
return 0; return 0;
err_reg: err_reg:
...@@ -3588,6 +3589,8 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net) ...@@ -3588,6 +3589,8 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net)
proc_net_remove(net, "ip_vs_stats_percpu"); proc_net_remove(net, "ip_vs_stats_percpu");
proc_net_remove(net, "ip_vs_stats"); proc_net_remove(net, "ip_vs_stats");
proc_net_remove(net, "ip_vs"); proc_net_remove(net, "ip_vs");
cancel_delayed_work_sync(&ipvs->defense_work);
cancel_work_sync(&ipvs->defense_work.work);
free_percpu(ipvs->cpustats); free_percpu(ipvs->cpustats);
kfree(ipvs->tot_stats); kfree(ipvs->tot_stats);
} }
...@@ -3631,9 +3634,6 @@ int __init ip_vs_control_init(void) ...@@ -3631,9 +3634,6 @@ int __init ip_vs_control_init(void)
goto err_net; goto err_net;
} }
/* Hook the defense timer */
schedule_delayed_work(&defense_work, DEFENSE_TIMER_PERIOD);
LeaveFunction(2); LeaveFunction(2);
return 0; return 0;
...@@ -3648,8 +3648,6 @@ void ip_vs_control_cleanup(void) ...@@ -3648,8 +3648,6 @@ void ip_vs_control_cleanup(void)
{ {
EnterFunction(2); EnterFunction(2);
ip_vs_trash_cleanup(); ip_vs_trash_cleanup();
cancel_delayed_work_sync(&defense_work);
cancel_work_sync(&defense_work.work);
unregister_pernet_subsys(&ipvs_control_ops); unregister_pernet_subsys(&ipvs_control_ops);
ip_vs_genl_unregister(); ip_vs_genl_unregister();
nf_unregister_sockopt(&ip_vs_sockopts); nf_unregister_sockopt(&ip_vs_sockopts);
......
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