aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Schillstrom <hans.schillstrom@ericsson.com>2011-01-03 08:44:58 -0500
committerSimon Horman <horms@verge.net.au>2011-01-12 20:30:28 -0500
commita0840e2e165a370ca24a59545e564e9881a55891 (patch)
treedeb10e3931be9410aebbb55e5fccbd42a5edd633
parent6e67e586e7289c144d5a189d6e0fa7141d025746 (diff)
IPVS: netns, ip_vs_ctl local vars moved to ipvs struct.
Moving global vars to ipvs struct, except for svc table lock. Next patch for ctl will be drop-rate handling. *v3 __ip_vs_mutex remains global ip_vs_conntrack_enabled(struct netns_ipvs *ipvs) Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--include/net/ip_vs.h27
-rw-r--r--include/net/netns/ip_vs.h37
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c7
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c34
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c291
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_sctp.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_tcp.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_udp.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c9
9 files changed, 230 insertions, 181 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index f82c0ffdee74..af9acf44e40a 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -41,7 +41,7 @@ static inline struct netns_ipvs *net_ipvs(struct net* net)
41 * Get net ptr from skb in traffic cases 41 * Get net ptr from skb in traffic cases
42 * use skb_sknet when call is from userland (ioctl or netlink) 42 * use skb_sknet when call is from userland (ioctl or netlink)
43 */ 43 */
44static inline struct net *skb_net(struct sk_buff *skb) 44static inline struct net *skb_net(const struct sk_buff *skb)
45{ 45{
46#ifdef CONFIG_NET_NS 46#ifdef CONFIG_NET_NS
47#ifdef CONFIG_IP_VS_DEBUG 47#ifdef CONFIG_IP_VS_DEBUG
@@ -69,7 +69,7 @@ static inline struct net *skb_net(struct sk_buff *skb)
69#endif 69#endif
70} 70}
71 71
72static inline struct net *skb_sknet(struct sk_buff *skb) 72static inline struct net *skb_sknet(const struct sk_buff *skb)
73{ 73{
74#ifdef CONFIG_NET_NS 74#ifdef CONFIG_NET_NS
75#ifdef CONFIG_IP_VS_DEBUG 75#ifdef CONFIG_IP_VS_DEBUG
@@ -1023,13 +1023,6 @@ extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
1023/* 1023/*
1024 * IPVS control data and functions (from ip_vs_ctl.c) 1024 * IPVS control data and functions (from ip_vs_ctl.c)
1025 */ 1025 */
1026extern int sysctl_ip_vs_cache_bypass;
1027extern int sysctl_ip_vs_expire_nodest_conn;
1028extern int sysctl_ip_vs_expire_quiescent_template;
1029extern int sysctl_ip_vs_sync_threshold[2];
1030extern int sysctl_ip_vs_nat_icmp_send;
1031extern int sysctl_ip_vs_conntrack;
1032extern int sysctl_ip_vs_snat_reroute;
1033extern struct ip_vs_stats ip_vs_stats; 1026extern struct ip_vs_stats ip_vs_stats;
1034extern const struct ctl_path net_vs_ctl_path[]; 1027extern const struct ctl_path net_vs_ctl_path[];
1035extern int sysctl_ip_vs_sync_ver; 1028extern int sysctl_ip_vs_sync_ver;
@@ -1119,11 +1112,13 @@ extern int ip_vs_icmp_xmit_v6
1119extern int ip_vs_drop_rate; 1112extern int ip_vs_drop_rate;
1120extern int ip_vs_drop_counter; 1113extern int ip_vs_drop_counter;
1121 1114
1122static __inline__ int ip_vs_todrop(void) 1115static inline int ip_vs_todrop(struct netns_ipvs *ipvs)
1123{ 1116{
1124 if (!ip_vs_drop_rate) return 0; 1117 if (!ipvs->drop_rate)
1125 if (--ip_vs_drop_counter > 0) return 0; 1118 return 0;
1126 ip_vs_drop_counter = ip_vs_drop_rate; 1119 if (--ipvs->drop_counter > 0)
1120 return 0;
1121 ipvs->drop_counter = ipvs->drop_rate;
1127 return 1; 1122 return 1;
1128} 1123}
1129 1124
@@ -1211,9 +1206,9 @@ static inline void ip_vs_notrack(struct sk_buff *skb)
1211 * Netfilter connection tracking 1206 * Netfilter connection tracking
1212 * (from ip_vs_nfct.c) 1207 * (from ip_vs_nfct.c)
1213 */ 1208 */
1214static inline int ip_vs_conntrack_enabled(void) 1209static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
1215{ 1210{
1216 return sysctl_ip_vs_conntrack; 1211 return ipvs->sysctl_conntrack;
1217} 1212}
1218 1213
1219extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, 1214extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
@@ -1226,7 +1221,7 @@ extern void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);
1226 1221
1227#else 1222#else
1228 1223
1229static inline int ip_vs_conntrack_enabled(void) 1224static inline int ip_vs_conntrack_enabled(struct netns_ipvs *ipvs)
1230{ 1225{
1231 return 0; 1226 return 0;
1232} 1227}
diff --git a/include/net/netns/ip_vs.h b/include/net/netns/ip_vs.h
index 1acfb334e69b..c4b1abf258e4 100644
--- a/include/net/netns/ip_vs.h
+++ b/include/net/netns/ip_vs.h
@@ -61,13 +61,46 @@ struct netns_ipvs {
61 struct list_head sctp_apps[SCTP_APP_TAB_SIZE]; 61 struct list_head sctp_apps[SCTP_APP_TAB_SIZE];
62 spinlock_t sctp_app_lock; 62 spinlock_t sctp_app_lock;
63#endif 63#endif
64 /* ip_vs_conn */
65 atomic_t conn_count; /* connection counter */
66
64 /* ip_vs_ctl */ 67 /* ip_vs_ctl */
65 struct ip_vs_stats *tot_stats; /* Statistics & est. */ 68 struct ip_vs_stats *tot_stats; /* Statistics & est. */
66 struct ip_vs_cpu_stats __percpu *cpustats; /* Stats per cpu */ 69 struct ip_vs_cpu_stats __percpu *cpustats; /* Stats per cpu */
67 seqcount_t *ustats_seq; /* u64 read retry */ 70 seqcount_t *ustats_seq; /* u64 read retry */
68 71
69 /* ip_vs_conn */ 72 int num_services; /* no of virtual services */
70 atomic_t conn_count; /* connection counter */ 73 /* 1/rate drop and drop-entry variables */
74 int drop_rate;
75 int drop_counter;
76 atomic_t dropentry;
77 /* locks in ctl.c */
78 spinlock_t dropentry_lock; /* drop entry handling */
79 spinlock_t droppacket_lock; /* drop packet handling */
80 spinlock_t securetcp_lock; /* state and timeout tables */
81 rwlock_t rs_lock; /* real services table */
82 /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */
83 struct lock_class_key ctl_key; /* ctl_mutex debuging */
84 /* sys-ctl struct */
85 struct ctl_table_header *sysctl_hdr;
86 struct ctl_table *sysctl_tbl;
87 /* sysctl variables */
88 int sysctl_amemthresh;
89 int sysctl_am_droprate;
90 int sysctl_drop_entry;
91 int sysctl_drop_packet;
92 int sysctl_secure_tcp;
93#ifdef CONFIG_IP_VS_NFCT
94 int sysctl_conntrack;
95#endif
96 int sysctl_snat_reroute;
97 int sysctl_sync_ver;
98 int sysctl_cache_bypass;
99 int sysctl_expire_nodest_conn;
100 int sysctl_expire_quiescent_template;
101 int sysctl_sync_threshold[2];
102 int sysctl_nat_icmp_send;
103
71 /* ip_vs_lblc */ 104 /* ip_vs_lblc */
72 int sysctl_lblc_expiration; 105 int sysctl_lblc_expiration;
73 struct ctl_table_header *lblc_ctl_header; 106 struct ctl_table_header *lblc_ctl_header;
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 0d5e4feabc1b..5ba205a4d79c 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -686,13 +686,14 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
686int ip_vs_check_template(struct ip_vs_conn *ct) 686int ip_vs_check_template(struct ip_vs_conn *ct)
687{ 687{
688 struct ip_vs_dest *dest = ct->dest; 688 struct ip_vs_dest *dest = ct->dest;
689 struct netns_ipvs *ipvs = net_ipvs(ip_vs_conn_net(ct));
689 690
690 /* 691 /*
691 * Checking the dest server status. 692 * Checking the dest server status.
692 */ 693 */
693 if ((dest == NULL) || 694 if ((dest == NULL) ||
694 !(dest->flags & IP_VS_DEST_F_AVAILABLE) || 695 !(dest->flags & IP_VS_DEST_F_AVAILABLE) ||
695 (sysctl_ip_vs_expire_quiescent_template && 696 (ipvs->sysctl_expire_quiescent_template &&
696 (atomic_read(&dest->weight) == 0))) { 697 (atomic_read(&dest->weight) == 0))) {
697 IP_VS_DBG_BUF(9, "check_template: dest not available for " 698 IP_VS_DBG_BUF(9, "check_template: dest not available for "
698 "protocol %s s:%s:%d v:%s:%d " 699 "protocol %s s:%s:%d v:%s:%d "
@@ -879,7 +880,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p,
879 * IP_VS_CONN_F_ONE_PACKET too. 880 * IP_VS_CONN_F_ONE_PACKET too.
880 */ 881 */
881 882
882 if (ip_vs_conntrack_enabled()) 883 if (ip_vs_conntrack_enabled(ipvs))
883 cp->flags |= IP_VS_CONN_F_NFCT; 884 cp->flags |= IP_VS_CONN_F_NFCT;
884 885
885 /* Hash it in the ip_vs_conn_tab finally */ 886 /* Hash it in the ip_vs_conn_tab finally */
@@ -1198,7 +1199,7 @@ static void ip_vs_conn_flush(struct net *net)
1198 struct ip_vs_conn *cp; 1199 struct ip_vs_conn *cp;
1199 struct netns_ipvs *ipvs = net_ipvs(net); 1200 struct netns_ipvs *ipvs = net_ipvs(net);
1200 1201
1201 flush_again: 1202flush_again:
1202 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) { 1203 for (idx = 0; idx < ip_vs_conn_tab_size; idx++) {
1203 /* 1204 /*
1204 * Lock is actually needed in this loop. 1205 * Lock is actually needed in this loop.
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 7205b49c56c1..a7c59a722af3 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -499,6 +499,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
499int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, 499int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
500 struct ip_vs_proto_data *pd) 500 struct ip_vs_proto_data *pd)
501{ 501{
502 struct netns_ipvs *ipvs;
502 __be16 _ports[2], *pptr; 503 __be16 _ports[2], *pptr;
503 struct ip_vs_iphdr iph; 504 struct ip_vs_iphdr iph;
504 int unicast; 505 int unicast;
@@ -521,7 +522,8 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
521 /* if it is fwmark-based service, the cache_bypass sysctl is up 522 /* if it is fwmark-based service, the cache_bypass sysctl is up
522 and the destination is a non-local unicast, then create 523 and the destination is a non-local unicast, then create
523 a cache_bypass connection entry */ 524 a cache_bypass connection entry */
524 if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) { 525 ipvs = net_ipvs(skb_net(skb));
526 if (ipvs->sysctl_cache_bypass && svc->fwmark && unicast) {
525 int ret, cs; 527 int ret, cs;
526 struct ip_vs_conn *cp; 528 struct ip_vs_conn *cp;
527 unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && 529 unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
@@ -733,6 +735,7 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
733 struct ip_vs_protocol *pp, 735 struct ip_vs_protocol *pp,
734 unsigned int offset, unsigned int ihl) 736 unsigned int offset, unsigned int ihl)
735{ 737{
738 struct netns_ipvs *ipvs;
736 unsigned int verdict = NF_DROP; 739 unsigned int verdict = NF_DROP;
737 740
738 if (IP_VS_FWD_METHOD(cp) != 0) { 741 if (IP_VS_FWD_METHOD(cp) != 0) {
@@ -754,6 +757,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
754 if (!skb_make_writable(skb, offset)) 757 if (!skb_make_writable(skb, offset))
755 goto out; 758 goto out;
756 759
760 ipvs = net_ipvs(skb_net(skb));
761
757#ifdef CONFIG_IP_VS_IPV6 762#ifdef CONFIG_IP_VS_IPV6
758 if (af == AF_INET6) 763 if (af == AF_INET6)
759 ip_vs_nat_icmp_v6(skb, pp, cp, 1); 764 ip_vs_nat_icmp_v6(skb, pp, cp, 1);
@@ -763,11 +768,11 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
763 768
764#ifdef CONFIG_IP_VS_IPV6 769#ifdef CONFIG_IP_VS_IPV6
765 if (af == AF_INET6) { 770 if (af == AF_INET6) {
766 if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0) 771 if (ipvs->sysctl_snat_reroute && ip6_route_me_harder(skb) != 0)
767 goto out; 772 goto out;
768 } else 773 } else
769#endif 774#endif
770 if ((sysctl_ip_vs_snat_reroute || 775 if ((ipvs->sysctl_snat_reroute ||
771 skb_rtable(skb)->rt_flags & RTCF_LOCAL) && 776 skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
772 ip_route_me_harder(skb, RTN_LOCAL) != 0) 777 ip_route_me_harder(skb, RTN_LOCAL) != 0)
773 goto out; 778 goto out;
@@ -979,6 +984,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
979 struct ip_vs_conn *cp, int ihl) 984 struct ip_vs_conn *cp, int ihl)
980{ 985{
981 struct ip_vs_protocol *pp = pd->pp; 986 struct ip_vs_protocol *pp = pd->pp;
987 struct netns_ipvs *ipvs;
982 988
983 IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet"); 989 IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet");
984 990
@@ -1014,13 +1020,15 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
1014 * if it came from this machine itself. So re-compute 1020 * if it came from this machine itself. So re-compute
1015 * the routing information. 1021 * the routing information.
1016 */ 1022 */
1023 ipvs = net_ipvs(skb_net(skb));
1024
1017#ifdef CONFIG_IP_VS_IPV6 1025#ifdef CONFIG_IP_VS_IPV6
1018 if (af == AF_INET6) { 1026 if (af == AF_INET6) {
1019 if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0) 1027 if (ipvs->sysctl_snat_reroute && ip6_route_me_harder(skb) != 0)
1020 goto drop; 1028 goto drop;
1021 } else 1029 } else
1022#endif 1030#endif
1023 if ((sysctl_ip_vs_snat_reroute || 1031 if ((ipvs->sysctl_snat_reroute ||
1024 skb_rtable(skb)->rt_flags & RTCF_LOCAL) && 1032 skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
1025 ip_route_me_harder(skb, RTN_LOCAL) != 0) 1033 ip_route_me_harder(skb, RTN_LOCAL) != 0)
1026 goto drop; 1034 goto drop;
@@ -1057,6 +1065,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
1057 struct ip_vs_protocol *pp; 1065 struct ip_vs_protocol *pp;
1058 struct ip_vs_proto_data *pd; 1066 struct ip_vs_proto_data *pd;
1059 struct ip_vs_conn *cp; 1067 struct ip_vs_conn *cp;
1068 struct netns_ipvs *ipvs;
1060 1069
1061 EnterFunction(11); 1070 EnterFunction(11);
1062 1071
@@ -1131,10 +1140,11 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
1131 * Check if the packet belongs to an existing entry 1140 * Check if the packet belongs to an existing entry
1132 */ 1141 */
1133 cp = pp->conn_out_get(af, skb, &iph, iph.len, 0); 1142 cp = pp->conn_out_get(af, skb, &iph, iph.len, 0);
1143 ipvs = net_ipvs(net);
1134 1144
1135 if (likely(cp)) 1145 if (likely(cp))
1136 return handle_response(af, skb, pd, cp, iph.len); 1146 return handle_response(af, skb, pd, cp, iph.len);
1137 if (sysctl_ip_vs_nat_icmp_send && 1147 if (ipvs->sysctl_nat_icmp_send &&
1138 (pp->protocol == IPPROTO_TCP || 1148 (pp->protocol == IPPROTO_TCP ||
1139 pp->protocol == IPPROTO_UDP || 1149 pp->protocol == IPPROTO_UDP ||
1140 pp->protocol == IPPROTO_SCTP)) { 1150 pp->protocol == IPPROTO_SCTP)) {
@@ -1580,7 +1590,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
1580 if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { 1590 if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
1581 /* the destination server is not available */ 1591 /* the destination server is not available */
1582 1592
1583 if (sysctl_ip_vs_expire_nodest_conn) { 1593 if (ipvs->sysctl_expire_nodest_conn) {
1584 /* try to expire the connection immediately */ 1594 /* try to expire the connection immediately */
1585 ip_vs_conn_expire_now(cp); 1595 ip_vs_conn_expire_now(cp);
1586 } 1596 }
@@ -1610,15 +1620,15 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
1610 */ 1620 */
1611 1621
1612 if (cp->flags & IP_VS_CONN_F_ONE_PACKET) 1622 if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
1613 pkts = sysctl_ip_vs_sync_threshold[0]; 1623 pkts = ipvs->sysctl_sync_threshold[0];
1614 else 1624 else
1615 pkts = atomic_add_return(1, &cp->in_pkts); 1625 pkts = atomic_add_return(1, &cp->in_pkts);
1616 1626
1617 if ((ipvs->sync_state & IP_VS_STATE_MASTER) && 1627 if ((ipvs->sync_state & IP_VS_STATE_MASTER) &&
1618 cp->protocol == IPPROTO_SCTP) { 1628 cp->protocol == IPPROTO_SCTP) {
1619 if ((cp->state == IP_VS_SCTP_S_ESTABLISHED && 1629 if ((cp->state == IP_VS_SCTP_S_ESTABLISHED &&
1620 (pkts % sysctl_ip_vs_sync_threshold[1] 1630 (pkts % ipvs->sysctl_sync_threshold[1]
1621 == sysctl_ip_vs_sync_threshold[0])) || 1631 == ipvs->sysctl_sync_threshold[0])) ||
1622 (cp->old_state != cp->state && 1632 (cp->old_state != cp->state &&
1623 ((cp->state == IP_VS_SCTP_S_CLOSED) || 1633 ((cp->state == IP_VS_SCTP_S_CLOSED) ||
1624 (cp->state == IP_VS_SCTP_S_SHUT_ACK_CLI) || 1634 (cp->state == IP_VS_SCTP_S_SHUT_ACK_CLI) ||
@@ -1632,8 +1642,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
1632 else if ((ipvs->sync_state & IP_VS_STATE_MASTER) && 1642 else if ((ipvs->sync_state & IP_VS_STATE_MASTER) &&
1633 (((cp->protocol != IPPROTO_TCP || 1643 (((cp->protocol != IPPROTO_TCP ||
1634 cp->state == IP_VS_TCP_S_ESTABLISHED) && 1644 cp->state == IP_VS_TCP_S_ESTABLISHED) &&
1635 (pkts % sysctl_ip_vs_sync_threshold[1] 1645 (pkts % ipvs->sysctl_sync_threshold[1]
1636 == sysctl_ip_vs_sync_threshold[0])) || 1646 == ipvs->sysctl_sync_threshold[0])) ||
1637 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && 1647 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
1638 ((cp->state == IP_VS_TCP_S_FIN_WAIT) || 1648 ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
1639 (cp->state == IP_VS_TCP_S_CLOSE) || 1649 (cp->state == IP_VS_TCP_S_CLOSE) ||
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index cbd58c60e1bf..183ac18bded5 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -58,42 +58,7 @@ static DEFINE_MUTEX(__ip_vs_mutex);
58/* lock for service table */ 58/* lock for service table */
59static DEFINE_RWLOCK(__ip_vs_svc_lock); 59static DEFINE_RWLOCK(__ip_vs_svc_lock);
60 60
61/* lock for table with the real services */
62static DEFINE_RWLOCK(__ip_vs_rs_lock);
63
64/* lock for state and timeout tables */
65static DEFINE_SPINLOCK(ip_vs_securetcp_lock);
66
67/* lock for drop entry handling */
68static DEFINE_SPINLOCK(__ip_vs_dropentry_lock);
69
70/* lock for drop packet handling */
71static DEFINE_SPINLOCK(__ip_vs_droppacket_lock);
72
73/* 1/rate drop and drop-entry variables */
74int ip_vs_drop_rate = 0;
75int ip_vs_drop_counter = 0;
76static atomic_t ip_vs_dropentry = ATOMIC_INIT(0);
77
78/* number of virtual services */
79static int ip_vs_num_services = 0;
80
81/* sysctl variables */ 61/* sysctl variables */
82static int sysctl_ip_vs_drop_entry = 0;
83static int sysctl_ip_vs_drop_packet = 0;
84static int sysctl_ip_vs_secure_tcp = 0;
85static int sysctl_ip_vs_amemthresh = 1024;
86static int sysctl_ip_vs_am_droprate = 10;
87int sysctl_ip_vs_cache_bypass = 0;
88int sysctl_ip_vs_expire_nodest_conn = 0;
89int sysctl_ip_vs_expire_quiescent_template = 0;
90int sysctl_ip_vs_sync_threshold[2] = { 3, 50 };
91int sysctl_ip_vs_nat_icmp_send = 0;
92#ifdef CONFIG_IP_VS_NFCT
93int sysctl_ip_vs_conntrack;
94#endif
95int sysctl_ip_vs_snat_reroute = 1;
96int sysctl_ip_vs_sync_ver = 1; /* Default version of sync proto */
97 62
98#ifdef CONFIG_IP_VS_DEBUG 63#ifdef CONFIG_IP_VS_DEBUG
99static int sysctl_ip_vs_debug_level = 0; 64static int sysctl_ip_vs_debug_level = 0;
@@ -142,73 +107,73 @@ static void update_defense_level(struct netns_ipvs *ipvs)
142 /* si_swapinfo(&i); */ 107 /* si_swapinfo(&i); */
143 /* availmem = availmem - (i.totalswap - i.freeswap); */ 108 /* availmem = availmem - (i.totalswap - i.freeswap); */
144 109
145 nomem = (availmem < sysctl_ip_vs_amemthresh); 110 nomem = (availmem < ipvs->sysctl_amemthresh);
146 111
147 local_bh_disable(); 112 local_bh_disable();
148 113
149 /* drop_entry */ 114 /* drop_entry */
150 spin_lock(&__ip_vs_dropentry_lock); 115 spin_lock(&ipvs->dropentry_lock);
151 switch (sysctl_ip_vs_drop_entry) { 116 switch (ipvs->sysctl_drop_entry) {
152 case 0: 117 case 0:
153 atomic_set(&ip_vs_dropentry, 0); 118 atomic_set(&ipvs->dropentry, 0);
154 break; 119 break;
155 case 1: 120 case 1:
156 if (nomem) { 121 if (nomem) {
157 atomic_set(&ip_vs_dropentry, 1); 122 atomic_set(&ipvs->dropentry, 1);
158 sysctl_ip_vs_drop_entry = 2; 123 ipvs->sysctl_drop_entry = 2;
159 } else { 124 } else {
160 atomic_set(&ip_vs_dropentry, 0); 125 atomic_set(&ipvs->dropentry, 0);
161 } 126 }
162 break; 127 break;
163 case 2: 128 case 2:
164 if (nomem) { 129 if (nomem) {
165 atomic_set(&ip_vs_dropentry, 1); 130 atomic_set(&ipvs->dropentry, 1);
166 } else { 131 } else {
167 atomic_set(&ip_vs_dropentry, 0); 132 atomic_set(&ipvs->dropentry, 0);
168 sysctl_ip_vs_drop_entry = 1; 133 ipvs->sysctl_drop_entry = 1;
169 }; 134 };
170 break; 135 break;
171 case 3: 136 case 3:
172 atomic_set(&ip_vs_dropentry, 1); 137 atomic_set(&ipvs->dropentry, 1);
173 break; 138 break;
174 } 139 }
175 spin_unlock(&__ip_vs_dropentry_lock); 140 spin_unlock(&ipvs->dropentry_lock);
176 141
177 /* drop_packet */ 142 /* drop_packet */
178 spin_lock(&__ip_vs_droppacket_lock); 143 spin_lock(&ipvs->droppacket_lock);
179 switch (sysctl_ip_vs_drop_packet) { 144 switch (ipvs->sysctl_drop_packet) {
180 case 0: 145 case 0:
181 ip_vs_drop_rate = 0; 146 ipvs->drop_rate = 0;
182 break; 147 break;
183 case 1: 148 case 1:
184 if (nomem) { 149 if (nomem) {
185 ip_vs_drop_rate = ip_vs_drop_counter 150 ipvs->drop_rate = ipvs->drop_counter
186 = sysctl_ip_vs_amemthresh / 151 = ipvs->sysctl_amemthresh /
187 (sysctl_ip_vs_amemthresh-availmem); 152 (ipvs->sysctl_amemthresh-availmem);
188 sysctl_ip_vs_drop_packet = 2; 153 ipvs->sysctl_drop_packet = 2;
189 } else { 154 } else {
190 ip_vs_drop_rate = 0; 155 ipvs->drop_rate = 0;
191 } 156 }
192 break; 157 break;
193 case 2: 158 case 2:
194 if (nomem) { 159 if (nomem) {
195 ip_vs_drop_rate = ip_vs_drop_counter 160 ipvs->drop_rate = ipvs->drop_counter
196 = sysctl_ip_vs_amemthresh / 161 = ipvs->sysctl_amemthresh /
197 (sysctl_ip_vs_amemthresh-availmem); 162 (ipvs->sysctl_amemthresh-availmem);
198 } else { 163 } else {
199 ip_vs_drop_rate = 0; 164 ipvs->drop_rate = 0;
200 sysctl_ip_vs_drop_packet = 1; 165 ipvs->sysctl_drop_packet = 1;
201 } 166 }
202 break; 167 break;
203 case 3: 168 case 3:
204 ip_vs_drop_rate = sysctl_ip_vs_am_droprate; 169 ipvs->drop_rate = ipvs->sysctl_am_droprate;
205 break; 170 break;
206 } 171 }
207 spin_unlock(&__ip_vs_droppacket_lock); 172 spin_unlock(&ipvs->droppacket_lock);
208 173
209 /* secure_tcp */ 174 /* secure_tcp */
210 spin_lock(&ip_vs_securetcp_lock); 175 spin_lock(&ipvs->securetcp_lock);
211 switch (sysctl_ip_vs_secure_tcp) { 176 switch (ipvs->sysctl_secure_tcp) {
212 case 0: 177 case 0:
213 if (old_secure_tcp >= 2) 178 if (old_secure_tcp >= 2)
214 to_change = 0; 179 to_change = 0;
@@ -217,7 +182,7 @@ static void update_defense_level(struct netns_ipvs *ipvs)
217 if (nomem) { 182 if (nomem) {
218 if (old_secure_tcp < 2) 183 if (old_secure_tcp < 2)
219 to_change = 1; 184 to_change = 1;
220 sysctl_ip_vs_secure_tcp = 2; 185 ipvs->sysctl_secure_tcp = 2;
221 } else { 186 } else {
222 if (old_secure_tcp >= 2) 187 if (old_secure_tcp >= 2)
223 to_change = 0; 188 to_change = 0;
@@ -230,7 +195,7 @@ static void update_defense_level(struct netns_ipvs *ipvs)
230 } else { 195 } else {
231 if (old_secure_tcp >= 2) 196 if (old_secure_tcp >= 2)
232 to_change = 0; 197 to_change = 0;
233 sysctl_ip_vs_secure_tcp = 1; 198 ipvs->sysctl_secure_tcp = 1;
234 } 199 }
235 break; 200 break;
236 case 3: 201 case 3:
@@ -238,11 +203,11 @@ static void update_defense_level(struct netns_ipvs *ipvs)
238 to_change = 1; 203 to_change = 1;
239 break; 204 break;
240 } 205 }
241 old_secure_tcp = sysctl_ip_vs_secure_tcp; 206 old_secure_tcp = ipvs->sysctl_secure_tcp;
242 if (to_change >= 0) 207 if (to_change >= 0)
243 ip_vs_protocol_timeout_change(ipvs, 208 ip_vs_protocol_timeout_change(ipvs,
244 sysctl_ip_vs_secure_tcp > 1); 209 ipvs->sysctl_secure_tcp > 1);
245 spin_unlock(&ip_vs_securetcp_lock); 210 spin_unlock(&ipvs->securetcp_lock);
246 211
247 local_bh_enable(); 212 local_bh_enable();
248} 213}
@@ -260,7 +225,7 @@ static void defense_work_handler(struct work_struct *work)
260 struct netns_ipvs *ipvs = net_ipvs(&init_net); 225 struct netns_ipvs *ipvs = net_ipvs(&init_net);
261 226
262 update_defense_level(ipvs); 227 update_defense_level(ipvs);
263 if (atomic_read(&ip_vs_dropentry)) 228 if (atomic_read(&ipvs->dropentry))
264 ip_vs_random_dropentry(); 229 ip_vs_random_dropentry();
265 230
266 schedule_delayed_work(&defense_work, DEFENSE_TIMER_PERIOD); 231 schedule_delayed_work(&defense_work, DEFENSE_TIMER_PERIOD);
@@ -602,7 +567,7 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol,
602 */ 567 */
603 hash = ip_vs_rs_hashkey(af, daddr, dport); 568 hash = ip_vs_rs_hashkey(af, daddr, dport);
604 569
605 read_lock(&__ip_vs_rs_lock); 570 read_lock(&ipvs->rs_lock);
606 list_for_each_entry(dest, &ipvs->rs_table[hash], d_list) { 571 list_for_each_entry(dest, &ipvs->rs_table[hash], d_list) {
607 if ((dest->af == af) 572 if ((dest->af == af)
608 && ip_vs_addr_equal(af, &dest->addr, daddr) 573 && ip_vs_addr_equal(af, &dest->addr, daddr)
@@ -610,11 +575,11 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol,
610 && ((dest->protocol == protocol) || 575 && ((dest->protocol == protocol) ||
611 dest->vfwmark)) { 576 dest->vfwmark)) {
612 /* HIT */ 577 /* HIT */
613 read_unlock(&__ip_vs_rs_lock); 578 read_unlock(&ipvs->rs_lock);
614 return dest; 579 return dest;
615 } 580 }
616 } 581 }
617 read_unlock(&__ip_vs_rs_lock); 582 read_unlock(&ipvs->rs_lock);
618 583
619 return NULL; 584 return NULL;
620} 585}
@@ -788,9 +753,9 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
788 * Put the real service in rs_table if not present. 753 * Put the real service in rs_table if not present.
789 * For now only for NAT! 754 * For now only for NAT!
790 */ 755 */
791 write_lock_bh(&__ip_vs_rs_lock); 756 write_lock_bh(&ipvs->rs_lock);
792 ip_vs_rs_hash(ipvs, dest); 757 ip_vs_rs_hash(ipvs, dest);
793 write_unlock_bh(&__ip_vs_rs_lock); 758 write_unlock_bh(&ipvs->rs_lock);
794 } 759 }
795 atomic_set(&dest->conn_flags, conn_flags); 760 atomic_set(&dest->conn_flags, conn_flags);
796 761
@@ -1022,14 +987,16 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
1022 */ 987 */
1023static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest) 988static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest)
1024{ 989{
990 struct netns_ipvs *ipvs = net_ipvs(net);
991
1025 ip_vs_kill_estimator(net, &dest->stats); 992 ip_vs_kill_estimator(net, &dest->stats);
1026 993
1027 /* 994 /*
1028 * Remove it from the d-linked list with the real services. 995 * Remove it from the d-linked list with the real services.
1029 */ 996 */
1030 write_lock_bh(&__ip_vs_rs_lock); 997 write_lock_bh(&ipvs->rs_lock);
1031 ip_vs_rs_unhash(dest); 998 ip_vs_rs_unhash(dest);
1032 write_unlock_bh(&__ip_vs_rs_lock); 999 write_unlock_bh(&ipvs->rs_lock);
1033 1000
1034 /* 1001 /*
1035 * Decrease the refcnt of the dest, and free the dest 1002 * Decrease the refcnt of the dest, and free the dest
@@ -1092,7 +1059,6 @@ static int
1092ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) 1059ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
1093{ 1060{
1094 struct ip_vs_dest *dest; 1061 struct ip_vs_dest *dest;
1095 struct net *net = svc->net;
1096 __be16 dport = udest->port; 1062 __be16 dport = udest->port;
1097 1063
1098 EnterFunction(2); 1064 EnterFunction(2);
@@ -1121,7 +1087,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
1121 /* 1087 /*
1122 * Delete the destination 1088 * Delete the destination
1123 */ 1089 */
1124 __ip_vs_del_dest(net, dest); 1090 __ip_vs_del_dest(svc->net, dest);
1125 1091
1126 LeaveFunction(2); 1092 LeaveFunction(2);
1127 1093
@@ -1140,6 +1106,7 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u,
1140 struct ip_vs_scheduler *sched = NULL; 1106 struct ip_vs_scheduler *sched = NULL;
1141 struct ip_vs_pe *pe = NULL; 1107 struct ip_vs_pe *pe = NULL;
1142 struct ip_vs_service *svc = NULL; 1108 struct ip_vs_service *svc = NULL;
1109 struct netns_ipvs *ipvs = net_ipvs(net);
1143 1110
1144 /* increase the module use count */ 1111 /* increase the module use count */
1145 ip_vs_use_count_inc(); 1112 ip_vs_use_count_inc();
@@ -1219,7 +1186,7 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u,
1219 1186
1220 /* Count only IPv4 services for old get/setsockopt interface */ 1187 /* Count only IPv4 services for old get/setsockopt interface */
1221 if (svc->af == AF_INET) 1188 if (svc->af == AF_INET)
1222 ip_vs_num_services++; 1189 ipvs->num_services++;
1223 1190
1224 /* Hash the service into the service table */ 1191 /* Hash the service into the service table */
1225 write_lock_bh(&__ip_vs_svc_lock); 1192 write_lock_bh(&__ip_vs_svc_lock);
@@ -1359,12 +1326,13 @@ static void __ip_vs_del_service(struct ip_vs_service *svc)
1359 struct ip_vs_dest *dest, *nxt; 1326 struct ip_vs_dest *dest, *nxt;
1360 struct ip_vs_scheduler *old_sched; 1327 struct ip_vs_scheduler *old_sched;
1361 struct ip_vs_pe *old_pe; 1328 struct ip_vs_pe *old_pe;
1329 struct netns_ipvs *ipvs = net_ipvs(svc->net);
1362 1330
1363 pr_info("%s: enter\n", __func__); 1331 pr_info("%s: enter\n", __func__);
1364 1332
1365 /* Count only IPv4 services for old get/setsockopt interface */ 1333 /* Count only IPv4 services for old get/setsockopt interface */
1366 if (svc->af == AF_INET) 1334 if (svc->af == AF_INET)
1367 ip_vs_num_services--; 1335 ipvs->num_services--;
1368 1336
1369 ip_vs_kill_estimator(svc->net, &svc->stats); 1337 ip_vs_kill_estimator(svc->net, &svc->stats);
1370 1338
@@ -1589,42 +1557,31 @@ proc_do_sync_mode(ctl_table *table, int write,
1589 1557
1590/* 1558/*
1591 * IPVS sysctl table (under the /proc/sys/net/ipv4/vs/) 1559 * IPVS sysctl table (under the /proc/sys/net/ipv4/vs/)
1560 * Do not change order or insert new entries without
1561 * align with netns init in __ip_vs_control_init()
1592 */ 1562 */
1593 1563
1594static struct ctl_table vs_vars[] = { 1564static struct ctl_table vs_vars[] = {
1595 { 1565 {
1596 .procname = "amemthresh", 1566 .procname = "amemthresh",
1597 .data = &sysctl_ip_vs_amemthresh,
1598 .maxlen = sizeof(int),
1599 .mode = 0644,
1600 .proc_handler = proc_dointvec,
1601 },
1602#ifdef CONFIG_IP_VS_DEBUG
1603 {
1604 .procname = "debug_level",
1605 .data = &sysctl_ip_vs_debug_level,
1606 .maxlen = sizeof(int), 1567 .maxlen = sizeof(int),
1607 .mode = 0644, 1568 .mode = 0644,
1608 .proc_handler = proc_dointvec, 1569 .proc_handler = proc_dointvec,
1609 }, 1570 },
1610#endif
1611 { 1571 {
1612 .procname = "am_droprate", 1572 .procname = "am_droprate",
1613 .data = &sysctl_ip_vs_am_droprate,
1614 .maxlen = sizeof(int), 1573 .maxlen = sizeof(int),
1615 .mode = 0644, 1574 .mode = 0644,
1616 .proc_handler = proc_dointvec, 1575 .proc_handler = proc_dointvec,
1617 }, 1576 },
1618 { 1577 {
1619 .procname = "drop_entry", 1578 .procname = "drop_entry",
1620 .data = &sysctl_ip_vs_drop_entry,
1621 .maxlen = sizeof(int), 1579 .maxlen = sizeof(int),
1622 .mode = 0644, 1580 .mode = 0644,
1623 .proc_handler = proc_do_defense_mode, 1581 .proc_handler = proc_do_defense_mode,
1624 }, 1582 },
1625 { 1583 {
1626 .procname = "drop_packet", 1584 .procname = "drop_packet",
1627 .data = &sysctl_ip_vs_drop_packet,
1628 .maxlen = sizeof(int), 1585 .maxlen = sizeof(int),
1629 .mode = 0644, 1586 .mode = 0644,
1630 .proc_handler = proc_do_defense_mode, 1587 .proc_handler = proc_do_defense_mode,
@@ -1632,7 +1589,6 @@ static struct ctl_table vs_vars[] = {
1632#ifdef CONFIG_IP_VS_NFCT 1589#ifdef CONFIG_IP_VS_NFCT
1633 { 1590 {
1634 .procname = "conntrack", 1591 .procname = "conntrack",
1635 .data = &sysctl_ip_vs_conntrack,
1636 .maxlen = sizeof(int), 1592 .maxlen = sizeof(int),
1637 .mode = 0644, 1593 .mode = 0644,
1638 .proc_handler = &proc_dointvec, 1594 .proc_handler = &proc_dointvec,
@@ -1640,25 +1596,62 @@ static struct ctl_table vs_vars[] = {
1640#endif 1596#endif
1641 { 1597 {
1642 .procname = "secure_tcp", 1598 .procname = "secure_tcp",
1643 .data = &sysctl_ip_vs_secure_tcp,
1644 .maxlen = sizeof(int), 1599 .maxlen = sizeof(int),
1645 .mode = 0644, 1600 .mode = 0644,
1646 .proc_handler = proc_do_defense_mode, 1601 .proc_handler = proc_do_defense_mode,
1647 }, 1602 },
1648 { 1603 {
1649 .procname = "snat_reroute", 1604 .procname = "snat_reroute",
1650 .data = &sysctl_ip_vs_snat_reroute,
1651 .maxlen = sizeof(int), 1605 .maxlen = sizeof(int),
1652 .mode = 0644, 1606 .mode = 0644,
1653 .proc_handler = &proc_dointvec, 1607 .proc_handler = &proc_dointvec,
1654 }, 1608 },
1655 { 1609 {
1656 .procname = "sync_version", 1610 .procname = "sync_version",
1657 .data = &sysctl_ip_vs_sync_ver,
1658 .maxlen = sizeof(int), 1611 .maxlen = sizeof(int),
1659 .mode = 0644, 1612 .mode = 0644,
1660 .proc_handler = &proc_do_sync_mode, 1613 .proc_handler = &proc_do_sync_mode,
1661 }, 1614 },
1615 {
1616 .procname = "cache_bypass",
1617 .maxlen = sizeof(int),
1618 .mode = 0644,
1619 .proc_handler = proc_dointvec,
1620 },
1621 {
1622 .procname = "expire_nodest_conn",
1623 .maxlen = sizeof(int),
1624 .mode = 0644,
1625 .proc_handler = proc_dointvec,
1626 },
1627 {
1628 .procname = "expire_quiescent_template",
1629 .maxlen = sizeof(int),
1630 .mode = 0644,
1631 .proc_handler = proc_dointvec,
1632 },
1633 {
1634 .procname = "sync_threshold",
1635 .maxlen =
1636 sizeof(((struct netns_ipvs *)0)->sysctl_sync_threshold),
1637 .mode = 0644,
1638 .proc_handler = proc_do_sync_threshold,
1639 },
1640 {
1641 .procname = "nat_icmp_send",
1642 .maxlen = sizeof(int),
1643 .mode = 0644,
1644 .proc_handler = proc_dointvec,
1645 },
1646#ifdef CONFIG_IP_VS_DEBUG
1647 {
1648 .procname = "debug_level",
1649 .data = &sysctl_ip_vs_debug_level,
1650 .maxlen = sizeof(int),
1651 .mode = 0644,
1652 .proc_handler = proc_dointvec,
1653 },
1654#endif
1662#if 0 1655#if 0
1663 { 1656 {
1664 .procname = "timeout_established", 1657 .procname = "timeout_established",
@@ -1745,41 +1738,6 @@ static struct ctl_table vs_vars[] = {
1745 .proc_handler = proc_dointvec_jiffies, 1738 .proc_handler = proc_dointvec_jiffies,
1746 }, 1739 },
1747#endif 1740#endif
1748 {
1749 .procname = "cache_bypass",
1750 .data = &sysctl_ip_vs_cache_bypass,
1751 .maxlen = sizeof(int),
1752 .mode = 0644,
1753 .proc_handler = proc_dointvec,
1754 },
1755 {
1756 .procname = "expire_nodest_conn",
1757 .data = &sysctl_ip_vs_expire_nodest_conn,
1758 .maxlen = sizeof(int),
1759 .mode = 0644,
1760 .proc_handler = proc_dointvec,
1761 },
1762 {
1763 .procname = "expire_quiescent_template",
1764 .data = &sysctl_ip_vs_expire_quiescent_template,
1765 .maxlen = sizeof(int),
1766 .mode = 0644,
1767 .proc_handler = proc_dointvec,
1768 },
1769 {
1770 .procname = "sync_threshold",
1771 .data = &sysctl_ip_vs_sync_threshold,
1772 .maxlen = sizeof(sysctl_ip_vs_sync_threshold),
1773 .mode = 0644,
1774 .proc_handler = proc_do_sync_threshold,
1775 },
1776 {
1777 .procname = "nat_icmp_send",
1778 .data = &sysctl_ip_vs_nat_icmp_send,
1779 .maxlen = sizeof(int),
1780 .mode = 0644,
1781 .proc_handler = proc_dointvec,
1782 },
1783 { } 1741 { }
1784}; 1742};
1785 1743
@@ -1791,8 +1749,6 @@ const struct ctl_path net_vs_ctl_path[] = {
1791}; 1749};
1792EXPORT_SYMBOL_GPL(net_vs_ctl_path); 1750EXPORT_SYMBOL_GPL(net_vs_ctl_path);
1793 1751
1794static struct ctl_table_header * sysctl_header;
1795
1796#ifdef CONFIG_PROC_FS 1752#ifdef CONFIG_PROC_FS
1797 1753
1798struct ip_vs_iter { 1754struct ip_vs_iter {
@@ -2543,7 +2499,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2543 struct ip_vs_getinfo info; 2499 struct ip_vs_getinfo info;
2544 info.version = IP_VS_VERSION_CODE; 2500 info.version = IP_VS_VERSION_CODE;
2545 info.size = ip_vs_conn_tab_size; 2501 info.size = ip_vs_conn_tab_size;
2546 info.num_services = ip_vs_num_services; 2502 info.num_services = ipvs->num_services;
2547 if (copy_to_user(user, &info, sizeof(info)) != 0) 2503 if (copy_to_user(user, &info, sizeof(info)) != 0)
2548 ret = -EFAULT; 2504 ret = -EFAULT;
2549 } 2505 }
@@ -3014,7 +2970,7 @@ static int ip_vs_genl_dump_dests(struct sk_buff *skb,
3014 struct ip_vs_service *svc; 2970 struct ip_vs_service *svc;
3015 struct ip_vs_dest *dest; 2971 struct ip_vs_dest *dest;
3016 struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1]; 2972 struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1];
3017 struct net *net; 2973 struct net *net = skb_sknet(skb);
3018 2974
3019 mutex_lock(&__ip_vs_mutex); 2975 mutex_lock(&__ip_vs_mutex);
3020 2976
@@ -3023,7 +2979,7 @@ static int ip_vs_genl_dump_dests(struct sk_buff *skb,
3023 IPVS_CMD_ATTR_MAX, ip_vs_cmd_policy)) 2979 IPVS_CMD_ATTR_MAX, ip_vs_cmd_policy))
3024 goto out_err; 2980 goto out_err;
3025 2981
3026 net = skb_sknet(skb); 2982
3027 svc = ip_vs_genl_find_service(net, attrs[IPVS_CMD_ATTR_SERVICE]); 2983 svc = ip_vs_genl_find_service(net, attrs[IPVS_CMD_ATTR_SERVICE]);
3028 if (IS_ERR(svc) || svc == NULL) 2984 if (IS_ERR(svc) || svc == NULL)
3029 goto out_err; 2985 goto out_err;
@@ -3215,8 +3171,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
3215 int ret = 0, cmd; 3171 int ret = 0, cmd;
3216 int need_full_svc = 0, need_full_dest = 0; 3172 int need_full_svc = 0, need_full_dest = 0;
3217 struct net *net; 3173 struct net *net;
3174 struct netns_ipvs *ipvs;
3218 3175
3219 net = skb_sknet(skb); 3176 net = skb_sknet(skb);
3177 ipvs = net_ipvs(net);
3220 cmd = info->genlhdr->cmd; 3178 cmd = info->genlhdr->cmd;
3221 3179
3222 mutex_lock(&__ip_vs_mutex); 3180 mutex_lock(&__ip_vs_mutex);
@@ -3326,8 +3284,10 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
3326 void *reply; 3284 void *reply;
3327 int ret, cmd, reply_cmd; 3285 int ret, cmd, reply_cmd;
3328 struct net *net; 3286 struct net *net;
3287 struct netns_ipvs *ipvs;
3329 3288
3330 net = skb_sknet(skb); 3289 net = skb_sknet(skb);
3290 ipvs = net_ipvs(net);
3331 cmd = info->genlhdr->cmd; 3291 cmd = info->genlhdr->cmd;
3332 3292
3333 if (cmd == IPVS_CMD_GET_SERVICE) 3293 if (cmd == IPVS_CMD_GET_SERVICE)
@@ -3530,9 +3490,21 @@ int __net_init __ip_vs_control_init(struct net *net)
3530{ 3490{
3531 int idx; 3491 int idx;
3532 struct netns_ipvs *ipvs = net_ipvs(net); 3492 struct netns_ipvs *ipvs = net_ipvs(net);
3493 struct ctl_table *tbl;
3533 3494
3534 if (!net_eq(net, &init_net)) /* netns not enabled yet */ 3495 if (!net_eq(net, &init_net)) /* netns not enabled yet */
3535 return -EPERM; 3496 return -EPERM;
3497
3498 atomic_set(&ipvs->dropentry, 0);
3499 spin_lock_init(&ipvs->dropentry_lock);
3500 spin_lock_init(&ipvs->droppacket_lock);
3501 spin_lock_init(&ipvs->securetcp_lock);
3502 ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock);
3503
3504 /* Initialize rs_table */
3505 for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++)
3506 INIT_LIST_HEAD(&ipvs->rs_table[idx]);
3507
3536 /* procfs stats */ 3508 /* procfs stats */
3537 ipvs->tot_stats = kzalloc(sizeof(struct ip_vs_stats), GFP_KERNEL); 3509 ipvs->tot_stats = kzalloc(sizeof(struct ip_vs_stats), GFP_KERNEL);
3538 if (ipvs->tot_stats == NULL) { 3510 if (ipvs->tot_stats == NULL) {
@@ -3553,14 +3525,51 @@ int __net_init __ip_vs_control_init(struct net *net)
3553 proc_net_fops_create(net, "ip_vs_stats", 0, &ip_vs_stats_fops); 3525 proc_net_fops_create(net, "ip_vs_stats", 0, &ip_vs_stats_fops);
3554 proc_net_fops_create(net, "ip_vs_stats_percpu", 0, 3526 proc_net_fops_create(net, "ip_vs_stats_percpu", 0,
3555 &ip_vs_stats_percpu_fops); 3527 &ip_vs_stats_percpu_fops);
3556 sysctl_header = register_net_sysctl_table(net, net_vs_ctl_path, 3528
3529 if (!net_eq(net, &init_net)) {
3530 tbl = kmemdup(vs_vars, sizeof(vs_vars), GFP_KERNEL);
3531 if (tbl == NULL)
3532 goto err_dup;
3533 } else
3534 tbl = vs_vars;
3535 /* Initialize sysctl defaults */
3536 idx = 0;
3537 ipvs->sysctl_amemthresh = 1024;
3538 tbl[idx++].data = &ipvs->sysctl_amemthresh;
3539 ipvs->sysctl_am_droprate = 10;
3540 tbl[idx++].data = &ipvs->sysctl_am_droprate;
3541 tbl[idx++].data = &ipvs->sysctl_drop_entry;
3542 tbl[idx++].data = &ipvs->sysctl_drop_packet;
3543#ifdef CONFIG_IP_VS_NFCT
3544 tbl[idx++].data = &ipvs->sysctl_conntrack;
3545#endif
3546 tbl[idx++].data = &ipvs->sysctl_secure_tcp;
3547 ipvs->sysctl_snat_reroute = 1;
3548 tbl[idx++].data = &ipvs->sysctl_snat_reroute;
3549 ipvs->sysctl_sync_ver = 1;
3550 tbl[idx++].data = &ipvs->sysctl_sync_ver;
3551 tbl[idx++].data = &ipvs->sysctl_cache_bypass;
3552 tbl[idx++].data = &ipvs->sysctl_expire_nodest_conn;
3553 tbl[idx++].data = &ipvs->sysctl_expire_quiescent_template;
3554 ipvs->sysctl_sync_threshold[0] = 3;
3555 ipvs->sysctl_sync_threshold[1] = 50;
3556 tbl[idx].data = &ipvs->sysctl_sync_threshold;
3557 tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
3558 tbl[idx++].data = &ipvs->sysctl_nat_icmp_send;
3559
3560
3561 ipvs->sysctl_hdr = register_net_sysctl_table(net, net_vs_ctl_path,
3557 vs_vars); 3562 vs_vars);
3558 if (sysctl_header == NULL) 3563 if (ipvs->sysctl_hdr == NULL)
3559 goto err_reg; 3564 goto err_reg;
3560 ip_vs_new_estimator(net, ipvs->tot_stats); 3565 ip_vs_new_estimator(net, ipvs->tot_stats);
3566 ipvs->sysctl_tbl = tbl;
3561 return 0; 3567 return 0;
3562 3568
3563err_reg: 3569err_reg:
3570 if (!net_eq(net, &init_net))
3571 kfree(tbl);
3572err_dup:
3564 free_percpu(ipvs->cpustats); 3573 free_percpu(ipvs->cpustats);
3565err_alloc: 3574err_alloc:
3566 kfree(ipvs->tot_stats); 3575 kfree(ipvs->tot_stats);
@@ -3575,7 +3584,7 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net)
3575 return; 3584 return;
3576 3585
3577 ip_vs_kill_estimator(net, ipvs->tot_stats); 3586 ip_vs_kill_estimator(net, ipvs->tot_stats);
3578 unregister_net_sysctl_table(sysctl_header); 3587 unregister_net_sysctl_table(ipvs->sysctl_hdr);
3579 proc_net_remove(net, "ip_vs_stats_percpu"); 3588 proc_net_remove(net, "ip_vs_stats_percpu");
3580 proc_net_remove(net, "ip_vs_stats"); 3589 proc_net_remove(net, "ip_vs_stats");
3581 proc_net_remove(net, "ip_vs"); 3590 proc_net_remove(net, "ip_vs");
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index 550365a690c7..fb2d04ac5d4e 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -34,7 +34,7 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
34 &iph.daddr, sh->dest))) { 34 &iph.daddr, sh->dest))) {
35 int ignored; 35 int ignored;
36 36
37 if (ip_vs_todrop()) { 37 if (ip_vs_todrop(net_ipvs(net))) {
38 /* 38 /*
39 * It seems that we are very loaded. 39 * It seems that we are very loaded.
40 * We have to drop this packet :( 40 * We have to drop this packet :(
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index d8b3f9f15826..c0cc341b840d 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -54,7 +54,7 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
54 &iph.daddr, th->dest))) { 54 &iph.daddr, th->dest))) {
55 int ignored; 55 int ignored;
56 56
57 if (ip_vs_todrop()) { 57 if (ip_vs_todrop(net_ipvs(net))) {
58 /* 58 /*
59 * It seems that we are very loaded. 59 * It seems that we are very loaded.
60 * We have to drop this packet :( 60 * We have to drop this packet :(
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index 581157bbded5..f1282cbe6fe3 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -50,7 +50,7 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
50 if (svc) { 50 if (svc) {
51 int ignored; 51 int ignored;
52 52
53 if (ip_vs_todrop()) { 53 if (ip_vs_todrop(net_ipvs(net))) {
54 /* 54 /*
55 * It seems that we are very loaded. 55 * It seems that we are very loaded.
56 * We have to drop this packet :( 56 * We have to drop this packet :(
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index f85e47daecc3..b1780562c42b 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -394,7 +394,7 @@ void ip_vs_sync_switch_mode(struct net *net, int mode)
394 394
395 if (!ipvs->sync_state & IP_VS_STATE_MASTER) 395 if (!ipvs->sync_state & IP_VS_STATE_MASTER)
396 return; 396 return;
397 if (mode == sysctl_ip_vs_sync_ver || !ipvs->sync_buff) 397 if (mode == ipvs->sysctl_sync_ver || !ipvs->sync_buff)
398 return; 398 return;
399 399
400 spin_lock_bh(&ipvs->sync_buff_lock); 400 spin_lock_bh(&ipvs->sync_buff_lock);
@@ -521,7 +521,7 @@ void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp)
521 unsigned int len, pe_name_len, pad; 521 unsigned int len, pe_name_len, pad;
522 522
523 /* Handle old version of the protocol */ 523 /* Handle old version of the protocol */
524 if (sysctl_ip_vs_sync_ver == 0) { 524 if (ipvs->sysctl_sync_ver == 0) {
525 ip_vs_sync_conn_v0(net, cp); 525 ip_vs_sync_conn_v0(net, cp);
526 return; 526 return;
527 } 527 }
@@ -650,7 +650,7 @@ control:
650 if (cp->flags & IP_VS_CONN_F_TEMPLATE) { 650 if (cp->flags & IP_VS_CONN_F_TEMPLATE) {
651 int pkts = atomic_add_return(1, &cp->in_pkts); 651 int pkts = atomic_add_return(1, &cp->in_pkts);
652 652
653 if (pkts % sysctl_ip_vs_sync_threshold[1] != 1) 653 if (pkts % ipvs->sysctl_sync_threshold[1] != 1)
654 return; 654 return;
655 } 655 }
656 goto sloop; 656 goto sloop;
@@ -724,6 +724,7 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
724{ 724{
725 struct ip_vs_dest *dest; 725 struct ip_vs_dest *dest;
726 struct ip_vs_conn *cp; 726 struct ip_vs_conn *cp;
727 struct netns_ipvs *ipvs = net_ipvs(net);
727 728
728 if (!(flags & IP_VS_CONN_F_TEMPLATE)) 729 if (!(flags & IP_VS_CONN_F_TEMPLATE))
729 cp = ip_vs_conn_in_get(param); 730 cp = ip_vs_conn_in_get(param);
@@ -794,7 +795,7 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
794 795
795 if (opt) 796 if (opt)
796 memcpy(&cp->in_seq, opt, sizeof(*opt)); 797 memcpy(&cp->in_seq, opt, sizeof(*opt));
797 atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]); 798 atomic_set(&cp->in_pkts, ipvs->sysctl_sync_threshold[0]);
798 cp->state = state; 799 cp->state = state;
799 cp->old_state = cp->state; 800 cp->old_state = cp->state;
800 /* 801 /*