}
state->offer =
dhcp_message_new(&ap->addr, &ap->net);
- } else
+ } else
state->offer =
dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
if (state->offer) {
if (type == RTM_DELADDR) {
if (state->new &&
- state->new->yiaddr == addr->s_addr)
+ (state->new->yiaddr == addr->s_addr ||
+ (state->new->yiaddr == INADDR_ANY &&
+ state->new->ciaddr == addr->s_addr)))
+ {
syslog(LOG_INFO, "%s: removing IP address %s/%d",
ifp->name, inet_ntoa(state->lease.addr),
inet_ntocidr(state->lease.net));
+ dhcp_drop(ifp, "EXPIRE");
+ }
return;
}
s = D_CSTATE(ifp);
if (s->net.s_addr == INADDR_BROADCAST ||
- s->net.s_addr == INADDR_ANY ||
- (ifp->options->options &
- (DHCPCD_INFORM | DHCPCD_STATIC) &&
- ifp->options->req_addr.s_addr == INADDR_ANY))
+ s->net.s_addr == INADDR_ANY)
return rt;
r = malloc(sizeof(*r));
}
return r;
}
-
+
static int
delete_address(struct interface *ifp)
{
return r;
}
+static struct ipv4_state *
+ipv4_getstate(struct interface *ifp)
+{
+ struct ipv4_state *state;
+
+ state = IPV4_STATE(ifp);
+ if (state == NULL) {
+ ifp->if_data[IF_DATA_IPV4] = malloc(sizeof(*state));
+ state = IPV4_STATE(ifp);
+ if (state == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ return NULL;
+ }
+ TAILQ_INIT(&state->addrs);
+ }
+ return state;
+}
+
void
ipv4_applyaddr(void *arg)
{
struct dhcp_lease *lease;
struct if_options *ifo = ifp->options;
struct ipv4_addr *ap;
+ struct ipv4_state *istate;
struct rt *rt;
int r;
syslog(LOG_ERR, "%s: ipv4_addaddress: %m", __func__);
return;
}
+ istate = ipv4_getstate(ifp);
+ ap = malloc(sizeof(*ap));
+ ap->addr = lease->addr;
+ ap->net = lease->net;
+ ap->dst.s_addr = INADDR_ANY;
+ TAILQ_INSERT_TAIL(&istate->addrs, ap, next);
}
/* Now delete the old address if different */
if (ifp == NULL)
return;
- state = IPV4_STATE(ifp);
- if (state == NULL) {
- ifp->if_data[IF_DATA_IPV4] = malloc(sizeof(*state));
- state = IPV4_STATE(ifp);
- if (state == NULL) {
- syslog(LOG_ERR, "%s: %m", __func__);
- return;
- }
- TAILQ_INIT(&state->addrs);
- ap = NULL;
- } else
- ap = ipv4_findaddr(ifp, addr, net);
+ state = ipv4_getstate(ifp);
+ if (state == NULL)
+ return;
+ ap = ipv4_findaddr(ifp, addr, net);
if (type == RTM_NEWADDR && ap == NULL) {
ap = malloc(sizeof(*ap));
if (ap == NULL) {