diff options
-rw-r--r-- | include/net/ip_vs.h | 27 | ||||
-rw-r--r-- | include/net/netns/ip_vs.h | 37 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_conn.c | 7 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 34 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 291 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_proto_sctp.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_proto_tcp.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_proto_udp.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sync.c | 9 |
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 | */ |
44 | static inline struct net *skb_net(struct sk_buff *skb) | 44 | static 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 | ||
72 | static inline struct net *skb_sknet(struct sk_buff *skb) | 72 | static 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 | */ |
1026 | extern int sysctl_ip_vs_cache_bypass; | ||
1027 | extern int sysctl_ip_vs_expire_nodest_conn; | ||
1028 | extern int sysctl_ip_vs_expire_quiescent_template; | ||
1029 | extern int sysctl_ip_vs_sync_threshold[2]; | ||
1030 | extern int sysctl_ip_vs_nat_icmp_send; | ||
1031 | extern int sysctl_ip_vs_conntrack; | ||
1032 | extern int sysctl_ip_vs_snat_reroute; | ||
1033 | extern struct ip_vs_stats ip_vs_stats; | 1026 | extern struct ip_vs_stats ip_vs_stats; |
1034 | extern const struct ctl_path net_vs_ctl_path[]; | 1027 | extern const struct ctl_path net_vs_ctl_path[]; |
1035 | extern int sysctl_ip_vs_sync_ver; | 1028 | extern int sysctl_ip_vs_sync_ver; |
@@ -1119,11 +1112,13 @@ extern int ip_vs_icmp_xmit_v6 | |||
1119 | extern int ip_vs_drop_rate; | 1112 | extern int ip_vs_drop_rate; |
1120 | extern int ip_vs_drop_counter; | 1113 | extern int ip_vs_drop_counter; |
1121 | 1114 | ||
1122 | static __inline__ int ip_vs_todrop(void) | 1115 | static 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 | */ |
1214 | static inline int ip_vs_conntrack_enabled(void) | 1209 | static 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 | ||
1219 | extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, | 1214 | extern 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 | ||
1229 | static inline int ip_vs_conntrack_enabled(void) | 1224 | static 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) | |||
686 | int ip_vs_check_template(struct ip_vs_conn *ct) | 686 | int 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: | 1202 | flush_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, | |||
499 | int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | 499 | int 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 */ |
59 | static DEFINE_RWLOCK(__ip_vs_svc_lock); | 59 | static DEFINE_RWLOCK(__ip_vs_svc_lock); |
60 | 60 | ||
61 | /* lock for table with the real services */ | ||
62 | static DEFINE_RWLOCK(__ip_vs_rs_lock); | ||
63 | |||
64 | /* lock for state and timeout tables */ | ||
65 | static DEFINE_SPINLOCK(ip_vs_securetcp_lock); | ||
66 | |||
67 | /* lock for drop entry handling */ | ||
68 | static DEFINE_SPINLOCK(__ip_vs_dropentry_lock); | ||
69 | |||
70 | /* lock for drop packet handling */ | ||
71 | static DEFINE_SPINLOCK(__ip_vs_droppacket_lock); | ||
72 | |||
73 | /* 1/rate drop and drop-entry variables */ | ||
74 | int ip_vs_drop_rate = 0; | ||
75 | int ip_vs_drop_counter = 0; | ||
76 | static atomic_t ip_vs_dropentry = ATOMIC_INIT(0); | ||
77 | |||
78 | /* number of virtual services */ | ||
79 | static int ip_vs_num_services = 0; | ||
80 | |||
81 | /* sysctl variables */ | 61 | /* sysctl variables */ |
82 | static int sysctl_ip_vs_drop_entry = 0; | ||
83 | static int sysctl_ip_vs_drop_packet = 0; | ||
84 | static int sysctl_ip_vs_secure_tcp = 0; | ||
85 | static int sysctl_ip_vs_amemthresh = 1024; | ||
86 | static int sysctl_ip_vs_am_droprate = 10; | ||
87 | int sysctl_ip_vs_cache_bypass = 0; | ||
88 | int sysctl_ip_vs_expire_nodest_conn = 0; | ||
89 | int sysctl_ip_vs_expire_quiescent_template = 0; | ||
90 | int sysctl_ip_vs_sync_threshold[2] = { 3, 50 }; | ||
91 | int sysctl_ip_vs_nat_icmp_send = 0; | ||
92 | #ifdef CONFIG_IP_VS_NFCT | ||
93 | int sysctl_ip_vs_conntrack; | ||
94 | #endif | ||
95 | int sysctl_ip_vs_snat_reroute = 1; | ||
96 | int 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 |
99 | static int sysctl_ip_vs_debug_level = 0; | 64 | static 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 | */ |
1023 | static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest) | 988 | static 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 | |||
1092 | ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) | 1059 | ip_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 | ||
1594 | static struct ctl_table vs_vars[] = { | 1564 | static 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 | }; |
1792 | EXPORT_SYMBOL_GPL(net_vs_ctl_path); | 1750 | EXPORT_SYMBOL_GPL(net_vs_ctl_path); |
1793 | 1751 | ||
1794 | static struct ctl_table_header * sysctl_header; | ||
1795 | |||
1796 | #ifdef CONFIG_PROC_FS | 1752 | #ifdef CONFIG_PROC_FS |
1797 | 1753 | ||
1798 | struct ip_vs_iter { | 1754 | struct 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 | ||
3563 | err_reg: | 3569 | err_reg: |
3570 | if (!net_eq(net, &init_net)) | ||
3571 | kfree(tbl); | ||
3572 | err_dup: | ||
3564 | free_percpu(ipvs->cpustats); | 3573 | free_percpu(ipvs->cpustats); |
3565 | err_alloc: | 3574 | err_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 | /* |