From: Roy Marples Date: Sun, 28 Jul 2019 14:37:05 +0000 (+0100) Subject: IP: If no address lifetime support don't re-add the address X-Git-Tag: v8.0.2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=377c8d1eafb5d76d1e1b6a5284d920d18f74c6d3;p=thirdparty%2Fdhcpcd.git IP: If no address lifetime support don't re-add the address 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. --- diff --git a/src/ipv4.c b/src/ipv4.c index 0618da07..16ed3812 100644 --- a/src/ipv4.c +++ b/src/ipv4.c @@ -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) { diff --git a/src/ipv4.h b/src/ipv4.h index 4e04e9b2..d8204a7d 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -75,6 +75,10 @@ #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];