[NET] IPV4: Fix whitespace errors.
[safe/jmp/linux-2.6] / net / ipv4 / route.c
index fca5fe0..56d6602 100644 (file)
@@ -20,7 +20,7 @@
  *             (rco@di.uminho.pt)      Routing table insertion and update
  *             Linus Torvalds  :       Rewrote bits to be sensible
  *             Alan Cox        :       Added BSD route gw semantics
- *             Alan Cox        :       Super /proc >4K 
+ *             Alan Cox        :       Super /proc >4K
  *             Alan Cox        :       MTU in route table
  *             Alan Cox        :       MSS actually. Also added the window
  *                                     clamper.
@@ -38,7 +38,7 @@
  *             Alan Cox        :       Faster /proc handling
  *     Alexey Kuznetsov        :       Massive rework to support tree based routing,
  *                                     routing caches and better behaviour.
- *             
+ *
  *             Olaf Erb        :       irtt wasn't being copied right.
  *             Bjorn Ekwall    :       Kerneld route support.
  *             Alan Cox        :       Multicast fixed (I hope)
@@ -55,6 +55,8 @@
  *     Robert Olsson           :       Added rt_cache statistics
  *     Arnaldo C. Melo         :       Convert proc stuff to seq_file
  *     Eric Dumazet            :       hashed spinlocks and rt_check_expire() fixes.
+ *     Ilia Sotnikov           :       Ignore TOS on PMTUD and Redirect
+ *     Ilia Sotnikov           :       Removed TOS from hash calculations
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
@@ -62,7 +64,6 @@
  *             2 of the License, or (at your option) any later version.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <net/icmp.h>
 #include <net/xfrm.h>
 #include <net/ip_mp_alg.h>
+#include <net/netevent.h>
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 #endif
@@ -204,21 +206,27 @@ __u8 ip_tos2prio[16] = {
 struct rt_hash_bucket {
        struct rtable   *chain;
 };
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || \
+       defined(CONFIG_PROVE_LOCKING)
 /*
  * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks
  * The size of this table is a power of two and depends on the number of CPUS.
+ * (on lockdep we have a quite big spinlock_t, so keep the size down there)
  */
-#if NR_CPUS >= 32
-#define RT_HASH_LOCK_SZ        4096
-#elif NR_CPUS >= 16
-#define RT_HASH_LOCK_SZ        2048
-#elif NR_CPUS >= 8
-#define RT_HASH_LOCK_SZ        1024
-#elif NR_CPUS >= 4
-#define RT_HASH_LOCK_SZ        512
+#ifdef CONFIG_LOCKDEP
+# define RT_HASH_LOCK_SZ       256
 #else
-#define RT_HASH_LOCK_SZ        256
+# if NR_CPUS >= 32
+#  define RT_HASH_LOCK_SZ      4096
+# elif NR_CPUS >= 16
+#  define RT_HASH_LOCK_SZ      2048
+# elif NR_CPUS >= 8
+#  define RT_HASH_LOCK_SZ      1024
+# elif NR_CPUS >= 4
+#  define RT_HASH_LOCK_SZ      512
+# else
+#  define RT_HASH_LOCK_SZ      256
+# endif
 #endif
 
 static spinlock_t      *rt_hash_locks;
@@ -242,17 +250,21 @@ static unsigned int               rt_hash_rnd;
 
 static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
 #define RT_CACHE_STAT_INC(field) \
-       (per_cpu(rt_cache_stat, raw_smp_processor_id()).field++)
+       (__raw_get_cpu_var(rt_cache_stat).field++)
 
 static int rt_intern_hash(unsigned hash, struct rtable *rth,
                                struct rtable **res);
 
-static unsigned int rt_hash_code(u32 daddr, u32 saddr, u8 tos)
+static unsigned int rt_hash_code(u32 daddr, u32 saddr)
 {
-       return (jhash_3words(daddr, saddr, (u32) tos, rt_hash_rnd)
+       return (jhash_2words(daddr, saddr, rt_hash_rnd)
                & rt_hash_mask);
 }
 
+#define rt_hash(daddr, saddr, idx) \
+       rt_hash_code((__force u32)(__be32)(daddr),\
+                    (__force u32)(__be32)(saddr) ^ ((idx) << 5))
+
 #ifdef CONFIG_PROC_FS
 struct rt_cache_iter_state {
        int bucket;
@@ -349,8 +361,8 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
                                       dev_queue_xmit) : 0,
                        r->rt_spec_dst);
                seq_printf(seq, "%-127s\n", temp);
-        }
-       return 0;
+       }
+       return 0;
 }
 
 static struct seq_operations rt_cache_seq_ops = {
@@ -417,7 +429,7 @@ static void *rt_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
                return &per_cpu(rt_cache_stat, cpu);
        }
        return NULL;
-       
+
 }
 
 static void rt_cpu_seq_stop(struct seq_file *seq, void *v)
@@ -433,7 +445,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
                seq_printf(seq, "entries  in_hit in_slow_tot in_slow_mc in_no_route in_brd in_martian_dst in_martian_src  out_hit out_slow_tot out_slow_mc  gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n");
                return 0;
        }
