From: Roy Marples Date: Tue, 26 Jul 2016 19:06:54 +0000 (+0000) Subject: Because struct rt has src addr, we no longer need ipv4_srcaddr. X-Git-Tag: v6.11.2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=404186d82daf697b3d0a31c379b60642df39fbd3;p=thirdparty%2Fdhcpcd.git Because struct rt has src addr, we no longer need ipv4_srcaddr. While here, add src to struct rt6 as well for future use. --- diff --git a/if-bsd.c b/if-bsd.c index ec46684f..636dcfd5 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -668,13 +668,12 @@ if_route(unsigned char cmd, const struct rt *rt) #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 @@ -686,8 +685,6 @@ if_route(unsigned char cmd, const struct rt *rt) #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)) diff --git a/if-linux.c b/if-linux.c index 687a1d38..bfaac490 100644 --- a/if-linux.c +++ b/if-linux.c @@ -1390,8 +1390,6 @@ int 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)); @@ -1414,10 +1412,9 @@ if_route(unsigned char cmd, const struct rt *rt) 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; @@ -1439,9 +1436,9 @@ if_route(unsigned char cmd, const struct rt *rt) 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]; @@ -1624,15 +1621,26 @@ if_route6(unsigned char cmd, const struct rt6 *rt) 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, diff --git a/ipv4.c b/ipv4.c index 79d205d5..33bb8a79 100644 --- a/ipv4.c +++ b/ipv4.c @@ -190,53 +190,6 @@ ipv4_findmaskaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr) 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) { @@ -770,8 +723,8 @@ ipv4_doroute(struct rt *rt, struct rt_head *nrs) #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) diff --git a/ipv4.h b/ipv4.h index fd320390..bb8adf4e 100644 --- a/ipv4.h +++ b/ipv4.h @@ -141,7 +141,6 @@ struct ipv4_addr *ipv4_iffindlladdr(struct interface *); 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); diff --git a/ipv6.c b/ipv6.c index 27434b67..b4dacfde 100644 --- a/ipv6.c +++ b/ipv6.c @@ -2288,6 +2288,7 @@ make_prefix(const struct interface *ifp, const struct ra *rap, r->gate = in6addr_loopback; } else r->gate = in6addr_any; + r->src = addr->addr; return r; } @@ -2433,15 +2434,14 @@ ipv6_buildroutes(struct dhcpcd_ctx *ctx) /* 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) diff --git a/ipv6.h b/ipv6.h index 103fc49f..5171c100 100644 --- a/ipv6.h +++ b/ipv6.h @@ -197,6 +197,7 @@ struct rt6 { 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;