]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
If config file changed, drop leases and re-disover.
authorRoy Marples <roy@marples.name>
Fri, 1 May 2015 12:39:06 +0000 (12:39 +0000)
committerRoy Marples <roy@marples.name>
Fri, 1 May 2015 12:39:06 +0000 (12:39 +0000)
Fix minor issues with IN_IFF_TENTATIVE.

arp.c
dhcp.c
dhcpcd.c
if-options.c
if-options.h
ipv4.c
ipv4.h

diff --git a/arp.c b/arp.c
index 614a7b66323ed299b4efc1c9970f2c499d20066d..01a8ba44011ee25a0533d9c102d523e39f4aa958 100644 (file)
--- a/arp.c
+++ b/arp.c
@@ -41,6 +41,7 @@
 #define ELOOP_QUEUE 5
 #include "config.h"
 #include "arp.h"
+#include "if.h"
 #include "ipv4.h"
 #include "common.h"
 #include "dhcp.h"
@@ -406,7 +407,7 @@ arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
                        if (flags & IN_IFF_DUPLICATED) {
                                if (astate->conflicted_cb)
                                        astate->conflicted_cb(astate, NULL);
-                       } else if (!(flags & IN_IFF_TENTATIVE)) {
+                       } else if (!(flags & IN_IFF_NOTUSEABLE)) {
                                if (astate->probed_cb)
                                        astate->probed_cb(astate);
                        }