-       
+
        seq_printf(seq,"%08x  %08x %08x %08x %08x %08x %08x %08x "
                   " %08x %08x %08x %08x %08x %08x %08x %08x %08x \n",
                   atomic_read(&ipv4_dst_ops.entries),
@@ -447,7 +459,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
 
                   st->out_hit,
                   st->out_slow_tot,
-                  st->out_slow_mc, 
+                  st->out_slow_mc,
 
                   st->gc_total,
                   st->gc_ignored,
@@ -481,7 +493,7 @@ static struct file_operations rt_cpu_seq_fops = {
 };
 
 #endif /* CONFIG_PROC_FS */
-  
+
 static __inline__ void rt_free(struct rtable *rt)
 {
        multipath_remove(rt);
@@ -554,9 +566,13 @@ static inline u32 rt_score(struct rtable *rt)
 
 static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
 {
-       return memcmp(&fl1->nl_u.ip4_u, &fl2->nl_u.ip4_u, sizeof(fl1->nl_u.ip4_u)) == 0 &&
-              fl1->oif     == fl2->oif &&
-              fl1->iif     == fl2->iif;
+       return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
+               (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) |
+               (fl1->mark ^ fl2->mark) |
+               (*(u16 *)&fl1->nl_u.ip4_u.tos ^
+                *(u16 *)&fl2->nl_u.ip4_u.tos) |
+               (fl1->oif ^ fl2->oif) |
+               (fl1->iif ^ fl2->iif)) == 0;
 }
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
@@ -656,8 +672,8 @@ static void rt_check_expire(unsigned long dummy)
                                rt_free(rth);
                        }
 #else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
-                       *rthp = rth->u.rt_next;
-                       rt_free(rth);
+                       *rthp = rth->u.rt_next;
+                       rt_free(rth);
 #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
                }
                spin_unlock(rt_hash_lock_addr(i));
@@ -723,7 +739,7 @@ void rt_cache_flush(int delay)
 
                if (user_mode && tmo < ip_rt_max_delay-ip_rt_min_delay)
                        tmo = 0;
-               
+
                if (delay > tmo)
                        delay = tmo;
        }
@@ -1066,7 +1082,7 @@ static void ip_select_fb_ident(struct iphdr *iph)
        u32 salt;
 
        spin_lock_bh(&ip_fb_id_lock);
-       salt = secure_ip_id(ip_fallback_id ^ iph->daddr);
+       salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr);
        iph->id = htons(salt & 0xFFFF);
        ip_fallback_id = salt;
        spin_unlock_bh(&ip_fb_id_lock);
@@ -1088,7 +1104,7 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
                        return;
                }
        } else
-               printk(KERN_DEBUG "rt_bind_peer(0) @%p\n", 
+               printk(KERN_DEBUG "rt_bind_peer(0) @%p\n",
                       __builtin_return_address(0));
 
        ip_select_fb_ident(iph);
@@ -1110,16 +1126,15 @@ static void rt_del(unsigned hash, struct rtable *rt)
        spin_unlock_bh(rt_hash_lock_addr(hash));
 }
 
-void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
-                   u32 saddr, u8 tos, struct net_device *dev)
+void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
+                   __be32 saddr, struct net_device *dev)
 {
        int i, k;
        struct in_device *in_dev = in_dev_get(dev);
        struct rtable *rth, **rthp;
-       u32  skeys[2] = { saddr, 0 };
+       __be32  skeys[2] = { saddr, 0 };
        int  ikeys[2] = { dev->ifindex, 0 };
-
-       tos &= IPTOS_RT_MASK;
+       struct netevent_redirect netevent;
 
        if (!in_dev)
                return;
@@ -1140,9 +1155,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
 
        for (i = 0; i < 2; i++) {
                for (k = 0; k < 2; k++) {
-                       unsigned hash = rt_hash_code(daddr,
-                                                    skeys[i] ^ (ikeys[k] << 5),
-                                                    tos);
+                       unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]);
 
                        rthp=&rt_hash_table[hash].chain;
 
@@ -1152,7 +1165,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
 
                                if (rth->fl.fl4_dst != daddr ||
                                    rth->fl.fl4_src != skeys[i] ||
-                                   rth->fl.fl4_tos != tos ||
                                    rth->fl.oif != ikeys[k] ||
                                    rth->fl.iif != 0) {
                                        rthp = &rth->u.rt_next;
@@ -1178,7 +1190,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
 
                                /* Copy all the information. */
                                *rt = *rth;
-                               INIT_RCU_HEAD(&rt->u.dst.rcu_head);
+                               INIT_RCU_HEAD(&rt->u.dst.rcu_head);
                                rt->u.dst.__use         = 1;
                                atomic_set(&rt->u.dst.__refcnt, 1);
                                rt->u.dst.child         = NULL;
@@ -1214,6 +1226,11 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
                                        goto do_next;
                                }
 
+                               netevent.old = &rth->u.dst;
+                               netevent.new = &rt->u.dst;
+                               call_netevent_notifiers(NETEVENT_REDIRECT,
+                                                       &netevent);
+
                                rt_del(hash, rth);
                                if (!rt_intern_hash(hash, rt, &rt))
                                        ip_rt_put(rt);
@@ -1232,10 +1249,9 @@ reject_redirect:
        if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
                printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about "
                        "%u.%u.%u.%u ignored.\n"
-                       "  Advised path = %u.%u.%u.%u -> %u.%u.%u.%u, "
-                       "tos %02x\n",
+                       "  Advised path = %u.%u.%u.%u -> %u.%u.%u.%u\n",
                       NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw),
