While here, add src to struct rt6 as well for future use.
 #endif
 
        if (cmd == RTM_ADD || cmd == RTM_CHANGE) {
-               int subnet;
-
-               rtm.hdr.rtm_addrs |= RTA_GATEWAY | RTA_IFA | RTA_IFP;
+               rtm.hdr.rtm_addrs |= RTA_GATEWAY | RTA_IFP;
+               if (rt->src.s_addr != htonl(INADDR_ANY))
+                       rtm.hdr.rtm_addrs |= RTA_IFA;
                /* Subnet routes are clonning or connected if supported.
                 * All other routes are static. */
-               subnet = ipv4_srcaddr(rt, &src_addr);
-               if (subnet == 1) {
+               if (rt->gate.s_addr == htonl(INADDR_ANY)) {
 #ifdef RTF_CLONING
                        rtm.hdr.rtm_flags |= RTF_CLONING;
 #endif
 #endif
                } else
                        rtm.hdr.rtm_flags |= RTF_STATIC;
-               if (subnet == -1) /* unikely */
-                       rtm.hdr.rtm_addrs &= ~RTA_IFA;
        }
        if (rt->mask.s_addr == htonl(INADDR_BROADCAST) &&
            rt->gate.s_addr == htonl(INADDR_ANY))
 
 if_route(unsigned char cmd, const struct rt *rt)
 {
        struct nlmr nlm;
-       struct in_addr src_addr;
-       int subnet;
 
        memset(&nlm, 0, sizeof(nlm));
        nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
 
        if (cmd == RTM_DELETE) {
                nlm.rt.rtm_scope = RT_SCOPE_NOWHERE;
-               subnet = -1;
        } else {
                /* Subnet routes are RTPROT_KERNEL otherwise RTPROT_BOOT */
-               if ((subnet = ipv4_srcaddr(rt, &src_addr)) == 1)
+               if (rt->gate.s_addr == ntohl(INADDR_ANY))
                        nlm.rt.rtm_protocol = RTPROT_KERNEL;
                else
                        nlm.rt.rtm_protocol = RTPROT_BOOT;
                if (rt->gate.s_addr != htonl(INADDR_ANY))
                        add_attr_l(&nlm.hdr, sizeof(nlm), RTA_GATEWAY,
                            &rt->gate.s_addr, sizeof(rt->gate.s_addr));
-               if (subnet != -1) {
+               if (rt->src.s_addr != ntohl(INADDR_ANY)) {
                        add_attr_l(&nlm.hdr, sizeof(nlm), RTA_PREFSRC,
-                           &src_addr.s_addr, sizeof(src_addr.s_addr));
+                           &rt->src.s_addr, sizeof(rt->src.s_addr));
                }
                if (rt->mtu) {
                        char metricsbuf[32];
        if (rt->metric)
                add_attr_32(&nlm.hdr, sizeof(nlm), RTA_PRIORITY, rt->metric);
 
-       if (cmd != RTM_DELETE && rt->mtu) {
-               char metricsbuf[32];
-               struct rtattr *metrics = (void *)metricsbuf;
+       if (cmd == RTM_ADD || cmd == RTM_CHANGE) {
+#if 0
+               /* XXX This fails to work, why? */
+               if (!IN6_IS_ADDR_UNSPECIFIED(&rt->src)) {
+                       add_attr_l(&nlm.hdr, sizeof(nlm), RTA_PREFSRC,
+                           &rt->src.s6_addr, sizeof(rt->src.s6_addr));
+               }
+#endif
+               if (rt->mtu) {
+                       char metricsbuf[32];
+                       struct rtattr *metrics = (void *)metricsbuf;
 
-               metrics->rta_type = RTA_METRICS;
-               metrics->rta_len = RTA_LENGTH(0);
-               rta_add_attr_32(metrics, sizeof(metricsbuf), RTAX_MTU, rt->mtu);
-               add_attr_l(&nlm.hdr, sizeof(nlm), RTA_METRICS,
-                   RTA_DATA(metrics), (unsigned short)RTA_PAYLOAD(metrics));
+                       metrics->rta_type = RTA_METRICS;
+                       metrics->rta_len = RTA_LENGTH(0);
+                       rta_add_attr_32(metrics, sizeof(metricsbuf),
+                           RTAX_MTU, rt->mtu);
+                       add_attr_l(&nlm.hdr, sizeof(nlm), RTA_METRICS,
+                           RTA_DATA(metrics),
+                           (unsigned short)RTA_PAYLOAD(metrics));
+               }
        }
 
        return send_netlink(rt->iface->ctx, NULL,
 
        return NULL;
 }
 
-int
-ipv4_srcaddr(const struct rt *rt, struct in_addr *addr)
-{
-       const struct dhcp_state *dstate;
-       const struct ipv4ll_state *istate;
-
-       if (rt->iface == NULL) {
-               errno = ENOENT;
-               return -1;
-       }
-
-       /* Prefer DHCP source address if matching */
-       dstate = D_CSTATE(rt->iface);
-       if (dstate && dstate->addr &&
-           rt->mask.s_addr == dstate->addr->mask.s_addr &&
-           rt->dest.s_addr ==
-           (dstate->addr->addr.s_addr & dstate->addr->mask.s_addr))
-       {
-               *addr = dstate->addr->addr;
-               return 1;
-       }
-
-       /* Then IPv4LL source address if matching */
-       istate = IPV4LL_CSTATE(rt->iface);
-       if (istate && istate->addr &&
-           rt->mask.s_addr == istate->addr->mask.s_addr &&
-           rt->dest.s_addr ==
-           (istate->addr->addr.s_addr & istate->addr->mask.s_addr))
-       {
-               *addr = istate->addr->addr;
-               return 1;
-       }
-
-       /* If neither match, return DHCP then IPv4LL */
-       if (dstate && dstate->addr) {
-               *addr = dstate->addr->addr;
-               return 0;
-       }
-       if (istate && istate->addr) {
-               *addr = istate->addr->addr;
-               return 0;
-       }
-
-       errno = ESRCH;
-       return -1;
-}
-
 int
 ipv4_hasaddr(const struct interface *ifp)
 {
 #ifdef HAVE_ROUTE_METRIC
                    or->metric != rt->metric ||
 #endif
-                   or->src.s_addr != rt->src.s_addr ||
                    or->gate.s_addr != rt->gate.s_addr ||
+                   or->src.s_addr != rt->src.s_addr ||
                    or->mtu != rt->mtu)
                {
                        if (c_route(or, rt) != 0)
 
 struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
 struct ipv4_addr *ipv4_findmaskaddr(struct dhcpcd_ctx *,
     const struct in_addr *);
-int ipv4_srcaddr(const struct rt *, struct in_addr *);
 void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *,
     const struct in_addr *, const struct in_addr *, const struct in_addr *,
     int);
 
                r->gate = in6addr_loopback;
        } else
                r->gate = in6addr_any;
+       r->src = addr->addr;
        return r;
 }
 
                /* Is this route already in our table? */
                if (find_route6(nrs, rt) != NULL)
                        continue;
-               //rt->src.s_addr = ifp->addr.s_addr;
                /* Do we already manage it? */
                if ((or = find_route6(ctx->ipv6->routes, rt))) {
                        if (or->iface != rt->iface ||
 #ifdef HAVE_ROUTE_METRIC
                            rt->metric != or->metric ||
 #endif
-               //          or->src.s_addr != ifp->addr.s_addr ||
                            !IN6_ARE_ADDR_EQUAL(&or->gate, &rt->gate) ||
+                           // !IN6_ARE_ADDR_EQUAL(&or->src, &rt->src) ||
                            or->mtu != rt->mtu)
                        {
                                if (c_route(or, rt) != 0)
 
        struct in6_addr mask;
        struct in6_addr gate;
        const struct interface *iface;
+       struct in6_addr src;
        unsigned int flags;
 #ifdef HAVE_ROUTE_METRIC
        unsigned int metric;