]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Only build the routing tables for the address family we are interested in.
authorRoy Marples <roy@marples.name>
Sat, 19 Nov 2016 10:17:07 +0000 (10:17 +0000)
committerRoy Marples <roy@marples.name>
Sat, 19 Nov 2016 10:17:07 +0000 (10:17 +0000)
13 files changed:
dhcp.c
dhcp6.c
if-bsd.c
if-linux.c
if-options.c
if-sun.c
if.h
ipv4.c
ipv4ll.c
ipv6.c
ipv6nd.c
route.c
route.h

diff --git a/dhcp.c b/dhcp.c
index 0a475e169a9d8b001a9bb941d037471e10c6ed0b..2763cfe4a8ff7bad1ee6887a2c7f3fd7be68e4c5 100644 (file)
--- 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 50f281c2ec59d9f654f28a36159da6b8646aec64..13280154ca6495657ac43d909133f02b829bc5ab 100644 (file)
--- 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
index ea6f9170962898325970f5e014c6fc04f82878bc..3cfba2d309cf5d2a68b622c2d2c5f58bdcafda5b 100644 (file)
--- 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;
 
index 6fb8596157dca4139e646ca04a9658c29f6c5acb..4fabe792deb78c2907b0163c5b69c317a06e798c 100644 (file)
@@ -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);
 }
index 1ecf1cabb4dc2a521efd6d9881383a57eccaa0b9..f08d671e583b4e6609f8eb2556e06c38a5210623 100644 (file)
@@ -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);
index 3aeeb20b82e31a849809fa3a11abf339e708b8c4..55d508896e36925942fd0f5e59893a066b938473 100644 (file)
--- 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 a8555a434719544e993787e089d807d09b5f239c..4e13ef8feb370577cf66fe0b452d723fc4278402 100644 (file)
--- 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 2f64f38229f207031d100d8c7797aa8aedb19ff4..57a19dfe29f36a43f827d9b99845cd4d9775895a 100644 (file)
--- 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
index 1b6ce4e760d2ecb38df8c8cb8070a58b1a98d26a..6e96956a4a7827b47650fc33c23d51bbad7568da 100644 (file)
--- 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 3ed0526330dac82859ce761d2f72d610ce6ae4e2..80bb5f1e5bb42ff7564e6ab1d80ba99fd6a2bd95 100644 (file)
--- 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 {
index be81c9543ca004fe9ac7269a00a387904c3f2ea9..1a80a91016b9da0548d2c33b542f9a0475c761c3 100644 (file)
--- 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 3c2416fd76d560c2d485ca30a0b4ce97fe6397b8..1e6bd84eea34117da5ab4fa48ce0eacba5a3dd20 100644 (file)
--- 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 1da393bd516f143ffee76222262ae471718363d7..f5735d1fcf8a81e05217fcdd8fbe674f7a9321af 100644 (file)
--- 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 *);