if (fi) {
                struct fib_nh_common *nhc = FIB_RES_NHC(*res);
-               struct fib_nh *nh = container_of(nhc, struct fib_nh, nh_common);
+               struct fib_nh *nh;
 
-               if (nh->fib_nh_gw4 && nh->fib_nh_scope == RT_SCOPE_LINK) {
-                       rt->rt_gw4 = nh->fib_nh_gw4;
-                       rt->rt_gw_family = AF_INET;
+               if (nhc->nhc_gw_family && nhc->nhc_scope == RT_SCOPE_LINK) {
+                       rt->rt_gw_family = nhc->nhc_gw_family;
+                       /* only INET and INET6 are supported */
+                       if (likely(nhc->nhc_gw_family == AF_INET))
+                               rt->rt_gw4 = nhc->nhc_gw.ipv4;
+                       else
+                               rt->rt_gw6 = nhc->nhc_gw.ipv6;
                }
+
                ip_dst_init_metrics(&rt->dst, fi->fib_metrics);
 
+               nh = container_of(nhc, struct fib_nh, nh_common);
 #ifdef CONFIG_IP_ROUTE_CLASSID
                rt->dst.tclassid = nh->nh_tclassid;
 #endif
                rt->rt_gw_family = ort->rt_gw_family;
                if (rt->rt_gw_family == AF_INET)
                        rt->rt_gw4 = ort->rt_gw4;
+               else if (rt->rt_gw_family == AF_INET6)
+                       rt->rt_gw6 = ort->rt_gw6;
 
                INIT_LIST_HEAD(&rt->rt_uncached);
        }
                        goto nla_put_failure;
        }
        if (rt->rt_gw_family == AF_INET &&
-           nla_put_in_addr(skb, RTA_GATEWAY, rt->rt_gw4))
+           nla_put_in_addr(skb, RTA_GATEWAY, rt->rt_gw4)) {
                goto nla_put_failure;
+       } else if (rt->rt_gw_family == AF_INET6) {
+               int alen = sizeof(struct in6_addr);
+               struct nlattr *nla;
+               struct rtvia *via;
+
+               nla = nla_reserve(skb, RTA_VIA, alen + 2);
+               if (!nla)
+                       goto nla_put_failure;
+
+               via = nla_data(nla);
+               via->rtvia_family = AF_INET6;
+               memcpy(via->rtvia_addr, &rt->rt_gw6, alen);
+       }
 
        expires = rt->dst.expires;
        if (expires) {
 
        xdst->u.rt.rt_gw_family = rt->rt_gw_family;
        if (rt->rt_gw_family == AF_INET)
                xdst->u.rt.rt_gw4 = rt->rt_gw4;
+       else if (rt->rt_gw_family == AF_INET6)
+               xdst->u.rt.rt_gw6 = rt->rt_gw6;
        xdst->u.rt.rt_pmtu = rt->rt_pmtu;
        xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked;
        INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
 
                if (rt->rt_gw_family == AF_INET)
                        err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gw4,
                                         skb);
-               else
-                       err = -EAFNOSUPPORT;
+               else if (rt->rt_gw_family == AF_INET6)
+                       err = neigh_xmit(NEIGH_ND_TABLE, out_dev, &rt->rt_gw6,
+                                        skb);
        } else if (rt6) {
                if (ipv6_addr_v4mapped(&rt6->rt6i_gateway)) {
                        /* 6PE (RFC 4798) */