]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv4/route.c
[FS] seq_file: Introduce the seq_open_private()
[net-next-2.6.git] / net / ipv4 / route.c
index 88fa648d7ba33cf23757d1db1544c2954a230706..307e1f1107ca846230742289121e5d73709b10b9 100644 (file)
@@ -81,6 +81,7 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/workqueue.h>
 #include <linux/skbuff.h>
 #include <linux/inetdevice.h>
 #include <linux/igmp.h>
@@ -91,6 +92,7 @@
 #include <linux/jhash.h>
 #include <linux/rcupdate.h>
 #include <linux/times.h>
+#include <net/net_namespace.h>
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/route.h>
@@ -135,7 +137,8 @@ static unsigned long rt_deadline;
 #define RTprint(a...)  printk(KERN_DEBUG a)
 
 static struct timer_list rt_flush_timer;
-static struct timer_list rt_periodic_timer;
+static void rt_check_expire(struct work_struct *work);
+static DECLARE_DELAYED_WORK(expires_work, rt_check_expire);
 static struct timer_list rt_secret_timer;
 
 /*
@@ -243,7 +246,7 @@ static spinlock_t   *rt_hash_locks;
 
 static struct rt_hash_bucket   *rt_hash_table;
 static unsigned                        rt_hash_mask;
-static int                     rt_hash_log;
+static unsigned int            rt_hash_log;
 static unsigned int            rt_hash_rnd;
 
 static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
@@ -374,8 +377,9 @@ static int rt_cache_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct rt_cache_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct rt_cache_iter_state *s;
 
+       s = kzalloc(sizeof(*s), GFP_KERNEL);
        if (!s)
                goto out;
        rc = seq_open(file, &rt_cache_seq_ops);
@@ -383,7 +387,6 @@ static int rt_cache_seq_open(struct inode *inode, struct file *file)
                goto out_kfree;
        seq          = file->private_data;
        seq->private = s;
-       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
@@ -571,33 +574,32 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
                (fl1->iif ^ fl2->iif)) == 0;
 }
 
-/* This runs via a timer and thus is always in BH context. */
-static void rt_check_expire(unsigned long dummy)
+static void rt_check_expire(struct work_struct *work)
 {
        static unsigned int rover;
        unsigned int i = rover, goal;
        struct rtable *rth, **rthp;
-       unsigned long now = jiffies;
        u64 mult;
 
        mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
        if (ip_rt_gc_timeout > 1)
                do_div(mult, ip_rt_gc_timeout);
        goal = (unsigned int)mult;
-       if (goal > rt_hash_mask) goal = rt_hash_mask + 1;
+       if (goal > rt_hash_mask)
+               goal = rt_hash_mask + 1;
        for (; goal > 0; goal--) {
                unsigned long tmo = ip_rt_gc_timeout;
 
                i = (i + 1) & rt_hash_mask;
                rthp = &rt_hash_table[i].chain;
 
-               if (*rthp == 0)
+               if (*rthp == NULL)
                        continue;
-               spin_lock(rt_hash_lock_addr(i));
+               spin_lock_bh(rt_hash_lock_addr(i));
                while ((rth = *rthp) != NULL) {
                        if (rth->u.dst.expires) {
                                /* Entry is expired even if it is in use */
-                               if (time_before_eq(now, rth->u.dst.expires)) {
+                               if (time_before_eq(jiffies, rth->u.dst.expires)) {
                                        tmo >>= 1;
                                        rthp = &rth->u.dst.rt_next;
                                        continue;
@@ -612,14 +614,10 @@ static void rt_check_expire(unsigned long dummy)
                        *rthp = rth->u.dst.rt_next;
                        rt_free(rth);
                }
-               spin_unlock(rt_hash_lock_addr(i));
-
-               /* Fallback loop breaker. */
-               if (time_after(jiffies, now))
-                       break;
+               spin_unlock_bh(rt_hash_lock_addr(i));
        }
        rover = i;
-       mod_timer(&rt_periodic_timer, jiffies + ip_rt_gc_interval);
+       schedule_delayed_work(&expires_work, ip_rt_gc_interval);
 }
 
 /* This can run from both BH and non-BH contexts, the latter
@@ -1404,8 +1402,8 @@ static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
 {
        struct rtable *rt = (struct rtable *) dst;
        struct in_device *idev = rt->idev;
-       if (dev != &loopback_dev && idev && idev->dev == dev) {
-               struct in_device *loopback_idev = in_dev_get(&loopback_dev);
+       if (dev != init_net.loopback_dev && idev && idev->dev == dev) {
+               struct in_device *loopback_idev = in_dev_get(init_net.loopback_dev);
                if (loopback_idev) {
                        rt->idev = loopback_idev;
                        in_dev_put(idev);
@@ -1557,7 +1555,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 #endif
        rth->rt_iif     =
        rth->fl.iif     = dev->ifindex;
-       rth->u.dst.dev  = &loopback_dev;
+       rth->u.dst.dev  = init_net.loopback_dev;
        dev_hold(rth->u.dst.dev);
        rth->idev       = in_dev_get(rth->u.dst.dev);
        rth->fl.oif     = 0;
@@ -1814,7 +1812,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        if (res.type == RTN_LOCAL) {
                int result;
                result = fib_validate_source(saddr, daddr, tos,
-                                            loopback_dev.ifindex,
+                                            init_net.loopback_dev->ifindex,
                                             dev, &spec_dst, &itag);
                if (result < 0)
                        goto martian_source;
@@ -1881,7 +1879,7 @@ local_input:
 #endif
        rth->rt_iif     =
        rth->fl.iif     = dev->ifindex;
-       rth->u.dst.dev  = &loopback_dev;
+       rth->u.dst.dev  = init_net.loopback_dev;
        dev_hold(rth->u.dst.dev);
        rth->idev       = in_dev_get(rth->u.dst.dev);
        rth->rt_gateway = daddr;
@@ -2151,7 +2149,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                                                  RT_SCOPE_UNIVERSE),
                                      } },
                            .mark = oldflp->mark,
-                           .iif = loopback_dev.ifindex,
+                           .iif = init_net.loopback_dev->ifindex,
                            .oif = oldflp->oif };
        struct fib_result res;
        unsigned flags = 0;
@@ -2212,7 +2210,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
 
 
        if (oldflp->oif) {
-               dev_out = dev_get_by_index(oldflp->oif);
+               dev_out = dev_get_by_index(&init_net, oldflp->oif);
                err = -ENODEV;
                if (dev_out == NULL)
                        goto out;
@@ -2245,9 +2243,9 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK);
                if (dev_out)
                        dev_put(dev_out);
-               dev_out = &loopback_dev;
+               dev_out = init_net.loopback_dev;
                dev_hold(dev_out);
-               fl.oif = loopback_dev.ifindex;
+               fl.oif = init_net.loopback_dev->ifindex;
                res.type = RTN_LOCAL;
                flags |= RTCF_LOCAL;
                goto make_route;
@@ -2292,7 +2290,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        fl.fl4_src = fl.fl4_dst;
                if (dev_out)
                        dev_put(dev_out);
-               dev_out = &loopback_dev;
+               dev_out = init_net.loopback_dev;
                dev_hold(dev_out);
                fl.oif = dev_out->ifindex;
                if (res.fi)
@@ -2591,7 +2589,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        if (iif) {
                struct net_device *dev;
 
-               dev = __dev_get_by_index(iif);
+               dev = __dev_get_by_index(&init_net, iif);
                if (dev == NULL) {
                        err = -ENODEV;
                        goto errout_free;
@@ -2967,7 +2965,7 @@ int __init ip_rt_init(void)
 
        ipv4_dst_ops.kmem_cachep =
                kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0,
-                                 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+                                 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
 
        ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep;
 
@@ -2992,17 +2990,14 @@ int __init ip_rt_init(void)
 
        init_timer(&rt_flush_timer);
        rt_flush_timer.function = rt_run_flush;
-       init_timer(&rt_periodic_timer);
-       rt_periodic_timer.function = rt_check_expire;
        init_timer(&rt_secret_timer);
        rt_secret_timer.function = rt_secret_rebuild;
 
        /* All the timers, started at system startup tend
           to synchronize. Perturb it a bit.
         */
-       rt_periodic_timer.expires = jiffies + net_random() % ip_rt_gc_interval +
-                                       ip_rt_gc_interval;
-       add_timer(&rt_periodic_timer);
+       schedule_delayed_work(&expires_work,
+               net_random() % ip_rt_gc_interval + ip_rt_gc_interval);
 
        rt_secret_timer.expires = jiffies + net_random() % ip_rt_secret_interval +
                ip_rt_secret_interval;
@@ -3011,15 +3006,15 @@ int __init ip_rt_init(void)
 #ifdef CONFIG_PROC_FS
        {
        struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */
-       if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
+       if (!proc_net_fops_create(&init_net, "rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
            !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
-                                            proc_net_stat))) {
+                                            init_net.proc_net_stat))) {
                return -ENOMEM;
        }
        rtstat_pde->proc_fops = &rt_cpu_seq_fops;
        }
 #ifdef CONFIG_NET_CLS_ROUTE
-       create_proc_read_entry("rt_acct", 0, proc_net, ip_rt_acct_read, NULL);
+       create_proc_read_entry("rt_acct", 0, init_net.proc_net, ip_rt_acct_read, NULL);
 #endif
 #endif
 #ifdef CONFIG_XFRM