]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Remove the complex ARP logic when binding a lease and fix adding a lease.
authorRoy Marples <roy@marples.name>
Fri, 26 Jun 2015 17:43:34 +0000 (17:43 +0000)
committerRoy Marples <roy@marples.name>
Fri, 26 Jun 2015 17:43:34 +0000 (17:43 +0000)
dhcp.c
ipv4.c
ipv4.h

diff --git a/dhcp.c b/dhcp.c
index a8da8190c510c4c40981be995448924f44b303c7..69b1ed49e378a9b501cc535abae1449b671aec8b 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -1857,14 +1857,12 @@ dhcp_renew(void *arg)
        send_renew(ifp);
 }
 
-#ifndef IN_IFF_TENTATIVE
 static void
 dhcp_arp_announced(struct arp_state *astate)
 {
 
        arp_close(astate->iface);
 }
-#endif
 
 static void
 dhcp_rebind(void *arg)
@@ -1891,12 +1889,12 @@ dhcp_arp_probed(struct arp_state *astate)
        struct dhcp_state *state;
        struct if_options *ifo;
 
-       /* We didn't find a profile for this
-        * address or hwaddr, so move to the next
-        * arping profile */
        state = D_STATE(astate->iface);
        ifo = astate->iface->options;
        if (state->arping_index < ifo->arping_len) {
+               /* We didn't find a profile for this
+                * address or hwaddr, so move to the next
+                * arping profile */
                if (++state->arping_index < ifo->arping_len) {
                        astate->addr.s_addr =
                            ifo->arping[state->arping_index - 1];
@@ -1905,17 +1903,10 @@ dhcp_arp_probed(struct arp_state *astate)
                dhcpcd_startinterface(astate->iface);
                return;
        }
-       dhcp_close(astate->iface);
 
-       eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate->iface);
-#ifdef IN_IFF_TENTATIVE
        logger(astate->iface->ctx, LOG_DEBUG, "%s: DAD completed for %s",
            astate->iface->name, inet_ntoa(astate->addr));
-       ipv4_finaliseaddr(astate->iface);
-       arp_close(astate->iface);
-#else
        dhcp_bind(astate->iface);
-#endif
 
        /* Stop IPv4LL now we have a working DHCP address */
        ipv4ll_drop(astate->iface);
@@ -1996,13 +1987,7 @@ dhcp_bind(struct interface *ifp)
        struct dhcp_state *state = D_STATE(ifp);
        struct if_options *ifo = ifp->options;
        struct dhcp_lease *lease = &state->lease;
-       struct arp_state *astate;
 
-       if (state->state == DHS_BOUND)
-               goto applyaddr;
-#ifdef IN_IFF_TENTATIVE
-       state->added |= STATE_TENTATIVE;
-#endif
        state->reason = NULL;
        free(state->old);
        state->old = state->new;
@@ -2109,40 +2094,7 @@ dhcp_bind(struct interface *ifp)
                        logger(ifp->ctx, LOG_ERR,
                            "%s: write_lease: %m", __func__);
 
-applyaddr:
-#ifdef IN_IFF_TENTATIVE
-       if ((astate = arp_find(ifp, &lease->addr)) == NULL) {
-               if ((astate = arp_new(ifp, &lease->addr)) != NULL) {
-                       astate->probed_cb = dhcp_arp_probed;
-                       astate->conflicted_cb = dhcp_arp_conflicted;
-               }
-       }
-#endif
-
        ipv4_applyaddr(ifp);
-       if (ifo->options & DHCPCD_ARP &&
-           !(ifp->ctx->options & DHCPCD_FORKED))
-       {
-#ifdef IN_IFF_TENTATIVE
-               if (astate)
-                       arp_free_but(astate);
-               else
-                       arp_close(ifp);
-#else
-               if (state->added) {
-                       if (astate == NULL) {
-                               astate = arp_new(ifp, &state->addr);
-                               astate->announced_cb =
-                                   dhcp_arp_announced;
-                       }
-                       if (astate) {
-                               arp_announce(astate);
-                               arp_free_but(astate);
-                       }
-               } else
-                       arp_close(ifp);
-#endif
-       }
 }
 
 static void
@@ -2488,6 +2440,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
        size_t auth_len;
        char *msg;
        struct ipv4_addr *ia;
+       struct arp_state *astate;
 
        /* We may have found a BOOTP server */
        if (get_option_uint8(ifp->ctx, &type, dhcp, DHO_MESSAGETYPE) == -1)
@@ -2760,7 +2713,6 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
                    ifo->options &= ~DHCPCD_STATIC;
        }
 
-
        /* No NAK, so reset the backoff
         * We don't reset on an OFFER message because the server could
         * potentially NAK the REQUEST. */
@@ -2777,21 +2729,35 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
        lease->frominfo = 0;
        eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
