]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
If a normal default route is added, delete our IPv4LL default route.
authorRoy Marples <roy@marples.name>
Fri, 8 Apr 2016 20:02:41 +0000 (20:02 +0000)
committerRoy Marples <roy@marples.name>
Fri, 8 Apr 2016 20:02:41 +0000 (20:02 +0000)
If a normal defaulr route is deleted, and no other exists, add our IPv4LL
default route.

Fixes [bd6daf1d59].

if-bsd.c
if-linux.c
ipv4.c
ipv4.h
ipv4ll.c
ipv4ll.h

index 82fb73b0b354ef963f808dcac1905aa1931c837d..0930b9553c05439f1aa3e1595c6bfb2ce1bc2fce 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -768,7 +768,7 @@ if_initrt(struct interface *ifp)
        for (p = buf; p < end; p += rtm->rtm_msglen) {
                rtm = (void *)p;
                if (if_copyrt(ifp->ctx, &rt, rtm) == 0)
-                       ipv4_handlert(ifp->ctx, RTM_ADD, &rt);
+                       ipv4_handlert(ifp->ctx, RTM_ADD, &rt, 1);
        }
        free(buf);
        return 0;
@@ -1316,7 +1316,7 @@ if_managelink(struct dhcpcd_ctx *ctx)
 #ifdef INET
                        case AF_INET:
                                if (if_copyrt(ctx, &rt, rtm) == 0)
-                                       ipv4_handlert(ctx, rtm->rtm_type, &rt);
+                                       ipv4_handlert(ctx, rtm->rtm_type,&rt,0);
                                break;
 #endif
 #ifdef INET6
index 3d2603991058d32ed0b6d77b23e9abb554f48362..08be09557eedc362594dc4d1384ec2179391d7e5 100644 (file)
@@ -608,7 +608,7 @@ link_route(struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
 #ifdef INET
        case AF_INET:
                if (if_copyrt(ctx, &rt, nlm) == 0)
-                       ipv4_handlert(ctx, cmd, &rt);
+                       ipv4_handlert(ctx, cmd, &rt, 0);
                break;
 #endif
 #ifdef INET6
@@ -1463,7 +1463,7 @@ _if_initrt(struct dhcpcd_ctx *ctx, __unused struct interface *ifp,
        struct rt rt;
 
        if (if_copyrt(ctx, &rt, nlm) == 0)
-               ipv4_handlert(ctx, RTM_ADD, &rt);
+               ipv4_handlert(ctx, RTM_ADD, &rt, 1);
        return 0;
 }
 
diff --git a/ipv4.c b/ipv4.c
index 33768dc0dcb63509759b3e7ba0bb3b5fd476323e..a00f705b2e560edf5f3193c65fbb8aaa91e4572e 100644 (file)
--- a/ipv4.c
+++ b/ipv4.c
@@ -397,7 +397,7 @@ ipv4_findrt(struct dhcpcd_ctx *ctx, const struct rt *rt, int flags)
        TAILQ_FOREACH(r, ctx->ipv4_kroutes, next) {
                if (rt->dest.s_addr == r->dest.s_addr &&
 #ifdef HAVE_ROUTE_METRIC
-                   rt->iface == r->iface &&
+                   (rt->iface == NULL || rt->iface == r->iface) &&
                    (!flags || rt->metric == r->metric) &&
 #else
                    (!flags || rt->iface == r->iface) &&
@@ -422,7 +422,7 @@ ipv4_freerts(struct rt_head *routes)
 /* If something other than dhcpcd removes a route,
  * we need to remove it from our internal table. */
 int
-ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, const struct rt *rt)
+ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, const struct rt *rt, int flags)
 {
        struct rt *f;
 
@@ -453,7 +453,8 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, int cmd, const struct rt *rt)
                }
                break;
        }
-       return 0;
+
+       return flags ? 0 : ipv4ll_handlert(ctx, cmd, rt);
 }
 
 #define n_route(a)      nc_route(NULL, a)
@@ -869,15 +870,21 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
                ipv4_freeroutes(dnr);
        }
 
-       /* If we don't manage a default route, grab one without a
+       /* If there is no default route, grab one without a
         * gateway for any IPv4LL enabled interfaces. */
        if (!has_default) {
-               TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-                       if ((rt = ipv4ll_default_route(ifp)) != NULL) {
-                               if (ipv4_doroute(rt, nrs) == 1)
-                                       TAILQ_INSERT_TAIL(nrs, rt, next);
-                               else
-                                       free(rt);
+               struct rt def;
+
+               memset(&def, 0, sizeof(def));
+               if (ipv4_findrt(ctx, &def, 0) == NULL) {
+                       TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+                               if ((rt = ipv4ll_default_route(ifp)) != NULL) {
+                                       if (ipv4_doroute(rt, nrs) == 1) {
+                                               TAILQ_INSERT_TAIL(nrs, rt, next);
+                                               break;
+                                       } else
+                                               free(rt);
+                               }
                        }
                }
        }
diff --git a/ipv4.h b/ipv4.h
index ec6489b0d4e3c6fb7506b93a4264265ec5573796..f38d0ce1c8c3a93871ec4369fae1615b345fbfe2 100644 (file)
--- a/ipv4.h
+++ b/ipv4.h
@@ -114,7 +114,7 @@ int ipv4_preferanother(struct interface *);
 struct ipv4_addr *ipv4_addaddr(struct interface *,
     const struct in_addr *, const struct in_addr *, const struct in_addr *);
 void ipv4_applyaddr(void *);
-int ipv4_handlert(struct dhcpcd_ctx *, int, const struct rt *);
+int ipv4_handlert(struct dhcpcd_ctx *, int, const struct rt *, int);
 void ipv4_freerts(struct rt_head *);
 
 struct ipv4_addr *ipv4_iffindaddr(struct interface *,
index a1f103032ef74fdab7797071afb41d942db26e78..07d4a5dca660a3988a8a8533fc770b94449ec812 100644 (file)
--- a/ipv4ll.c
+++ b/ipv4ll.c
@@ -444,3 +444,25 @@ ipv4ll_freedrop(struct interface *ifp, int drop)
                }
        }
 }
+
+int
+ipv4ll_handlert(struct dhcpcd_ctx *ctx, __unused int cmd, const struct rt *rt)
+{
+       struct interface *ifp;
+
+       /* Only interested in default route changes. */
+       if (rt->dest.s_addr != INADDR_ANY)
+               return 0;
+
+       /* If any interface is running IPv4LL, rebuild our routing table. */
+       TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+               if (IPV4LL_STATE_RUNNING(ifp))
+                       break;
+       }
+       if (ifp != NULL) {
+               if_initrt(ifp);
+               ipv4_buildroutes(ctx);
+       }
+
+       return 0;
+}
index fe5e70d75dff54074fd961b2a781ab3aca239e6e..37093f38eef73542315c380b70ed014f9d767868 100644 (file)
--- a/ipv4ll.h
+++ b/ipv4ll.h
@@ -65,7 +65,7 @@ ssize_t ipv4ll_env(char **, const char *, const struct interface *);
 void ipv4ll_start(void *);
 void ipv4ll_claimed(void *);
 void ipv4ll_handle_failure(void *);
-int ipv4ll_handlert(struct dhcpcd_ctx *, int, struct rt *);
+int ipv4ll_handlert(struct dhcpcd_ctx *, int, const struct rt *);
 
 #define ipv4ll_free(ifp) ipv4ll_freedrop((ifp), 0);
 #define ipv4ll_drop(ifp) ipv4ll_freedrop((ifp), 1);