diff --git a/lib/ip.h b/lib/ip.h
index 45e073d..2642813 100644
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -216,23 +216,15 @@ static inline int ipa_nonzero2(ip_addr a)
  *	Hash and compare functions
  */
 
-static inline uint ip4_hash(ip4_addr a)
+static inline u32 ip4_hash(ip4_addr a)
 {
-  /* Returns a 16-bit value */
-  u32 x = _I(a);
-  x ^= x >> 16;
-  x ^= x << 10;
-  return x & 0xffff;
+  u64 h = 2902958171u;
+  h *= _I(a);
+  h ^=  h >> 32;
+  return h;
 }
 
-static inline u32 ip4_hash32(ip4_addr a)
-{
-  /* Returns a 32-bit value, although low-order bits are not mixed */
-  u32 x = _I(a);
-  x ^= x << 16;
-  x ^= x << 12;
-  return x;
-}
+#define ip4_hash32 ip4_hash
 
 static inline uint ip6_hash(ip6_addr a)
 {
diff --git a/nest/rt-fib.c b/nest/rt-fib.c
index b9c7d2a..4522968 100644
--- a/nest/rt-fib.c
+++ b/nest/rt-fib.c
@@ -43,7 +43,7 @@
 #define HASH_DEF_ORDER 10
 #define HASH_HI_MARK *4
 #define HASH_HI_STEP 2
-#define HASH_HI_MAX 16			/* Must be at most 16 */
+#define HASH_HI_MAX 24
 #define HASH_LO_MARK /5
 #define HASH_LO_STEP 2
 #define HASH_LO_MIN 10
@@ -52,7 +52,7 @@ static void
 fib_ht_alloc(struct fib *f)
 {
   f->hash_size = 1 << f->hash_order;
-  f->hash_shift = 16 - f->hash_order;
+  f->hash_shift = 32 - f->hash_order;
   if (f->hash_order > HASH_HI_MAX - HASH_HI_STEP)
     f->entries_max = ~0;
   else
@@ -209,7 +209,7 @@ fib_get(struct fib *f, ip_addr *a, int len)
   unsigned int h = ipa_hash(*a);
   struct fib_node **ee = f->hash_table + (h >> f->hash_shift);
   struct fib_node *g, *e = *ee;
-  u32 uid = h << 16;
+  u32 uid = h << 8;
 
   while (e && (e->pxlen != len || !ipa_equal(*a, e->prefix)))
     e = e->next;
@@ -228,7 +228,7 @@ fib_get(struct fib *f, ip_addr *a, int len)
       uid++;
     }
 
-  if ((uid >> 16) != h)
+  if ((uid >> 8) != (h & 0xffffff))
     log(L_ERR "FIB hash table chains are too long");
 
   // log (L_WARN "FIB_GET %I %x %x", *a, h, uid);