-                      NIPQUAD(saddr), NIPQUAD(daddr), tos);
+                      NIPQUAD(saddr), NIPQUAD(daddr));
 #endif
        in_dev_put(in_dev);
 }
@@ -1251,10 +1267,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
                        ret = NULL;
                } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
                           rt->u.dst.expires) {
-                       unsigned hash = rt_hash_code(rt->fl.fl4_dst,
-                                                    rt->fl.fl4_src ^
-                                                       (rt->fl.oif << 5),
-                                                    rt->fl.fl4_tos);
+                       unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
+                                               rt->fl.oif);
 #if RT_CACHE_DEBUG >= 1
                        printk(KERN_DEBUG "ip_rt_advice: redirect to "
                                          "%u.%u.%u.%u/%02x dropped\n",
@@ -1311,7 +1325,8 @@ void ip_rt_send_redirect(struct sk_buff *skb)
        /* Check for load limit; set rate_last to the latest sent
         * redirect.
         */
-       if (time_after(jiffies,
+       if (rt->u.dst.rate_tokens == 0 ||
+           time_after(jiffies,
                       (rt->u.dst.rate_last +
                        (ip_rt_redirect_load << rt->u.dst.rate_tokens)))) {
                icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
@@ -1328,7 +1343,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 #endif
        }
 out:
-        in_dev_put(in_dev);
+       in_dev_put(in_dev);
 }
 
 static int ip_error(struct sk_buff *skb)
@@ -1364,7 +1379,7 @@ static int ip_error(struct sk_buff *skb)
 
 out:   kfree_skb(skb);
        return 0;
-} 
+}
 
 /*
  *     The last two values are not from the RFC but
@@ -1377,7 +1392,7 @@ static const unsigned short mtu_plateau[] =
 static __inline__ unsigned short guess_mtu(unsigned short old_mtu)
 {
        int i;
-       
+
        for (i = 0; i < ARRAY_SIZE(mtu_plateau); i++)
                if (old_mtu > mtu_plateau[i])
                        return mtu_plateau[i];
@@ -1389,16 +1404,15 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
        int i;
        unsigned short old_mtu = ntohs(iph->tot_len);
        struct rtable *rth;
-       u32  skeys[2] = { iph->saddr, 0, };
-       u32  daddr = iph->daddr;
-       u8   tos = iph->tos & IPTOS_RT_MASK;
+       __be32  skeys[2] = { iph->saddr, 0, };
+       __be32  daddr = iph->daddr;
        unsigned short est_mtu = 0;
 
        if (ipv4_config.no_pmtu_disc)
                return 0;
 
        for (i = 0; i < 2; i++) {
-               unsigned hash = rt_hash_code(daddr, skeys[i], tos);
+               unsigned hash = rt_hash(daddr, skeys[i], 0);
 
                rcu_read_lock();
                for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -1407,7 +1421,6 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
                            rth->fl.fl4_src == skeys[i] &&
                            rth->rt_dst  == daddr &&
                            rth->rt_src  == iph->saddr &&
-                           rth->fl.fl4_tos == tos &&
                            rth->fl.iif == 0 &&
                            !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
                                unsigned short mtu = new_mtu;
@@ -1423,7 +1436,7 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
                                        mtu = guess_mtu(old_mtu);
                                }
                                if (mtu <= rth->u.dst.metrics[RTAX_MTU-1]) {
-                                       if (mtu < rth->u.dst.metrics[RTAX_MTU-1]) { 
+                                       if (mtu < rth->u.dst.metrics[RTAX_MTU-1]) {
                                                dst_confirm(&rth->u.dst);
                                                if (mtu < ip_rt_min_pmtu) {
                                                        mtu = ip_rt_min_pmtu;
@@ -1453,6 +1466,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
                }
                dst->metrics[RTAX_MTU-1] = mtu;
                dst_set_expires(dst, ip_rt_mtu_expires);
+               call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
        }
 }
 
@@ -1523,7 +1537,7 @@ static int ip_rt_bug(struct sk_buff *skb)
 
 void ip_rt_get_source(u8 *addr, struct rtable *rt)
 {
-       u32 src;
+       __be32 src;
        struct fib_result res;
 
        if (rt->fl.iif == 0)
@@ -1586,15 +1600,15 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
 #endif
        set_class_tag(rt, itag);
 #endif
-        rt->rt_type = res->type;
+       rt->rt_type = res->type;
 }
 
-static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
+static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                                u8 tos, struct net_device *dev, int our)
 {
        unsigned hash;
        struct rtable *rth;
-       u32 spec_dst;
+       __be32 spec_dst;
        struct in_device *in_dev = in_dev_get(dev);
        u32 itag = 0;
 
@@ -1628,9 +1642,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
        rth->fl.fl4_tos = tos;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= skb->nfmark;
-#endif
+       rth->fl.mark    = skb->mark;
        rth->fl.fl4_src = saddr;
        rth->rt_src     = saddr;
 #ifdef CONFIG_NET_CLS_ROUTE
@@ -1658,7 +1670,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
        RT_CACHE_STAT_INC(in_slow_mc);
 
        in_dev_put(in_dev);
-       hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos);
+       hash = rt_hash(daddr, saddr, dev->ifindex);
        return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst);
 
 e_nobufs:
@@ -1674,8 +1686,8 @@ e_inval:
 static void ip_handle_martian_source(struct net_device *dev,
                                     struct in_device *in_dev,
                                     struct sk_buff *skb,
-                                    u32 daddr,
-                                    u32 saddr) 
+                                    __be32 daddr,
+                                    __be32 saddr)
 {
        RT_CACHE_STAT_INC(in_martian_src);
 #ifdef CONFIG_IP_ROUTE_VERBOSE
@@ -1702,18 +1714,19 @@ static void ip_handle_martian_source(struct net_device *dev,
 #endif
 }
 
-static inline int __mkroute_input(struct sk_buff *skb, 
-                                 struct fib_result* res, 
-                                 struct in_device *in_dev, 
-                                 u32 daddr, u32 saddr, u32 tos, 
-                                 struct rtable **result) 
+static inline int __mkroute_input(struct sk_buff *skb,
+                                 struct fib_result* res,
+                                 struct in_device *in_dev,
+                                 __be32 daddr, __be32 saddr, u32 tos,
+                                 struct rtable **result)
 {
 
        struct rtable *rth;
        int err;
        struct in_device *out_dev;
        unsigned flags = 0;
-       u32 spec_dst, itag;
+       __be32 spec_dst;
+       u32 itag;
 
        /* get a working reference to the output device */
        out_dev = in_dev_get(FIB_RES_DEV(*res));
