Merge branch 'stealer/ipvs/sync-daemon-cleanup-for-next' of git://git.stealer.net...
[safe/jmp/linux-2.6] / net / ipv4 / ipvs / ip_vs_ctl.c
index 8b08d9c..9a5ace0 100644 (file)
@@ -5,8 +5,6 @@
  *              high-performance and highly available server based on a
  *              cluster of servers.
  *
- * Version:     $Id: ip_vs_ctl.c,v 1.36 2003/06/08 09:31:19 wensong Exp $
- *
  * Authors:     Wensong Zhang <wensong@linuxvirtualserver.org>
  *              Peter Kese <peter.kese@ijs.si>
  *              Julian Anastasov <ja@ssi.bg>
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
 #include <linux/swap.h>
-#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/mutex.h>
 
+#include <net/net_namespace.h>
 #include <net/ip.h>
 #include <net/route.h>
 #include <net/sock.h>
@@ -579,6 +577,31 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
        return NULL;
 }
 
+/*
+ * Find destination by {daddr,dport,vaddr,protocol}
+ * Cretaed to be used in ip_vs_process_message() in
+ * the backup synchronization daemon. It finds the
+ * destination to be bound to the received connection
+ * on the backup.
+ *
+ * ip_vs_lookup_real_service() looked promissing, but
+ * seems not working as expected.
+ */
+struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport,
+                                   __be32 vaddr, __be16 vport, __u16 protocol)
+{
+       struct ip_vs_dest *dest;
+       struct ip_vs_service *svc;
+
+       svc = ip_vs_service_get(0, protocol, vaddr, vport);
+       if (!svc)
+               return NULL;
+       dest = ip_vs_lookup_dest(svc, daddr, dport);
+       if (dest)
+               atomic_inc(&dest->refcnt);
+       ip_vs_service_put(svc);
+       return dest;
+}
 
 /*
  *  Lookup dest by {svc,addr,port} in the destination trash.
@@ -679,7 +702,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc,
        conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
 
        /* check if local node and update the flags */
