diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index 32183d0a..de0b97fc 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd February 5, 2013 +.Dd March 27, 2013 .Dt DHCPCD.CONF 5 SMM .Os .Sh NAME @@ -179,6 +179,9 @@ Metrics are used to prefer an interface over another one, lowest wins. will supply a default metric of 200 + .Xr if_nametoindex 3 . An extra 100 will be added for wireless interfaces. +.It Ic noalias +IPv4 addresses added will overwrite a pre-existing address instead of working +alongside. .It Ic noarp Don't send any ARP requests. This also disables IPv4LL. diff --git a/if-bsd.c b/if-bsd.c index 45b3a48b..e9d32f52 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -201,7 +201,8 @@ if_address(const struct interface *iface, const struct in_addr *address, #undef ADDADDR return ioctl(socket_afnet, - action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifa); + action < 0 ? SIOCDIFADDR : + action == 2 ? SIOCSIFADDR : SIOCAIFADDR, &ifa); } int diff --git a/if-options.c b/if-options.c index a75027e3..f058636b 100644 --- a/if-options.c +++ b/if-options.c @@ -61,6 +61,7 @@ unsigned long long options = 0; #define O_IPV6RA_FORK O_BASE + 6 #define O_IPV6RA_OWN O_BASE + 7 #define O_IPV6RA_OWN_D O_BASE + 8 +#define O_NOALIAS O_BASE + 9 const struct option cf_options[] = { {"background", no_argument, NULL, 'b'}, @@ -118,6 +119,7 @@ const struct option cf_options[] = { {"ipv6ra_own_default", no_argument, NULL, O_IPV6RA_OWN_D}, {"ipv4only", no_argument, NULL, '4'}, {"ipv6only", no_argument, NULL, '6'}, + {"noalias", no_argument, NULL, O_NOALIAS}, {NULL, 0, NULL, '\0'} }; @@ -915,6 +917,9 @@ parse_option(struct if_options *ifo, int opt, const char *arg) case O_IPV6RA_OWN_D: ifo->options |= DHCPCD_IPV6RA_OWN_DEFAULT; break; + case O_NOALIAS: + ifo->options |= DHCPCD_NOALIAS; + break; default: return 0; } diff --git a/if-options.h b/if-options.h index c6032b7c..81715d2c 100644 --- a/if-options.h +++ b/if-options.h @@ -88,6 +88,7 @@ #define DHCPCD_FORKED (1ULL << 36) #define DHCPCD_IPV6 (1ULL << 37) #define DHCPCD_STARTED (1ULL << 38) +#define DHCPCD_NOALIAS (1ULL << 39) extern const struct option cf_options[]; diff --git a/ipv4.c b/ipv4.c index 46d14b6b..b4e128e1 100644 --- a/ipv4.c +++ b/ipv4.c @@ -592,6 +592,7 @@ ipv4_applyaddr(void *arg) struct dhcp_lease *lease; struct if_options *ifo = ifp->options; struct rt *rt; + int r; /* As we are now adjusting an interface, we need to ensure * we have them in the right order for routing and configuration. */ @@ -619,10 +620,13 @@ ipv4_applyaddr(void *arg) syslog(LOG_DEBUG, "%s: adding IP address %s/%d", ifp->name, inet_ntoa(lease->addr), inet_ntocidr(lease->net)); - if (ipv4_addaddress(ifp, - &lease->addr, &lease->net, &lease->brd) == -1 && - errno != EEXIST) - { + if (ifo->options & DHCPCD_NOALIAS) + r = ipv4_setaddress(ifp, + &lease->addr, &lease->net, &lease->brd); + else + r = ipv4_addaddress(ifp, + &lease->addr, &lease->net, &lease->brd); + if (r == -1 && errno != EEXIST) { syslog(LOG_ERR, "%s: ipv4_addaddress: %m", __func__); return; } diff --git a/ipv4.h b/ipv4.h index 712b5339..bc1c691a 100644 --- a/ipv4.h +++ b/ipv4.h @@ -61,6 +61,8 @@ int if_address(const struct interface *, const struct in_addr *, int); #define ipv4_addaddress(iface, addr, net, brd) \ if_address(iface, addr, net, brd, 1) +#define ipv4_setaddress(iface, addr, net, brd) \ + if_address(iface, addr, net, brd, 2) #define ipv4_deleteaddress(iface, addr, net) \ if_address(iface, addr, net, NULL, -1) #define ipv4_hasaddress(iface, addr, net) \