VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / net / ipv4 / route.c
index 0c6d859..15d9eca 100644 (file)
@@ -138,6 +138,7 @@ static struct timer_list rt_secret_timer;
 
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
 static void             ipv4_dst_destroy(struct dst_entry *dst);
+static void             ipv4_dst_ifdown(struct dst_entry *dst, int how);
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void             ipv4_link_failure(struct sk_buff *skb);
 static void             ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
@@ -150,6 +151,7 @@ static struct dst_ops ipv4_dst_ops = {
        .gc =                   rt_garbage_collect,
        .check =                ipv4_dst_check,
        .destroy =              ipv4_dst_destroy,
+       .ifdown =               ipv4_dst_ifdown,
        .negative_advice =      ipv4_negative_advice,
        .link_failure =         ipv4_link_failure,
        .update_pmtu =          ip_rt_update_pmtu,
@@ -430,20 +432,20 @@ static struct file_operations rt_cpu_seq_fops = {
        .open    = rt_cpu_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release_private,
+       .release = seq_release,
 };
 
 #endif /* CONFIG_PROC_FS */
   
 static __inline__ void rt_free(struct rtable *rt)
 {
-       call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst);
+       call_rcu(&rt->u.dst.rcu_head, dst_rcu_free);
 }
 
 static __inline__ void rt_drop(struct rtable *rt)
 {
        ip_rt_put(rt);
-       call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst);
+       call_rcu(&rt->u.dst.rcu_head, dst_rcu_free);
 }
 
 static __inline__ int rt_fast_clean(struct rtable *rth)
@@ -1040,6 +1042,8 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
                                rt->u.dst.child         = NULL;
                                if (rt->u.dst.dev)
                                        dev_hold(rt->u.dst.dev);
+                               if (rt->idev)
+                                       in_dev_hold(rt->idev);
                                rt->u.dst.obsolete      = 0;
                                rt->u.dst.lastuse       = jiffies;
                                rt->u.dst.path          = &rt->u.dst;
@@ -1321,11 +1325,27 @@ static void ipv4_dst_destroy(struct dst_entry *dst)
 {
        struct rtable *rt = (struct rtable *) dst;
        struct inet_peer *peer = rt->peer;
+       struct in_device *idev = rt->idev;
 
        if (peer) {
                rt->peer = NULL;
                inet_putpeer(peer);
        }
+
+       if (idev) {
+               rt->idev = NULL;
+               in_dev_put(idev);
+       }
+}
+
+static void ipv4_dst_ifdown(struct dst_entry *dst, int how)
+{
+       struct rtable *rt = (struct rtable *) dst;
+       struct in_device *idev = rt->idev;
+       if (idev) {
+               rt->idev = NULL;
+               in_dev_put(idev);
+       }
 }
 
 static void ipv4_link_failure(struct sk_buff *skb)
@@ -1339,8 +1359,10 @@ static void ipv4_link_failure(struct sk_buff *skb)
                dst_set_expires(&rt->u.dst, 0);
 }
 
-static int ip_rt_bug(struct sk_buff *skb)
+static int ip_rt_bug(struct sk_buff **pskb)
 {
+       struct sk_buff *skb = *pskb;
+
        printk(KERN_DEBUG "ip_rt_bug: %u.%u.%u.%u -> %u.%u.%u.%u, %s\n",
                NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr),
                skb->dev ? skb->dev->name : "?");
@@ -1486,6 +1508,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
        rth->fl.iif     = dev->ifindex;
        rth->u.dst.dev  = &loopback_dev;
        dev_hold(rth->u.dst.dev);
+       rth->idev       = in_dev_get(rth->u.dst.dev);
        rth->fl.oif     = 0;
        rth->rt_gateway = daddr;
        rth->rt_spec_dst= spec_dst;
@@ -1695,6 +1718,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
        rth->fl.iif     = dev->ifindex;
        rth->u.dst.dev  = out_dev->dev;
        dev_hold(rth->u.dst.dev);
+       rth->idev       = in_dev_get(rth->u.dst.dev);
        rth->fl.oif     = 0;
        rth->rt_spec_dst= spec_dst;
 
@@ -1705,17 +1729,6 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
 
        rth->rt_flags = flags;
 
-#ifdef CONFIG_NET_FASTROUTE
-       if (netdev_fastroute && !(flags&(RTCF_NAT|RTCF_MASQ|RTCF_DOREDIRECT))) {
-               struct net_device *odev = rth->u.dst.dev;
-               if (odev != dev &&
-                   dev->accept_fastpath &&
-                   odev->mtu >= dev->mtu &&
-                   dev->accept_fastpath(dev, &rth->u.dst) == 0)
-                       rth->rt_flags |= RTCF_FAST;
-       }
-#endif
-
 intern:
        err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
 done:
@@ -1774,6 +1787,7 @@ local_input:
        rth->fl.iif     = dev->ifindex;
        rth->u.dst.dev  = &loopback_dev;
        dev_hold(rth->u.dst.dev);
+       rth->idev       = in_dev_get(rth->u.dst.dev);
        rth->rt_gateway = daddr;
        rth->rt_spec_dst= spec_dst;
        rth->u.dst.input= ip_local_deliver;
@@ -2157,6 +2171,7 @@ make_route:
        rth->rt_iif     = oldflp->oif ? : dev_out->ifindex;
        rth->u.dst.dev  = dev_out;
        dev_hold(dev_out);
+       rth->idev       = in_dev_get(dev_out);
        rth->rt_gateway = fl.fl4_dst;
        rth->rt_spec_dst= fl.fl4_src;
 
@@ -2482,11 +2497,11 @@ void ip_rt_multicast_event(struct in_device *in_dev)
 static int flush_delay;
 
 static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write,
-                                       struct file *filp, void *buffer,
-                                       size_t *lenp)
+                                       struct file *filp, void __user *buffer,
+                                       size_t *lenp, loff_t *ppos)
 {
        if (write) {
-               proc_dointvec(ctl, write, filp, buffer, lenp);
+               proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
                rt_cache_flush(flush_delay);
                return 0;
        } 
@@ -2494,15 +2509,19 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write,
        return -EINVAL;
 }
 
-static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, int *name,
-                                               int nlen, void *oldval,
-                                               size_t *oldlenp, void *newval,
-                                               size_t newlen, void **context)
+static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
+                                               int __user *name,
+                                               int nlen,
+                                               void __user *oldval,
+                                               size_t __user *oldlenp,
+                                               void __user *newval,
+                                               size_t newlen,
+                                               void **context)
 {
        int delay;
        if (newlen != sizeof(int))
                return -EINVAL;
-       if (get_user(delay, (int *)newval))
+       if (get_user(delay, (int __user *)newval))
                return -EFAULT; 
        rt_cache_flush(delay); 
        return 0;