@@ -1725,12 +1738,12 @@ static inline int __mkroute_input(struct sk_buff *skb,
        }
 
 
-       err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), 
+       err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res),
                                  in_dev->dev, &spec_dst, &itag);
        if (err < 0) {
-               ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, 
+               ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
                                         saddr);
-               
+
                err = -EINVAL;
                goto cleanup;
        }
@@ -1768,14 +1781,12 @@ static inline int __mkroute_input(struct sk_buff *skb,
 #endif
        if (in_dev->cnf.no_policy)
                rth->u.dst.flags |= DST_NOPOLICY;
-       if (in_dev->cnf.no_xfrm)
+       if (out_dev->cnf.no_xfrm)
                rth->u.dst.flags |= DST_NOXFRM;
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
        rth->fl.fl4_tos = tos;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= skb->nfmark;
-#endif
+       rth->fl.mark    = skb->mark;
        rth->fl.fl4_src = saddr;
        rth->rt_src     = saddr;
        rth->rt_gateway = daddr;
@@ -1800,13 +1811,13 @@ static inline int __mkroute_input(struct sk_buff *skb,
        /* release the working reference to the output device */
        in_dev_put(out_dev);
        return err;
-}                                              
+}
 
-static inline int ip_mkroute_input_def(struct sk_buff *skb, 
-                                      struct fib_result* res, 
+static inline int ip_mkroute_input_def(struct sk_buff *skb,
+                                      struct fib_result* res,
                                       const struct flowi *fl,
                                       struct in_device *in_dev,
-                                      u32 daddr, u32 saddr, u32 tos)
+                                      __be32 daddr, __be32 saddr, u32 tos)
 {
        struct rtable* rth = NULL;
        int err;
@@ -1823,15 +1834,15 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
                return err;
 
        /* put it into the cache */
-       hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
-       return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);   
+       hash = rt_hash(daddr, saddr, fl->iif);
+       return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
 }
 
-static inline int ip_mkroute_input(struct sk_buff *skb, 
-                                  struct fib_result* res, 
+static inline int ip_mkroute_input(struct sk_buff *skb,
+                                  struct fib_result* res,
                                   const struct flowi *fl,
                                   struct in_device *in_dev,
-                                  u32 daddr, u32 saddr, u32 tos)
+                                  __be32 daddr, __be32 saddr, u32 tos)
 {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
        struct rtable* rth = NULL, *rtres;
@@ -1848,7 +1859,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
        if (hopcount < 2)
                return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
                                            saddr, tos);
-       
+
        /* add all alternatives to the routing cache */
        for (hop = 0; hop < hopcount; hop++) {
                res->nh_sel = hop;
@@ -1864,7 +1875,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
                        return err;
 
                /* put it into the cache */
-               hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
+               hash = rt_hash(daddr, saddr, fl->iif);
                err = rt_intern_hash(hash, rth, &rtres);
                if (err)
                        return err;
@@ -1894,7 +1905,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
  *     2. IP spoofing attempts are filtered with 100% of guarantee.
  */
 
-static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
+static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                               u8 tos, struct net_device *dev)
 {
        struct fib_result res;
@@ -1904,16 +1915,14 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
                                        .saddr = saddr,
                                        .tos = tos,
                                        .scope = RT_SCOPE_UNIVERSE,
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                                       .fwmark = skb->nfmark
-#endif
                                      } },
+                           .mark = skb->mark,
                            .iif = dev->ifindex };
        unsigned        flags = 0;
        u32             itag = 0;
        struct rtable * rth;
        unsigned        hash;
