]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Try and fix removal of the ip address when using INFORM.
authorRoy Marples <roy@marples.name>
Fri, 6 Sep 2013 15:23:22 +0000 (15:23 +0000)
committerRoy Marples <roy@marples.name>
Fri, 6 Sep 2013 15:23:22 +0000 (15:23 +0000)
dhcp.c
ipv4.c

diff --git a/dhcp.c b/dhcp.c
index b13778c218cee59a38a8b2908789f03f85cc7b10..18f44a771318dfe342291f4bfd2deee21f2c9f85 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -1901,7 +1901,7 @@ dhcp_inform(struct interface *ifp)
                        }
                        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) {
@@ -2707,10 +2707,15 @@ dhcp_handleifa(int type, struct interface *ifp,
 
        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;
        }
 
diff --git a/ipv4.c b/ipv4.c
index 06dc761af4be7efbe64c453d0bc8131a29f2e233..ecfb1bb1ea81d3416a791297e2fcc7dcf5bb4219 100644 (file)
--- a/ipv4.c
+++ b/ipv4.c
@@ -320,10 +320,7 @@ add_subnet_route(struct rt_head *rt, const struct interface *ifp)
 
        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));
@@ -585,7 +582,7 @@ delete_address1(struct interface *ifp,
        }
        return r;
 }
-    
+
 static int
 delete_address(struct interface *ifp)
 {
@@ -604,6 +601,24 @@ 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)
 {
@@ -613,6 +628,7 @@ 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;
 
@@ -660,6 +676,12 @@ ipv4_applyaddr(void *arg)
                        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 */
@@ -712,18 +734,10 @@ ipv4_handleifa(int type, struct if_head *ifs, const char *ifname,
        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) {