From: Roy Marples Date: Wed, 19 Jun 2013 16:02:19 +0000 (+0000) Subject: Add a route from the IPv4 address to the loopback address. X-Git-Tag: v6.0.0~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bc349b818558ab09dabcbfc1a2dd724fe2df2c12;p=thirdparty%2Fdhcpcd.git Add a route from the IPv4 address to the loopback address. This allows for machine-internal communications to this address can use the large loopback mtu. --- diff --git a/if-bsd.c b/if-bsd.c index 566ddeb4..96f483d9 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -260,6 +260,9 @@ if_route(const struct rt *rt, int action) if (rt->dest.s_addr == rt->gate.s_addr && rt->net.s_addr == INADDR_BROADCAST) rtm.hdr.rtm_flags |= RTF_HOST; + else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) && + rt->net.s_addr == INADDR_BROADCAST) + rtm.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY; else { rtm.hdr.rtm_addrs |= RTA_NETMASK; if (rtm.hdr.rtm_flags & RTF_STATIC) @@ -269,7 +272,8 @@ if_route(const struct rt *rt, int action) } ADDADDR(&rt->dest); - if (rtm.hdr.rtm_flags & RTF_HOST || + if ((rtm.hdr.rtm_flags & RTF_HOST && + rt->gate.s_addr != htonl(INADDR_LOOPBACK)) || !(rtm.hdr.rtm_flags & RTF_STATIC)) { /* Make us a link layer socket for the host gateway */ diff --git a/ipv4.c b/ipv4.c index 567a1f23..c2be11d3 100644 --- a/ipv4.c +++ b/ipv4.c @@ -229,6 +229,10 @@ desc_route(const char *cmd, const struct rt *rt) rt->net.s_addr == INADDR_BROADCAST) syslog(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) + syslog(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) syslog(LOG_INFO, "%s: %s default route via %s", ifname, cmd, inet_ntoa(rt->gate)); @@ -341,6 +345,32 @@ add_subnet_route(struct rt_head *rt, const struct interface *ifp) return rt; } +static struct rt_head * +add_loopback_route(struct rt_head *rt, const struct interface *ifp) +{ + struct rt *r; + const struct dhcp_state *s; + + if (rt == NULL) /* earlier malloc failed */ + return NULL; + + s = D_CSTATE(ifp); + if (s->addr.s_addr == INADDR_ANY) + return rt; + + r = malloc(sizeof(*r)); + if (r == NULL) { + syslog(LOG_ERR, "%s: %m", __func__); + ipv4_freeroutes(rt); + return NULL; + } + r->dest.s_addr = s->addr.s_addr; + r->net.s_addr = INADDR_BROADCAST; + r->gate.s_addr = htonl(INADDR_LOOPBACK); + TAILQ_INSERT_HEAD(rt, r, next); + return rt; +} + static struct rt_head * get_routes(struct interface *ifp) { @@ -488,6 +518,7 @@ ipv4_buildroutes(void) dnr = get_routes(ifp); dnr = massage_host_routes(dnr, ifp); dnr = add_subnet_route(dnr, ifp); + dnr = add_loopback_route(dnr, ifp); if (ifp->options->options & DHCPCD_GATEWAY) { dnr = add_router_host_route(dnr, ifp); dnr = add_destination_route(dnr, ifp);