-       u32             spec_dst;
+       __be32          spec_dst;
        int             err = -EINVAL;
        int             free_res = 0;
 
@@ -1929,7 +1938,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
        if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr))
                goto martian_source;
 
-       if (daddr == 0xFFFFFFFF || (saddr == 0 && daddr == 0))
+       if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
                goto brd_input;
 
        /* Accept zero addresses only to limited broadcast;
@@ -1979,7 +1988,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
                goto e_nobufs;
        if (err == -EINVAL)
                goto e_inval;
-       
+
 done:
        in_dev_put(in_dev);
        if (free_res)
@@ -2018,9 +2027,7 @@ local_input:
        rth->fl.fl4_dst = daddr;
        rth->rt_dst     = daddr;
        rth->fl.fl4_tos = tos;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= skb->nfmark;
-#endif
+       rth->fl.mark    = skb->mark;
        rth->fl.fl4_src = saddr;
        rth->rt_src     = saddr;
 #ifdef CONFIG_NET_CLS_ROUTE
@@ -2041,7 +2048,7 @@ local_input:
                rth->rt_flags   &= ~RTCF_LOCAL;
        }
        rth->rt_type    = res.type;
-       hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5), tos);
+       hash = rt_hash(daddr, saddr, fl.iif);
        err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
        goto done;
 
@@ -2064,8 +2071,8 @@ martian_destination:
 #endif
 
 e_hostunreach:
-        err = -EHOSTUNREACH;
-        goto done;
+       err = -EHOSTUNREACH;
+       goto done;
 
 e_inval:
        err = -EINVAL;
@@ -2080,7 +2087,7 @@ martian_source:
        goto e_inval;
 }
 
-int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
+int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                   u8 tos, struct net_device *dev)
 {
        struct rtable * rth;
@@ -2088,7 +2095,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
        int iif = dev->ifindex;
 
        tos &= IPTOS_RT_MASK;
-       hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos);
+       hash = rt_hash(daddr, saddr, iif);
 
        rcu_read_lock();
        for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2097,9 +2104,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
                    rth->fl.fl4_src == saddr &&
                    rth->fl.iif == iif &&
                    rth->fl.oif == 0 &&
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                   rth->fl.fl4_fwmark == skb->nfmark &&
-#endif
+                   rth->fl.mark == skb->mark &&
                    rth->fl.fl4_tos == tos) {
                        rth->u.dst.lastuse = jiffies;
                        dst_hold(&rth->u.dst);
@@ -2148,11 +2153,11 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
 }
 
 static inline int __mkroute_output(struct rtable **result,
-                                  struct fib_result* res, 
+                                  struct fib_result* res,
                                   const struct flowi *fl,
-                                  const struct flowi *oldflp, 
-                                  struct net_device *dev_out, 
-                                  unsigned flags) 
+                                  const struct flowi *oldflp,
+                                  struct net_device *dev_out,
+                                  unsigned flags)
 {
        struct rtable *rth;
        struct in_device *in_dev;
@@ -2162,7 +2167,7 @@ static inline int __mkroute_output(struct rtable **result,
        if (LOOPBACK(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
                return -EINVAL;
 
-       if (fl->fl4_dst == 0xFFFFFFFF)
+       if (fl->fl4_dst == htonl(0xFFFFFFFF))
                res->type = RTN_BROADCAST;
        else if (MULTICAST(fl->fl4_dst))
                res->type = RTN_MULTICAST;
@@ -2185,7 +2190,7 @@ static inline int __mkroute_output(struct rtable **result,
                }
        } else if (res->type == RTN_MULTICAST) {
                flags |= RTCF_MULTICAST|RTCF_LOCAL;
-               if (!ip_check_mc(in_dev, oldflp->fl4_dst, oldflp->fl4_src, 
+               if (!ip_check_mc(in_dev, oldflp->fl4_dst, oldflp->fl4_src,
                                 oldflp->proto))
                        flags &= ~RTCF_LOCAL;
                /* If multicast route do not exist use
@@ -2203,7 +2208,7 @@ static inline int __mkroute_output(struct rtable **result,
        if (!rth) {
                err = -ENOBUFS;
                goto cleanup;
-       }               
+       }
 
        atomic_set(&rth->u.dst.__refcnt, 1);
        rth->u.dst.flags= DST_HOST;
@@ -2223,13 +2228,11 @@ static inline int __mkroute_output(struct rtable **result,
        rth->fl.fl4_tos = tos;
        rth->fl.fl4_src = oldflp->fl4_src;
        rth->fl.oif     = oldflp->oif;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-       rth->fl.fl4_fwmark= oldflp->fl4_fwmark;
-#endif
+       rth->fl.mark    = oldflp->mark;
        rth->rt_dst     = fl->fl4_dst;
        rth->rt_src     = fl->fl4_src;
        rth->rt_iif     = oldflp->oif ? : dev_out->ifindex;
-       /* get references to the devices that are to be hold by the routing 
+       /* get references to the devices that are to be hold by the routing
           cache entry */
        rth->u.dst.dev  = dev_out;
        dev_hold(dev_out);
