]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
dhcpcd: Simplify the link handling even more
authorRoy Marples <roy@marples.name>
Wed, 7 Oct 2020 13:11:47 +0000 (14:11 +0100)
committerRoy Marples <roy@marples.name>
Wed, 7 Oct 2020 13:11:47 +0000 (14:11 +0100)
Move the IS_LINK_UP macro to if_is_link_up function to reduce
binary size.
Rather than DHCPCD_LINK option controlling the carrier state,
use it in if_is_link_up to determine the outcome.

src/arp.c
src/dhcp.c
src/dhcp6.c
src/dhcpcd.c
src/dhcpcd.h
src/if-bsd.c
src/if.c
src/if.h
src/ipv6.c
src/ipv6nd.c

index cc1f8a8903751ed13d0c7fa549008d41baf678eb..6f24ebf73f4a76989140782ad17a71949b193706 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 || !IS_LINK_UP(ifp))
+               if (!ifp->active || !if_is_link_up(ifp))
                        continue;
                iap = ipv4_iffindaddr(ifp, ia, NULL);
                if (iap == NULL)
index 93809628c40e13a53e7a5c78fafc4079bc1fb211..cbfb2bc8f8c8e9dc9606f1873b1b3cf436cdfb8a 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 (!IS_LINK_UP(ifp))
+               if (!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 (!IS_LINK_UP(ifp))
+               if (!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 && !IS_LINK_UP(ifp)) {
+       if (ifo->options & DHCPCD_LINK && !if_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 (IS_LINK_UP(ifp) &&
+               if (if_is_link_up(ifp) &&
                    state->new != NULL &&
                    state->lease.server.s_addr != INADDR_ANY)
                {
index 725555f910c32e6650d2f3d6ea3b1b40aca6229f..eda42e209bf1ddb6fae71a64632cd77f23045e8b 100644 (file)
@@ -1237,7 +1237,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
        };
        char uaddr[INET6_ADDRSTRLEN];
 
-       if (!callback && !IS_LINK_UP(ifp))
+       if (!callback && !if_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 (IS_LINK_UP(ifp))
+               if (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 (!IS_LINK_UP(ifp))
+       if (!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 (!IS_LINK_UP(ifd)) {
+                                       if (!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 (!IS_LINK_UP(ifd)) {
+                                       if (!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 (IS_LINK_UP(ifp) &&
+                       if (if_is_link_up(ifp) &&
                            state->state != DH6S_RELEASED &&
                            state->state != DH6S_INFORMED)
                        {
index 45d467466d083e06119c3ccafbc7fc02a5d7311c..8f429bc5def7df0f4089b1e83b4730e654b1fedb 100644 (file)
@@ -701,19 +701,13 @@ dhcpcd_reportssid(struct interface *ifp)
 void
 dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
 {
-       bool nolink = ifp->options == NULL ||
-           !(ifp->options->options & DHCPCD_LINK);
+       bool was_link_up = if_is_link_up(ifp);
 
+       ifp->carrier = carrier;
        ifp->flags = flags;
-       /* 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)
-                       return;
-               ifp->carrier = LINK_DOWN;
-               if (!ifp->active || nolink)
+       if (!if_is_link_up(ifp)) {
+               if (!was_link_up || !ifp->active)
                        return;
                loginfox("%s: carrier lost", ifp->name);
                script_runreason(ifp, "NOCARRIER");
@@ -734,13 +728,13 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
 #endif
                        dhcpcd_drop(ifp, 0);
                if (ifp->options->options & DHCPCD_ANONYMOUS) {
-                       bool was_up = ifp->flags & IFF_UP;
+                       bool is_up = ifp->flags & IFF_UP;
 
-                       if (was_up)
+                       if (is_up)
                                if_down(ifp);
                        if (if_randomisemac(ifp) == -1 && errno != ENXIO)
                                logerr(__func__);
-                       if (was_up)
+                       if (is_up)
                                if_up(ifp);
                }
                return;
@@ -753,9 +747,9 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
         * The consideration of any other information about carrier should
         * be handled in the OS specific if_carrier() function.
         */
-       if (ifp->carrier == carrier)
+       if (was_link_up)
                return;
-       ifp->carrier = carrier;
+
        if (ifp->active) {
                if (carrier == LINK_UNKNOWN)
                        loginfox("%s: carrier unknown, assuming up", ifp->name);
@@ -792,7 +786,7 @@ dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
                }
        }
 
-       if (!ifp->active || nolink)
+       if (!ifp->active)
                return;
 
        dhcpcd_initstate(ifp, 0);
@@ -867,7 +861,7 @@ dhcpcd_startinterface(void *arg)
        struct interface *ifp = arg;
        struct if_options *ifo = ifp->options;
 
-       if (ifo->options & DHCPCD_LINK && !IS_LINK_UP(ifp)) {
+       if (ifo->options & DHCPCD_LINK && !if_is_link_up(ifp)) {
                loginfox("%s: waiting for carrier", ifp->name);
                return;
        }
@@ -989,7 +983,7 @@ run_preinit(struct interface *ifp)
                return;
 
        script_runreason(ifp, "PREINIT");
-       if (ifp->wireless && ifp->carrier == LINK_UP)
+       if (ifp->wireless && if_is_link_up(ifp))
                dhcpcd_reportssid(ifp);
        if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN)
                script_runreason(ifp,
@@ -1356,7 +1350,7 @@ dhcpcd_ifrenew(struct interface *ifp)
        if (!ifp->active)
                return;
 
-       if (ifp->options->options & DHCPCD_LINK && !IS_LINK_UP(ifp))
+       if (ifp->options->options & DHCPCD_LINK && !if_is_link_up(ifp))
                return;
 
 #ifdef INET
@@ -2461,8 +2455,7 @@ printpidfile:
        TAILQ_FOREACH(ifp, ctx.ifaces, next) {
                if (ifp->active) {
                        run_preinit(ifp);
-                       if (!(ifp->options->options & DHCPCD_LINK) ||
-                           ifp->carrier != LINK_DOWN)
+                       if (if_is_link_up(ifp))
                                opt = 1;
                }
        }
index bbc125c3d8155cf5fafdbdc4316254b90fb61b29..8cdd3c191040e8d0a233562245f88e13b8d1d181 100644 (file)
@@ -55,7 +55,6 @@
 #define        LINK_UP         1
 #define        LINK_UNKNOWN    0
 #define        LINK_DOWN       -1
-#define        IS_LINK_UP(ifp) (((ifp)->flags & IFF_UP) && (ifp)->carrier != LINK_DOWN)
 
 #define IF_DATA_IPV4   0
 #define IF_DATA_ARP    1
index 8f10acdcf14d25909047260be3779f2939efd29b..94f58b319d06fb56c68a4f2b1900044455a3268d 100644 (file)
@@ -385,7 +385,7 @@ static int if_indirect_ioctl(struct dhcpcd_ctx *ctx,
 }
 
 int
-if_carrier(__unused struct interface *ifp, const void *ifadata)
+if_carrier(struct interface *ifp, const void *ifadata)
 {
        const struct if_data *ifi = ifadata;
 
@@ -398,8 +398,15 @@ if_carrier(__unused struct interface *ifp, const void *ifadata)
 
        if (ifi->ifi_link_state >= LINK_STATE_UP)
                return LINK_UP;
-       if (ifi->ifi_link_state == LINK_STATE_UNKNOWN)
+       if (ifi->ifi_link_state == LINK_STATE_UNKNOWN) {
+               /*
+                * Work around net80211 issues in some BSDs.
+                * Wireless MUST support link state change.
+                */
+               if (ifp->wireless)
+                       return LINK_DOWN;
                return LINK_UNKNOWN;
+       }
        return LINK_DOWN;
 }
 
index 67586150bc0bea200cd29d6e9bda943b81894bf3..d21625efc383f1ca444cdbf105096f31c5b99def 100644 (file)
--- a/src/if.c
+++ b/src/if.c
@@ -193,6 +193,17 @@ if_setflag(struct interface *ifp, short setflag, short unsetflag)
        return 0;
 }
 
+bool
+if_is_link_up(const struct interface *ifp)
+{
+
+       return ifp->flags & IFF_UP &&
+           (ifp->carrier == LINK_UP ||
+            (ifp->carrier == LINK_UNKNOWN &&
+             !(ifp->options == NULL ||
+               ifp->options->options & DHCPCD_LINK)));
+}
+
 int
 if_randomisemac(struct interface *ifp)
 {
@@ -692,12 +703,6 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
 
                ifp->active = active;
                ifp->carrier = if_carrier(ifp, ifa->ifa_data);
-
-               /* Wireless devices must support carrier change,
-                * so treat UNKNOWN as down. */
-               if (ifp->wireless && ifp->carrier == LINK_UNKNOWN)
-                       ifp->carrier = LINK_DOWN;
-
                TAILQ_INSERT_TAIL(ifs, ifp, next);
        }
 
index fc046820bca4b621900b25d9c0b2194986857037..8474deb70d71a0093657383e98cd658a3dd3821f 100644 (file)
--- a/src/if.h
+++ b/src/if.h
@@ -146,6 +146,7 @@ int if_getflags(struct interface *);
 int if_setflag(struct interface *, short, short);
 #define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING), 0)
 #define if_down(ifp) if_setflag((ifp), 0, IFF_UP);
+bool if_is_link_up(const struct interface *);
 bool if_valid_hwaddr(const uint8_t *, size_t);
 struct if_head *if_discover(struct dhcpcd_ctx *, struct ifaddrs **,
     int, char * const *);
index 78996314c7a207d0b936c6c81d4dfe94e60fd071..3f0c1d8cf941f2c0d758e51b4674ac8409fb4723 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) || IS_LINK_UP((ifp)))
+    (!((ifp)->options->options & DHCPCD_LINK) || if_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 63d311a57a35c3d8e2c62b5cc913d456cffb9063..1c082ae4a2b2be3a60d11518815417763fdd3892 100644 (file)
@@ -437,7 +437,7 @@ ipv6nd_sendadvertisement(void *arg)
        const struct rs_state *state = RS_CSTATE(ifp);
        int s;
 
-       if (state == NULL || !IS_LINK_UP(ifp))
+       if (state == NULL || !if_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 || !IS_LINK_UP(ifp))
+               if (state == NULL || !if_is_link_up(ifp))
                        continue;
 
                TAILQ_FOREACH(iap, &state->addrs, next) {