]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
IP: If no address lifetime support don't re-add the address
authorRoy Marples <roy@marples.name>
Sun, 28 Jul 2019 14:37:05 +0000 (15:37 +0100)
committerRoy Marples <roy@marples.name>
Sun, 28 Jul 2019 14:37:05 +0000 (15:37 +0100)
Unless we need to. If we do, there is a chance that the OS
will scrub the subnet route and re-add it. We want to avoid
this as it's likely in use.

src/ipv4.c
src/ipv4.h

index 0618da07246390c0b9682238e9c18679291847db..16ed38128bce555cc8edd89ff0b746bd4dad99de 100644 (file)
@@ -659,8 +659,13 @@ ipv4_addaddr(struct interface *ifp, const struct in_addr *addr,
 
        ia->mask = *mask;
        ia->brd = *bcast;
+#ifdef IP_LIFETIME
        ia->vltime = vltime;
        ia->pltime = pltime;
+#else
+       UNUSED(vltime);
+       UNUSED(pltime);
+#endif
        snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
            inet_ntoa(*addr), inet_ntocidr(*mask));
 
@@ -746,16 +751,27 @@ ipv4_applyaddr(void *arg)
                return;
        }
 
-#if __linux__
-       /* If the netmask or broadcast is different, re-add the addresss */
        ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
-       if (ia != NULL &&
+       /* If the netmask or broadcast is different, re-add the addresss.
+        * If IP addresses do not have lifetimes, there is a very real chance
+        * that re-adding them will scrub the subnet route temporarily
+        * which is a bad thing, so avoid it. */
+       if (ia == NULL &&
            (ia->mask.s_addr != lease->mask.s_addr ||
            ia->brd.s_addr != lease->brd.s_addr))
-               ipv4_deladdr(ia, 0);
+       {
+#ifdef __linux__
+               if (ia != NULL)
+                       ipv4_deladdr(ia, 0);
+#elif !defined(IP_LIFETIME)
+               if (ipv4_daddaddr(ifp, lease) == -1 && errno != EEXIST)
+                       return;
 #endif
+       }
+#if IP_LIFETIME
        if (ipv4_daddaddr(ifp, lease) == -1 && errno != EEXIST)
                return;
+#endif
 
        ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
        if (ia == NULL) {
index 4e04e9b22bbdaaca3dec7d5908d6aac7426dbedc..d8204a7dcd842a28c18323f546f3957cc8f7b433 100644 (file)
 #define IN_ARE_ADDR_EQUAL(a, b)                ((a)->s_addr == (b)->s_addr)
 #define IN_IS_ADDR_UNSPECIFIED(a)      ((a)->s_addr == INADDR_ANY)
 
+#ifdef __linux__
+#define IP_LIFETIME
+#endif
+
 struct ipv4_addr {
        TAILQ_ENTRY(ipv4_addr) next;
        struct in_addr addr;
@@ -83,8 +87,10 @@ struct ipv4_addr {
        struct interface *iface;
        int addr_flags;
        unsigned int flags;
+#ifdef IP_LIFETIME
        uint32_t vltime;
        uint32_t pltime;
+#endif
        char saddr[INET_ADDRSTRLEN + 3];
 #ifdef ALIAS_ADDR
        char alias[IF_NAMESIZE];