(amsg->sip.s_addr == 0 &&
amsg->tip.s_addr == state->offer->yiaddr))))
{
+#ifdef IN_IFF_DUPLICATED
+ struct ipv4_addr *ia;
+#endif
+
if (amsg)
astate->failed.s_addr = state->offer->yiaddr;
else
unlink(state->leasefile);
if (!state->lease.frominfo)
dhcp_decline(astate->iface);
+#ifdef IN_IFF_DUPLICATED
+ ia = ipv4_iffindaddr(astate->iface, &astate->addr, NULL);
+ if (ia)
+ ipv4_deladdr(astate->iface, &ia->addr, &ia->net);
+#endif
eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
astate->iface);
eloop_timeout_add_sec(astate->iface->ctx->eloop,
ifp, dhcp, from);
if (type)
dhcp_decline(ifp);
+ ipv4_deladdr(ifp, &ia->addr, &ia->net);
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
eloop_timeout_add_sec(ifp->ctx->eloop,
DHCP_RAND_MAX, dhcp_discover, ifp);
return;
if (cmd == RTM_DELADDR) {
- if (state->new &&
- (state->new->yiaddr == addr->s_addr ||
- (state->new->yiaddr == INADDR_ANY &&
- state->new->ciaddr == addr->s_addr)))
+ if (state->addr.s_addr == addr->s_addr &&
+ state->net.s_addr == net->s_addr)
{
logger(ifp->ctx, LOG_INFO,
"%s: removing IP address %s/%d",
- ifp->name, inet_ntoa(state->lease.addr),
- inet_ntocidr(state->lease.net));
+ ifp->name, inet_ntoa(state->addr),
+ inet_ntocidr(state->net));
dhcp_drop(ifp, "EXPIRE");
}
return;
ctx->ipv4_routes = nrs;
}
-static int
-delete_address1(struct interface *ifp,
+int
+ipv4_deladdr(struct interface *ifp,
const struct in_addr *addr, const struct in_addr *net)
{
+ struct dhcp_state *dstate;
int r;
struct ipv4_state *state;
struct ipv4_addr *ap;
logger(ifp->ctx, LOG_DEBUG, "%s: deleting IP address %s/%d",
ifp->name, inet_ntoa(*addr), inet_ntocidr(*net));
+
r = if_deladdress(ifp, addr, net);
if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO &&
errno != ENODEV)
logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
+ dstate = D_STATE(ifp);
+ if (dstate->addr.s_addr == addr->s_addr &&
+ dstate->net.s_addr == net->s_addr)
+ {
+ dstate->added = 0;
+ dstate->addr.s_addr = 0;
+ dstate->net.s_addr = 0;
+ }
+
state = IPV4_STATE(ifp);
TAILQ_FOREACH(ap, &state->addrs, next) {
if (ap->addr.s_addr == addr->s_addr &&
if (ifo->options & DHCPCD_INFORM ||
(ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
return 0;
- r = delete_address1(ifp, &state->addr, &state->net);
- state->added = 0;
- state->addr.s_addr = 0;
- state->net.s_addr = 0;
+ r = ipv4_deladdr(ifp, &state->addr, &state->net);
return r;
}
TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) {
if (ia->addr.s_addr != lease->addr.s_addr)
- delete_address1(ifp, &ia->addr, &ia->net);
+ ipv4_deladdr(ifp, &ia->addr, &ia->net);
}
}
ifn->name,
inet_ntoa(lease->addr),
ifp->name);
- delete_address1(ifn, &nstate->addr, &nstate->net);
+ ipv4_deladdr(ifn, &nstate->addr, &nstate->net);
nstate->added = 0;
break;
}
continue;
ap = ipv4_iffindaddr(ifn, &lease->addr, NULL);
if (ap)
- delete_address1(ifn, &ap->addr, &ap->net);
+ ipv4_deladdr(ifn, &ap->addr, &ap->net);
}
}
/* If the netmask is different, delete the addresss */
ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
if (ap && ap->net.s_addr != lease->net.s_addr)
- delete_address1(ifp, &ap->addr, &ap->net);
+ ipv4_deladdr(ifp, &ap->addr, &ap->net);
if (ipv4_iffindaddr(ifp, &lease->addr, &lease->net))
logger(ifp->ctx, LOG_DEBUG,