From: Roy Marples Date: Sat, 19 Nov 2016 10:17:07 +0000 (+0000) Subject: Only build the routing tables for the address family we are interested in. X-Git-Tag: v7.0.0-beta1~106 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ded03af2e9cf2a457c741ef4780c416914eaaa97;p=thirdparty%2Fdhcpcd.git Only build the routing tables for the address family we are interested in. --- diff --git a/dhcp.c b/dhcp.c index 0a475e16..2763cfe4 100644 --- a/dhcp.c +++ b/dhcp.c @@ -3410,7 +3410,7 @@ dhcp_init(struct interface *ifp) state->raw_fd = -1; /* Now is a good time to find IPv4 routes */ - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET); } state->state = DHS_INIT; diff --git a/dhcp6.c b/dhcp6.c index 50f281c2..13280154 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -2650,7 +2650,7 @@ dhcp6_delegate_prefix(struct interface *ifp) if (k && !carrier_warned) { ifd_state = D6_STATE(ifd); ipv6_addaddrs(&ifd_state->addrs); - if_initrt(ifd->ctx); + if_initrt(ifd->ctx, AF_INET6); rt_build(ifd->ctx, AF_INET6); dhcp6_script_try_run(ifd, 1); } @@ -2717,7 +2717,7 @@ dhcp6_find_delegates(struct interface *ifp) state = D6_STATE(ifp); state->state = DH6S_DELEGATED; ipv6_addaddrs(&state->addrs); - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET6); rt_build(ifp->ctx, AF_INET6); dhcp6_script_try_run(ifp, 1); } @@ -3233,7 +3233,7 @@ dhcp6_handledata(void *arg) else if (state->expire == 0) logger(ifp->ctx, has_new ? LOG_INFO : LOG_DEBUG, "%s: will expire", ifp->name); - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET6); rt_build(ifp->ctx, AF_INET6); dhcp6_writelease(ifp); #ifndef SMALL diff --git a/if-bsd.c b/if-bsd.c index ea6f9170..3cfba2d3 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -567,7 +567,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) } int -if_initrt(struct dhcpcd_ctx *ctx) +if_initrt(struct dhcpcd_ctx *ctx, int af) { struct rt_msghdr *rtm; int mib[6]; @@ -575,12 +575,12 @@ if_initrt(struct dhcpcd_ctx *ctx) char *buf, *p, *end; struct rt rt; - rt_headclear(&ctx->kroutes); + rt_headclear(&ctx->kroutes, AF_UNSPEC); mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; - mib[3] = AF_UNSPEC; + mib[3] = af; mib[4] = NET_RT_DUMP; mib[5] = 0; diff --git a/if-linux.c b/if-linux.c index 6fb85961..4fabe792 100644 --- a/if-linux.c +++ b/if-linux.c @@ -1270,18 +1270,18 @@ _if_initrt(struct dhcpcd_ctx *ctx, __unused struct interface *ifp, } int -if_initrt(struct dhcpcd_ctx *ctx) +if_initrt(struct dhcpcd_ctx *ctx, int af) { struct nlmr nlm; - rt_headclear(&ctx->kroutes); + rt_headclear(&ctx->kroutes, af); memset(&nlm, 0, sizeof(nlm)); nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); nlm.hdr.nlmsg_type = RTM_GETROUTE; nlm.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH; nlm.rt.rtm_table = RT_TABLE_MAIN; - nlm.rt.rtm_family = AF_UNSPEC; + nlm.rt.rtm_family = af; return send_netlink(ctx, NULL, NETLINK_ROUTE, &nlm.hdr, &_if_initrt); } diff --git a/if-options.c b/if-options.c index 1ecf1cab..f08d671e 100644 --- a/if-options.c +++ b/if-options.c @@ -2585,7 +2585,7 @@ free_options(struct if_options *ifo) free(ifo->config[i++]); free(ifo->config); } - rt_headclear(&ifo->routes); + rt_headclear(&ifo->routes, AF_UNSPEC); free(ifo->script); free(ifo->arping); free(ifo->blacklist); diff --git a/if-sun.c b/if-sun.c index 3aeeb20b..55d50889 100644 --- a/if-sun.c +++ b/if-sun.c @@ -1283,16 +1283,18 @@ out: int -if_initrt(struct dhcpcd_ctx *ctx) +if_initrt(struct dhcpcd_ctx *ctx, int af) { - rt_headclear(&ctx->kroutes); + rt_headclear(&ctx->kroutes, af); #ifdef INET - if (if_parsert(ctx, MIB2_IP,MIB2_IP_ROUTE, if_walkrt) == -1) + if ((af == AF_UNSPEC || af == AF_INET) && + if_parsert(ctx, MIB2_IP,MIB2_IP_ROUTE, if_walkrt) == -1) return -1; #endif #ifdef INET6 - if (if_parsert(ctx, MIB2_IP6, MIB2_IP6_ROUTE, if_walkrt6) == -1) + if ((af == AF_UNSPEC || af == AF_INET6) && + if_parsert(ctx, MIB2_IP6, MIB2_IP6_ROUTE, if_walkrt6) == -1) return -1; #endif return 0; diff --git a/if.h b/if.h index a8555a43..4e13ef8f 100644 --- a/if.h +++ b/if.h @@ -183,7 +183,7 @@ int if_addrflags(const struct interface *, const struct in_addr *, const char *); int if_route(unsigned char, const struct rt *rt); -int if_initrt(struct dhcpcd_ctx *); +int if_initrt(struct dhcpcd_ctx *, int); #endif #ifdef INET6 diff --git a/ipv4.c b/ipv4.c index 2f64f382..57a19dfe 100644 --- a/ipv4.c +++ b/ipv4.c @@ -828,7 +828,7 @@ ipv4_applyaddr(void *arg) /* Find any freshly added routes, such as the subnet route. * We do this because we cannot rely on recieving the kernel * notification right now via our link socket. */ - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET); rt_build(ifp->ctx, AF_INET); #ifdef ARP diff --git a/ipv4ll.c b/ipv4ll.c index 1b6ce4e7..6e96956a 100644 --- a/ipv4ll.c +++ b/ipv4ll.c @@ -498,7 +498,7 @@ ipv4ll_recvrt(__unused int cmd, const struct rt *rt) ctx = rt->rt_ifp->ctx; TAILQ_FOREACH(ifp, ctx->ifaces, next) { if (IPV4LL_STATE_RUNNING(ifp)) { - if_initrt(ctx); + if_initrt(ctx, AF_INET); rt_build(ctx, AF_INET); break; } diff --git a/ipv6.c b/ipv6.c index 3ed05263..80bb5f1e 100644 --- a/ipv6.c +++ b/ipv6.c @@ -1589,7 +1589,7 @@ ipv6_startstatic(struct interface *ifp) ia->prefix_pltime = ND6_INFINITE_LIFETIME; ia->dadcallback = ipv6_staticdadcallback; ipv6_addaddr(ia, NULL); - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET6); rt_build(ifp->ctx, AF_INET6); if (run_script) script_runreason(ifp, "STATIC6"); @@ -1633,7 +1633,7 @@ ipv6_start(struct interface *ifp) } /* Load existing routes */ - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET6); return 0; } @@ -1658,7 +1658,7 @@ ipv6_freedrop(struct interface *ifp, int drop) ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL); if (drop) { if (ifp->ctx->ipv6 != NULL) { - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET6); rt_build(ifp->ctx, AF_INET6); } } else { diff --git a/ipv6nd.c b/ipv6nd.c index be81c954..1a80a910 100644 --- a/ipv6nd.c +++ b/ipv6nd.c @@ -1105,7 +1105,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp, /* Find any freshly added routes, such as the subnet route. * We do this because we cannot rely on recieving the kernel * notification right now via our link socket. */ - if_initrt(ifp->ctx); + if_initrt(ifp->ctx, AF_INET6); rt_build(ifp->ctx, AF_INET6); if (ipv6nd_scriptrun(rap)) diff --git a/route.c b/route.c index 3c2416fd..1e6bd84e 100644 --- a/route.c +++ b/route.c @@ -102,21 +102,25 @@ rt_desc(const char *cmd, const struct rt *rt) } void -rt_headclear(struct rt_head *rts) +rt_headclear(struct rt_head *rts, int af) { - struct rt *rt; + struct rt *rt, *rtn; struct dhcpcd_ctx *ctx; if (rts == NULL) return; - ctx = NULL; - while ((rt = TAILQ_FIRST(rts))) { + if ((rt = TAILQ_FIRST(rts)) == NULL) + return; + ctx = rt->rt_ifp->ctx; + assert(&ctx->froutes != rts); + + TAILQ_FOREACH_SAFE(rt, rts, rt_next, rtn) { + if (af != AF_UNSPEC && + rt->rt_dest.sa_family != af && + rt->rt_gateway.sa_family != af) + continue; TAILQ_REMOVE(rts, rt, rt_next); - if (ctx == NULL) { - ctx = rt->rt_ifp->ctx; - assert(&ctx->froutes != rts); - } TAILQ_INSERT_TAIL(&ctx->froutes, rt, rt_next); } } @@ -532,7 +536,7 @@ rt_build(struct dhcpcd_ctx *ctx, int af) TAILQ_INSERT_TAIL(&ctx->froutes, rt, rt_next); } - rt_headclear(&ctx->routes); + rt_headclear(&ctx->routes, af); TAILQ_CONCAT(&ctx->routes, &added, rt_next); - rt_headclear(&routes); + rt_headclear(&routes, AF_UNSPEC); } diff --git a/route.h b/route.h index 1da393bd..f5735d1f 100644 --- a/route.h +++ b/route.h @@ -78,7 +78,7 @@ void rt_dispose(struct dhcpcd_ctx *); struct rt * rt_find(struct rt_head *, const struct rt *); void rt_free(struct rt *); void rt_freeif(struct interface *); -void rt_headclear(struct rt_head *); +void rt_headclear(struct rt_head *, int); void rt_headfreeif(struct rt_head *); struct rt * rt_new(struct interface *); void rt_recvrt(int, const struct rt *);