/*
  *     Returns hash value for IPVS DH entry
  */
-static inline unsigned ip_vs_dh_hashkey(__be32 addr)
+static inline unsigned ip_vs_dh_hashkey(int af, const union nf_inet_addr *addr)
 {
-       return (ntohl(addr)*2654435761UL) & IP_VS_DH_TAB_MASK;
+       __be32 addr_fold = addr->ip;
+
+#ifdef CONFIG_IP_VS_IPV6
+       if (af == AF_INET6)
+               addr_fold = addr->ip6[0]^addr->ip6[1]^
+                           addr->ip6[2]^addr->ip6[3];
+#endif
+       return (ntohl(addr_fold)*2654435761UL) & IP_VS_DH_TAB_MASK;
 }
 
 
  *      Get ip_vs_dest associated with supplied parameters.
  */
 static inline struct ip_vs_dest *
-ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __be32 addr)
+ip_vs_dh_get(int af, struct ip_vs_dh_bucket *tbl,
+            const union nf_inet_addr *addr)
 {
-       return (tbl[ip_vs_dh_hashkey(addr)]).dest;
+       return (tbl[ip_vs_dh_hashkey(af, addr)]).dest;
 }
 
 
 {
        struct ip_vs_dest *dest;
        struct ip_vs_dh_bucket *tbl;
-       struct iphdr *iph = ip_hdr(skb);
+       struct ip_vs_iphdr iph;
+
+       ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
        IP_VS_DBG(6, "ip_vs_dh_schedule(): Scheduling...\n");
 
        tbl = (struct ip_vs_dh_bucket *)svc->sched_data;
-       dest = ip_vs_dh_get(tbl, iph->daddr);
+       dest = ip_vs_dh_get(svc->af, tbl, &iph.daddr);
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
                return NULL;
        }
 
-       IP_VS_DBG(6, "DH: destination IP address %pI4 --> server %pI4:%d\n",
-                 &iph->daddr, &dest->addr.ip, ntohs(dest->port));
+       IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n",
+                     IP_VS_DBG_ADDR(svc->af, &iph.daddr),
+                     IP_VS_DBG_ADDR(svc->af, &dest->addr),
+                     ntohs(dest->port));
 
        return dest;
 }
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
 #ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        0,
+       .supports_ipv6 =        1,
 #endif
        .init_service =         ip_vs_dh_init_svc,
        .done_service =         ip_vs_dh_done_svc,
 
 /*
  *     Returns hash value for IPVS SH entry
  */
-static inline unsigned ip_vs_sh_hashkey(__be32 addr)
+static inline unsigned ip_vs_sh_hashkey(int af, const union nf_inet_addr *addr)
 {
-       return (ntohl(addr)*2654435761UL) & IP_VS_SH_TAB_MASK;
+       __be32 addr_fold = addr->ip;
+
+#ifdef CONFIG_IP_VS_IPV6
+       if (af == AF_INET6)
+               addr_fold = addr->ip6[0]^addr->ip6[1]^
+                           addr->ip6[2]^addr->ip6[3];
+#endif
+       return (ntohl(addr_fold)*2654435761UL) & IP_VS_SH_TAB_MASK;
 }
 
 
  *      Get ip_vs_dest associated with supplied parameters.
  */
 static inline struct ip_vs_dest *
-ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __be32 addr)
+ip_vs_sh_get(int af, struct ip_vs_sh_bucket *tbl,
+            const union nf_inet_addr *addr)
 {
-       return (tbl[ip_vs_sh_hashkey(addr)]).dest;
+       return (tbl[ip_vs_sh_hashkey(af, addr)]).dest;
 }
 
 
 {
        struct ip_vs_dest *dest;
        struct ip_vs_sh_bucket *tbl;
-       struct iphdr *iph = ip_hdr(skb);
+       struct ip_vs_iphdr iph;
+
+       ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
        IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
 
        tbl = (struct ip_vs_sh_bucket *)svc->sched_data;
-       dest = ip_vs_sh_get(tbl, iph->saddr);
+       dest = ip_vs_sh_get(svc->af, tbl, &iph.saddr);
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
                return NULL;
        }
 
-       IP_VS_DBG(6, "SH: source IP address %pI4 --> server %pI4:%d\n",
-                 &iph->saddr, &dest->addr.ip, ntohs(dest->port));
+       IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
+                     IP_VS_DBG_ADDR(svc->af, &iph.saddr),
+                     IP_VS_DBG_ADDR(svc->af, &dest->addr),
+                     ntohs(dest->port));
 
        return dest;
 }
        .module =               THIS_MODULE,
        .n_list  =              LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
 #ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        0,
+       .supports_ipv6 =        1,
 #endif
        .init_service =         ip_vs_sh_init_svc,
        .done_service =         ip_vs_sh_done_svc,