@@ -2247,7 +2250,7 @@ static inline int __mkroute_output(struct rtable **result,
        }
        if (flags & (RTCF_BROADCAST | RTCF_MULTICAST)) {
                rth->rt_spec_dst = fl->fl4_src;
-               if (flags & RTCF_LOCAL && 
+               if (flags & RTCF_LOCAL &&
                    !(dev_out->flags & IFF_LOOPBACK)) {
                        rth->u.dst.output = ip_mc_output;
                        RT_CACHE_STAT_INC(out_slow_mc);
@@ -2286,13 +2289,10 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
        int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
        unsigned hash;
        if (err == 0) {
-               u32 tos = RT_FL_TOS(oldflp);
-
-               hash = rt_hash_code(oldflp->fl4_dst, 
-                                   oldflp->fl4_src ^ (oldflp->oif << 5), tos);
+               hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif);
                err = rt_intern_hash(hash, rth, rp);
        }
-       
+
        return err;
 }
 
@@ -2304,7 +2304,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
                                    unsigned flags)
 {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       u32 tos = RT_FL_TOS(oldflp);
        unsigned char hop;
        unsigned hash;
        int err = -EINVAL;
@@ -2332,9 +2331,8 @@ static inline int ip_mkroute_output(struct rtable** rp,
                        if (err != 0)
                                goto cleanup;
 
-                       hash = rt_hash_code(oldflp->fl4_dst, 
-                                           oldflp->fl4_src ^
-                                           (oldflp->oif << 5), tos);
+                       hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src,
+                                       oldflp->oif);
                        err = rt_intern_hash(hash, rth, rp);
 
                        /* forward hop information to multipath impl. */
@@ -2374,10 +2372,8 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                                        .scope = ((tos & RTO_ONLINK) ?
                                                  RT_SCOPE_LINK :
                                                  RT_SCOPE_UNIVERSE),
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                                       .fwmark = oldflp->fl4_fwmark
-#endif
                                      } },
+                           .mark = oldflp->mark,
                            .iif = loopback_dev.ifindex,
                            .oif = oldflp->oif };
        struct fib_result res;
@@ -2413,7 +2409,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                 */
 
                if (oldflp->oif == 0
-                   && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF)) {
+                   && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
                        /* Special hack: user can direct multicasts
                           and limited broadcast via necessary interface
                           without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
@@ -2450,7 +2446,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        goto out;       /* Wrong error code */
                }
 
-               if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == 0xFFFFFFFF) {
+               if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
                        if (!fl.fl4_src)
                                fl.fl4_src = inet_select_addr(dev_out, 0,
                                                              RT_SCOPE_LINK);
@@ -2563,7 +2559,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
        unsigned hash;
        struct rtable *rth;
 
-       hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5), flp->fl4_tos);
+       hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif);
 
        rcu_read_lock_bh();
        for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2572,9 +2568,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
                    rth->fl.fl4_src == flp->fl4_src &&
                    rth->fl.iif == 0 &&
                    rth->fl.oif == flp->oif &&
-#ifdef CONFIG_IP_ROUTE_FWMARK
-                   rth->fl.fl4_fwmark == flp->fl4_fwmark &&
-#endif
+                   rth->fl.mark == flp->mark &&
                    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
                            (IPTOS_RT_MASK | RTO_ONLINK))) {
 
@@ -2635,74 +2629,68 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 {
        struct rtable *rt = (struct rtable*)skb->dst;
        struct rtmsg *r;
-       struct nlmsghdr  *nlh;
-       unsigned char    *b = skb->tail;
-       struct rta_cacheinfo ci;
-#ifdef CONFIG_IP_MROUTE
-       struct rtattr *eptr;
-#endif
-       nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
-       r = NLMSG_DATA(nlh);
+       struct nlmsghdr *nlh;
+       long expires;
+       u32 id = 0, ts = 0, tsage = 0, error;
+
+       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
+       if (nlh == NULL)
+               return -EMSGSIZE;
+
+       r = nlmsg_data(nlh);
        r->rtm_family    = AF_INET;
        r->rtm_dst_len  = 32;
        r->rtm_src_len  = 0;
        r->rtm_tos      = rt->fl.fl4_tos;
        r->rtm_table    = RT_TABLE_MAIN;
+       NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
        r->rtm_type     = rt->rt_type;
        r->rtm_scope    = RT_SCOPE_UNIVERSE;
        r->rtm_protocol = RTPROT_UNSPEC;
        r->rtm_flags    = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
        if (rt->rt_flags & RTCF_NOTIFY)
                r->rtm_flags |= RTM_F_NOTIFY;
-       RTA_PUT(skb, RTA_DST, 4, &rt->rt_dst);
+
+       NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst);
+
        if (rt->fl.fl4_src) {
                r->rtm_src_len = 32;
-               RTA_PUT(skb, RTA_SRC, 4, &rt->fl.fl4_src);
+               NLA_PUT_BE32(skb, RTA_SRC, rt->fl.fl4_src);
        }
        if (rt->u.dst.dev)
-               RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->u.dst.dev->ifindex);
+               NLA_PUT_U32(skb, RTA_OIF, rt->u.dst.dev->ifindex);
 #ifdef CONFIG_NET_CLS_ROUTE
        if (rt->u.dst.tclassid)