-       if (inet_addr_type(udest->addr) == RTN_LOCAL) {
+       if (inet_addr_type(&init_net, udest->addr) == RTN_LOCAL) {
                conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
                        | IP_VS_CONN_F_LOCALNODE;
        }
@@ -731,7 +754,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest,
 
        EnterFunction(2);
 
-       atype = inet_addr_type(udest->addr);
+       atype = inet_addr_type(&init_net, udest->addr);
        if (atype != RTN_LOCAL && atype != RTN_UNICAST)
                return -EINVAL;
 
@@ -909,7 +932,7 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
        write_lock_bh(&__ip_vs_svc_lock);
 
        /* Wait until all other svc users go away */
-       while (atomic_read(&svc->usecnt) > 1) {};
+       IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
 
        /* call the update_service, because server weight may be changed */
        svc->scheduler->update_service(svc);
@@ -1399,7 +1422,6 @@ proc_do_sync_threshold(ctl_table *table, int write, struct file *filp,
 
 static struct ctl_table vs_vars[] = {
        {
-               .ctl_name       = NET_IPV4_VS_AMEMTHRESH,
                .procname       = "amemthresh",
                .data           = &sysctl_ip_vs_amemthresh,
                .maxlen         = sizeof(int),
@@ -1408,7 +1430,6 @@ static struct ctl_table vs_vars[] = {
        },
 #ifdef CONFIG_IP_VS_DEBUG
        {
-               .ctl_name       = NET_IPV4_VS_DEBUG_LEVEL,
                .procname       = "debug_level",
                .data           = &sysctl_ip_vs_debug_level,
                .maxlen         = sizeof(int),
@@ -1417,7 +1438,6 @@ static struct ctl_table vs_vars[] = {
        },
 #endif
        {
-               .ctl_name       = NET_IPV4_VS_AMDROPRATE,
                .procname       = "am_droprate",
                .data           = &sysctl_ip_vs_am_droprate,
                .maxlen         = sizeof(int),
@@ -1425,7 +1445,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = NET_IPV4_VS_DROP_ENTRY,
                .procname       = "drop_entry",
                .data           = &sysctl_ip_vs_drop_entry,
                .maxlen         = sizeof(int),
@@ -1433,7 +1452,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_do_defense_mode,
        },
        {
-               .ctl_name       = NET_IPV4_VS_DROP_PACKET,
                .procname       = "drop_packet",
                .data           = &sysctl_ip_vs_drop_packet,
                .maxlen         = sizeof(int),
@@ -1441,7 +1459,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_do_defense_mode,
        },
        {
-               .ctl_name       = NET_IPV4_VS_SECURE_TCP,
                .procname       = "secure_tcp",
                .data           = &sysctl_ip_vs_secure_tcp,
                .maxlen         = sizeof(int),
@@ -1450,7 +1467,6 @@ static struct ctl_table vs_vars[] = {
        },
 #if 0
        {
-               .ctl_name       = NET_IPV4_VS_TO_ES,
                .procname       = "timeout_established",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_ESTABLISHED],
                .maxlen         = sizeof(int),
@@ -1458,7 +1474,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_SS,
                .procname       = "timeout_synsent",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_SENT],
                .maxlen         = sizeof(int),
@@ -1466,7 +1481,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_SR,
                .procname       = "timeout_synrecv",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_RECV],
                .maxlen         = sizeof(int),
@@ -1474,7 +1488,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_FW,
                .procname       = "timeout_finwait",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_FIN_WAIT],
                .maxlen         = sizeof(int),
@@ -1482,7 +1495,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_TW,
                .procname       = "timeout_timewait",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_TIME_WAIT],
                .maxlen         = sizeof(int),
@@ -1490,7 +1502,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_CL,
                .procname       = "timeout_close",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE],
                .maxlen         = sizeof(int),
@@ -1498,7 +1509,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_CW,
                .procname       = "timeout_closewait",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE_WAIT],
                .maxlen         = sizeof(int),
@@ -1506,7 +1516,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_LA,
                .procname       = "timeout_lastack",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_LAST_ACK],
                .maxlen         = sizeof(int),
@@ -1514,7 +1523,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_LI,
                .procname       = "timeout_listen",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_LISTEN],
                .maxlen         = sizeof(int),
@@ -1522,7 +1530,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_SA,
                .procname       = "timeout_synack",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_SYNACK],
                .maxlen         = sizeof(int),
@@ -1530,7 +1537,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_UDP,
                .procname       = "timeout_udp",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_UDP],
                .maxlen         = sizeof(int),
@@ -1538,7 +1544,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
-               .ctl_name       = NET_IPV4_VS_TO_ICMP,
                .procname       = "timeout_icmp",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_ICMP],
                .maxlen         = sizeof(int),
