]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
dhcpcd: Simplify carrier handling more by using IS_LINK_UP macro
authorRoy Marples <roy@marples.name>
Tue, 6 Oct 2020 06:10:41 +0000 (07:10 +0100)
committerRoy Marples <roy@marples.name>
Tue, 6 Oct 2020 06:10:41 +0000 (07:10 +0100)
Removes the need for the LINK_DOWN_IFFUP state.
While here, remove the check for IFF_RUNNING when LINK_UNKNOWN
because that is OS specific.

src/arp.c
src/dhcp.c
src/dhcp6.c
src/dhcpcd.c
src/dhcpcd.h
src/ipv6.c
src/ipv6nd.c
src/script.c

index 62602f93c0fe4839dc55599647855089bc47b87c..cc1f8a8903751ed13d0c7fa549008d41baf678eb 100644 (file)
--- a/src/arp.c
+++ b/src/arp.c
@@ -506,7 +506,7 @@ arp_announceaddr(struct dhcpcd_ctx *ctx, const struct in_addr *ia)
        struct ipv4_addr *iap;
 
        TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-               if (!ifp->active || ifp->carrier <= LINK_DOWN)
+               if (!ifp->active || !IS_LINK_UP(ifp))
                        continue;
                iap = ipv4_iffindaddr(ifp, ia, NULL);
                if (iap == NULL)