-#ifndef IN_IFF_TENTATIVE
-       if (ifo->options & DHCPCD_ARP
-           && state->addr.s_addr != state->offer->yiaddr)
-       {
-               addr.s_addr = state->offer->yiaddr;
-               /* If the interface already has the address configured
-                * then we can't ARP for duplicate detection. */
-               ia = ipv4_findaddr(ifp->ctx, &addr);
+       addr.s_addr = state->offer->yiaddr;
+       /* If the interface already has the address configured
+        * then we can't ARP for duplicate detection. */
+       ia = ipv4_findaddr(ifp->ctx, &addr);
+
+#ifdef IN_IFF_TENTATIVE
+       if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) {
+               if ((astate = arp_new(ifp, &addr)) != NULL) {
+                       astate->probed_cb = dhcp_arp_probed;
+                       astate->conflicted_cb = dhcp_arp_conflicted;
+                       astate->announced_cb = dhcp_arp_announced;
+               }
                if (ia == NULL) {
-                       struct arp_state *astate;
+                       struct dhcp_lease l;
 
-                       astate = arp_new(ifp, &addr);
-                       if (astate) {
+                       get_lease(ifp->ctx, &l, state->offer);
+                       /* Add the address now, let the kernel handle DAD. */
+                       ipv4_addaddr(ifp, &l.addr, &l.net, &l.brd);
+               }
+               return;
+       }
+#else
+       if (ifo->options & DHCPCD_ARP) {
+               if (ia == NULL) {
+                       if ((astate = arp_new(ifp, &addr)) != NULL) {
                                astate->probed_cb = dhcp_arp_probed;
                                astate->conflicted_cb = dhcp_arp_conflicted;
+                               astate->announced_cb = dhcp_arp_announced;
+                               /* We need to handle DAD. */
                                arp_probe(astate);
                        }
                        return;
diff --git a/ipv4.c b/ipv4.c
index 5a2b56406de40600f893b25f4c7d90d982ed3830..73bea357cdd3e38edc4b2db8e4207dc09c7b1cfd 100644 (file)
--- a/ipv4.c
+++ b/ipv4.c
@@ -864,52 +864,14 @@ ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease)
                return -1;
 
        state = D_STATE(ifp);
-#ifdef IN_IFF_TENTATIVE
-       state->added |= STATE_ADDED;
-#else
        state->added = STATE_ADDED;
-#endif
+
        state->addr.s_addr = lease->addr.s_addr;
        state->net.s_addr = lease->net.s_addr;
 
        return 0;
 }
 
-static void
-ipv4_finalisert(struct interface *ifp)
-{
-       const struct dhcp_state *state = D_CSTATE(ifp);
-
-       assert(state != NULL);
-
-       /* Find any freshly added routes, such as the subnet route.
-        * We do this because we cannot rely on recieving the kernel
-        * notification right now via our link socket. */
-       if_initrt(ifp);
-       ipv4_buildroutes(ifp->ctx);
-       script_runreason(ifp, state->reason);
-
-       dhcpcd_daemonise(ifp->ctx);
-}
-
-void
-ipv4_finaliseaddr(struct interface *ifp)
-{
-       struct dhcp_state *state = D_STATE(ifp);
-       struct dhcp_lease *lease;
-
-       lease = &state->lease;
-
-       /* Delete the old address if different */
-       if (state->addr.s_addr != lease->addr.s_addr &&
-           state->addr.s_addr != 0 &&
-           ipv4_iffindaddr(ifp, &lease->addr, NULL))
-               delete_address(ifp);
-
-       state->added &= (uint8_t)~(STATE_FAKE | STATE_TENTATIVE);
-       ipv4_finalisert(ifp);
-}
-
 int
 ipv4_preferanother(struct interface *ifp)
 {
@@ -996,7 +958,6 @@ ipv4_applyaddr(void *arg)
                                    ifp->name,
                                    inet_ntoa(lease->addr),
                                    ifn->name);
-                               state->added &= (uint8_t)~STATE_TENTATIVE;
                                return;
                        }
                        logger(ifp->ctx, LOG_INFO, "%s: preferring %s on %s",
@@ -1045,7 +1006,24 @@ ipv4_applyaddr(void *arg)
                return;
 #endif
 
-       ipv4_finaliseaddr(ifp);
+       /* Delete the old address if different */
+       if (state->addr.s_addr != lease->addr.s_addr &&
+           state->addr.s_addr != 0 &&
+           ipv4_iffindaddr(ifp, &lease->addr, NULL))
+               delete_address(ifp);
+
+       state->added = STATE_ADDED;
+       state->addr.s_addr = lease->addr.s_addr;
+       state->net.s_addr = lease->net.s_addr;
+
+       /* Find any freshly added routes, such as the subnet route.
+        * We do this because we cannot rely on recieving the kernel
+        * notification right now via our link socket. */
+       if_initrt(ifp);
+       ipv4_buildroutes(ifp->ctx);
+       script_runreason(ifp, state->reason);
+
+       dhcpcd_daemonise(ifp->ctx);
 }
 
 void
diff --git a/ipv4.h b/ipv4.h
index 53e1b7187a6370a009ed783efe3968bdda300d1f..0fec7628605dbf12ca999ceec70f7fd2f057aa01 100644 (file)
--- a/ipv4.h
+++ b/ipv4.h
@@ -104,10 +104,8 @@ int ipv4_hasaddr(const struct interface *);
 
 #define STATE_ADDED            0x01
 #define STATE_FAKE             0x02
-#define STATE_TENTATIVE                0x04
 
 void ipv4_buildroutes(struct dhcpcd_ctx *);
-void ipv4_finaliseaddr(struct interface *);
 int ipv4_deladdr(struct interface *, const struct in_addr *,
     const struct in_addr *);
 int ipv4_preferanother(struct interface *);