@@ -1547,7 +1552,6 @@ static struct ctl_table vs_vars[] = {
        },
 #endif
        {
-               .ctl_name       = NET_IPV4_VS_CACHE_BYPASS,
                .procname       = "cache_bypass",
                .data           = &sysctl_ip_vs_cache_bypass,
                .maxlen         = sizeof(int),
@@ -1555,7 +1559,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = NET_IPV4_VS_EXPIRE_NODEST_CONN,
                .procname       = "expire_nodest_conn",
                .data           = &sysctl_ip_vs_expire_nodest_conn,
                .maxlen         = sizeof(int),
@@ -1563,7 +1566,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE,
                .procname       = "expire_quiescent_template",
                .data           = &sysctl_ip_vs_expire_quiescent_template,
                .maxlen         = sizeof(int),
@@ -1571,7 +1573,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_dointvec,
        },
        {
-               .ctl_name       = NET_IPV4_VS_SYNC_THRESHOLD,
                .procname       = "sync_threshold",
                .data           = &sysctl_ip_vs_sync_threshold,
                .maxlen         = sizeof(sysctl_ip_vs_sync_threshold),
@@ -1579,7 +1580,6 @@ static struct ctl_table vs_vars[] = {
                .proc_handler   = &proc_do_sync_threshold,
        },
        {
-               .ctl_name       = NET_IPV4_VS_NAT_ICMP_SEND,
                .procname       = "nat_icmp_send",
                .data           = &sysctl_ip_vs_nat_icmp_send,
                .maxlen         = sizeof(int),
@@ -1589,35 +1589,13 @@ static struct ctl_table vs_vars[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table vs_table[] = {
-       {
-               .ctl_name       = NET_IPV4_VS,
-               .procname       = "vs",
-               .mode           = 0555,
-               .child          = vs_vars
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ipvs_ipv4_table[] = {
-       {
-               .ctl_name       = NET_IPV4,
-               .procname       = "ipv4",
-               .mode           = 0555,
-               .child          = vs_table,
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table vs_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipvs_ipv4_table,
-       },
-       { .ctl_name = 0 }
+struct ctl_path net_vs_ctl_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ipv4", .ctl_name = NET_IPV4, },
+       { .procname = "vs", },
+       { }
 };
+EXPORT_SYMBOL_GPL(net_vs_ctl_path);
 
 static struct ctl_table_header * sysctl_header;
 
@@ -1783,7 +1761,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations ip_vs_info_seq_ops = {
+static const struct seq_operations ip_vs_info_seq_ops = {
        .start = ip_vs_info_seq_start,
        .next  = ip_vs_info_seq_next,
        .stop  = ip_vs_info_seq_stop,
@@ -1792,24 +1770,8 @@ static struct seq_operations ip_vs_info_seq_ops = {
 
 static int ip_vs_info_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int rc = -ENOMEM;
-       struct ip_vs_iter *s = kzalloc(sizeof(*s), GFP_KERNEL);
-
-       if (!s)
-               goto out;
-
-       rc = seq_open(file, &ip_vs_info_seq_ops);
-       if (rc)
-               goto out_kfree;
-
-       seq          = file->private_data;
-       seq->private = s;
-out:
-       return rc;
-out_kfree:
-       kfree(s);
-       goto out;
+       return seq_open_private(file, &ip_vs_info_seq_ops,
+                       sizeof(struct ip_vs_iter));
 }
 
 static const struct file_operations ip_vs_info_fops = {
@@ -2340,6 +2302,7 @@ static struct nf_sockopt_ops ip_vs_sockopts = {
        .get_optmin     = IP_VS_BASE_CTL,
        .get_optmax     = IP_VS_SO_GET_MAX+1,
        .get            = do_ip_vs_get_ctl,
+       .owner          = THIS_MODULE,
 };
 
 
@@ -2356,10 +2319,10 @@ int ip_vs_control_init(void)
                return ret;
        }
 
-       proc_net_fops_create("ip_vs", 0, &ip_vs_info_fops);
-       proc_net_fops_create("ip_vs_stats",0, &ip_vs_stats_fops);
+       proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops);
+       proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops);
 
-       sysctl_header = register_sysctl_table(vs_root_table, 0);
+       sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars);
 
        /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */
        for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++)  {
@@ -2387,10 +2350,11 @@ void ip_vs_control_cleanup(void)
        EnterFunction(2);
        ip_vs_trash_cleanup();
        cancel_rearming_delayed_work(&defense_work);
+       cancel_work_sync(&defense_work.work);
        ip_vs_kill_estimator(&ip_vs_stats);
        unregister_sysctl_table(sysctl_header);
-       proc_net_remove("ip_vs_stats");
-       proc_net_remove("ip_vs");
+       proc_net_remove(&init_net, "ip_vs_stats");
+       proc_net_remove(&init_net, "ip_vs");
        nf_unregister_sockopt(&ip_vs_sockopts);
        LeaveFunction(2);
 }