diff --git a/dhcp.c b/dhcp.c
index 8d2d946f7e8351019185f0bd8d59f5167148e6f6..67e0b505d3bcd5d358dda175906648d80b8f91be 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -1589,6 +1589,9 @@ send_message(struct interface *ifp, uint8_t type,
        in_addr_t a = INADDR_ANY;
        struct timespec tv;
        int s;
+#ifdef IN_IFF_NOTUSEABLE
+       struct ipv4_addr *ia;
+#endif
 
        if (!callback)
                logger(ifp->ctx, LOG_DEBUG, "%s: sending %s with xid 0x%x",
@@ -1621,6 +1624,10 @@ send_message(struct interface *ifp, uint8_t type,
        if (state->added && !(state->added & STATE_FAKE) &&
            state->addr.s_addr != INADDR_ANY &&
            state->new != NULL &&
+#ifdef IN_IFF_NOTUSEABLE
+           ((ia = ipv4_iffindaddr(ifp, &state->addr, NULL)) &&
+           !(ia->addr_flags & IN_IFF_NOTUSEABLE)) &&
+#endif
            (state->new->cookie == htonl(MAGIC_COOKIE) ||
            ifp->options->options & DHCPCD_INFORM))
        {
@@ -2438,6 +2445,9 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
        size_t auth_len;
        char *msg;
        struct arp_state *astate;
+#ifdef IN_IFF_DUPLICATED
+       struct ipv4_addr *ia;
+#endif
 
        /* We may have found a BOOTP server */
        if (get_option_uint8(ifp->ctx, &type, dhcp, DHO_MESSAGETYPE) == -1)
@@ -2648,13 +2658,23 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
                return;
        }
 
-       if ((type == 0 || type == DHCP_OFFER) &&
-           (state->state == DHS_DISCOVER || state->state == DHS_IPV4LL_BOUND))
-       {
 #ifdef IN_IFF_DUPLICATED
-               struct ipv4_addr *ia;
+       ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
+       if (ia && ia->addr_flags & IN_IFF_DUPLICATED) {
+               log_dhcp(LOG_WARNING, "declined duplicate address",
+                   ifp, dhcp, from);
+               if (type)
+                       dhcp_decline(ifp);
+               eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+               eloop_timeout_add_sec(ifp->ctx->eloop,
+                   DHCP_RAND_MAX, dhcp_discover, ifp);
+               return;
+       }
 #endif
 
+       if ((type == 0 || type == DHCP_OFFER) &&
+           (state->state == DHS_DISCOVER || state->state == DHS_IPV4LL_BOUND))
+       {
                lease->frominfo = 0;
                lease->addr.s_addr = dhcp->yiaddr;
                lease->cookie = dhcp->cookie;
@@ -2663,18 +2683,6 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
                    &lease->server, dhcp, DHO_SERVERID) != 0)
                        lease->server.s_addr = INADDR_ANY;
                log_dhcp(LOG_INFO, "offered", ifp, dhcp, from);
-#ifdef IN_IFF_DUPLICATED
-               ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
-               if (ia && ia->addr_flags & IN_IFF_DUPLICATED) {
-                       log_dhcp(LOG_WARNING, "declined duplicate address",
-                           ifp, dhcp, from);
-                       dhcp_decline(ifp);
-                       eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
-                       eloop_timeout_add_sec(ifp->ctx->eloop,
-                           DHCP_RAND_MAX, dhcp_discover, ifp);
-                       return;
-               }
-#endif
                free(state->offer);
                state->offer = dhcp;
                *dhcpp = NULL;
@@ -2739,13 +2747,19 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
        lease->frominfo = 0;
        eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
        astate = NULL;
-       if (ifo->options & DHCPCD_ARP &&
-           state->addr.s_addr != state->offer->yiaddr)
+
+#ifndef IN_IFF_TENTATIVE
+       if (ifo->options & DHCPCD_ARP
+           && state->addr.s_addr != state->offer->yiaddr)
+#endif
        {
+               addr.s_addr = state->offer->yiaddr;
+#ifndef IN_IFF_TENTATIVE
                /* If the interface already has the address configured
                 * then we can't ARP for duplicate detection. */
-               addr.s_addr = state->offer->yiaddr;
-               if (!ipv4_iffindaddr(ifp, &addr, NULL)) {
+               ia = ipv4_findaddr(ifp->ctx, &addr);
+               if (ia) {
+#endif
                        astate = arp_new(ifp, &addr);
                        if (astate) {
                                astate->probed_cb = dhcp_arp_probed;
@@ -2756,8 +2770,8 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
                        }
 #ifndef IN_IFF_TENTATIVE
                        return;
-#endif
                }
+#endif
        }
 
        dhcp_bind(ifp, astate);
@@ -3141,7 +3155,8 @@ dhcp_start1(void *arg)
                        /* Don't log an error if some other process
                         * is handling this. */
                        if (errno != EADDRINUSE)
-                               logger(ifp->ctx, LOG_ERR, "dhcp_openudp: %m");
+                               logger(ifp->ctx, LOG_ERR,
+                                   "%s: dhcp_openudp: %m", __func__);
                } else
                        eloop_event_add(ifp->ctx->eloop,
                            ifp->ctx->udp_fd, dhcp_handleudp,
index c5389d5cfa7028f6ca1ad50e9792d5c875c048f3..a9fbc601f56749d562b915883fa5caefc52d7b45 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -350,7 +350,7 @@ stop_interface(struct interface *ifp)
 }
 
 static void
-configure_interface1(struct interface *ifp, struct if_options *old)
+configure_interface1(struct interface *ifp)
 {
        struct if_options *ifo = ifp->options;
        int ra_global, ra_iface;
@@ -516,16 +516,6 @@ configure_interface1(struct interface *ifp, struct if_options *old)
        /* If we are not sending an authentication option, don't require it */
        if (!(ifo->auth.options & DHCPCD_AUTH_SEND))
                ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE;
-
-       /* If we ARPing something or options have changed,
-        * drop leases and restart */
-       if (old) {
-               /* Remove warning options for a fair comparison */
-               old->options &= ~(DHCPCD_WARNINGS | DHCPCD_CONF);
-               if (ifo->arping_len || memcmp(ifo, old, sizeof(*old)))
-                       dhcpcd_drop(ifp, 0);
-               free(old);
-       }
 }
 
 int
@@ -559,16 +549,10 @@ dhcpcd_selectprofile(struct interface *ifp, const char *profile)
        } else
                *ifp->profile = '\0';
 
-       if (profile) {
-               struct if_options *old;
-
-               old = ifp->options;
-               ifp->options = ifo;
-               configure_interface1(ifp, old);
-       } else {
-               free_options(ifp->options);
-               ifp->options = ifo;
-       }
+       free_options(ifp->options);
+       ifp->options = ifo;
+       if (profile)
+               configure_interface1(ifp);
        return 1;
 }
 
@@ -576,13 +560,20 @@ static void
 configure_interface(struct interface *ifp, int argc, char **argv,
     unsigned long long options)
 {
-       struct if_options *old;
+       time_t old;
 
-       old = ifp->options;
+       old = ifp->options ? ifp->options->mtime : 0;
        dhcpcd_selectprofile(ifp, NULL);
        add_options(ifp->ctx, ifp->name, ifp->options, argc, argv);
        ifp->options->options |= options;
-       configure_interface1(ifp, old);
+       configure_interface1(ifp);
+
+       /* If the mtime has changed drop any old lease */
+       if (ifp->options && old != 0 && ifp->options->mtime != old) {
+               logger(ifp->ctx, LOG_WARNING,
+                   "%s: confile file changed, expiring leases", ifp->name);
+               dhcpcd_drop(ifp, 0);
+       }
 }
 
 static void
index 4a4c650723e8de400a3b1f57b24a86e83cc4a5a3..85b6e8e5e662c41aff84b01b77be36030a01297f 100644 (file)
@@ -28,6 +28,7 @@
 #define _WITH_GETLINE /* Stop FreeBSD bitching */
 
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 
 #include <arpa/inet.h>
@@ -2040,6 +2041,7 @@ read_config(struct dhcpcd_ctx *ctx,
 {
        struct if_options *ifo;
        FILE *fp;
+       struct stat sb;
        char *line, *buf, *option, *p;
        size_t buflen;
        ssize_t vlen;
@@ -2196,6 +2198,8 @@ read_config(struct dhcpcd_ctx *ctx,
                free(buf);
                return ifo;
        }
+       if (stat(ctx->cffile, &sb) == 0)
+               ifo->mtime = sb.st_mtime;
 
        ldop = edop = NULL;
        while ((line = get_line(&buf, &buflen, fp))) {
index 5544e23cdb9502596d1bad5e1aad59bb59469939..4d1de15dd43b3fcb64df3e75674a90fb369b7974 100644 (file)
@@ -144,6 +144,7 @@ struct vivco {
 };
 
 struct if_options {
+       time_t mtime;
        uint8_t iaid[4];
        int metric;
        uint8_t requestmask[256 / NBBY];
diff --git a/ipv4.c b/ipv4.c
index d49984a01ebc2fa9101c6a45f756553323c7889d..5f4acaa54b037b2f7ea6a0a63dfed5466fb4099e 100644 (file)
--- a/ipv4.c
+++ b/ipv4.c
@@ -987,13 +987,13 @@ ipv4_applyaddr(void *arg)
                        return;
        }
 
-#ifdef IN_IFF_TENTATIVE
+#ifdef IN_IFF_NOTUSEABLE
        ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
        if (ap == NULL) {
                logger(ifp->ctx, LOG_ERR, "%s: added address vanished",
                    ifp->name);
                return;
-       } else if (ap->addr_flags & IN_IFF_TENTATIVE)
+       } else if (ap->addr_flags & IN_IFF_NOTUSEABLE)
                return;
 #endif
 
diff --git a/ipv4.h b/ipv4.h
index a33e6737a10df881c36e9f4848e4762d9085c7fc..ed694c9278447b5291c498cf927c5c1bad327ac3 100644 (file)
--- a/ipv4.h
+++ b/ipv4.h
 
 #include "dhcpcd.h"
 
+#ifdef IN_IFF_TENTATIVE
+#define IN_IFF_NOTUSEABLE \
+        (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED | IN_IFF_DETACHED)
+#endif
+
 struct rt {
        TAILQ_ENTRY(rt) next;
        struct in_addr dest;