index 10671c6c6a39812af9ed97268d23c47aa68a70e5..93809628c40e13a53e7a5c78fafc4079bc1fb211 100644 (file)
@@ -1712,7 +1712,7 @@ send_message(struct interface *ifp, uint8_t type,
 
        if (callback == NULL) {
                /* No carrier? Don't bother sending the packet. */
-               if (ifp->carrier <= LINK_DOWN)
+               if (!IS_LINK_UP(ifp))
                        return;
                logdebugx("%s: sending %s with xid 0x%x",
                    ifp->name,
@@ -1731,7 +1731,7 @@ send_message(struct interface *ifp, uint8_t type,
                    (arc4random_uniform(MSEC_PER_SEC * 2) - MSEC_PER_SEC);
                /* No carrier? Don't bother sending the packet.
                 * However, we do need to advance the timeout. */
-               if (ifp->carrier <= LINK_DOWN)
+               if (!IS_LINK_UP(ifp))
                        goto fail;
                logdebugx("%s: sending %s (xid 0x%x), next in %0.1f seconds",
                    ifp->name,
@@ -2633,7 +2633,7 @@ dhcp_reboot(struct interface *ifp)
        state->state = DHS_REBOOT;
        state->interval = 0;
 
-       if (ifo->options & DHCPCD_LINK && ifp->carrier <= LINK_DOWN) {
+       if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) {
                loginfox("%s: waiting for carrier", ifp->name);
                return;
        }
@@ -2733,7 +2733,7 @@ dhcp_drop(struct interface *ifp, const char *reason)
                state->state = DHS_RELEASE;
 
                dhcp_unlink(ifp->ctx, state->leasefile);
-               if (ifp->carrier > LINK_DOWN &&
+               if (IS_LINK_UP(ifp) &&
                    state->new != NULL &&
                    state->lease.server.s_addr != INADDR_ANY)
                {
index 0dbf83332a428880bb73525be8431c2a82225d84..725555f910c32e6650d2f3d6ea3b1b40aca6229f 100644 (file)
@@ -1237,7 +1237,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
        };
        char uaddr[INET6_ADDRSTRLEN];
 
-       if (!callback && ifp->carrier <= LINK_DOWN)
+       if (!callback && !IS_LINK_UP(ifp))
                return 0;
 
        if (!IN6_IS_ADDR_UNSPECIFIED(&state->unicast)) {
@@ -1298,7 +1298,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
                    + (unsigned int)((float)state->RT
                    * ((float)lr / DHCP6_RAND_DIV));
 
-               if (ifp->carrier > LINK_DOWN)
+               if (IS_LINK_UP(ifp))
                        logdebugx("%s: %s %s (xid 0x%02x%02x%02x)%s%s,"
                            " next in %0.1f seconds",
                            ifp->name,
@@ -1320,7 +1320,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
                }
        }
 
-       if (ifp->carrier <= LINK_DOWN)
+       if (!IS_LINK_UP(ifp))
                return 0;
 
        /* Update the elapsed time */
@@ -2906,7 +2906,7 @@ dhcp6_delegate_prefix(struct interface *ifp)
                                if (ia->sla_len == 0) {
                                        /* no SLA configured, so lets
                                         * automate it */
-                                       if (ifd->carrier != LINK_UP) {
+                                       if (!IS_LINK_UP(ifd)) {
                                                logdebugx(
                                                    "%s: has no carrier, cannot"
                                                    " delegate addresses",
@@ -2922,7 +2922,7 @@ dhcp6_delegate_prefix(struct interface *ifp)
                                        sla = &ia->sla[j];
                                        if (strcmp(ifd->name, sla->ifname))
                                                continue;
-                                       if (ifd->carrier != LINK_UP) {
+                                       if (!IS_LINK_UP(ifd)) {
                                                logdebugx(
                                                    "%s: has no carrier, cannot"
                                                    " delegate addresses",
@@ -4029,7 +4029,7 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
                if (drop && options & DHCPCD_RELEASE &&
                    state->state != DH6S_DELEGATED)
                {
-                       if (ifp->carrier == LINK_UP &&
+                       if (IS_LINK_UP(ifp) &&
                            state->state != DH6S_RELEASED &&
                            state->state != DH6S_INFORMED)
                        {
index 604a08ca7f188a3610b5837fe14a057f7a0a28c3..45d467466d083e06119c3ccafbc7fc02a5d7311c 100644 (file)
@@ -97,9 +97,6 @@ const int dhcpcd_signals_ignore[] = {
 const size_t dhcpcd_signals_ignore_len = __arraycount(dhcpcd_signals_ignore);
 #endif
 
-#define IF_UPANDRUNNING(a) \
-       (((a)->flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
-
 const char *dhcpcd_default_script = SCRIPT;
 
 static void
@@ -708,106 +705,110 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
            !(ifp->options->options & DHCPCD_LINK);
 
        ifp->flags = flags;
-       if (carrier == LINK_UNKNOWN) {
-               if (ifp->wireless)
-                       carrier = LINK_DOWN;
-               else
-                       carrier = IF_UPANDRUNNING(ifp) ? LINK_UP : LINK_DOWN;
-       }
+       /* Wireless *must* support link state changes. */
+       if (carrier == LINK_UNKNOWN && ifp->wireless)
+               carrier = LINK_DOWN;
 
        if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
-               if (ifp->carrier != LINK_DOWN) {
-#ifdef NOCARRIER_PRESERVE_IP
-                       if (ifp->flags & IFF_UP &&
-                           (ifp->options == NULL ||
-                           !(ifp->options->options & DHCPCD_ANONYMOUS)))
-                               ifp->carrier = LINK_DOWN_IFFUP;
-                       else
-#endif
-                               ifp->carrier = LINK_DOWN;
-                       if (!ifp->active || nolink)
-                               return;
-                       loginfox("%s: carrier lost", ifp->name);
-                       script_runreason(ifp, "NOCARRIER");
+               if (ifp->carrier == LINK_DOWN)
+                       return;
+               ifp->carrier = LINK_DOWN;
+               if (!ifp->active || nolink)
+                       return;
+               loginfox("%s: carrier lost", ifp->name);
+               script_runreason(ifp, "NOCARRIER");
 #ifdef NOCARRIER_PRESERVE_IP
-                       if (ifp->flags & IFF_UP &&
-                           !(ifp->options->options & DHCPCD_ANONYMOUS))
-                       {
+               if (ifp->flags & IFF_UP &&
+                   !(ifp->options->options & DHCPCD_ANONYMOUS))
+               {
 #ifdef ARP
-                               arp_drop(ifp);
+                       arp_drop(ifp);
 #endif
 #ifdef INET
-                               dhcp_abort(ifp);
+                       dhcp_abort(ifp);
 #endif
 #ifdef DHCP6
-                               dhcp6_abort(ifp);
+                       dhcp6_abort(ifp);
 #endif
-                       } else
+               } else
 #endif
-                               dhcpcd_drop(ifp, 0);
-                       if (ifp->options->options & DHCPCD_ANONYMOUS) {
-                               bool was_up = ifp->flags & IFF_UP;
+                       dhcpcd_drop(ifp, 0);
+               if (ifp->options->options & DHCPCD_ANONYMOUS) {
+                       bool was_up = ifp->flags & IFF_UP;
 
-                               if (was_up)
-                                       if_down(ifp);
-                               if (if_randomisemac(ifp) == -1 && errno != ENXIO)
-                                       logerr(__func__);
-                               if (was_up)
-                                       if_up(ifp);
-                       }
+                       if (was_up)
+                               if_down(ifp);
+                       if (if_randomisemac(ifp) == -1 && errno != ENXIO)
+                               logerr(__func__);
+                       if (was_up)
+                               if_up(ifp);
                }
-       } else if (carrier == LINK_UP && ifp->flags & IFF_UP) {
-               if (ifp->carrier != LINK_UP) {
-                       ifp->carrier = LINK_UP;
-                       if (ifp->active)
-                               loginfox("%s: carrier acquired", ifp->name);
+               return;
+       }
+
+       /*
+        * At this point carrier is NOT DOWN and we have IFF_UP.
+        * We should treat LINK_UNKNOWN as up as the driver may not support
+        * link state changes.
+        * The consideration of any other information about carrier should
+        * be handled in the OS specific if_carrier() function.
+        */
+       if (ifp->carrier == carrier)
+               return;
+       ifp->carrier = carrier;
+       if (ifp->active) {
+               if (carrier == LINK_UNKNOWN)
+                       loginfox("%s: carrier unknown, assuming up", ifp->name);
+               else
+                       loginfox("%s: carrier acquired", ifp->name);
+       }
+
 #if !defined(__linux__) && !defined(__NetBSD__)
-                       /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the
-                        * hardware address changes so we have to go
-                        * through the disovery process to work it out. */
-                       dhcpcd_handleinterface(ifp->ctx, 0, ifp->name);
-#endif
-                       if (ifp->wireless) {
-                               uint8_t ossid[IF_SSIDLEN];
-                               size_t olen;
-
-                               olen = ifp->ssid_len;
-                               memcpy(ossid, ifp->ssid, ifp->ssid_len);
-                               if_getssid(ifp);
-
-                               /* If we changed SSID network, drop leases */
-                               if ((ifp->ssid_len != olen ||
-                                   memcmp(ifp->ssid, ossid, ifp->ssid_len)) &&
-                                   ifp->active)
-                               {
-                                       dhcpcd_reportssid(ifp);
+       /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the
+        * hardware address changes so we have to go
+        * through the disovery process to work it out. */
+       dhcpcd_handleinterface(ifp->ctx, 0, ifp->name);
+#endif
+
+       if (ifp->wireless) {
+               uint8_t ossid[IF_SSIDLEN];
+               size_t olen;
+
+               olen = ifp->ssid_len;
+               memcpy(ossid, ifp->ssid, ifp->ssid_len);
+               if_getssid(ifp);
+
+               /* If we changed SSID network, drop leases */
+               if ((ifp->ssid_len != olen ||
+                   memcmp(ifp->ssid, ossid, ifp->ssid_len)) && ifp->active)
+               {
+                       dhcpcd_reportssid(ifp);
 #ifdef NOCARRIER_PRESERVE_IP
-                                       dhcpcd_drop(ifp, 0);
+                       dhcpcd_drop(ifp, 0);
 #endif
 #ifdef IPV4LL
-                                       ipv4ll_reset(ifp);
+                       ipv4ll_reset(ifp);
 #endif
-                               }
-                       }
-                       if (!ifp->active || nolink)
-                               return;
-                       dhcpcd_initstate(ifp, 0);
-                       script_runreason(ifp, "CARRIER");
+               }
+       }
+
+       if (!ifp->active || nolink)
+               return;
+
+       dhcpcd_initstate(ifp, 0);
+       script_runreason(ifp, "CARRIER");
 #ifdef INET6
 #ifdef NOCARRIER_PRESERVE_IP
-                       /* Set any IPv6 Routers we remembered to expire
-                        * faster than they would normally as we
-                        * maybe on a new network. */
-                       ipv6nd_startexpire(ifp);
+       /* Set any IPv6 Routers we remembered to expire faster than they
+        * would normally as we maybe on a new network. */
+       ipv6nd_startexpire(ifp);
 #endif
 #ifdef IPV6_MANAGETEMPADDR
-                       /* RFC4941 Section 3.5 */
-                       ipv6_regentempaddrs(ifp);
+       /* RFC4941 Section 3.5 */
+       ipv6_regentempaddrs(ifp);
 #endif
 #endif
-                       dhcpcd_startinterface(ifp);
-               }
-       }
+       dhcpcd_startinterface(ifp);
 }
 
 static void
@@ -866,9 +867,7 @@ dhcpcd_startinterface(void *arg)
        struct interface *ifp = arg;
        struct if_options *ifo = ifp->options;
 
-       if (ifo->options & DHCPCD_LINK && (ifp->carrier == LINK_DOWN ||
-           (ifp->carrier == LINK_UNKNOWN && !IF_UPANDRUNNING(ifp))))
-       {
+       if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) {
                loginfox("%s: waiting for carrier", ifp->name);
                return;
        }
@@ -959,7 +958,7 @@ dhcpcd_prestartinterface(void *arg)
        struct dhcpcd_ctx *ctx = ifp->ctx;
        bool anondown;
 
-       if (ifp->carrier == LINK_DOWN &&
+       if (ifp->carrier <= LINK_DOWN &&
            ifp->options->options & DHCPCD_ANONYMOUS &&
            ifp->flags & IFF_UP)
        {
@@ -1357,8 +1356,7 @@ dhcpcd_ifrenew(struct interface *ifp)
        if (!ifp->active)
                return;
 
-       if (ifp->options->options & DHCPCD_LINK &&
-           ifp->carrier == LINK_DOWN)
+       if (ifp->options->options & DHCPCD_LINK && !IS_LINK_UP(ifp))
                return;
 
 #ifdef INET
index d2c90c1ce75e552a5506313b022732cbef49985f..bbc125c3d8155cf5fafdbdc4316254b90fb61b29 100644 (file)
@@ -55,7 +55,7 @@
 #define        LINK_UP         1
 #define        LINK_UNKNOWN    0
 #define        LINK_DOWN       -1
-#define        LINK_DOWN_IFFUP -2
+#define        IS_LINK_UP(ifp) (((ifp)->flags & IFF_UP) && (ifp)->carrier != LINK_DOWN)
 
 #define IF_DATA_IPV4   0
 #define IF_DATA_ARP    1
index 5442ebdedc3ad8b26c817991f95f2d6c1597600b..78996314c7a207d0b936c6c81d4dfe94e60fd071 100644 (file)
     defined(IFF_NOLINKLOCAL)
 /* Only add the LL address if we have a carrier, so DaD works. */
 #define        CAN_ADD_LLADDR(ifp) \
-    (!((ifp)->options->options & DHCPCD_LINK) || (ifp)->carrier != LINK_DOWN)
+    (!((ifp)->options->options & DHCPCD_LINK) || IS_LINK_UP((ifp)))
 #ifdef __sun
 /* Although we can add our own LL address, we cannot drop it
  * without unplumbing the if which is a lot of code.
index 4afbf1fbad6f5abdf100d929f78b329f2d7888fe..63d311a57a35c3d8e2c62b5cc913d456cffb9063 100644 (file)
@@ -437,7 +437,7 @@ ipv6nd_sendadvertisement(void *arg)
        const struct rs_state *state = RS_CSTATE(ifp);
        int s;
 
-       if (state == NULL || ifp->carrier <= LINK_DOWN)
+       if (state == NULL || !IS_LINK_UP(ifp))
                goto freeit;
 
 #ifdef SIN6_LEN
@@ -505,7 +505,7 @@ ipv6nd_advertise(struct ipv6_addr *ia)
        iaf = NULL;
        TAILQ_FOREACH(ifp, ctx->ifaces, next) {
                state = IPV6_STATE(ifp);
-               if (state == NULL || ifp->carrier <= LINK_DOWN)
+               if (state == NULL || !IS_LINK_UP(ifp))
                        continue;
 
                TAILQ_FOREACH(iap, &state->addrs, next) {
index d611a644c65b7caa75b2db7ff83ce1a07d1481ec..ce48b3bac53d8b52151e6ae9aa2678862eb59ac6 100644 (file)
@@ -589,7 +589,6 @@ send_interface(struct fd_list *fd, const struct interface *ifp, int af)
                        reason = "CARRIER";
                        break;
                case LINK_DOWN:
-               case LINK_DOWN_IFFUP:
                        reason = "NOCARRIER";
                        break;
                default: