sysctl: remove "struct file *" argument of ->proc_handler
[safe/jmp/linux-2.6] / net / ipv4 / route.c
index 65b3a8b..bb41992 100644 (file)
@@ -1093,8 +1093,27 @@ restart:
                 * If we drop it here, the callers have no way to resolve routes
                 * when we're not caching.  Instead, just point *rp at rt, so
                 * the caller gets a single use out of the route
+                * Note that we do rt_free on this new route entry, so that
+                * once its refcount hits zero, we are still able to reap it
+                * (Thanks Alexey)
+                * Note also the rt_free uses call_rcu.  We don't actually
+                * need rcu protection here, this is just our path to get
+                * on the route gc list.
                 */
-               goto report_and_exit;
+
+               if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
+                       int err = arp_bind_neighbour(&rt->u.dst);
+                       if (err) {
+                               if (net_ratelimit())
+                                       printk(KERN_WARNING
+                                           "Neighbour table failure & not caching routes.\n");
+                               rt_drop(rt);
+                               return err;
+                       }
+               }
+
+               rt_free(rt);
+               goto skip_hashing;
        }
 
        rthp = &rt_hash_table[hash].chain;
@@ -1211,7 +1230,8 @@ restart:
 #if RT_CACHE_DEBUG >= 2
        if (rt->u.dst.rt_next) {
                struct rtable *trt;
-               printk(KERN_DEBUG "rt_cache @%02x: %pI4", hash, &rt->rt_dst);
+               printk(KERN_DEBUG "rt_cache @%02x: %pI4",
+                      hash, &rt->rt_dst);
                for (trt = rt->u.dst.rt_next; trt; trt = trt->u.dst.rt_next)
                        printk(" . %pI4", &trt->rt_dst);
                printk("\n");
@@ -1226,7 +1246,7 @@ restart:
 
        spin_unlock_bh(rt_hash_lock_addr(hash));
 
-report_and_exit:
+skip_hashing:
        if (rp)
                *rp = rt;
        else
@@ -1494,13 +1514,17 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
 void ip_rt_send_redirect(struct sk_buff *skb)
 {
        struct rtable *rt = skb_rtable(skb);
-       struct in_device *in_dev = in_dev_get(rt->u.dst.dev);
+       struct in_device *in_dev;
+       int log_martians;
 
-       if (!in_dev)
+       rcu_read_lock();
+       in_dev = __in_dev_get_rcu(rt->u.dst.dev);
+       if (!in_dev || !IN_DEV_TX_REDIRECTS(in_dev)) {
+               rcu_read_unlock();
                return;
-
-       if (!IN_DEV_TX_REDIRECTS(in_dev))
-               goto out;
+       }
+       log_martians = IN_DEV_LOG_MARTIANS(in_dev);
+       rcu_read_unlock();
 
        /* No redirected packets during ip_rt_redirect_silence;
         * reset the algorithm.
@@ -1513,7 +1537,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
         */
        if (rt->u.dst.rate_tokens >= ip_rt_redirect_number) {
                rt->u.dst.rate_last = jiffies;
-               goto out;
+               return;
        }
 
        /* Check for load limit; set rate_last to the latest sent
@@ -1527,7 +1551,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
                rt->u.dst.rate_last = jiffies;
                ++rt->u.dst.rate_tokens;
 #ifdef CONFIG_IP_ROUTE_VERBOSE
-               if (IN_DEV_LOG_MARTIANS(in_dev) &&
+               if (log_martians &&
                    rt->u.dst.rate_tokens == ip_rt_redirect_number &&
                    net_ratelimit())
                        printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n",
@@ -1535,8 +1559,6 @@ void ip_rt_send_redirect(struct sk_buff *skb)
                                &rt->rt_dst, &rt->rt_gateway);
 #endif
        }
-out:
-       in_dev_put(in_dev);
 }
 
 static int ip_error(struct sk_buff *skb)
@@ -3014,7 +3036,7 @@ void ip_rt_multicast_event(struct in_device *in_dev)
 
 #ifdef CONFIG_SYSCTL
 static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
-                                       struct file *filp, void __user *buffer,
+                                       void __user *buffer,
                                        size_t *lenp, loff_t *ppos)
 {
        if (write) {
@@ -3024,7 +3046,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
 
                memcpy(&ctl, __ctl, sizeof(ctl));
                ctl.data = &flush_delay;
-               proc_dointvec(&ctl, write, filp, buffer, lenp, ppos);
+               proc_dointvec(&ctl, write, buffer, lenp, ppos);
 
                net = (struct net *)__ctl->extra1;
                rt_cache_flush(net, flush_delay);
@@ -3084,12 +3106,11 @@ static void rt_secret_reschedule(int old)
 }
 
 static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
-                                         struct file *filp,
                                          void __user *buffer, size_t *lenp,
                                          loff_t *ppos)
 {
        int old = ip_rt_secret_interval;
-       int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos);
+       int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos);
 
        rt_secret_reschedule(old);
 
@@ -3392,7 +3413,7 @@ int __init ip_rt_init(void)
                alloc_large_system_hash("IP route cache",
                                        sizeof(struct rt_hash_bucket),
                                        rhash_entries,
-                                       (num_physpages >= 128 * 1024) ?
+                                       (totalram_pages >= 128 * 1024) ?
                                        15 : 17,
                                        0,
                                        &rt_hash_log,
@@ -3422,7 +3443,7 @@ int __init ip_rt_init(void)
                printk(KERN_ERR "Unable to create route proc files\n");
 #ifdef CONFIG_XFRM
        xfrm_init();
-       xfrm4_init();
+       xfrm4_init(ip_rt_max_size);
 #endif
        rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL);