From: Roy Marples Date: Wed, 15 Apr 2015 22:02:15 +0000 (+0000) Subject: Store a host route as the kernel would like it, rather than varying forms of X-Git-Tag: v6.8.2~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b6c50a83e7589d89272e5b937461f1d2a2d9fb5;p=thirdparty%2Fdhcpcd.git Store a host route as the kernel would like it, rather than varying forms of how it's set in a DHCP message. --- diff --git a/if-bsd.c b/if-bsd.c index 00a5f32d..69af7b6d 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -605,8 +605,8 @@ if_route(unsigned char cmd, const struct rt *rt) #endif } } - if (rt->dest.s_addr == rt->gate.s_addr && - rt->net.s_addr == INADDR_BROADCAST) + if (rt->net.s_addr == htonl(INADDR_BROADCAST) && + rt->gate.s_addr == htonl(INADDR_ANY)) { #ifdef RTF_CLONING /* We add a cloning network route for a single host. @@ -621,7 +621,7 @@ if_route(unsigned char cmd, const struct rt *rt) rtm.hdr.rtm_flags |= RTF_HOST; #endif } else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) && - rt->net.s_addr == INADDR_BROADCAST) + rt->net.s_addr == htonl(INADDR_BROADCAST)) { rtm.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY; /* Going via lo0 so remove the interface flags */ diff --git a/if-linux.c b/if-linux.c index 4e449be3..51d8b742 100644 --- a/if-linux.c +++ b/if-linux.c @@ -1359,10 +1359,9 @@ if_route(unsigned char cmd, const struct rt *rt) add_attr_l(&nlm.hdr, sizeof(nlm), RTA_PREFSRC, &state->addr.s_addr, sizeof(state->addr.s_addr)); } - /* If destination == gateway then don't add the gateway */ + /* If a host route then don't add the gateway */ if ((cmd == RTM_ADD || cmd == RTM_CHANGE) && - (rt->dest.s_addr != rt->gate.s_addr || - rt->net.s_addr != INADDR_BROADCAST)) + rt->net.s_addr != INADDR_BROADCAST) add_attr_l(&nlm.hdr, sizeof(nlm), RTA_GATEWAY, &rt->gate.s_addr, sizeof(rt->gate.s_addr)); diff --git a/ipv4.c b/ipv4.c index 3b1bedc7..feb48d27 100644 --- a/ipv4.c +++ b/ipv4.c @@ -270,18 +270,18 @@ desc_route(const char *cmd, const struct rt *rt) const char *ifname = rt->iface ? rt->iface->name : NULL; strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr)); - if (rt->gate.s_addr == INADDR_ANY) - logger(ctx, LOG_INFO, "%s: %s route to %s/%d", - ifname, cmd, addr, inet_ntocidr(rt->net)); - else if (rt->gate.s_addr == rt->dest.s_addr && - rt->net.s_addr == INADDR_BROADCAST) + if (rt->net.s_addr == htonl(INADDR_BROADCAST) && + rt->gate.s_addr == htonl(INADDR_ANY)) logger(ctx, LOG_INFO, "%s: %s host route to %s", ifname, cmd, addr); - else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) && - rt->net.s_addr == INADDR_BROADCAST) + else if (rt->net.s_addr == htonl(INADDR_BROADCAST)) logger(ctx, LOG_INFO, "%s: %s host route to %s via %s", ifname, cmd, addr, inet_ntoa(rt->gate)); - else if (rt->dest.s_addr == INADDR_ANY && rt->net.s_addr == INADDR_ANY) + else if (rt->gate.s_addr == htonl(INADDR_ANY)) + logger(ctx, LOG_INFO, "%s: %s route to %s/%d", + ifname, cmd, addr, inet_ntocidr(rt->net)); + else if (rt->dest.s_addr == htonl(INADDR_ANY) && + rt->net.s_addr == htonl(INADDR_ANY)) logger(ctx, LOG_INFO, "%s: %s default route via %s", ifname, cmd, inet_ntoa(rt->gate)); else @@ -332,12 +332,6 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt *rt) if (ctx->ipv4_kroutes == NULL) return 0; - /* DHCP host routes have a gateway of the destination. - * We need to emulate that */ - if (rt->gate.s_addr == INADDR_ANY && - rt->net.s_addr == INADDR_BROADCAST) - rt->gate = rt->dest; - f = ipv4_findrt(ctx, rt, 1); switch (cmd) { case RTM_ADD: @@ -524,8 +518,8 @@ get_routes(struct interface *ifp) } /* Some DHCP servers add set host routes by setting the gateway - * to the assinged IP address. This differs from our notion of a host route - * where the gateway is the destination address, so we fix it. */ + * to the assigned IP address or the destination address. + * We need to change this. */ static struct rt_head * massage_host_routes(struct rt_head *rt, const struct interface *ifp) { @@ -533,14 +527,18 @@ massage_host_routes(struct rt_head *rt, const struct interface *ifp) if (rt) { TAILQ_FOREACH(r, rt, next) { - if (r->gate.s_addr == D_CSTATE(ifp)->addr.s_addr && - r->net.s_addr == INADDR_BROADCAST) - r->gate.s_addr = r->dest.s_addr; + if (r->gate.s_addr == D_CSTATE(ifp)->addr.s_addr || + r->gate.s_addr == r->dest.s_addr) + { + r->gate.s_addr = htonl(INADDR_ANY); + r->net.s_addr = htonl(INADDR_BROADCAST); + } } } return rt; } + static struct rt_head * add_destination_route(struct rt_head *rt, const struct interface *ifp) { @@ -630,8 +628,8 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp) return NULL; } rtn->dest.s_addr = rtp->gate.s_addr; - rtn->net.s_addr = INADDR_BROADCAST; - rtn->gate.s_addr = rtp->gate.s_addr; + rtn->net.s_addr = htonl(INADDR_BROADCAST); + rtn->gate.s_addr = htonl(INADDR_ANY); TAILQ_INSERT_BEFORE(rtp, rtn, next); } return rt;