the interface when we want to add our own.
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 3, 2014
+.Dd December 13, 2014
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
.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.
+Any pre-existing IPv4 addresses existing address will be removed from the
+interface when adding a new IPv4 address.
.It Ic noarp
Don't send any ARP requests.
This also disables IPv4LL.
#include <net/route.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
+#include <netinet/in_var.h>
#include <netinet6/in6_var.h>
#include <netinet6/nd6.h>
#ifdef __DragonFly__
}
int
-if_address(const struct interface *iface, const struct in_addr *address,
+if_address(const struct interface *ifp, const struct in_addr *address,
const struct in_addr *netmask, const struct in_addr *broadcast,
int action)
{
int s, r;
- struct ifaliasreq ifa;
- union {
- struct sockaddr *sa;
- struct sockaddr_in *sin;
- } _s;
+ struct in_aliasreq ifra;
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
return -1;
- memset(&ifa, 0, sizeof(ifa));
- strlcpy(ifa.ifra_name, iface->name, sizeof(ifa.ifra_name));
-
-#define ADDADDR(_var, _addr) { \
- _s.sa = &_var; \
- _s.sin->sin_family = AF_INET; \
- _s.sin->sin_len = sizeof(*_s.sin); \
- memcpy(&_s.sin->sin_addr, _addr, sizeof(_s.sin->sin_addr)); \
- }
-
- ADDADDR(ifa.ifra_addr, address);
- ADDADDR(ifa.ifra_mask, netmask);
- if (action >= 0 && broadcast) {
- ADDADDR(ifa.ifra_broadaddr, broadcast);
- }
+ memset(&ifra, 0, sizeof(ifra));
+ strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name));
+
+#define ADDADDR(var, addr) do { \
+ (var)->sin_family = AF_INET; \
+ (var)->sin_len = sizeof(*(var)); \
+ (var)->sin_addr = *(addr); \
+ } while (/*CONSTCOND*/0)
+ ADDADDR(&ifra.ifra_addr, address);
+ ADDADDR(&ifra.ifra_mask, netmask);
+ if (action >= 0 && broadcast)
+ ADDADDR(&ifra.ifra_broadaddr, broadcast);
#undef ADDADDR
r = ioctl(s,
- action < 0 ? SIOCDIFADDR :
- action == 2 ? SIOCSIFADDR : SIOCAIFADDR, &ifa);
+ action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
close(s);
return r;
}
int if_address(const struct interface *,
const struct in_addr *, const struct in_addr *,
const struct in_addr *, int);
-#define if_addaddress(iface, addr, net, brd) \
- if_address(iface, addr, net, brd, 1)
-#define if_setaddress(iface, addr, net, brd) \
- if_address(iface, addr, net, brd, 2)
-#define if_deladdress(iface, addr, net) \
- if_address(iface, addr, net, NULL, -1)
+#define if_addaddress(ifp, addr, net, brd) \
+ if_address(ifp, addr, net, brd, 1)
+#define if_deladdress(ifp, addr, net) \
+ if_address(ifp, addr, net, NULL, -1)
int if_route(const struct rt *rt, int);
#define if_addroute(rt) if_route(rt, 1)
}
static int
-ipv4_addaddr(const struct interface *ifp, const struct dhcp_lease *lease)
+ipv4_addaddr(struct interface *ifp, const struct dhcp_lease *lease)
{
int r;
+ if (ifp->options->options & DHCPCD_NOALIAS) {
+ struct ipv4_state *state;
+ struct ipv4_addr *ap, *apn;
+
+ state = IPV4_STATE(ifp);
+ TAILQ_FOREACH_SAFE(ap, &state->addrs, next, apn) {
+ if (ap->addr.s_addr != lease->addr.s_addr)
+ delete_address1(ifp, &ap->addr, &ap->net);
+ }
+ }
+
syslog(LOG_DEBUG, "%s: adding IP address %s/%d",
ifp->name, inet_ntoa(lease->addr),
inet_ntocidr(lease->net));
- if (ifp->options->options & DHCPCD_NOALIAS)
- r = if_setaddress(ifp,
- &lease->addr, &lease->net, &lease->brd);
- else
- r = if_addaddress(ifp,
- &lease->addr, &lease->net, &lease->brd);
+ r = if_addaddress(ifp, &lease->addr, &lease->net, &lease->brd);
if (r == -1 && errno != EEXIST)
syslog(LOG_ERR, "%s: if_addaddress: %m", __func__);
return r;
/* Now delete the old address if different */
if (state->addr.s_addr != lease->addr.s_addr &&
- state->addr.s_addr != 0)
+ state->addr.s_addr != 0 &&
+ ipv4_iffindaddr(ifp, &lease->addr, NULL))
delete_address(ifp);
state->added = STATE_ADDED;