-               RTA_PUT(skb, RTA_FLOW, 4, &rt->u.dst.tclassid);
+               NLA_PUT_U32(skb, RTA_FLOW, rt->u.dst.tclassid);
 #endif
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-       if (rt->rt_multipath_alg != IP_MP_ALG_NONE) {
-               __u32 alg = rt->rt_multipath_alg;
-
-               RTA_PUT(skb, RTA_MP_ALGO, 4, &alg);
-       }
+       if (rt->rt_multipath_alg != IP_MP_ALG_NONE)
+               NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
 #endif
        if (rt->fl.iif)
-               RTA_PUT(skb, RTA_PREFSRC, 4, &rt->rt_spec_dst);
+               NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
        else if (rt->rt_src != rt->fl.fl4_src)
-               RTA_PUT(skb, RTA_PREFSRC, 4, &rt->rt_src);
+               NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
+
        if (rt->rt_dst != rt->rt_gateway)
-               RTA_PUT(skb, RTA_GATEWAY, 4, &rt->rt_gateway);
+               NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway);
+
        if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
-               goto rtattr_failure;
-       ci.rta_lastuse  = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
-       ci.rta_used     = rt->u.dst.__use;
-       ci.rta_clntref  = atomic_read(&rt->u.dst.__refcnt);
-       if (rt->u.dst.expires)
-               ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
-       else
-               ci.rta_expires = 0;
-       ci.rta_error    = rt->u.dst.error;
-       ci.rta_id       = ci.rta_ts = ci.rta_tsage = 0;
+               goto nla_put_failure;
+
+       error = rt->u.dst.error;
+       expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0;
        if (rt->peer) {
-               ci.rta_id = rt->peer->ip_id_count;
+               id = rt->peer->ip_id_count;
                if (rt->peer->tcp_ts_stamp) {
-                       ci.rta_ts = rt->peer->tcp_ts;
-                       ci.rta_tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp;
+                       ts = rt->peer->tcp_ts;
+                       tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp;
                }
        }
-#ifdef CONFIG_IP_MROUTE
-       eptr = (struct rtattr*)skb->tail;
-#endif
-       RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
+
        if (rt->fl.iif) {
 #ifdef CONFIG_IP_MROUTE
-               u32 dst = rt->rt_dst;
+               __be32 dst = rt->rt_dst;
 
                if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
                    ipv4_devconf.mc_forwarding) {
@@ -2711,104 +2699,116 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                                if (!nowait) {
                                        if (err == 0)
                                                return 0;
-                                       goto nlmsg_failure;
+                                       goto nla_put_failure;
                                } else {
                                        if (err == -EMSGSIZE)
-                                               goto nlmsg_failure;
-                                       ((struct rta_cacheinfo*)RTA_DATA(eptr))->rta_error = err;
+                                               goto nla_put_failure;
+                                       error = err;
                                }
                        }
                } else
 #endif
-                       RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif);
+                       NLA_PUT_U32(skb, RTA_IIF, rt->fl.iif);
        }
 
-       nlh->nlmsg_len = skb->tail - b;
-       return skb->len;
+       if (rtnl_put_cacheinfo(skb, &rt->u.dst, id, ts, tsage,
+                              expires, error) < 0)
+               goto nla_put_failure;
 
-nlmsg_failure:
-rtattr_failure:
-       skb_trim(skb, b - skb->data);
-       return -1;
+       return nlmsg_end(skb, nlh);
+
+nla_put_failure:
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
 {
-       struct rtattr **rta = arg;
-       struct rtmsg *rtm = NLMSG_DATA(nlh);
+       struct rtmsg *rtm;
+       struct nlattr *tb[RTA_MAX+1];
        struct rtable *rt = NULL;
-       u32 dst = 0;
-       u32 src = 0;
-       int iif = 0;
-       int err = -ENOBUFS;
+       __be32 dst = 0;
+       __be32 src = 0;
+       u32 iif;
+       int err;
        struct sk_buff *skb;
 
+       err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy);
+       if (err < 0)
+               goto errout;
+
+       rtm = nlmsg_data(nlh);
+
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
-       if (!skb)
-               goto out;
+       if (skb == NULL) {
+               err = -ENOBUFS;
+               goto errout;
+       }
 
        /* Reserve room for dummy headers, this skb can pass
           through good chunk of routing engine.
         */
-       skb->mac.raw = skb->data;
+       skb->mac.raw = skb->nh.raw = skb->data;
+
+       /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */
+       skb->nh.iph->protocol = IPPROTO_ICMP;
        skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
 
