From: Roy Marples Date: Fri, 1 May 2015 14:02:36 +0000 (+0000) Subject: Delete duplicated addresses. X-Git-Tag: v6.8.2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26e5154f95c08a5e0a6d2e8863ae2d03c2f46e46;p=thirdparty%2Fdhcpcd.git Delete duplicated addresses. --- diff --git a/dhcp.c b/dhcp.c index 4fa3eb04..abdfc787 100644 --- a/dhcp.c +++ b/dhcp.c @@ -2415,6 +2415,10 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg) (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 @@ -2423,6 +2427,11 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg) 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, @@ -2663,6 +2672,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, 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); @@ -3347,15 +3357,13 @@ dhcp_handleifa(int cmd, struct interface *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; diff --git a/dhcpcd.c b/dhcpcd.c index a9fbc601..76205e20 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -638,7 +638,9 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags, ifp->name); ifp->carrier = LINK_DOWN; script_runreason(ifp, "NOCARRIER"); -#ifndef NOCARRIER_PRESERVE_IP +#ifdef NOCARRIER_PRESERVE_IP + arp_close(ifp); +#else dhcpcd_drop(ifp, 0); #endif } @@ -1716,7 +1718,6 @@ main(int argc, char **argv) } } - if (ctx.options & DHCPCD_MASTER) { if (control_start(&ctx, NULL) == -1) logger(&ctx, LOG_ERR, "control_start: %m"); diff --git a/ipv4.c b/ipv4.c index 5f4acaa5..e517bcbb 100644 --- a/ipv4.c +++ b/ipv4.c @@ -731,21 +731,32 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx) 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 && @@ -771,10 +782,7 @@ delete_address(struct interface *ifp) 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; } @@ -812,7 +820,7 @@ ipv4_addaddr(struct interface *ifp, const struct dhcp_lease *lease) 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); } } @@ -954,7 +962,7 @@ ipv4_applyaddr(void *arg) 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; } @@ -967,14 +975,14 @@ ipv4_applyaddr(void *arg) 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, diff --git a/ipv4.h b/ipv4.h index ed694c92..cd52c41b 100644 --- a/ipv4.h +++ b/ipv4.h @@ -82,6 +82,8 @@ int ipv4_addrexists(struct dhcpcd_ctx *, const struct in_addr *); void ipv4_buildroutes(struct dhcpcd_ctx *); void ipv4_finaliseaddr(struct interface *); +int ipv4_deladdr(struct interface *ifp, const struct in_addr *, + const struct in_addr *); void ipv4_applyaddr(void *); int ipv4_handlert(struct dhcpcd_ctx *, int, struct rt *); void ipv4_freerts(struct rt_head *);