-       if (rta[RTA_SRC - 1])
-               memcpy(&src, RTA_DATA(rta[RTA_SRC - 1]), 4);
-       if (rta[RTA_DST - 1])
-               memcpy(&dst, RTA_DATA(rta[RTA_DST - 1]), 4);
-       if (rta[RTA_IIF - 1])
-               memcpy(&iif, RTA_DATA(rta[RTA_IIF - 1]), sizeof(int));
+       src = tb[RTA_SRC] ? nla_get_be32(tb[RTA_SRC]) : 0;
+       dst = tb[RTA_DST] ? nla_get_be32(tb[RTA_DST]) : 0;
+       iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0;
 
        if (iif) {
-               struct net_device *dev = __dev_get_by_index(iif);
-               err = -ENODEV;
-               if (!dev)
-                       goto out_free;
+               struct net_device *dev;
+
+               dev = __dev_get_by_index(iif);
+               if (dev == NULL) {
+                       err = -ENODEV;
+                       goto errout_free;
+               }
+
                skb->protocol   = htons(ETH_P_IP);
                skb->dev        = dev;
                local_bh_disable();
                err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
                local_bh_enable();
-               rt = (struct rtable*)skb->dst;
-               if (!err && rt->u.dst.error)
+
+               rt = (struct rtable*) skb->dst;
+               if (err == 0 && rt->u.dst.error)
                        err = -rt->u.dst.error;
        } else {
-               struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dst,
-                                                        .saddr = src,
-                                                        .tos = rtm->rtm_tos } } };
-               int oif = 0;
-               if (rta[RTA_OIF - 1])
-                       memcpy(&oif, RTA_DATA(rta[RTA_OIF - 1]), sizeof(int));
-               fl.oif = oif;
+               struct flowi fl = {
+                       .nl_u = {
+                               .ip4_u = {
+                                       .daddr = dst,
+                                       .saddr = src,
+                                       .tos = rtm->rtm_tos,
+                               },
+                       },
+                       .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0,
+               };
                err = ip_route_output_key(&rt, &fl);
        }
+
        if (err)
-               goto out_free;
+               goto errout_free;
 
        skb->dst = &rt->u.dst;
        if (rtm->rtm_flags & RTM_F_NOTIFY)
                rt->rt_flags |= RTCF_NOTIFY;
 
-       NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
-
        err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
                                RTM_NEWROUTE, 0, 0);
-       if (!err)
-               goto out_free;
-       if (err < 0) {
-               err = -EMSGSIZE;
-               goto out_free;
-       }
+       if (err <= 0)
+               goto errout_free;
 
-       err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
-       if (err > 0)
-               err = 0;
-out:   return err;
+       err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+errout:
+       return err;
 
-out_free:
+errout_free:
        kfree_skb(skb);
-       goto out;
+       goto errout;
 }
 
 int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
@@ -2830,7 +2830,7 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
                                continue;
                        skb->dst = dst_clone(&rt->u.dst);
                        if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
-                                        cb->nlh->nlmsg_seq, RTM_NEWROUTE, 
+                                        cb->nlh->nlmsg_seq, RTM_NEWROUTE,
                                         1, NLM_F_MULTI) <= 0) {
                                dst_release(xchg(&skb->dst, NULL));
                                rcu_read_unlock_bh();
@@ -2863,7 +2863,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write,
                proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
                rt_cache_flush(flush_delay);
                return 0;
-       } 
+       }
 
        return -EINVAL;
 }
@@ -2874,20 +2874,19 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
                                                void __user *oldval,
                                                size_t __user *oldlenp,
                                                void __user *newval,
-                                               size_t newlen,
-                                               void **context)
+                                               size_t newlen)
 {
        int delay;
        if (newlen != sizeof(int))
                return -EINVAL;
        if (get_user(delay, (int __user *)newval))
-               return -EFAULT; 
-       rt_cache_flush(delay); 
+               return -EFAULT;
+       rt_cache_flush(delay);
        return 0;
 }
 
 ctl_table ipv4_route_table[] = {
-        {
+       {
                .ctl_name       = NET_IPV4_ROUTE_FLUSH,
                .procname       = "flush",
                .data           = &flush_delay,
@@ -2932,7 +2931,7 @@ ctl_table ipv4_route_table[] = {
        },
        {
                /*  Deprecated. Use gc_min_interval_ms */
+
                .ctl_name       = NET_IPV4_ROUTE_GC_MIN_INTERVAL,
                .procname       = "gc_min_interval",
                .data           = &ip_rt_gc_min_interval,
@@ -3092,7 +3091,7 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
                memcpy(dst, src, length);
 
                /* Add the other cpus in, one int at a time */
-               for_each_cpu(i) {
+               for_each_possible_cpu(i) {
                        unsigned int j;
 
                        src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset;
@@ -3136,13 +3135,9 @@ int __init ip_rt_init(void)
        }
 #endif
 
-       ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache",
-                                                    sizeof(struct rtable),
-                                                    0, SLAB_HWCACHE_ALIGN,
-                                                    NULL, NULL);
-
-       if (!ipv4_dst_ops.kmem_cachep)
-               panic("IP: failed to allocate ip_dst_cache\n");
+       ipv4_dst_ops.kmem_cachep =
+               kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0,
+                                 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
 
        rt_hash_table = (struct rt_hash_bucket *)
                alloc_large_system_hash("IP route cache",
@@ -3150,7 +3145,7 @@ int __init ip_rt_init(void)
                                        rhash_entries,
                                        (num_physpages >= 128 * 1024) ?
                                        15 : 17,
-                                       HASH_HIGHMEM,
+                                       0,
                                        &rt_hash_log,
                                        &rt_hash_mask,
                                        0);
@@ -3185,8 +3180,8 @@ int __init ip_rt_init(void)
        {
        struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */
        if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
-           !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO, 
-                                            proc_net_stat))) {
+           !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
+                                            proc_net_stat))) {
                return -ENOMEM;
        }
        rtstat_pde->proc_fops = &rt_cpu_seq_fops;